相关说明:
开发板:CT107D (IAP15F2K61S2)
开发环境:Keil5
涉及题目:第十二届蓝桥杯单片机省赛真题
主要函数代码及说明:
#include "stdio.h"
#include "Timer.h"
#include "bsp_init.h"
#include "bsp_key.h"
#include "bsp_seg.h"
#include "bsp_led.h"
#include "bsp_onewire.h"
#include "bsp_iic.h"
//--定时器滴答变量
unsigned long ms_Tick = 0;
//--定时器减速变量
unsigned int Key_Slow_Down;
unsigned int Seg_Slow_Down;
unsigned int Led_Slow_Down;
unsigned int Volatge_Output_Slow_Down;
//--按键专用变量
unsigned char Key_Value;
unsigned char Key_Old, Key_Down;
//--数码管专用变量
unsigned char seg_string[10];
unsigned char seg_buf[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
unsigned char pos;
//--LED专用变量
unsigned char ucLed = 0x00;
unsigned char Disp_Interface = 0;//显示界面,0-温度显示,1-参数设置,2-DA输出界面
unsigned char Temp_Compare_Disp = 25;//温度比较值,单纯用来显示和设置时候使用
unsigned char Temp_Compare_Ctrl = 25;//温度比较值,真正起作用的
bit DA_Output_Mode = 0;//DA输出的模式,0-模式1;1-模式2
float Temp;//真实的温度数据
unsigned char DA_Inter_Num = 0;//控制DA输出电压的内部给定数值,0-255
void Key_Proc(void);
void Seg_Proc(void);
void Led_Proc(void);
void Voltage_Output_Proc(void);
void Delay750ms();//用来消除85°C显示
void main(void)
{
Cls_Peripheral();//关闭LED/继电器/蜂鸣器
Timer1Init();//定时器1初始化
EA = 1;//打开总中断
rd_temperature();
Delay750ms();//用于消除上电显示85°C的影响
while(1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
Voltage_Output_Proc();
}
}
void Key_Proc(void)
{
if(Key_Slow_Down) return;
Key_Slow_Down = 1;
//三行代码
Key_Value = Key_Read();
Key_Down = Key_Value & (Key_Old ^ Key_Value);//下降沿,按得哪个按键,这个值就是几
Key_Old = Key_Value;//检测电平,一直按着一直等于一个数
switch(Key_Down)
{
case 4://显示界面切换按键,0-温度显示,1-参数设置,2-DA输出界面
if(++Disp_Interface == 3) Disp_Interface = 0;
if(Disp_Interface == 2) Temp_Compare_Ctrl = Temp_Compare_Disp;//使能设定的比较值
break;
case 8://参数设置数值-
if(Disp_Interface == 1)
{
Temp_Compare_Disp--;
if(Temp_Compare_Disp > 200)//将下限设置为0
Temp_Compare_Disp = 0;
}
break;
case 9:///参数设置数值+
if(Disp_Interface == 1)
{
Temp_Compare_Disp++;
if(Temp_Compare_Disp > 99)//将上限设置为99
Temp_Compare_Disp = 99;
}
break;
case 5://DA输出的模式切换,0-模式1;1-模式2
DA_Output_Mode ^= 1;
break;
}
}
void Seg_Proc(void)
{
if(Seg_Slow_Down) return;
Seg_Slow_Down = 1;
Temp = rd_temperature()/16.0;//采集温度数据
switch(Disp_Interface)//显示界面切换按键,0-温度显示,1-参数设置,2-DA输出界面
{
case 0://温度显示
sprintf(seg_string,"C %5.2f",Temp);
break;
case 1://参数设置
sprintf(seg_string,"P %02d",(unsigned int)Temp_Compare_Disp);
break;
case 2://DA输出界面
sprintf(seg_string,"A %4.2f",DA_Inter_Num/51.0);
break;
}
Seg_Tran(seg_string, seg_buf);
}
void Voltage_Output_Proc(void)
{
if(Volatge_Output_Slow_Down) return;
Volatge_Output_Slow_Down = 1;
if(DA_Output_Mode == 0)//0-模式1;1-模式2
{
if(Temp < Temp_Compare_Ctrl)
DA_Inter_Num = 0;
else
DA_Inter_Num = 255;
}
else
{
if(Temp < 20)
DA_Inter_Num = 51;
else if(Temp > 40)
DA_Inter_Num = 204;
else
DA_Inter_Num = 7.65*Temp - 102;
}
Pcf8591_Dac(DA_Inter_Num);
}
void Led_Proc(void)
{
if(Led_Slow_Down) return;
Led_Slow_Down = 1;
if(DA_Output_Mode == 0)//0-模式1,L1点亮;1-模式2,L1熄灭
ucLed |= 0x01;
else
ucLed &= (~0x01);
switch(Disp_Interface)//显示界面切换按键,0-温度显示,1-参数设置,2-DA输出界面
{
case 0://温度显示,L2亮
ucLed &= (~0x0E);
ucLed |= 0x02;
break;
case 1://参数设置,L3亮
ucLed &= (~0x0E);
ucLed |= 0x04;
break;
case 2://DA输出界面,L4亮
ucLed &= (~0x0E);
ucLed |= 0x08;
break;
}
}
void tm1_isr() interrupt 3
{
ms_Tick++;//滴答定时器,能记录的数据长达29天
if(++Key_Slow_Down == 10) Key_Slow_Down = 0;//减速变量区,控制子函数的刷新频率
if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;
if(++Led_Slow_Down == 100) Led_Slow_Down = 0;
if(++Volatge_Output_Slow_Down == 500) Volatge_Output_Slow_Down = 0;
Seg_Disp(seg_buf, pos);//用于数码管显示
if(++pos == 8) pos = 0;
Led_Disp(ucLed);//用于LED显示
}
void Delay750ms() //@12.000MHz 用来消除85°C显示
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 35;
j = 51;
k = 182;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
省赛和国赛的题目最起码要做过一遍。主要训练逻辑思路,可以先用自己写好的各个模块驱动代码。比赛前几天全部代码都要重新写,包括新建工程开始,到各个驱动模块代码。比赛的时候,我是先写好大模板和各个模块的代码,然后才开始做按要求去实现功能的,功能由简单到难。