单片机基本知识
一、标题常用辅助开发软件
1、编写程序——Keil 5
Keil 5可以辅助你将C语言等编程语言转变为单片机看得懂的二进制代码,从而被单片机运行。
2、烧录程序——stc-isp
stc-isp可以将由Keil 5编写后生成的二进制代码下载进单片机里,每次下载时需重新启动单片机,下载的程序必须为.hex程序。当然,买单片机时商家也会附带一个针对本产品的烧录程序,但总体来说,stc-isp的使用具有广泛性。
二、写代码时应注意的点
1、由于单片机的内存相较电脑程序来说,实在太少,所以在定义变量时应尽可能减少内存的使用。如写C程序时常用int来声明变量类型,而单片机程序往往使用unsigned char和char来减少内存的浪费。
2、C语言程序,单片机程序有种独特的变量类型
- sfr:是一种扩充数据类型,点用一个内存单元,值域为0~255。利用它可以访问51单片机内部的所有特殊功能寄存器。
- sbit :可定义可位寻址对象。
(可位寻址:可以具体地对某一个对象进行0/1的赋值,而不用统一赋值。不可位寻址:不可对某一具体对象赋值,必须用统一赋值16进制数的方式赋值。原因:单片机串口资源的有限。)
LED 灯的学习
一、点亮一个LED灯
LCD的亮灭又P0端口控制,P0置1是灯灭,置0时灯亮。
void main()
{
P2=0xFE; //统一赋值
P2_0=0; //对点赋值
//二选其一即可
while(1)
{
}
}
二、LED灯闪烁
错误案例:
void main()
{
while(1)
{
P2=0xFE;
P2=0xFF;
}
}
由于单片机运行速度很快,平均每一微妙执行一个语句。这段代码由于被反复执行,而间隔时间极短,尽管事实上的确达到闪烁的目的,但却无法被人眼观测到,所以应在代码间加上延时函数Delay(习惯取名)。
void Delay(unsigned char xms) //xms 为延长的时间,单位毫秒
{
unsigned char i, j;
for(;xms>0;xms--)
{
_nop_(); //_nop_(); 延迟时间 1us,可以较为精确地控制延迟时间
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
因此控制LED灯闪烁的正确代码应为
void main()
{
while(1)
{
P2=0xFE;
Delay(500);
P2=0xFF;
Delay(500);
}
}
三、流水灯
流水灯:使8个LED灯从左到右依次闪烁(可借助位运算达成目的)。
void main()
{
unsigned char i;
while(1)
{
for(i=0;i<8;i++)
{
P2=~(0x01<<i);
Delay(500); //不要忘记Delay函数的引进
}
}
}
独立按键的学习
一、独立按键控制LED亮灭
这种情况下,当按键按下时,灯亮,松开时,灯灭。
void main()
{
while(1)
{
if(P3_1==0) //如果按下K1按键
{
P2_0=0; //LED1输出0,点亮
}
else
{
P2_0=1; //LED1输出1,熄灭
}
}
特别注意:
P3_1是K1,P3_0是K2.
二、独立按键控制LED亮灭
1、独立按键的抖动和消抖
独立按键的工作原理,在按下与松开时有一段时间的抖动,故我们在编写代码时需要消抖。
Delay(20); //按下消抖
while(P3_1==0);
Delay(20); //松开消抖
这样才可以保证一次按键只被读到一次,否则易造成多读。
2、独立按键通用函数
unsigned char key()
{
unsigned char keynum=0;
if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);keynum=1;}
if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);keynum=2;}
if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);keynum=3;}
if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);keynum=4;}
return keynum;
}
通过这个函数就可以更加方便地运用独立按键。
3、独立按键函数的应用
void main()
{
unsigned char keynum;
while(1)
{
keynum=key();
if(keynum==1){P2_0=0;}
if(keynum==2){P2_0=1;}
}
}
简单地运用key函数后就可以获取对应的值,然后再用if就可以实现按下某一独立按键后执行的操作。
数码管
1、静态数码管
-
1、选位
数码管的位置由P2_2、P2_3、P2_4三个引脚决定,它们共同组成了一个0~7的二进制数,对位置进行控制,其中P2_4是最高位,P2_2是最低位。数码管上位置由右到左依次为0、1、2、3、4、5、6、7。 -
2、显示
由图显示,P0控制着数码管上各个LED灯的亮灭,控制对应LED的亮灭,即可显示相应数字等。 -
3、具体代码演示
void main()
{
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
P0= 0x6D;
//在第一个位置显示5
while(1)
{
}
}
2、动态数码管
- 1、原理:由于单片机数码管的连接排布,使得每次只能控制一个位置显示数字。但借助于人眼的视觉残留和LED灯的余辉,如果在极短时间内对数码管一位一位进行扫描和清屏,就可以达到使人眼望去仿佛全都在发光的目的。
- 2、为了方便数码管显示数字代码的书写,通常会自定义函数Nixie,来达到简化代码的目的。
unsigned char NixieNum[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Nixie(unsigned char place,Date)
{
switch(place) //place是代表位置的参数
{
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=NixieNum[Date]; //Date代表要显示的数字
//接下来的代码运用于动态数码管而不用于静态数码管
Delay(1); //使LED亮一段时间
P0=0x00; //消影
}
完成本函数后,只需要在主函数调用一下就可以达到目标了。