1 LED笔记
1.1控制原理
右边的vcc表示的是正极。
初始状态LED两端都会接高电平,所以只需要通过编辑程序,使得左边电平变为低电平即能点亮LED。
其各个LED连接于单片机的位置为:
单片机的寄存机为8位,每一位可以控制其电平的正负
LED连接的寄存器名为P2
CPU可以访问寄存器去写值,然后使寄存器发送信息给驱动器,然后就可以控制完成我们想要的功能
若在寄存器的一位上写1则为高电平,写0则为低电频
1.2 点亮一个LED
点亮一个LED
#include <REGX52.H>
void main()
{
P2=0xFE;//大写P
}
这里的0xFE是二进制数1111 1110对应的16进制数
当单片机执行完这个任务后,会点亮第一个LED
如图:
如果想要点亮其他LED,改变P2的值即可
好!你现在已经完成伟大的一步了!
点亮是什么,点亮就是初生的婴儿!
现在你尽可以发挥想象,使用你的c语言知识去点亮!
1.3闪烁
很简单,你只需要延时点亮就行。
但需要注意的是这个延时的时间取决于你的单片机的金振频率。
所以我们需要在STC软件中找到自己的单片机型号,生成延时函数。
但这个代码会有一个函数 __ nop__(),这个函数需要一个头文件:#include<INTRINS.H>
__ nop__()是一个空语句
然后使用这个函数,再在主函数里调用
以上都可不看,这个函数暂时没有用处。直接删掉即可。
在stc中选择一个延时1毫秒的函数然后更改成
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
1.4通过按键控制LED
独立键盘处
有4个按键,分别为
K1,K2,K3,K4
由于设计时k1与k2接反,所以需要主要的是第一个按键为P3_1,第二个按键为P3_0,第三个按键为P3_2,第三个按键为P3_3
按键在不按下时默认值为1,若按下第一个键,则P3_1=0,若按下第二个键,则P3_0=0,按下第三个按键则P3_2=0…
独立按键按下与松开时存在按键抖动
所以需要消抖方式如下。
if(P3_1==0){
Delay(20);
while(P3_1==0);
Delay(20);
消抖后可以避免函数重复执行。
控制LED点亮与熄灭
#include <REGX52.H>
void main()
{
while(1)
{
if(P3_0==0){
P2_0=0;
}else{
P2_0=1;
}
}
}
1.5 led的亮点位移
简单的来说就是按一下按键K1,点亮第一个led,再按一下K1点亮第二个led…
这时候我们就要用上位移符号:<<和>>,他们分别是左移与右移
例如:P2从1111 1110到1111 1101,
P2=0x01<<1
再取反:即P2=~(0x01<<1)
为什么不用P2<<1呢?
这是因为左移的话,会变成这样1111 1100,右侧补零,左侧移出。
所以使0111 1111与1111 1110能够按一次左或右就能转换
则无法直接使用P2=P2<<1来实现,而需要一个中间变量LEDNum
请看以下范例,可以使用变量:
#include <REGX52.H>
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
unsigned char LEDNum=0;
void main()
{
P2=~0x01;
while(1)
{
if(P3_0==0)
{
Delay(20);
while(P3_0==0);
Delay(20);
LEDNum++;
if(LEDNum==8)
{
LEDNum=0;
}
P2=~(0x01<<LEDNum);
}
if(P3_1==0)
{
Delay(20);
while(P3_1==0);
Delay(20);
if(LEDNum==0)
{
LEDNum=7;
}else
{
LEDNum--;
}
P2=~(0x01<<LEDNum);
}
}
}
2 数码管学习笔记
2.1原理介绍
其每一个衡或竖都是一个LED加上右下角的一个点,每一个数字都刚好为8个二极管正好可以使用16进制数来控制其亮灭,其段码1111 1111分别对应为DP,G,F,E,D,C,B,A,其顺序是反过来的
看上图右侧可知,这是共阴极连接,控制单个数字的引脚是公用的。
所以这是控制单个数码管显示的原理图。
其工作原理为用3个口P2_2、P2_3、P2_4控制8个口LED1/2/3/4/5/6/7/8
其原理为用3个二进制的数可以表达2^3个数,即为8个数,如:000则表示LED1,111表示LED8等,但需要主要的是LED1在最右边,LED8在最左边
其作用为只让一个LED闪烁。
接下来请看实例来了解
如果想在第3位输入数字6
#include <REGX52.H>
void main()
{
P2_4=1;
P2_3=0;
P2_2=1;
P0=0x7D;
while(1)
{
}
}
这里要注意高位表示,即从P2_4开始往下写,得101。101对应的是16进制中的5(为什么这里是5而不是3)因为他是从右开始数的,且最右边的为000,右二则为001
P2_4=1;
P2_3=0;
P2_2=1;
这三行指的是第3个数码管亮
0x7D对应的则是数字6
2.1动态显示
通过函数的反复多次的扫描,执行我们就可以实现动态显示。
(为什么不能123位置同时显示呢,上面说了,他们的结构决定了他们不能同时静态地在123位置显示123,需要以多次反复地以人眼无法察觉的速度显示1或2或3,这样就可以看起来同时在123位置显示123了)
但在此之前我们还要先建立一个显示的函数。
每次都一个一个打,太麻烦,所以我们可以使用函数来实现这个功能。
unsigned char nixietable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x7D,0x07,0x7F,0x6F};
void nixie(unsigned char location,number)
{
switch(location)
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=nixietable[number];
Delay(1);
P0=0x00;
}
注意函数的的最后两行,他们的作用是消影。
如果没有他们,在动态显示时。
就会变成这样,由于先选位选再选段选,但在下一个位选选择时上一次的段选会篡到下一位的位选上。
当我们调用函数,nixie(1,2),这样,数码管的第一位就会显示2。
然后再多次调用显示。
#include <REGX52.H>
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
unsigned char nixietable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x7D,0x07,0x7F,0x6F};
void nixie(unsigned char location,number)
{
switch(location)
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=nixietable[number];
Delay(1);
P0=0x00;
}
void main()
{
while(1)
{
nixie(1,1);
nixie(2,2);
nixie(3,3);
}
}
单片机执行此函数后,就会在123位置显示123.