【蓝桥杯单片机组冲刺省一,之数码管模块】

蓝桥杯单片机组数码管模块扫描

这篇与上一篇led扫描样式一致,都是利用中断每隔一定时间来扫描一下数码管函数,从而实现数码管的完美控制。


前言

基于上一篇**led扫描控制,此篇在led基础上融合数码管的控制,轻松将底层模块学会,我将这些代码分享给大家,祝大家能够取得理想的成绩,针对于看不懂#define CODE_SEL_Y5 {P2 = (P2 & 0x1f) | 0xa0; P2 = P2&0x1f;}**部分代码的人,:推荐看我以往博客内容


一、基本控制方式:

首先在主函数里生成一个中断函数,并且将定时器配置为一定的时间段,这里我配置的为1ms进入中断一次:首先在这里生成了一个system.c文件在main函数里面我们调用system_init()函数来达到初始化系统的目的。我们以后会将各个模块扫描函数统一写入中断里面。

在这里插入图片描述

在这里插入图片描述

  1. 首先将数码管扫描函数写出来这个扫描函数与上一节led扫描函数一样都是在中断里面执行的。
  2. 在完成数码管的底层控制后,自己根据题目创建出show_R()函数

  1. 调用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

  • 18
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

对方正在输入 对方正在输入sk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值