使用上一课组装的实验板
1个共阳极单元数码管
2个共阴极4位数码管
蜂鸣器模块1个
电阻:10k 8或不含(用于P0上拉)
138解码器:74LS138 1个
(或者直接使用完整的开发板)
课程内容:1.共阳极LED数码管
对比这两个原理图,应该很容易发现几乎完全相同的abcdefg和dp分别对应8个LED的D1-D8。 那么,数码管显示数字的控制是不是和8个LED控制是否发光一样,比如显示0,就让g和dp不发光,其他发光即可。 给这8位的信号是11000000,光说不行,得做实验。 实践是检验真理的唯一标准。
在本课开始时,我们使用 P0 端口。 此 P0 端口与其他 P1、P2 和 P3 略有不同。 它的每个引脚需要添加一个电阻并连接到5V电源。 这称为上拉,使引脚首先获得默认值1。如果没有上拉电阻,引脚状态称为浮动,无法确定数据是0还是1。
将P0线连接到这个共阳极单元数码管上,然后按照刚才的思路修改程序。
无效主()
P0=0xC0; // 11000000
编译、下载并观看效果。 果然显示0。
其他的数字也可以计算出来。
我们先用前面LED点阵课中的数组方法来存储这组数字,其中还包括AbcdEFPHLy——这些常用字符的显示数据。
uchar代码light[] ={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x8C,0x89,0xC7,0x91,0xBF,0xFF };
放入function.h头文件中,方便以后使用。
无效主()
P0=光[3]; // 显示数组中的第 4 个数字。 注意C语言顺序是从0开始的
我们继续,让数字动起来,让数码管从0到8一一显示。这就需要用到上一课的循环和延时函数了。
无效主()
单位我; //循环变量,用于控制循环
对于(i=0;i
P0=光[i]; // 显示数组中的第 i 个数字。 注意C语言顺序是从0开始的
mDelay(1000);
编译下载到实验板,可以看到数字发生变化。
继续,让我们切换到倒计时模式并稍微更改一下程序。
无效主()
单位我; //循环变量,用于控制循环
for(i=9;i>0;i–)
P0=光[i]; // 显示数组中的第 i 个数字。 注意C语言顺序是从0开始的
mDelay(1000);
编译并下载实验板进行测试。 倒计时出来了,但是缺少0的显示。
看判断循环条件。 只有i>0时才执行循环,所以在0时不会进入循环,尝试改成i>=0;
无效主()
单位我; //循环变量,用于控制循环
for(i=9;i>=0;i–)
P0=光[i]; // 显示数组中的第 i 个数字。 注意C语言顺序是从0开始的
mDelay(1000);
编译,下载实验板,最后倒数到0。
但感觉有些不对劲。 在更改数字 >= 0 之前,我可以继续更改数字,但现在当它达到 0 时就停止了! !
2.BUG分析与排除
开发中总是难免有BUG,但错误必须改正。 关键是如何找出BUG点,然后去修复。
分析开始:
代码中,当i=0时,满足条件i>=0,因此进入循环体时显示0,然后执行i–。 这时候,问题就出现了。
第一行命令 uint i; 在Main()中定义了一个循环变量,用于控制循环。 这个i是uint类型的,代表一个正整数(即数学中的正数或整数)。
当i=0然后减1时,i变成负数,与定义的正整数不一致,程序终止。
维修:
有很多方法可以修复错误。 这是一种方法。 您可以通过更改代码并练习来尝试其他方法。
由于i必须是正整数,因此必须使用i>0作为循环条件,而不是i>=0。 同时循环体内数组显示改为P0= light[i-1]; 即显示前一个位置的数字。 达到显示0的效果。
无效主()
单位我; //循环变量,用于控制循环
for(i=9;i>0;i–)
P0=光[i-1]; //显示数组中第i-1个数。 注意C语言顺序是从0开始的
mDelay(1000);
编译并下载实验板。 这次效果终于正确了。 这就是bug检查和修复,是学习开发必须要学会的。
3. 蜂鸣器
看看倒计时程序。 这与火箭发射的倒计时非常相似。 只需为每个显示的数字添加一个“tic”即可。
这就需要使用蜂鸣器模块。
从蜂鸣器原理图可以看出,将其连接到P1的5脚,然后给该脚输入0信号,使其发声。
首先在function.h头文件中添加这个引脚sbit P15=P1^5的定义;
然后,修改主程序main()如下:
无效主()
单位我; //循环变量,用于控制循环
for(i=9;i>0;i–)
P0=光[i-1]; //显示数组中第i-1个数。 注意C语言顺序是从0开始的
P15=0; //给信号0,显示数字时蜂鸣器响。
mDelay(1000); //1秒延迟,可调
P15=1; //嘟1秒,够了,静音
mDelay(1000);//延时,否则直接进入下一个循环,立即再次响铃,不停顿。
编译下载实验板,效果就有了。
然而,倒计时到0后,我又回去从头开始倒计时。 火箭都跑了,还指望什么呢? 而且,不断的“嘟嘟”声也很烦人。 这不符合火箭发射倒计时的要求。 倒计时达到 0.at 0 后必须停止。
微控制器永远不会停止工作。 除非程序有bug,否则要阻止它并不容易。 既然它喜欢干活,那就让它在某处兜圈子,做无用功,达到在某处停下来的效果。
如何让它继续做无用的工作,这需要使用我们之前学过的for循环,让单片机做一个空的命令循环,只需要把空循环代码放在程序结束之前即可。
无效主()
单位我; //循环变量,用于控制循环
for(i=9;i>0;i–)
P0=光[i-1]; //显示数组中第i-1个数。 注意C语言顺序是从0开始的
P15=0; //给信号0,显示数字时蜂鸣器响。
mDelay(1000); //1秒延迟,可调
P15=1; //嘟1秒,够了,静音
mDelay(1000);//延时,否则直接进入下一个循环,立即再次响铃,不停顿。
为了(;;); //让程序停在这里,继续短接主体循环
编译并下载实验板。 如果达到了想要的效果,说明程序是正确的。
4.共阴极数码管
从原理图中可以看到,共阴极数码管将LED的负极连接在一起,由COM控制。 给COM一个0,然后传输8位数据,就会有显示。
共阴极LED数码管显示数字时,对应位的信号与共阳极的信号正好相反。 比如数字0,这里对应的数据就变成00111111。按照前面的方法,可以计算出共阴极数码管的显示数据。
uchar代码Elight[] ={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x73,0x76,0x38,0x6E,0x40,0x00 };
同样,放在function.h中,方便以后调用。
从原理图中我们可以看出,两个4位数码管的每条COM控制线正好是8位,所以我们用P2来连接这条控制线。
无效主()
单位我; //循环变量,用于控制循环
for(i=9;i>0;i–)
P0= Elight[i-1]; //显示数组中第i-1个数。 注意C语言顺序是从0开始的
P15=0; //给信号0,显示数字时蜂鸣器响。
mDelay(1000); //1秒延迟,可调
P15=1; //嘟1秒,够了,静音
mDelay(1000);//延时,否则直接进入下一个循环,立即再次响铃,不停顿。
为了(;;); //让程序停在这里,继续短接主体循环
那只是把显示阵列换成Elight而已。
编译并下载实验板进行测试。 为什么没有反应?
经过分析原来是控制口COM接P2,P2内部有上拉信号,即各引脚默认值为1,而且这是一个共阴极数码管,可以仅当给定 0 时才显示,因此当信号为 1 时,不再显示。
然后添加P2=0x00; 代码到代码:
无效主()
单位我; //循环变量,用于控制循环
P2=0x00; //控制数码管显示
for(i=9;i>0;i–)
P0= Elight[i-1]; //显示数组中第i-1个数。 注意C语言顺序是从0开始的
P15=0; //给信号0,显示数字时蜂鸣器响。
mDelay(1000); //1秒延迟,可调
P15=1; //嘟1秒,够了,静音
mDelay(1000);//延时,否则直接进入下一个循环,立即再次响铃,不停顿。
为了(;;); //让程序停在这里,继续短接主体循环
编译并下载实验板进行测试。 8根管子同时倒计时,相当壮观。
替换P2=0x00; 其中 P2=0xAA; 即10101010。编译并下载实验板进行测试。 您可以看到要显示哪个管,然后将 COM 信号 0 给该管。
5. 138解码器
这一点从上面的程序就可以看出。 所选数码管占用整个P2口和8个IO。 总共只有4组,每组51个微控制器。 这样使用效率很低。 于是138解码器就出来了。 将8个IO口的占用减少到只有3个IO。 为什么3个IO就够了? 3个IO可以从000计数到111,正好是十进制的0到7。 ,共8个数字,可以代表8个数码管的选择位。
拿某学习板的138电路原理图来说,那么J15直接连接8位数码管的COM控制端,P22、P23、P24这三个IO也是用来控制位选择的。
OK,在function.h中添加这三个IO的定义:
sbit P22=P2^2;
sbit P23=P2^3;
sbit P24=P2^4;
然后修改main()主程序:
无效主()
单位我; //循环变量,用于控制循环
P24=1; //
P23=0; // 100为十进制4,显示第五位数码管
P22=0; //
for(i=9;i>0;i–)
P0= Elight[i-1]; //显示数组中第i-1个数。 注意C语言顺序是从0开始的
P15=0; //给信号0,显示数字时蜂鸣器响。
mDelay(1000); //1秒延迟,可调
P15=1; //嘟1秒,够了,静音
mDelay(1000);//延时,否则直接进入下一个循环,立即再次响铃,不停顿。
为了(;;); //让程序停在这里,继续短接主体循环
同理,可以选择其他数码管。
6.让8位数码管动起来
这里的8位数码管只显示1位。 不,让我们让8位转盘显示不同的数字并移动它。
在前面的课程中,我们学习了使用移位的方法让LED依次点亮,这里也可以使用。 如果不使用138解码方式,可以直接用P2控制数码管的COM端,直接移位。 学生可以在课后进行自己的编程实验。 这里使用了138解码器,有一些变化,因为P22、P23、P24在P2中间,用01来表示这三个数字,即11100011(0为所选位),即0xE3。 那么只要这三个数字发生变化。
看一下代码中的注释。
无效主()
uchar a =0x00; //用于0到7的计算
uchar b =0x00;//用于使P22、P23、P24对应位置与a相同
单位我; //循环变量,用于控制循环
for(i=8;i>0;i–)
b=a