2-1点亮一个LED
#include <REGX52.H>
#include <INTRINS.H>
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
while(1)
{ P2 = 0xFE;//对应1111 1110即只有D1亮
Delay500ms();//亮了后等500ms
P2 = 0xFF;//对应 1111 1111 即都不亮
Delay500ms();//不亮后等500ms
}
}

解释:为什么1不亮0亮,是因为LED一端接了VCC高电平,则另一端应该给低电平即0,才有电流输出
2-3流水灯
①
#include<REGX52.H>
#include<INTRINS.H>
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
while(1)
{
P2 = 0xFE;//1111 1110
Delay500ms();
P2 = 0xFD;//1111 1101
Delay500ms();
P2 = 0xFB;//1111 1011
Delay500ms();
P2 = 0xF7;//1111 0111
Delay500ms();
P2 = 0xEF;//1110 1111
Delay500ms();
P2 = 0xDF;//1101 1111
Delay500ms();
P2 = 0xBF;//1011 1111
Delay500ms();
P2 = 0x7F;//0111 1111
Delay500ms();
}
}
②
#include <REGX52.H>
void Delay1ms(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
/*
*对while循环的理解:这个Delay1ms是针对1ms的,当下面程序需要n个1ms,就会循环n次1ms延时的程序
*/
while(xms)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
xms--;
}
}
//上面自定义函数
void main()
{
while(1)
{
P2 = 0xFE;//1111 1110
Delay1ms(500);
P2 = 0xFD;//1111 1101
Delay1ms(500);
P2 = 0xFB;//1111 1011
Delay1ms(500);
P2 = 0xF7;//1111 0111
Delay1ms(500);
P2 = 0xEF;//1110 1111
Delay1ms(500);
P2 = 0xDF;//1101 1111
Delay1ms(500);
P2 = 0xBF;//1011 1111
Delay1ms(500);
P2 = 0x7F;//0111 1111
Delay1ms(500);
}
}
3-1独立按键控制LED灯亮灭

#include <REGX52.H>
void main()
{
while(1)
{
if(P3_1 == 0)//P_3对应第一个独立按键,表示按下该按键时,执行下面语句
{
P2_0 = 0;
}
else
{
P2_0 = 1;
}
}
}
#include <REGX52.H>
void Delay(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
while(1)
{
if(P3_1 == 0)
{
Delay(20);
while(P3_1 == 0);//如果还按着,就不执行下面的,进入死循环
Delay(20);
P2_0 = ~P2_0;
}
}
}
3.3独立按键控制LED显示二进制
①
#include <REGX52.H>
void Delay(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main()
{
unsigned char LEDNum = 0;
while(1)
{
if(P3_1 == 0)
{
Delay(20);
while(P3_1 == 0);
Delay(20);
//P2 1111 1111 (初始化)
P2++;//P2溢出变为0000 0000
P2=~P2;//取反1111 1111
}
}
}
②
#include <REGX52.H>
void Delay(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main()
{
unsigned char LEDNum = 0;
while(1)
{
if(P3_1 == 0)
{
Delay(20);
while(P3_1 == 0);
Delay(20);
LEDNum++;//初始时LEDNum为0000 0000?
P2=~LEDNum;//取反
}
}
}
对于按键消抖,检测松手的理解:
if(P3_1 == 0)//如果按了P3_1
{
Delay(20);//先延时20ms,跳过抖动阶段(消抖)
while(P3_1 == 0);//如果还按着P3_1,则进入while的空循环,没有任何执行任务
Delay(20);//松开手后,跳出while循环,再次进入抖动阶段(消抖)
}
3-4独立按键控制LED位移
#include <REGX52.H>
unsigned char LEDNum;
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main()
{
P2 = ~0x01;
while(1)
{
if(P3_1 == 0)
{
//把P2 =~0x01; 挪过来也一样
Delay(20);
while(P3_1 == 0);
Delay(20);
LEDNum++;//实现每次右移,++几次就右移几下
if(LEDNum >= 8)
{
LEDNum = 0;
}
P2 =~(0x01<<LEDNum);
}
if(P3_0 == 0)
{
Delay(20);
while(P3_0 == 0);
Delay(20);
if(LEDNum == 0)//即此时亮的灯为D1,P2为0000 0001,当num=7后,0x01<<LEDNum<==>0000 0001的1往左移动7位,即1000 0000,亮的是D8,左移成功
{
LEDNum = 7;
}
else
{
LEDNum--;;//实现每次左移,++几次就左移几下
}
P2 =~(0x01<<LEDNum);
}
}
}
4-1静态数码管位移
共阴极,亮的为1(共阴极—高电平)
1011 1110为段码(显示6)
共阳极,亮的为0(共阳极—低电平)
段码为0100 0001
共阴极:
当只需要亮第三个数字时,第124的共阴极处连接高电平(给1),而第3的共阴极给0,则只有第三个灯会亮,至于怎么亮,看上面两个例子
ps:四组A/B/C….都接在同一个1174211053那里(共用引脚,四个数字只能是一样的 )
74HC245为双向数据缓冲器:VDD和GND为电源,OE为芯片使能端,A0与B0对应….
DIR—>direction,数据读取方向
当LE接VCC时,A0传数据给B0
高电平驱动能力弱,低电平驱动能力强,所以这个缓冲器可以增强信号,使数码管更亮
//以上是之前没在typora写的笔记,不再做过多的补充和修改
4-1静态数码管位移
目的:实现第三个数码管亮起

第三个灯对应的是LED6

P2_4 P2_3 P2_2——->Y5——->LED6
根据十进制转二进制,Y5的5转为二进制是101,则有
P2_4 = 1;
P2_3 = 0;
P2_2 = 1;

此时要让LED6亮起6,则acdefg为1(共阴极)因为他们后面接到了GND(低电平),要给他高电平对应),对应到P0口则是(要从下往上读,即从P0_7读到P0_0)0111 1101二进制转十六进制,则为0x7D
#include <REGX52.H>
void main()
{
//下面的三步操作是让P2接口对应到Y5,“101”是因为5(10进制)转为二进制时对应的值是101
P2_4 = 1;
P2_3 = 0;
P2_2 = 1;
//P0这看代码前面的解释
P0 = 0x7D;//为了让第三个位置的灯亮起
while(1)
{
}
}
使用数组实现
对于Number

静态显示(只能有一个数字)
#include <REGX52.H>
unsigned char NixieTable[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x5E,0x6E};
//0~9-->0~9 10-d 11-y
//自定义函数
void Nixie(unsigned char Location,Number)
{
switch(Location)
{
//单片机上第一个位置的灯对应的是LED8
//这里用138译码器实现,取值顺序CBA
case 1:P2_4 = 1;P2_3 = 1; P2_2 = 1;break;//111-8-第一盏灯
case 2:P2_4 = 1;P2_3 = 1; P2_2 = 0;break;//110-7-第二盏灯
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];//在该位置上亮起的数字
}
void main()
{
while(1)
{
Nixie(1,5);//位置(第几个数码管),数字(如果是字母的话,那就是所要的字母对应数组的位置的位次)
}
}
三位对应138译码器的ABC口

动态显示(多个数字,需要消影)
消影
位选 段选 位选 段选(进行下一次位选时,段选没有改变)
改成:位选 段选 清零 位选 段选
#include <REGX52.H>
unsigned char NixieTable[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x5E,0x6E};
//0~9-->0~9 10-d 11-y
void Delay(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void Nixie(unsigned char Location,Number)
{
switch(Location)
{
//1st light--> LED8
//8th light--> LED1
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);
//把这句话删掉的话就没那么亮,应该是让一个位置上的数据管亮完1ms后迅速清零,然后再亮下一个,三个管都亮完只需要3ms,且中间有清零过程,所以视觉上看到的时三管灯同时亮
P0 = 0x00;//清零过程,不让别的数码管瞎亮
}
void main()
{
while(1)
{
Nixie(1,5);
Nixie(2,2);
Nixie(3,10);
Nixie(4,11);
Nixie(5,5);
}
}