这一章,讲用程序控制 单片机输出I/O口的电平高低,进而控制 外围设备的实例。需要注意地, 51单片机上电后,默认输出高电平。上一章的很多程序模块,可直接拿来使用。
2.1 简单的控制实例——蜂鸣器
假设蜂鸣器的引脚和单片机的P3.7口相连。现在要让蜂鸣器大约响500ms,然后关闭。
程序是:
#includereg52.h
#define uint unsigned int
#define uchar unsigned char //宏定义
sbit beep=P3^7;
void delay() //延时500ms
{
uint x,y;
for(x=100;x0;x--)
for(y=580;y0;y--);
}
void main()
{
beep=0; //开蜂鸣器
delay();
beep=1; // 关蜂鸣器
while(1);
}
2.2 流水灯
流水灯由八个发光二极管组成,刚好是一个字节,发光二极管共阴极,它们的阳极与单片机的P0相连。可见,默认流水灯全亮。
例程1 发光二极管偶数灯和奇数灯交替亮500ms,偶数灯先亮。
#includereg52.h
#define uint unsigned int
#define uchar unsigned char //宏定义
void delay() //延时500ms
{
uint x,y;
for(x=100;x0;x--)
for(y=580;y0;y--);
}
void main()
{
while(1)
{
P0=0x55;
delay();
P0=~P0; //~表示按位取反
delay();
}
}
例程2 开始时,流水灯只有最底位D0亮,亮灯每隔500ms往高位流动,形成一个循环反复的过程。
#includereg52.h
#includeintrins.h //定义循环左移函数_crol_
#define uint unsigned int
#define uchar unsigned char //宏定义
void delay() //延时500ms
{
uint x,y;
for(x=100;x0;x--)
for(y=580;y0;y--);
}
void main()
{
uchar temp;
temp=0x01;
while(1)
{
P0=temp;
delay();
temp=_crol_(temp,1); //循环左移一位
}
}
例程3 间隔300ms先奇数亮再偶数亮,循环三次;一个灯上下循环三次;两个分别从两边往中间流动三次;再从中间往两边流动三次;8个全部闪烁3次;关闭发光管,程序停止。
#includereg52.h
#includeintrins.h
#define uint unsigned int
#define uchar unsigned char
void delay(uint);
void main()
{
uchar i,j,k,z,n,temp;
P0=0x00; //灯全熄灭
for(i=3;i0;i--)
{
P0=0xaa; //a大小写都可以
delay(450);
P0=0x55;
delay(450);
}
temp=0x01;
for(j=24;j0;j--)
{
P0=temp;
delay(450);
temp=_crol_(temp,1); //D0灯亮并上下循环三次
}
temp=0x01;
/*
for(i=3;i0;i--)
{
for(j=8;j0;j++)
{
P0=temp;
delay(450);
temp=_crol_(temp,1);//D0灯亮并上下循环
}
}
*/
P0=0x00;
for(k=3;k0;k--)
{
P0=0xc3;
delay(450);
P0=0x3c;
delay(450);
}
for(z=3;z0;z--)
{
P0=0x3c;
delay(450);
P0=0xc3;
delay(450);
}
for(n=3;n0;n--)
{
P0=0xff;
delay(450);
P0=0x00;
delay(450);
}
P0=0x00;
for(n=6;n0;n--)
{
P0=~P0; //~按位取反
delay(450);
}
while(1);
}
void delay(uint z)
{
uint x,y;
for(x=100;x0;x--)
for(y=z;y0;y--);
}
2.3 数码管
在我的实验板上,单片机通过芯片CH451(参考我写的CH451的使用总结)来控制数码管显示。CH451与八个数码管连接的原理图如下所示:
例程1 点亮0、2、4、6号数码管,让它们都显示1。
#includereg51.h
#includeintrins.h
#define uchar unsigned char
#define uint unsigned int
#define CH451_DIG0 0x0800 /*数码管位0显示*/
#define CH451_DIG1 0x0900 /*数码管位1显示*/
#define CH451_DIG2 0x0a00 /*数码管位2显示*/
#define CH451_DIG3 0x0b00 /*数码管位3显示*/
#define CH451_DIG4 0x0c00 /*数码管位4显示*/
#define CH451_DIG5 0x0d00 /*数码管位5显示*/
#define CH451_DIG6 0x0e00 /*数码管位6显示*/
#define CH451_DIG7 0x0f00 /*数码管位7显示*/
sbit ch451_din = P1^0;
sbit ch451_clk = P1^1;
sbit ch451_load = P1^2;
/********************************************************************
函 数 名:ch451_init()
功 能:对ch451芯片进行初始化
***********************************************************************/
void ch451_init(void)
{
ch451_din = 0; /*先低后高,选择4线输入*/
ch451_din = 1;
ch451_load = 1;
ch451_clk = 1;
}
/********************************************************************
函 数 名:ch451_write()
功 能:把12位的指令或数据写入ch451
说 明:12位数据或指令的写入顺序是低位
入口参数:command
***********************************************************************/
void ch451_write(unsigned int command)
{
unsigned char i;
ch451_load=0; /*命令开始*/
for(i=0;i12;i++)
{ /*送入12位数据,低位在前*,表按位与,如57=5,即:0101^0111=5*/
ch451_din=command1;
ch451_clk=0;
ch451_clk=1;
command=1; /*上升沿有效*/
}
ch451_load=1; /*加载数据*/
}
void main()
{
ch451_init();
//系统参数设定,参照说明书
ch451_write(0x401);
//显示参数设定,
ch451_write(0x580);
//第0位显示1
ch451_write(CH451_DIG0|1);
//第2位显示1
ch451_write(CH451_DIG2|1);
//第4位显示1
ch451_write(CH451_DIG4|1);
//第6位显示1
ch451_write(CH451_DIG6|1);
}
例程2 数码管位0位和1同时显示0、1、2、3、4,且循环显示这些数值。
#includereg52.h
#includeintrins.h
#define uchar unsigned char
#define uint unsigned int
#define CH451_DIG0 0x0800 /*数码管位0显示*/
#define CH451_DIG1 0x0900 /*数码管位1显示*/
#define CH451_DIG2 0x0a00 /*数码管位2显示*/
#define CH451_DIG3 0x0b00 /*数码管位3显示*/
#define CH451_DIG4 0x0c00 /*数码管位4显示*/
#define CH451_DIG5 0x0d00 /*数码管位5显示*/
#define CH451_DIG6 0x0e00 /*数码管位6显示*/
#define CH451_DIG7 0x0f00 /*数码管位7显示*/
uint table[5][2]={{CH451_DIG0|0,CH451_DIG1|0},{CH451_DIG0|1,CH451_DIG1|1},
{CH451_DIG0|2,CH451_DIG1|2},{CH451_DIG0|3,CH451_DIG1|3},{CH451_DIG0|4,CH451_DIG1|4}};
//定义二维数组
sbit ch451_din=P1^0;
sbit ch451_clk=P1^1;
sbit ch451_load=P1^2;
/********************************************************************
函 数 名:ch451_init()
功 能:对ch451芯片进行初始化
***********************************************************************/
void ch451_init(void)
{
ch451_din = 0; /*先低后高,选择4线输入*/
ch451_din = 1;
ch451_load = 1;
ch451_clk = 1;
}
/********************************************************************
函 数 名:ch451_write()
功 能:把12位的指令或数据写入ch451
说 明:12位数据或指令的写入顺序是低位
入口参数:command
***********************************************************************/
void ch451_write(unsigned int command)
{
unsigned char i;
ch451_load=0; /*命令开始*/
for(i=0;i12;i++)
{ /*送入12位数据,低位在前*,表按位与,如57=5,即:0101^0111=5*/
ch451_din=command1;
ch451_clk=0;
ch451_clk=1;
command=1; /*上升沿有效*/
}
ch451_load=1; /*加载数据*/
}
void delay() //延时函数
{
uint x,y;
for(x=100;x0;x--)
for(y=580;y0;y--);
}
void main()
{
uchar num,tt;
ch451_init();
//系统参数设定,参照说明书
ch451_write(0x401);
//显示参数设定,
ch451_write(0x580);
while(1)
{
for(num=0;num5;num++)
{for(tt=0;tt2;tt++)
ch451_write(table[num][tt]);
delay();
}
}
}
原文链接:https://www.eeworld.com.cn/mcu/article_2016092529798.html