蓝桥杯单片机组led模块扫描实现
利用中断每隔一定时间来扫描一下led函数,来达到完美控制led的目的,此次先写led的基本控制,后续陆续发布其他模块代码。
前言
距离蓝桥杯考核还有二十天左右的时间,在此我会保持一星期更新两篇左右的我所写的比较优秀的思路和模板供大家参考,我所写的工程是大部分都是扫描函数模式来达到控制各个模块的,没有延时函数的使用,在随后的数码管、按键等等,都没使用延时函数,大大提高了代码的实时性与反应灵敏性,我将这些代码分享给大家,祝大家能够取得理想的成绩,针对于看不懂**#define CODE_SEL_Y5 {P2 = (P2 & 0x1f) | 0xa0; P2 = P2&0x1f;}**部分代码的人,:推荐看我第二篇博客内容
一、如何实现扫描模式
首先在主函数里生成一个中断函数,并且将定时器配置为一定的时间段,这里我配置的为1ms进入中断一次:首先在这里生成了一个system.c文件在main函数里面我们调用system_init()函数来达到初始化系统的目的。我们以后会将各个模块扫描函数统一写入中断里面。
定时器初始化代码在system.c文件里面:
以后把写的模块函数初始化都放在system_init()里面,这样有利于代码的整合。这里只是对于led模块封装的一部分,之后会陆续写出来很多代码,大家有什么不懂的就来回对照着代码看就好。
led.c文件自己建立出来:这样写就是led扫描的模式,下面将会进行详解。
二、system.c详解
1.system.c文件解读
#include "system.h"
/* 利用宏定义简化控制74HC138译码器*/
#define CODE_SEL_Y5 {P2 = (P2 & 0x1f) | 0xa0; P2 = P2&0x1f;}
/*定时器Timer0的初始化*/
void Timer0_Init(void) //1毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA = 0;
PT0 = 1;
}
void system_init(void)
{ /*此处关闭电蜂鸣器与继电器 */
P0 = 0x00; CODE_SEL_Y5;
/*定时器Timer0初始化*/
Timer0_Init();
}
以后发布的文章里面不再讲述这部分代码。关于定时器Timer0的初始化,大家不必手动编写,利用isp软件生成即可。
三、led.c详解
1.led.c文件解读
#include "led.h"
/*同理于system.c文件上面所述,这里不过多赘述*/
#define CODE_SEL_Y4 {P2 = (P2 & 0x1f) | 0x80; P2 = P2&0x1f;}
/*定义一个控制led的状态量,以便后续控制led亮灭*/
unsigned char led_sta = 0xff;
/*初始化led,根据题意初始化即可*/
void led_init(unsigned char num)
{
P0 = num;
CODE_SEL_Y4;
}
/*指定第几个led灯开即可,0为第一个亮,7为第八个亮*/
void led_on(unsigned char num)
{
led_sta = led_sta & (~(0x01<<num));
}
/*同led_on()函数一样*/
void led_off(unsigned char num)
{
led_sta = led_sta | (0x01<<num);
}
/*这里较为重点,使用这个函数在中断里面进行,每过1ms就执行一次,根据led_sta状态量来改变哪几个灯亮*/
void led_scan(void)
{
/*这里P0 = 0xff;就是为了在扫描的时候都先关闭掉,之后再根据led_sta来控制哪个灯亮,避免了每次扫描上个灯还亮着的问题*/
P0 = 0xff;
CODE_SEL_Y4;
P0 = led_sta;
CODE_SEL_Y4;
}
这部分代码只是最基本的控制哪几个灯亮,之后想要再控制更高级的控制led灯亮灭的情况再补充。
省赛模拟题上面很多都是要led灯以某一时间段闪烁的,在这里留给大家自己琢磨。
四、main.c展示
#include <STC15F2K60S2.H>
#include "system.h"
#include "led.h"
void main(void)
{
system_init();
EA = 1;
while(1)
{
led_on(0);
led_on(2);
led_on(6);
}
}
void Timer0_Isr(void) interrupt 1
{
led_scan();
}
五、现象展示
总结
在我身边的很多朋友们,都觉得进行模块化封装写很麻烦,不如一股脑放在main文件里面写,其实这样很不规范并且写的很不好,写起来的代码让人看着都头大,作为亲身经历过来的人想告诉大家,从细节做起,规范好自己写代码的风格,只有好的代码别人才愿意看,并且一目了然。相信跟着我这些工程看完的朋友们,一定会有更深刻的理解O.0。