文章目录

前言

笔者参加的是第十一届蓝桥杯的单片机组,当时由于疫情,比赛一直推迟,推到最后还和电赛测评弄到了同一天,可以说相当刺激了,弄完蓝桥出来接着就是电赛测评,好在最后结果还比较让人满意,虽然没有国奖,但笔者自己觉得已经满足了。此系列主要是分享部分参赛经验,没有到国奖的水平,就提供一些省赛的基础技巧了,此篇主要是介绍STC的一些使用技巧。

巧用STC

其实蓝桥杯的门槛和难度在电子类竞赛中算是比较好拿奖的,只要运用好工具,需要自己记住的代码量是比较少的,用好STC会大大需要记忆的代码量。

STC生成定时器

首先是软件延时函数,打开STC后在上方工具栏找到软件延时计算器

然后按照一下步骤配置一下即可
1.选择系统频率,IAP15是内部晶振频率为12M;
2.选择所需的延时时间;
3.选择8051指令集,IAP15对应STC-Y5;
4.生成代码;
然后复制粘贴到自己的代码即可。

STC配置定时器(定时器中断

定时器

定时器是每届必考的,要记住整个配置过程也不难,步骤如下:

1.选择定时器时钟(AUXR寄存器);
2.配置定时器模式(TMOD寄存器);
3.高低八位的的初始值赋值(TLn和THn);
4.清除溢出标志位(TFn);
5.开启计时(TRn);
6.判断TF有没有溢出,溢出表示定时时间到,如果需要重复计时就需要清除溢出标志并对高低八位重新赋值。
但是为了节约时间和降低错误率,建议大家还是采用STC直接生成,步骤如下:

根据自己需求配置即可,这里一般是会配置一个1ms的定时器,这样方便后面做标志。

定时器中断

整个开发过程很少纯粹的使用定时器来进行计时,更多的是和中断结合起来,使得程序能够运行的更合理。
定时器中断的配置只是在定时器配置的基础上再多配制两个寄存器即可,步骤如下:
1.选择定时器时钟(AUXR寄存器);
2.配置定时器模式(TMOD寄存器);
3.高低八位的的初始值赋值(TLn和THn);
4.清除溢出标志位(TFn);
5.开启计时(TRn);
6.使能定时中断(ETn);
7.使能总中断(EA);
一钟二模三赋值;四清五开使六七;
然后编写对应的中断服务函数即可。
也就是说初始化的配置过程中只需要添加两个寄存器的配置即可。
例如配置定时器0的中断;

//初始化函数
void Timer_Init(void)
{
	AUXR |= 0x80;	
	TMOD &= 0xF0;
	TL0 = 0xCD;		
	TH0 = 0xD4;		
	TF0 = 0;		
	TR0 = 1;		
	ET0 = 1;
	EA=1; 
}
//中断服务函数
void timer0() interrupt 1  using 1   
{
//1ms进一次中断。
}

上述代码估计有同学会问,为什么中断服务函数为啥没有重新装载值,这是因为在上面定时器配置模式的时候已经开启了自动重装载。

切记中断服务函数需要注意中断号对应,不然就麻烦了。

当然如果你临场紧张了,一下子忘记了中断服务函数该咋写,不急,还有保命方案。
STC是没有直接配置定时器中断的工具的,但是他有示例,里面就有很多可以参考的例子。按照下图操作即可找到。

这个代码可能看起来有一堆复杂的寄存器没见过,最好的办法就是对他们视而不见,直接找自己认识的,有映像的,
例如上面这个例子中就可以提取出这些有用的东西:

/*-----------------------------------------------------------------
/* --- STC15F4K60S4 系列 定时器0的16位自动重装载模式举例---------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序        */
/* 如果要在文章中应用此代码,请在文章中注明使用了STC的资料及程序        */
/*---------------------------------------------------------------------*/
//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//若无特别说明,工作频率一般为11.0592MHz
#include "reg51.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
//-----------------------------------------------
#define FOSC 11059200L
#define T1MS (65536-FOSC/1000)      //1T模式
sfr AUXR = 0x8e;                    //Auxiliary register
sbit P10 = P1^0;
//-----------------------------------------------
/* Timer0 interrupt routine */
void tm0_isr() interrupt 1
{
    P10 = ! P10;                    //将测试口取反
}
//-----------------------------------------------

/* main program */
void main()
{
    AUXR |= 0x80;                   //定时器0为1T模式
//  AUXR &= 0x7f;                   //定时器0为12T模式

    TMOD = 0x00;                    //设置定时器为模式0(16位自动重装载)
    TL0 = T1MS;                     //初始化计时值
    TH0 = T1MS >> 8;
    TR0 = 1;                        //定时器0开始计时
    ET0 = 1;                        //使能定时器0中断
    EA = 1;
    while (1);
}

这不代码框架直接就有了吗,实测是可以用的,大家可以自己试试,看看哟没有bug。所以利用好STC可以省去很多麻烦。
友情提示:
在配置好定时框架后,一定务必要写一个测试函数,比如闪灯来检查一下自己的框架有没有问题。
整个比赛过程中一定要阶段性的编译检查和验证功能,不要托大一次写好多东西再去检查。

STC获取数码管码表

数码管的码表想必也是不少人的一个难题,还在自己根据这个推测或者硬记那就慢了。

快速使用小妙招:
按下图操作,在示例中找到任意一个右数码管的例程。

往下滑,就可以看见了一个标准字库,直接CV,解决问题。

但是需要注意一点,这里的是共阴码表,比赛平台是供阳码,所以在显示的时候需要做一个小小的处理(赋值时注意取个反就行了):

STC上升沿下降沿检测

类似第十届省赛的频率计,说白了还是记录单位时间的上升或者下降沿的个数,然后计算出频率。
这个可以用外部中断的方式,可能不是很熟悉整个中断体系的同学遇到这种会有些麻,但是请不要放弃,记住STC是个好东西。
继续来到示例,找到里面的

还是认识的就需要,不认识的就直接忽略。
就可以得到这样一个代码:

void Timer0Init(void)
{
    AUXR = 0x80;                    //定时器0为1T模式
    TMOD = 0x04;                    //设置定时器0为16位自动重装载外部记数模式
    TH0 = TL0 = 0xff;               //设置定时器0初始值
    TR0 = 1;                        //定时器0开始工作
    ET0 = 1;                        //开定时器0中断

    EA = 1;

}

  //中断服务程序
void t0int() interrupt 1            //中断入口
{
    P10 = !P10;                     //将测试口取反
}

这样就有了一个下降沿中断了,只需要在给一个准确的时间段,记录下降沿个数,然后二者相比就可以得到频率了。

其他

STC的示例代码中有很多例子,IIC、SPI、数码管甚至矩阵键盘这些都是有的,不一定能够直接拿来就用,但逻辑大致相同,有时间还是可以多看看和移植了试一试。

总结

蓝桥杯比赛时间是五个小时,希望此文能够节约大家代码框架搭建的时间,还有差不多一个月就比赛了,安安心心多练,拿到国赛门票是不难的笔者在此祝看到此文的学弟学妹都能取得让自己满意的成绩。此文如有不妥之处欢迎批评指正。

目录

蓝桥杯单片机组——榨干选手资源包(STC)

蓝桥杯单片机组——榨干选手资源包(芯片数据手册)
蓝桥杯单片机组——程序框架及客观题