1.点亮LED灯
1.1LED灯闪烁
LED点亮原理
电阻:作用限流,大小为102(其中2为倍率),即1000欧姆。
由CPU通过控制配置的寄存器控制硬件电路,寄存器后面连接导线,通过一个驱动器(增大电流),连接到io口端口,使引脚输出高低电平:(TTL电平)高电平5V,低电平0V。
左端VCC接电源正极,故端口输出高电平时(表示为1),负极接正,LED不点亮;
端口输出低电平时(表示为0),负极接负,LED点亮;
二进制应该换为16进制(0x为前缀)
注意:LED灯对应的二进制数字是从右往左一一对应,如0111 1111,是第8个灯亮,不是第一个灯亮
1.2控制LED灯按时闪烁:
#include <REGX52.H>
#include<INTRINS.H>
void Delay800ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
i = 7;
j = 21;
k = 96;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main(){
P2=0xFE;
Delay800ms();
P2=0xFF;
Delay800ms();
}
1.3 LED流水灯
#include <REGX52.H>
#include <INTRINS.H>
void Delay1ms(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main(){
while(1){
P2=0xFE; //1111 1110
Delay1ms(800);
P2=0xFD; //1111 1101
Delay1ms(700);
P2=0xFB; //1111 1011
Delay1ms(600);
P2=0xF7; //1111 0111
Delay1ms(500);
P2=0xEF; //1110 1111
Delay1ms(400);
P2=0xDF; //1101 1111
Delay1ms(300);
P2=0xBF; //1011 1111
Delay1ms(200);
P2=0x7F; //0111 1111
Delay1ms(100);
}
}
1.4二进制点灯
#include <REGX52.H>
#include <INTRINS.H>
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main(){
unsigned char LEDnum=0; //引入变量
while(1){
if(P3_1==0){
Delay(20); //通过delay去抖
while(P3_1==0); //while作用:
//按键启动if循环,松手走出while循环,运行下一步代码
Delay(20);
LEDnum++; //16进制0,1,2,3,4
P2=~LEDnum; //取反
}
}
2.独立按键控制LED灯
2.1按键控制LED亮灭
1.按键抖动:对于机械开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动
2.独立按键:一端共同接正极,当另一端(P3)连接低电平时,即表示按键接通
K1,K2,K3,K4分别对应代码的P3_1 P3_0 P3_2 P3_3
#include <REGX52.H>
#include <INTRINS.H>
void Delayms(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main(){
if(P3_1==0){ //按键执行
Delayms(20); //除去抖动
while(P3_1==0); //按键,进入空白循环,不执行下面
Delayms(20);
P2_1=~P2_1; //松键状态改变
}
}
2.2.按键控制灯左右移动
相关运算符
按位左移:0011 1100<<1 即0111 1000
按位右移:0011 1100>>2 即0000 1111
按位与:0001 1000& 0010 1010 每一位单独操作 结果0000 1000 即0&一切 为0 1&X为X本身
按位或:0001 1000 | 0010 1010 结果0011 1010 1|一切为1 0|X为X本身
按位异或:0001 1000^0010 1010 结果0011 0010 即一样为0,不一样为1
取反:~00001111 11110000
#include <REGX52.H>
#include <INTRINS.H>
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main(){
unsigned char LEDnum=0;
while(1){
if(P3_1==0){
Delay(20);
while(P3_1==0);
Delay(20);
if(LEDnum>=8){
LEDnum=0;
}
//LEDnum=1 0000 0001---0000 0010 取反1111 1101
P2=~(0x01<<LEDnum);
LEDnum++;
}
if(P3_3==0){
Delay(20);
while(P3_3==0);
Delay(20);
if(LEDnum==0){
LEDnum=7;
}
else{LEDnum--;}
P2=~(0x01<<LEDnum);
}
}
}
3.数码管
3.1静态数码管显示
3.1.1.一位数码管
共阴极连接(右上图):8个LED的阴极都连接到一个端口上
共阳极连接(右下图):8个LED的阳极都连接到一个端口上
51单片机的开发板为共阴极连接,即公共端阴极接低电平,未选端给相应数据,输入1即为亮;反之,共阳极连接则将公共端接正极电源,未选端输入0为亮
使这个数码管显示数字“6”,需要让A、F、E、D、C、G都亮起来。共阴极,首先3和8引脚都是要接地的(负极、低电平、0);然后A、F、E、D、C、G都接正极(高电平,1),B和DP接负极,这样就能得到一个数字“6”,即A、B、C、D、E、F、G、DP设置为1011 1110;
3.1.2.多位数码管
多分出几个小单元,公共端独立,未选端连在一起,作用是节省了io口,但同一个时刻下只能显示同样的数字,若要显示不同数字可通过动态数码管显示(利用人眼视觉暂留和数码管显示余晖的原理)
3.1.3. 138译码器
作用:和数码管相连接,8个io口简化为3个,
使用原理:
左边P2端123依次输入二进制数字,右边对应的十进制接口显示0,其他均为1
示例:输入二进制(101),对应十进制(5),即Y5口为0,对应LED口数据为1111 1011,(0即为接通,即第6个数码管显示,其他数码管不显示)(Y是从0开始计,Y5为0即LED6为0)
3.1.4. 74HC245
作用:单片机高电平驱动能力有限,输出的最大电流不能太大,低电平驱动能力强一些。加入缓冲器74HC245,提高驱动能力,吸收P0端口的微弱信号,再从VCC电源汲取能量,驱动数码管灯光更亮
3.1.5操作示例一:使第三个数码管显示6
P2口控制数码管显示的位置,0为接通,P0口控制数码管显示的数字,1为接通;
0对应0x3F、1对应0x06、2对应0x5B、3对应0x4F、4对应0x66、
5对应0x6D、6对应0x7D、7对应0x07、8对应0x7F、9对应0x6F
A对应0x77、B对应0x7C、C对应0x39、D对应0x5E、
E对应0x79、F对应0x71、空对应0x00,
#include <REGX52.H>
void main(){
P2_4=1; //第二个数码管
P2_3=1;
P2_2=0;
while(1){
P0=0x7D; //从下往上读数0111 1101显示6
}
}
#include <REGX52.H>
unsigned char NUM[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,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=NUM[number];
}
void main(){
Nixie(1,1);
while(1){};
}
3.2.动态数码管显示
#include <REGX52.H>
void Delayms(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms){
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
unsigned char NUM[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Nixie(unsigned char location,unsigned char 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=NUM[number];
Delayms(2);
P0=0x00; //把前一个数据清零,防止对下一个显示有影响
}
void main(){
while(1){
Nixie(1,1);
Nixie(2,3);
Nixie(3,1);
Nixie(4,4);
};
}
4.任务
#include <REGX52.H>
int a,b,c,num,i=0;
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x3E,0x40};//0~9 U -
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
xms--;
}
}
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;
}
unsigned char mode= 0;
void key()
{
if(P3_1==0) {Delay(20);while(P3_1==0);Delay(20);mode = 1;}
if(P3_0==0) {Delay(20);while(P3_1==0);Delay(20);mode = 2;}
if(P3_2==0) {Delay(20);while(P3_1==0);Delay(20);mode = 3;}
if(P3_3==0) {Delay(20);while(P3_1==0);Delay(20);mode = 4;}
}
void mode1()
{
while(1){
Nixie(1,10);
Nixie(2,1);
Nixie(7,0);
Nixie(8,1);
if(!P3_0||!P3_2||!P3_3)break;
}
}
void mode2()
{
for(i=1;1<2;i++)
{
a=230;
while(a--)
{
Nixie(1,10);
Nixie(2,2);
Nixie(7,num/10);
Nixie(8,num%10);
}
num++;
if(num==11)
{
num= 1;
}
if(!P3_1||!P3_2||!P3_3)break;
}
}
void mode3()
{
for(i=1;i<=1000;i++)
{
a=83;
while(a--)
{
Nixie(1,10);
Nixie(2,3);
Nixie(7,0);
Nixie(8,3);
Nixie(5,11);
Nixie(6,11);
}
if(!P3_0||!P3_1||!P3_3)break;
a=83;
while(a--)
{
Nixie(1,10);
Nixie(2,3);
Nixie(7,0);
Nixie(8,3);
}
if(!P3_0||!P3_1||!P3_3)break;
}
}
void mode4()
{
while(1){
Nixie(1,10);
Nixie(2,4);
Nixie(7,c);
Nixie(8,c);
if(P3_3==0)
{
while(P3_3==0)
{
Nixie(1,10);
Nixie(2,4);
Nixie(7,c);
Nixie(8,c);
}
c++;
}
if(c==10)
{
c = 0;
}
if(!P3_0||!P3_2||!P3_1)break;}
}
void main()
{
while(1)
{
key();
if(mode == 1) mode1();
if(mode == 2) mode2();
if(mode == 3) mode3();
if(mode == 4) mode4();
}
}