前段时间在学单片机的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--); }
|