本文记录51单片机学习过程,备忘与纪念用。材料为b站江科大视频。
点亮 LED
LED有8个灯管,本板为共阳极,调控P2管脚(16进制转2进制),设为0则输出低电平,灯泡亮。注意写入数据后使用死循环(while循环),节省CPU。
LED闪烁
使用stc-isp等辅助生成延时函数消抖,注意金振频率一致。
主函数main写前面时要声明。
#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 1111
Delay500ms();
P2=0xFF;//1111 1110
Delay500ms();
}
}
LED流水灯
主要利用延时函数,间隔500*2ms更换闪烁的LED。
常用函数可魔改后保存在桌面,随时取用。
以下延时函数修改为可调节时间。
#include <REGX52.H>
#include <INTRINS.H>
void Delay1ms(unsigned int xms) //@11.0592MHz
{
while(xms--)
{ unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
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);
}
}
独立按键
4个键,分别对应P3_1,0,2,3口。
a.控制LED亮灭
#include <REGX52.H>
void main()
{
while(1)
{
if(P3_1==0)
P2_0=0;//控制单个LED
else P2_0=1;
}
}
b.控制LED显示二进制
用~按位取反,转换LED亮灭状态;
定义变量a=0随按下按键递增再取反。
变量a设为unsigned char,节约空间。
void delay(unsigned int xms) //@11.0592MHz
{
while(xms--)
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main()
{
unsigned char a=0;
while(1)
{
if(P3_1==0)
{
delay(20);
while(P3_1==0);
delay(20);
a++;
P2=~a;//用~按位取反,转换LED亮灭状态
}
}
}
控制LED移位
以下省略头文件和延时函数。
a=0或a=8时重新赋值。
void main()
{
unsigned char a=0;
P2=0;
while(1)
{
if(P3_0==0)
{
delay(20);while(P3_0==0);delay(20);
a++;
if(a>=8) a=0;
}
if(P3_1==0)
{
delay(20);while(P3_1==0);delay(20);
if(a==0) a=7;
else a--;
}
P2=~(0X01<<a);
}
}
静态数码管显示
通过138译码器选中对应数码管,由P2_4读至P2_2三位数为二进制数0~7,
数码管实际从右至左数为0~7;
通过编辑P0(16进制)控制每位数码管内LED亮灭。
最后,应用数组匹配显示的数字与对应的16进制值。
#include <REGX52.H>
void nixie(unsigned char location,unsigned char number)
{
unsigned char numtab[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
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=numtab[number];
}
void main()
{
nixie(7,2);
while(1)
{
}
}
动态数码管显示
利用视觉暂留,在一个死循环内重复按次序扫描各个数码管显示所需数字,但需要在定位数码管位置及数字的函数内,delay1ms使显示稳定,随后置零消影。
#include <REGX52.H>
#include <intrins.h>
void main()
{
void delay(unsigned int xms);
void nixie(unsigned char location,unsigned char number);
while(1)
{
nixie(1,1);
nixie(2,3);
nixie(3,1);
nixie(4,4);
nixie(5,5);
nixie(6,2);
nixie(7,0);
}
}
void delay(unsigned int xms) //@11.0592MHz
{
while(xms--)
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void nixie(unsigned char location,unsigned char number)
{
void delay(unsigned int xms);
unsigned char numtab[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
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=numtab[number];
delay(1);
P0=0X00;
}