蓝桥杯单片机组数码管模块扫描
这篇与上一篇led扫描样式一致,都是利用中断每隔一定时间来扫描一下数码管函数,从而实现数码管的完美控制。
文章目录
前言
基于上一篇**led扫描控制,此篇在led基础上融合数码管的控制,轻松将底层模块学会,我将这些代码分享给大家,祝大家能够取得理想的成绩,针对于看不懂#define CODE_SEL_Y5 {P2 = (P2 & 0x1f) | 0xa0; P2 = P2&0x1f;}**部分代码的人,:推荐看我以往博客内容
一、基本控制方式:
首先在主函数里生成一个中断函数,并且将定时器配置为一定的时间段,这里我配置的为1ms进入中断一次:首先在这里生成了一个system.c文件在main函数里面我们调用system_init()函数来达到初始化系统的目的。我们以后会将各个模块扫描函数统一写入中断里面。
- 首先将数码管扫描函数写出来这个扫描函数与上一节led扫描函数一样都是在中断里面执行的。
- 在完成数码管的底层控制后,自己根据题目创建出show_R()函数
- 调用show_R函数在主函数里面使用,从而完成界面的显示
以后把写的模块函数初始化都放在system_init()里面,这样有利于代码的整合。这里是对于SMG模块封装的一部分,之后会陆续写出来很多代码,大家有什么不懂的就来回对照着代码看就好。
二、SMG.c详解
SMG.c文件解读
#include "SMG.h"
/*利用宏定义简化控制74HC138译码器*/
#define CODE_SEL_Y6 {P2 = (P2 & 0x1f) | 0xc0; P2 = P2&0x1f;}
#define CODE_SEL_Y7 {P2 = (P2 & 0x1f) | 0xe0; P2 = P2&0x1f;}
/*也是利用宏定义定义出各种字符 R/-等等*/
#define CODE_SEL_CHAR_R 0x88
#define CODE_SEL_CHAR_LINE 0xbf
/*可寻址片外ram (64k 地址范围FFFFH)*/
/*这里使用xdata来存储这些数据量*/
/*SMG_buf[8]相当于数码管显示的缓冲量,通过控制这些缓冲量来控制数码管显示*/
xdata unsigned char SMG_buf[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
/*利用数组来存储数码管显示字符数据,按顺序从0~9*/
xdata unsigned char code_num[10] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
/*数码管扫描函数,先位选后段选*/
void SMG_scan(void)
{
/*静态变量,通过index循环从0~7,来控制位选和段选*/
static unsigned char index = 0;
P0 = 0x01<<index; CODE_SEL_Y6;
P0 = SMG_buf[index]; CODE_SEL_Y7;
index = (index+1)%8;
}
/*自己根据题目设计界面,并且传入参数num,通过外部传入的数据来控制数码管显示内容*/
void show_R(unsigned int num)
{
/*显示字符*/
SMG_buf[0] = CODE_SEL_CHAR_R;
SMG_buf[1] = CODE_SEL_CHAR_LINE;
/*显示千百十位的数据,可以自己更改,但是不要超过65535数据即可*/
SMG_buf[2] = code_num[(num/1000)%10];
SMG_buf[3] = code_num[(num/100)%10];
SMG_buf[4] = code_num[(num/10)%10];
SMG_buf[4] = SMG_buf[4] & 0x7f
SMG_buf[5] = code_num[(num)%10];
SMG_buf[6] = CODE_SEL_CHAR_LINE;
/*想要数码管不显示就写0xff;*/
SMG_buf[7] = 0xff;
}
要是想让数码管上显示出小数点,就让SMG_buf[4] = SMG_buf[4] & 0x7f;即可。
四、main.c展示
#include <STC15F2K60S2.H>
#include "system.h"
#include "led.h"
#include "SMG.h"
void main(void)
{
system_init();
EA = 1;
while(1)
{
/*随便出入参数即可,数码管上显示出传入的数据*/
show_R(8866);
led_on(0);
led_on(2);
led_on(6);
}
}
/*1ms进入一次来执行扫面函数*/
void Timer0_Isr(void) interrupt 1
{
SMG_scan();
led_scan();
}
五、现象展示
由于拍摄问题,数码管显示的没那么清晰,但是人眼看到的还是很亮的。
总结
这里并没有过多的解释原理,因为已经默认大家会控制这些模块了,大家要是不理解为什么这样写的话,就在网站上搜一搜,有很多文章写的都很好。
在我身边的很多朋友们,都觉得进行模块化封装写很麻烦,不如一股脑放在main文件里面写,其实这样很不规范并且写的很不好,写起来的代码让人看着都头大,作为亲身经历过来的人想告诉大家,从细节做起,规范好自己写代码的风格,只有好的代码别人才愿意看,并且一目了然。相信跟着我这些工程看完的朋友们,一定会有更深刻的理解O.0。