C51单片机嵌入式开发课程学习自用,总结网上大佬们的教程编写自己的代码库
本文章总结了循环往复的流水灯的三种方法——采用按字节寻址、逻辑移位运算符、移位函数。并将结合这些方法的特性实现更为复杂有趣的流水灯显示。
利用Proteus进行仿真,并已经在开发板上验证通过。
01.LED专栏
根据普中科技C51小板LED模块(采用共阳极接法)及最小系统原理图可画出Proteus仿真原理图
一.函数库的调用和变量的宏定义
#include <stdio.h>
#include <intrins.h>
#include <reg52.h>
#define LED P2
typedef unsigned int u16;
typedef unsigned char u8;
根据开发板的CPU与LED模块的连接方式定义LED P2
将unsigned int和unsigned char类型分别用u16和u8表示,方便后续变量的定义
二.延时函数
延时可通过两种方法实现——循环延时和定时器延时
由于流水灯对时间精度无太高要求故采用较为简易的循环延时
void delay(u16 ms)
{
unsigned int i,j;
for(i=0;i<ms;++i)
for(j=0;j<110;++j);
}
三.实现单个灯流水效果
下面是三种不同的方式实现流水灯的方法
1.按字节寻址
法一:该方法简单粗暴,虽可通过CV快速实现,但当处理较为复杂的显示内容时,代码冗长,可读性不佳。
void main()
{
while (1)
{
LED = 0xfe; //1111 1110
delay(125);
LED = 0xfd; //1111 1101
delay(125);
LED = 0xfb; //1111 1011
delay(125);
LED = 0xf7; //1111 0111
delay(125);
LED = 0xef; //1110 1111
delay(125);
LED = 0xdf; //1101 1111
delay(125);
LED = 0xbf; //1011 1111
delay(125);
LED = 0x7f; //0111 1111
delay(125);
}
}
法二:故可将灯显示状态编写成字符型数组(跟OLED屏幕显示一张图片原理相似,通过点亮相应位置的像素点完成显示),再用for()函数依次输出
void main()
{
u16 i;
char led_L[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
char led_R[] = {0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
while (1)
{
for(i=0;i<7;++i)
{
LED = led_L[i];
delay(125);
}
for(i=0;i<7;++i)
{
LED = led_R[i];
delay(125);
}
}
}
2.逻辑移位运算符
void main()
{
u16 i;
while(1)
{
for(i=0;i<7;i++)
{
delay(125);
LED = ~(0x01<<i); //左移
}
for(i=0;i<7;i++)
{
delay(125);
LED = ~(0x80>>i); //右移
}
}
}
3.逻辑移位函数
用intrins.h中的 _ crol _() 和 _ cro _()函数可以分别实现左移和右移的功能
void main()
{
u16 i;
LED = 0xfe;
while(1)
{
for(i=0;i<7;i++)
{
LED = _crol_(LED,1);
delay(125);
}
for(i=0;i<7;i++)
{
LED = _cror_(LED,1);
delay(125);
}
}
最终实现效果如下图
四.花式流水灯
未完待续