前言
对于参加了蓝桥杯单片机组的同学来说,一个完整且好用,易理解的代码模板更利于那些刚刚踏入单片机学习的同学去理解和学习,本文将分享一个针对蓝桥杯比赛的超级完整代码模板,帮助参赛者提高编程效率,轻松应对各种题型。通过本文,你将了解到模板的结构、功能和使用方法,为蓝桥杯比赛做好充分准备。
写博客的原因
参加蓝桥杯的同学很多听取学长或者老师的建议在哔站跟着小蜜蜂老师学习代码和模块,的确,小蜜蜂老师针对蓝桥杯比赛的视频是很利于初学者来学习的(本人的启蒙老师也是小蜜蜂老师),但是我发现很多同学在学完一遍之后,拿到一道赛题不知道该怎么入手,逻辑不清楚,不知道该怎样将模块化整合起来,而且我发现有很大一部分同学因为Delay的延时函数而使主函数卡死,影响主函数运行等等问题,而且通过我参加蓝桥杯的获奖情况(省一,国一),就诞生了这样一个代码模板以供学习,非常适合逻辑不清楚的同学。全部干货,不掺杂一滴水!!
只介绍每个模块该如何去写,结构如何,效果是怎样,以及如何去调用等问题,模块的具体学习还请跟着哔站小蜜蜂老师学习,链接为:小蜜蜂老师哔站视频
这个代码整体是依靠定时器中断而完成的,因此例如LED,数码管等都是在定时器中实现,不会因为其他因素去影响主函数运行。
模板结构
整个模板分为主函数文件(main.c)和驱动函数文件(hardware.c)两部分,所以首先需要创建两个.c文件和一个.h文件,分别为main.c,hardware.c以及hardware.h这三个文件,小蜜蜂老师有讲如何去创建新文件,这里不再阐述
驱动函数文件(hardware.h)
定时器1的设置
定时器1是整个代码模板基础中的基础,我们需要在定时器1中调用LED驱动,数码管驱动,频率测量(NE555)以及PWM,主函数中也需要定时器1,这个到主函数文件中在讨论
比赛的时候使用的是官方头文件:
#include <STC15F2K60S2.H>
所以,我们可以直接用STC-ISP烧录软件生成的定时器1:具体设置按照下图:
值得注意的是这里生成的代码并没有开启定时器1的中断以及总中断,所以我们需要手动打开,具体设置如下:
void Timer1_Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x20; //设置定时初始值
TH1 = 0xD1; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1;
EA = 1;
}
定时器设置完成之后需要设置中断函数以供我们使用,定时器1的中断号为3,所以代码如下:
void TimerIsr() interrupt 3
{
}
再将定时器初始化函数在hardware.h中声明一下就可以了。
数码管
数码管的设置
这里有个好方法去查找字模,比赛可用哦!
首先打开STC-ISP烧录软件,找到范例程序-->STC开发板(试验箱4)演示程序 --> HC595驱动八个数码管 --> C,具体如下:
在118-126行可以找到字模,如下图:
特别注意:值得注意的是这个字模为阴极数码管,比赛所用板为阳极数码管,所以使用的时候一定要取反!!!!!!!!!!!!
复制拷贝到hardware.c中即可,数码管驱动函数具体如下:
/************* 本地常量声明 **************/
unsigned char code t_display[]={ //标准字库
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black - H J K L N o P U t G Q r M y
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1
unsigned char code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位码
unsigned char dig_buf[][8]= //显示界面以及每一位显示位的值
{
{16,16,16,16,16,16,16,16},
};
unsigned char *digs = dig_buf[0];//初始界面设置
unsigned char dig_com = 0;//位码切换标志位
/* ------------- 数码管驱动函数(定时器中自动运行) ------------- */
void dig_output()
{
P0 = 0x00;//消影
P2 |= 0xC0;
P2 &= ~0xE0;
P0 = ~t_display[digs[dig_com]];//段选
P2 |= 0xE0;
P2 &= ~0xE0;
P0 = T_COM[dig_com];//位选
P2 |= 0xC0;
P2 &= ~0xE0;
if(++dig_com >= 8)//位码标志位更新
{
dig_com = 0;
}
}
数码管的使用方法
还没有忘记刚才写的定时器1的中断函数吧,将其放入中断函数中调用即可,具体如下:
void TimerIsr() interrupt 3
{
dig_output();//数码管显示函数
}
将主函数中需要调用的变量在头文件中声明一下,值得注意的是声明的变量前面需要加上extern
具体为:
#ifndef __HARDWARE_H__
#define __HARDWARE_H__
extern unsigned char dig_buf[][8];//显示界面及显示位的值
extern unsigned char *digs;//指向dig_buf[][8]的指针,修改其可修改显示界面
void Timer1_Init(void);
#endif
然后在主函数调用即可,具体操作如下:
#include <STC15F2K60S2.H>
#include "hardware.h"
void main()
{
Timer1_Init();
}
需要改变某个界面的第几个数只需要改变 dig