嵌入式51单片机实验程序1

1.点亮一个流水灯

#include "reg52.h"

#include "intrins.h"

typedef unsigned int u16; //对系统默认数据类型进行重定义

typedef unsigned char u8;

 

#define LED_PORT P2 //使用宏定义P2端口

/*******************************************************************************

* 函 数 名       : delay_10us

* 函数功能  : 延时函数,ten_us=1时,大约延时10us

* 输    入       : ten_us

* 输    出      : 无

*******************************************************************************/

void delay_10us(u16 ten_us)

{

while(ten_us--);

}

void main()

{

    u8 i=0;

 

LED_PORT=~0x01;

delay_10us(50000);

while(1)

{

//方法1:使用移位+循环实现流水灯

    for(i=0;i<8;i++)

{

   LED_PORT=~(0x01<<i); //将1右移i位,然后取反将结果赋值到LED_PORT

   delay_10us(50000);

}

 

//方法2:使用循环+_crol_或_cror_函数实现流水灯

/* for(i=0;i<7;i++)  //将led左移一位

{   

LED_PORT=_crol_(LED_PORT,1);

delay_10us(50000);

}

for(i=0;i<7;i++) //将led右移一位

{

LED_PORT=_cror_(LED_PORT,1);

delay_10us(50000);

} */

}

}

2.灯闪烁

#include "reg52.h"

 

typedef unsigned int u16; //对系统默认数据类型进行重定义

typedef unsigned char u8;

 

sbit LED1=P2^0; //将P2.0管脚定义为LED1

/*******************************************************************************

* 函 数 名       : delay_10us

* 函数功能  : 延时函数,ten_us=1时,大约延时10us

* 输    入       : ten_us

* 输    出      : 无

*******************************************************************************/

void delay_10us(u16 ten_us)

{

while(ten_us--);

}

void main()

{

while(1)

{

LED1=0; //点亮

delay_10us(50000); //大约延时450ms

LED1=1; //熄灭

delay_10us(50000);

}

}

3实验名称:LED流水灯实验

接线说明:

实验现象:下载程序后“LED模块”的D1-D8指示左右点亮

注意事项:   

***************************************************************************************/

#include "reg52.h"

#include "intrins.h"

 

typedef unsigned int u16; //对系统默认数据类型进行重定义

typedef unsigned char u8;

 

#define LED_PORT P2 //使用宏定义P2端口

 

/*******************************************************************************

* 函 数 名       : delay_10us

* 函数功能  : 延时函数,ten_us=1时,大约延时10us

* 输    入       : ten_us

* 输    出      : 无

*******************************************************************************/

void delay_10us(u16 ten_us)

{

while(ten_us--);

}

/*******************************************************************************

* 函 数 名       : main

* 函数功能  : 主函数

* 输    入       : 无

* 输    出      : 无

*******************************************************************************/

void main()

{

    u8 i=0;

 

LED_PORT=~0x01;

delay_10us(50000);

while(1)

{

//方法1:使用移位+循环实现流水灯

    for(i=0;i<8;i++)

{

   LED_PORT=~(0x01<<i); //将1右移i位,然后取反将结果赋值到LED_PORT

   delay_10us(50000);

}

 

//方法2:使用循环+_crol_或_cror_函数实现流水灯

/* for(i=0;i<7;i++)  //将led左移一位

{   

LED_PORT=_crol_(LED_PORT,1);

delay_10us(50000);

}

for(i=0;i<7;i++) //将led右移一位

{

LED_PORT=_cror_(LED_PORT,1);

delay_10us(50000);

} */

}

}

4.蜂鸣器

#include "reg52.h"

 

typedef unsigned int u16; //对系统默认数据类型进行重定义

typedef unsigned char u8;

 

sbit BEEP=P2^5; //将P2.5管脚定义为BEEP

 

void delay_10us(u16 ten_us)

{

while(ten_us--);

}

 

void main()

{

u16 i=2000;

 

while(1)

{

    while(i--)//循环2000次

{

BEEP=!BEEP;//产生一定频率的脉冲信号

delay_10us(100);

}

i=0;//清零

BEEP=0;//关闭蜂鸣器

}

}

5.实验名称:静态数码管实验

接线说明:

实验现象:下载程序后“数码管模块”最左边数码管显示数字0

注意事项:   

***************************************************************************************/

#include "reg52.h"

 

typedef unsigned int u16; //对系统默认数据类型进行重定义

typedef unsigned char u8;

 

#define SMG_A_DP_PORT P0 //使用宏定义数码管段码口

 

//共阴极数码管显示0~F的段码数据

u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

/******************************************************************************

* 函 数 名       : main

* 函数功能  : 主函数

* 输    入       : 无

* 输    出      : 无

*******************************************************************************/

void main()

{

SMG_A_DP_PORT=gsmg_code[0];//将数组第1个数据赋值给数码管段选口

while(1)

{

   

}

}

6.实验名称:动态数码管实验

实验现象:下载程序后“数码管模块”显示01234567   

***************************************************************************************/

#include "reg52.h"

 

typedef unsigned int u16; //对系统默认数据类型进行重定义

typedef unsigned char u8;

 

#define SMG_A_DP_PORT P0 //使用宏定义数码管段码口

 

//定义数码管位选信号控制脚

sbit LSA=P2^2;

sbit LSB=P2^3;

sbit LSC=P2^4;

 

//共阴极数码管显示0~F的段码数据

u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

/******************************************************************************

* 函 数 名       : delay_10us

* 函数功能  : 延时函数,ten_us=1时,大约延时10us

* 输    入       : ten_us

* 输    出      : 无

*******************************************************************************/

void delay_10us(u16 ten_us)

{

while(ten_us--);

}

/******************************************************************************

* 函 数 名       : smg_display

* 函数功能  : 动态数码管显示

* 输    入       : 无

* 输    出      : 无

*******************************************************************************/

void smg_display(void)

{

u8 i=0;

 

for(i=0;i<8;i++)

{

    switch(i)//位选

{

case 0: LSC=1;LSB=1;LSA=1;break;

case 1: LSC=1;LSB=1;LSA=0;break;

case 2: LSC=1;LSB=0;LSA=1;break;

case 3: LSC=1;LSB=0;LSA=0;break;

case 4: LSC=0;LSB=1;LSA=1;break;

case 5: LSC=0;LSB=1;LSA=0;break;

case 6: LSC=0;LSB=0;LSA=1;break;

case 7: LSC=0;LSB=0;LSA=0;break;

}

SMG_A_DP_PORT=gsmg_code[i];//传送段选数据

delay_10us(100);//延时一段时间,等待显示稳定

SMG_A_DP_PORT=0x00;//消音

}

}

void main()

{

while(1)

{

    smg_display();

}

}

7.实验名称:独立按键实验

实验现象:下载程序后,按下“独立按键”模块中K1键,控制D1指示灯亮灭

***************************************************************************************/

#include "reg52.h"

 

typedef unsigned int u16; //对系统默认数据类型进行重定义

typedef unsigned char u8;

 

//定义独立按键控制脚

sbit KEY1=P3^1;

sbit KEY2=P3^0;

sbit KEY3=P3^2;

sbit KEY4=P3^3;

 

//定义LED1控制脚

sbit LED1=P2^0;

 

//使用宏定义独立按键按下的键值

#define KEY1_PRESS 1

#define KEY2_PRESS 2

#define KEY3_PRESS 3

#define KEY4_PRESS 4

#define KEY_UNPRESS 0

 

/*******************************************************************************

* 函 数 名       : delay_10us

* 函数功能  : 延时函数,ten_us=1时,大约延时10us

* 输    入       : ten_us

* 输    出      : 无

*******************************************************************************/

void delay_10us(u16 ten_us)

{

while(ten_us--);

}

/******************************************************************************

* 函 数 名       : key_scan

* 函数功能  : 检测独立按键是否按下,按下则返回对应键值

* 输    入       : mode=0:单次扫描按键

   mode=1:连续扫描按键

* 输    出      : KEY1_PRESS:K1按下

   KEY2_PRESS:K2按下

   KEY3_PRESS:K3按下

   KEY4_PRESS:K4按下

   KEY_UNPRESS:未有按键按下

*******************************************************************************/

u8 key_scan(u8 mode)

{

static u8 key=1;

 

if(mode)key=1;//连续扫描按键

if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))//任意按键按下

{

delay_10us(1000);//消抖

key=0;

if(KEY1==0)

return KEY1_PRESS;

else if(KEY2==0)

return KEY2_PRESS;

else if(KEY3==0)

return KEY3_PRESS;

else if(KEY4==0)

return KEY4_PRESS;

}

else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1) //无按键按下

{

key=1;

}

return KEY_UNPRESS;

}

void main()

{

u8 key=0;

 

while(1)

{

    key=key_scan(0);

if(key==KEY1_PRESS)//检测按键K1是否按下

LED1=!LED1;//LED1状态翻转

}

}

8.实验名称:矩阵按键实验

实验现象:下载程序后,按下“矩阵按键”模块中S1-S16键,对应数码管最左边显示0-F  

***************************************************************************************/

#include "reg52.h"

 

typedef unsigned int u16; //对系统默认数据类型进行重定义

typedef unsigned char u8;

 

#define KEY_MATRIX_PORT P1 //使用宏定义矩阵按键控制口

 

#define SMG_A_DP_PORT P0 //使用宏定义数码管段码口

 

//共阴极数码管显示0~F的段码数据

u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

/******************************************************************************

* 函 数 名       : delay_10us

* 函数功能  : 延时函数,ten_us=1时,大约延时10us

* 输    入       : ten_us

* 输    出      : 无

*******************************************************************************/

void delay_10us(u16 ten_us)

{

while(ten_us--);

}

/******************************************************************************

* 函 数 名       : key_matrix_ranks_scan

* 函数功能  : 使用行列式扫描方法,检测矩阵按键是否按下,按下则返回对应键值

* 输    入       : 无

* 输    出      : key_value:1-16,对应S1-S16键,

   0:按键未按下

*******************************************************************************/

u8 key_matrix_ranks_scan(void)

{

u8 key_value=0;

 

KEY_MATRIX_PORT=0xf7;//给第一列赋值0,其余全为1

if(KEY_MATRIX_PORT!=0xf7)//判断第一列按键是否按下

{

delay_10us(1000);//消抖

switch(KEY_MATRIX_PORT)//保存第一列按键按下后的键值

{

case 0x77: key_value=1;break;

case 0xb7: key_value=5;break;

case 0xd7: key_value=9;break;

case 0xe7: key_value=13;break;

}

}

while(KEY_MATRIX_PORT!=0xf7);//等待按键松开

 

KEY_MATRIX_PORT=0xfb;//给第二列赋值0,其余全为1

if(KEY_MATRIX_PORT!=0xfb)//判断第二列按键是否按下

{

delay_10us(1000);//消抖

switch(KEY_MATRIX_PORT)//保存第二列按键按下后的键值

{

case 0x7b: key_value=2;break;

case 0xbb: key_value=6;break;

case 0xdb: key_value=10;break;

case 0xeb: key_value=14;break;

}

}

while(KEY_MATRIX_PORT!=0xfb);//等待按键松开

 

KEY_MATRIX_PORT=0xfd;//给第三列赋值0,其余全为1

if(KEY_MATRIX_PORT!=0xfd)//判断第三列按键是否按下

{

delay_10us(1000);//消抖

switch(KEY_MATRIX_PORT)//保存第三列按键按下后的键值

{

case 0x7d: key_value=3;break;

case 0xbd: key_value=7;break;

case 0xdd: key_value=11;break;

case 0xed: key_value=15;break;

}

}

while(KEY_MATRIX_PORT!=0xfd);//等待按键松开

 

KEY_MATRIX_PORT=0xfe;//给第四列赋值0,其余全为1

if(KEY_MATRIX_PORT!=0xfe)//判断第四列按键是否按下

{

delay_10us(1000);//消抖

switch(KEY_MATRIX_PORT)//保存第四列按键按下后的键值

{

case 0x7e: key_value=4;break;

case 0xbe: key_value=8;break;

case 0xde: key_value=12;break;

case 0xee: key_value=16;break;

}

}

while(KEY_MATRIX_PORT!=0xfe);//等待按键松开

 

return key_value;

}

/******************************************************************************

* 函 数 名       : key_matrix_flip_scan

* 函数功能  : 使用线翻转扫描方法,检测矩阵按键是否按下,按下则返回对应键值

* 输    入       : 无

* 输    出      : key_value:1-16,对应S1-S16键,

   0:按键未按下

*******************************************************************************/

u8 key_matrix_flip_scan(void)

{

static u8 key_value=0;

 

KEY_MATRIX_PORT=0x0f;//给所有行赋值0,列全为1

if(KEY_MATRIX_PORT!=0x0f)//判断按键是否按下

{

delay_10us(1000);//消抖

if(KEY_MATRIX_PORT!=0x0f)

{

//测试列

KEY_MATRIX_PORT=0x0f;

switch(KEY_MATRIX_PORT)//保存行为0,按键按下后的列值

{

case 0x07: key_value=1;break;

case 0x0b: key_value=2;break;

case 0x0d: key_value=3;break;

case 0x0e: key_value=4;break;

}

//测试行

KEY_MATRIX_PORT=0xf0;

switch(KEY_MATRIX_PORT)//保存列为0,按键按下后的键值

{

case 0x70: key_value=key_value;break;

case 0xb0: key_value=key_value+4;break;

case 0xd0: key_value=key_value+8;break;

case 0xe0: key_value=key_value+12;break;

}

while(KEY_MATRIX_PORT!=0xf0);//等待按键松开

}

}

else

key_value=0;

 

return key_value;

}

/******************************************************************************

* 函 数 名       : main

* 函数功能  : 主函数

* 输    入       : 无

* 输    出      : 无

*******************************************************************************/

void main()

{

u8 key=0;

 

while(1)

{

    key=key_matrix_ranks_scan();

if(key!=0)

SMG_A_DP_PORT=gsmg_code[key-1];//得到的按键值减1换算成数组下标对应0-F段码

}

}

9.实验名称:IO扩展(串转并)实验-74HC595

接线说明:

实验现象:下载程序后,8*8LED点阵以一行循环滚动显示

注意事项:LED点阵旁的J24黄色跳线帽短接到GND一端   

***************************************************************************************/

#include "reg52.h"

 

typedef unsigned int u16; //对系统默认数据类型进行重定义

typedef unsigned char u8;

 

//定义74HC595控制管脚

sbit SRCLK=P3^6; //移位寄存器时钟输入

sbit RCLK=P3^5; //存储寄存器时钟输入

sbit SER=P3^4; //串行数据输入

 

#define LEDDZ_COL_PORT P0 //点阵列控制端口

 

u8 ghc595_buf[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

 

/******************************************************************************

* 函 数 名       : delay_10us

* 函数功能  : 延时函数,ten_us=1时,大约延时10us

* 输    入       : ten_us

* 输    出      : 无

*******************************************************************************/

void delay_10us(u16 ten_us)

{

while(ten_us--);

}

/******************************************************************************

* 函 数 名       : delay_ms

* 函数功能  : ms延时函数,ms=1时,大约延时1ms

* 输    入       : ten_us

* 输    出      : 无

*******************************************************************************/

void delay_ms(u16 ms)

{

u16 i,j;

for(i=ms;i>0;i--)

for(j=110;j>0;j--);

}

/******************************************************************************

* 函 数 名         : hc595_write_data(u8 dat)

* 函数功能    : 向74HC595写入一个字节的数据

* 输    入         : dat:数据

* 输    出         : 无

*******************************************************************************/

void hc595_write_data(u8 dat)

{

u8 i=0;

 

for(i=0;i<8;i++)//循环8次即可将一个字节写入寄存器中

{

SER=dat>>7;//优先传输一个字节中的高位

dat<<=1;//将低位移动到高位

SRCLK=0;

delay_10us(1);

SRCLK=1;

delay_10us(1);//移位寄存器时钟上升沿将端口数据送入寄存器中

}

RCLK=0;

delay_10us(1);

RCLK=1;//存储寄存器时钟上升沿将前面写入到寄存器的数据输出

}

/******************************************************************************

* 函 数 名       : main

* 函数功能  : 主函数

* 输    入       : 无

* 输    出      : 无

*******************************************************************************/

void main()

{

u8 i=0;

 

LEDDZ_COL_PORT=0x00;//将LED点阵列全部设置为0,即LED阴极为低电平

while(1)

{

for(i=0;i<8;i++)

{

hc595_write_data(0x00);//消除前面寄存器缓存数据

hc595_write_data(ghc595_buf[i]);//写入新的数据

delay_ms(500);//延时500ms

}

}

}

11.实验名称:LED点阵实验(显示数字)

接线说明:

实验现象:下载程序后,8*8LED点阵显示数字0

注意事项:LED点阵旁的J24黄色跳线帽短接到GND一端   

***************************************************************************************/

#include "reg52.h"

 

typedef unsigned int u16; //对系统默认数据类型进行重定义

typedef unsigned char u8;

 

//定义74HC595控制管脚

sbit SRCLK=P3^6; //移位寄存器时钟输入

sbit RCLK=P3^5; //存储寄存器时钟输入

sbit SER=P3^4; //串行数据输入

 

#define LEDDZ_COL_PORT P0 //点阵列控制端口

 

u8 gled_row[8]={0x00,0x7C,0x82,0x82,0x82,0x7C,0x00,0x00};//LED点阵显示数字0的行数据

u8 gled_col[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//LED点阵显示数字0的列数据

/******************************************************************************

* 函 数 名       : delay_10us

* 函数功能  : 延时函数,ten_us=1时,大约延时10us

* 输    入       : ten_us

* 输    出      : 无

*******************************************************************************/

void delay_10us(u16 ten_us)

{

while(ten_us--);

}

 

/*******************************************************************************

* 函 数 名         : hc595_write_data(u8 dat)

* 函数功能    : 向74HC595写入一个字节的数据

* 输    入         : dat:数据

* 输    出         : 无

*******************************************************************************/

void hc595_write_data(u8 dat)

{

u8 i=0;

 

for(i=0;i<8;i++)//循环8次即可将一个字节写入寄存器中

{

SER=dat>>7;//优先传输一个字节中的高位

dat<<=1;//将低位移动到高位

SRCLK=0;

delay_10us(1);

SRCLK=1;

delay_10us(1);//移位寄存器时钟上升沿将端口数据送入寄存器中

}

RCLK=0;

delay_10us(1);

RCLK=1;//存储寄存器时钟上升沿将前面写入到寄存器的数据输出

}

/*******************************************************************************

* 函 数 名       : main

* 函数功能  : 主函数

* 输    入       : 无

* 输    出      : 无

*******************************************************************************/

void main()

{

u8 i=0;

 

while(1)

{

for(i=0;i<8;i++)//循环8次扫描8行、列

{

LEDDZ_COL_PORT=gled_col[i];//传送列选数据

hc595_write_data(gled_row[i]);//传送行选数据

delay_10us(100);//延时一段时间,等待显示稳定

hc595_write_data(0x00);//消影

}

}

}

12.实验名称:LED点阵实验(显示图像)

实验现象:下载程序后,8*8LED点阵显示心形

注意事项:LED点阵旁的J24黄色跳线帽短接到GND一端   

***************************************************************************************/

#include "reg52.h"

 

typedef unsigned int u16; //对系统默认数据类型进行重定义

typedef unsigned char u8;

 

//定义74HC595控制管脚

sbit SRCLK=P3^6; //移位寄存器时钟输入

sbit RCLK=P3^5; //存储寄存器时钟输入

sbit SER=P3^4; //串行数据输入

 

#define LEDDZ_COL_PORT P0 //点阵列控制端口

 

u8 gled_row[8]={0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38};//LED点阵显示图像的行数据

u8 gled_col[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//LED点阵显示图像的列数据

/******************************************************************************

* 函 数 名       : delay_10us

* 函数功能  : 延时函数,ten_us=1时,大约延时10us

* 输    入       : ten_us

* 输    出      : 无

*******************************************************************************/

void delay_10us(u16 ten_us)

{

while(ten_us--);

}

/******************************************************************************

* 函 数 名         : hc595_write_data(u8 dat)

* 函数功能    : 向74HC595写入一个字节的数据

* 输    入         : dat:数据

* 输    出         : 无

*******************************************************************************/

void hc595_write_data(u8 dat)

{

u8 i=0;

 

for(i=0;i<8;i++)//循环8次即可将一个字节写入寄存器中

{

SER=dat>>7;//优先传输一个字节中的高位

dat<<=1;//将低位移动到高位

SRCLK=0;

delay_10us(1);

SRCLK=1;

delay_10us(1);//移位寄存器时钟上升沿将端口数据送入寄存器中

}

RCLK=0;

delay_10us(1);

RCLK=1;//存储寄存器时钟上升沿将前面写入到寄存器的数据输出

}

/******************************************************************************

* 函 数 名       : main

* 函数功能  : 主函数

* 输    入       : 无

* 输    出      : 无

*******************************************************************************/

void main()

{

u8 i=0;

 

while(1)

{

for(i=0;i<8;i++)//循环8次扫描8行、列

{

LEDDZ_COL_PORT=gled_col[i];//传送列选数据

hc595_write_data(gled_row[i]);//传送行选数据

delay_10us(100);//延时一段时间,等待显示稳定

hc595_write_data(0x00);//消影

}

}

}

posted on 2022-06-04 16:29  丰sir  阅读(408)  评论(0)    收藏  举报