前段时间在学单片机的LED发光二极管和蜂鸣器,再利用C语言雪系单片机的时候还是有些问题的,如在C语言中不能出现死循环,一旦出现死循环就会使程序坏掉,甚至会使电脑死机。但是在单片机程序里头就需要死循环来使某些指令和程序持续运行。
在图书馆借的书大部分使关于汇编语言和单片机的书籍,这就使人感觉比较郁闷的,花一年时间来学C语言就是为了为单片机打下个基础,现在还要去学汇编就得不偿失了,还使得我们原来的努力都成了无用功。换句话说现在我们只能靠网上的和图书馆借来的单片机书籍(上面的基础知识还是挺好的)来摸索着学习了。
最近在学数码管,比较困难的就是关于锁存器的理解。每个数码管有八个角,共有八个数码管,单片机上面控制数码管通短的端口加上锁存器的端口才十个。是如何让它显示出不一样的数字和运动的数字?就是用单片机的运算速度使数码管的端口不停地转换,人眼睛的视觉暂留在数码管的LED每秒超过25帧的时候从感官上看会觉得它是一直都在亮的。
再点亮数码管的时候避不开的东西就是对锁存器的操作,锁存器就是一些接口的集合,当锁存器不工作时,不管单片机输入高电平还是低电平,都不会改变,所以要先设置锁存器,下面这个程序在"51hei单片机学习板"上测试通过,大家可以借鉴一下,这个板子2片74hc573 一个控制段一个控制位都接在p0口上。
下面是电路图和程序:
#include<reg52.h>
#include <intrins.h> //一个移位函数的头文件
#define uint unsigned int //宏定义
#define uchar unsigned char //宏定义
sbit dula=P2^6; //数码管段选锁存端
sbit wela=P2^7; ////数码管位选锁存端
uchar code table[]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void display(uchar,uchar,uchar,uchar,uchar,uchar);
void delay(uint x);
void main()
{
while(1)
{
display(6,5,4,3,2,1); //始终显示
}
}
void display(uchar one,uchar two,uchar three,uchar four,uchar five,uchar six)
{
dula=1; //锁存器在未使用使都是打开的,先得关上,不然会控制不了
P0=table[one]; //送段数据,让数码管显示的数组对应的端口
dula=0; //关闭
P0=0xff; //送位数据前关闭所有显示,防止打开位选锁存后段选数据通过位选锁存器。若是在"dula=1;"处加上wela=1;就不用此句了。这是一个数码管清零的命令
wela=1;
P0=0xfe;
wela=0;
delay(1);
dula=1;
P0=table[two];
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay(1);
dula=1;
P0=table[three];
dula=0;
P0=0xff;
wela=1;
P0=0xfb;
wela=0;
delay(1);
dula=1;
P0=table[four];
dula=0;
P0=0xff;
wela=1;
P0=0xf7;
wela=0;
delay(1);
dula=1;
P0=table[five];
dula=0;
P0=0xff;
wela=1;
P0=0xef;
wela=0;
delay(1);
dula=1;
P0=table[six];
dula=0;
P0=0xff;
wela=1;
P0=0xdf;
wela=0;
delay(1);
}
void delay(uint x) //延时子函数
{
uint a,b;
for(a=x;a>0;a--)
for(y=110;y>0;y--);
}
|