第十四届蓝桥杯单片机第二场模拟赛程序(少量bug)
题目来源于4T评测网 www.4t.wiki
赛题:
一、基本要求
使用大赛组委会提供的国信长天单片机竞赛实训平台,完成本试题的程序设计与调试。程序编写、调试完成后,选手需通过考试系统提交以准考证号命名的hex文件。不符合以上文件提交要求的作品将被评为零分或者被酌情扣分。
硬件设置:
将IAP15F2K61S2单片机内部振荡器频率设定为12MHz,串口通信波特率为9600bps。
键盘工作模式跳线J5配置为KBD矩阵按键模式。
扩展方式跳线J13配置为IO模式。
请注意:选手需严格按照以上要求配置竞赛板,编写和调试程序,不符合以上配置要求的作品将被评为零分或者被酌情扣分。
二、硬件框图
图1 系统硬件框图
三、功能描述
3.1 基本功能描述
1)通过串口控制数码管显示界面:“温度显示界面”或“电压显示界面”;也可以返回当前数码管显示的数据。
2)通过读取DS18B20温度传感器,获取环境温度。
3)通过 PCF8591 的 ADC 通道测量电位器 RB2 的输出电压。
4)通过数码管显示获取的温度数据和采集的电压数据,显示界面可以通过串口切换。
5)通过LED指示灯完成题目要求的指示功能。
6)根据题目要求完成继电器和蜂鸣器的控制功能。
3.2 性能要求
1)按键动作响应时间:≤0.2 秒
2)指示灯动作响应时间:≤0.1 秒
3.3 显示功能
温度显示界面
温度显示界面如图2所示,显示内容包括界面提示符(U1)和温度数据,单位为℃。
图2 温度显示界面(27.5℃)
使用3位数码管显示温度数据,温度数据保留小数点后1位有效数字。
电压显示界面
电压显示界面如图3所示,显示内容包括界面提示符(U2)和电压数据,单位为V。
图3 电压显示界面(1.35V)
使用3位数码管显示温度数据,电压数据保留小数点后2位有效数字。
3.4 按键功能
1)按键S4定义为“锁定”按键,按下S4按键,能够锁定当前界面“温度显示界面”或“电压显示界面”,串口切换界面指令失效。
2)按键S5定义为“解锁”按键,在界面锁定时,按下S5按键,可取消界面锁定,串口指令恢复控制。
3)按键S12定义为“发送”按键,每次按下,串口将当前数码管显示的数据发送给PC端的串口调试工具。
注意:
(1)按键S5仅在界面锁定时有效。
(2)判断按键是否按下时,需进行消抖操作,避免单次按键操作,触发多次结果。
3.5 串口功能
1)串口发送指令字符‘A’,进入温度显示界面。
2)串口发送指令字符‘B’,进入电压显示界面。
3)串口返回数据格式:
“TEMP:27.5℃”或“Voltage:1.35V”
注意: 注意区分字母大小写。
3.6 LED指示灯功能
当前界面处于温度显示界面时,L1指示灯点亮,否则熄灭。
当前界面处于电压显示界面时,L2指示灯点亮,否则熄灭。
当前界面处于锁定状态时,L3指示灯以0.1s的时间间隔亮、灭,否则熄灭。
其余指示灯均处于熄灭状态。
3.7 继电器控制功能
继电器状态受温度控制,将采集的温度数据记为T,若当前采集的温度满足下列条件时,继电器吸合,否则,继电器断开。
T≥28℃
3.8 蜂鸣器控制功能
蜂鸣器状态受电压控制,将采集的电压数据记为V,若当前采集的电压满足下列条件时,蜂鸣器发声,否则蜂鸣器静音。
V>3.6V
3.9 初始化
上电数码管默认处于温度显示界面。
界面切换处于解锁状态。
指示灯全部熄灭。
程序 :
main.c
#include <STC15F2K60S2.h>
#include <onewire.h>
#include <iic.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit R3=P3^2;
sbit R4=P3^3;
sbit C1=P4^4;
sbit C2=P4^2;
sbit C3=P3^5;
sbit C4=P3^4;
code uchar tab[12]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xc1}; // U 1 1 0 0 0 0 0 1 即0xc1
// 0 1 2 3 4 5 6 7 8 9 灭 U
uchar dspbuff[8]={10,10,10,10,10,10,10,10};
uchar dspcom=0; //数码管位选标志位
uchar ad_value; //AD采集
uchar state=1; //界面切换标志位
uchar x=0xff; //LED标志
uint v_value; //AD显示
uint intr=0,intr1=0,intr2=0;
float temperature; //温度(浮点数)
uint temper; //温度(整数)
code uchar s1[]={"TEMP:"};
code uchar s2[]={"Voltage:"};
code uchar s3[]={"℃"};
uchar str[20];
uchar str1[10];
uchar str_re='A';
uchar rxcnt=0; //串口标志位
uchar Control;
bit flag,flag1,flag2;
bit rxc = 0; /数据接收标志位
void InitAll() //初始化,关闭所有LED,蜂鸣器,继电器
{
P2=(P2&0x1f)|0x80;
P0=0xff;
P2=(P2&0x1f)|0xa0;
P0=0x00;
P2=(P2&0x1f);
}
void Timer0Init(void) //2毫秒@12.000MHz 定时器初始化,软件自动生成
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x30; //设置定时初值
TH0 = 0xF8; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
}
void UartInit(void) //9600bps@12.000MHz 串口初始化,软件自动生成
{
SCON = 0x50; //8位数据,可变波特率
AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xE6; //设定定时初值
TH1 = 0xFF; //设定定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
ES = 1;
EA = 1;
}
void SendDate(uchar dat) //串口发送字符
{
SBUF=dat;
while(TI==0);
TI=0;
}
void SendString(uchar *s) //串口发送字符串
{
unsigned char *p;
p = s;
while(*p != '\0')
{
SBUF = *p;
while(TI == 0); //等待发送标志位置位
TI = 0;
p++;
}
}
void DisplaySMG() //数码管显示设置
{
P2=(P2&0x1f)|0xe0;
P0=0xff; //消隐
P2=P2&0x1f;
P2=(P2&0x1f)|0xc0;
P0=1<<dspcom;
P2=(P2&0x1f)|0xe0;
P0=tab[dspbuff[dspcom]];
P2=P2&0x1f;
if(state==1)
{
if(dspcom==6)
{
P2=(P2&0x1f)|0xe0;
P0=tab[dspbuff[dspcom]]&0x7f; //小数点
P2=P2&0x1f;
}
}
if(state==2)
{
if(dspcom==5)
{
P2=(P2&0x1f)|0xe0;
P0=tab[dspbuff[dspcom]]&0x7f; //小数点
P2=P2&0x1f;
}
}
if(++dspcom==8)
{
dspcom=0;
}
}
void displayWD() //数码管温度显示
{
dspbuff[0]=11;
dspbuff[1]=1;
dspbuff[5]=temper/100;
dspbuff[6]=temper%100/10;
dspbuff[7]=temper%10;
}
void displayAD() //数码管ADC显示
{
dspbuff[0]=11;
dspbuff[1]=2;
dspbuff[5]=v_value/100;
dspbuff[6]=v_value%100/10;
dspbuff[7]=v_value%10;
}
void displayL3() //LED闪烁
{
if(flag2)
{
flag2=0;
P2=(P2&0x1f)|0x80;
x=x^0x04;
P0=x;
P2=(P2&0x1f);
}
}
void Delay5ms() //@12.000MHz 软件延时,自动生成
{
unsigned char i, j;
i = 10;
j = 183;
do
{
while (--j);
} while (--i);
}
void Key_scan() //键盘扫描
{
C3=1;C1=0;C2=1;C4=1;
R3=1;R4=1;
if(R3==0) //S5
{
Delay5ms();
if(R3==0)
{
ES=1;
Control=0;
if(state==1)
{
P2=(P2&0x1f)|0x80;
P0=0xfe;
P2=P2&0x1f;
}
else if(state==2)
{
P2=(P2&0x1f)|0x80;
P0=0xfd;
P2=P2&0x1f;
}
}
while(!R3);
}
else if(R4==0) //S4
{
Delay5ms();
if(R4==0)
{
ES=0;
Control=1;
}
while(!R4);
}
C3=0;C1=1;C2=1;C4=1;
R3=1;R4=1;
if(R4==0) //S12
{
Delay5ms();
if(R4==0)
{
if(state==1)
{
sprintf(str,"%s",s1);
sprintf(str1,"%s",s3);
SendString(str);
SendDate(0x30+temper/100);
SendDate(0x30+temper%100/10);
SendDate('.');
SendDate(0x30+temper%10);
SendString(str1);
SendDate('\r');
SendDate('\n');
}
if(state==2)
{
sprintf(str,"%s",s2);
SendString(str);
SendDate(0x30+v_value/100);
SendDate('.');
SendDate(0x30+v_value%100/10);
SendDate(0x30+v_value%10);
SendDate('V');
SendDate('\r');
SendDate('\n');
}
}
while(!R4);
}
}
void main()
{
InitAll();
Timer0Init();
UartInit();
while(1)
{
if(flag)
{
flag=0;
temperature= rd_temperature();
temper=temperature*10;
}
if(flag1)
{
flag1=0;
Init_pcf8591(0x03);
ad_value= Read_pcf8591();
v_value=ad_value*100/51;
}
if(state==1)
{
displayWD();
}
else if(state==2)
{
displayAD();
}
if(rxc == 1)
{
rxc = 0;
switch(str_re){
case 'A':
{
state=1;
P2=(P2&0x1f)|0x80;
P0=0xfe;
P2=P2&0x1f;
}
break;
case 'B':
{
state=2;
P2=(P2&0x1f)|0x80;
P0=0xfd;
P2=P2&0x1f;
}
break;
}
ES = 1;
}
Key_scan();
if(Control==1)
{
P2=(P2&0x1f)|0x80;
P0=0xff;
displayL3();
}
if(temper>=280)
{
P2=(P2&0x1f)|0xa0;
P04=1;
P2=P2&0x1f;
}
else
{
P2=(P2&0x1f)|0xa0;
P04=0;
P2=P2&0x1f;
}
if(v_value>=360)
{
P2=(P2&0x1f)|0xa0;
P06=1;
//P2=P2&0x1f;
}
else
{
P2=(P2&0x1f)|0xa0;
P06=0;
//P2=P2&0x1f;
}
}
}
void intr_InitTimer() interrupt 1
{
DisplaySMG();
if(++intr==50)
{
intr=0;
flag=1;
}
if(++intr1==60)
{
intr1=0;
flag1=1;
}
if(++intr2==50)
{
intr2=0;
flag2=1;
}
}
void isr_uart(void) interrupt 4
{
if(RI)
{
RI = 0; //清除接收标志位
str_re=SBUF;
ES = 0;
rxc = 1;
}
}
iic.c文章来源:https://www.toymoban.com/news/detail-412937.html
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include "STC15F2K60S2.h"
#include "intrins.h"
#define DELAY_TIME 5
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//发送应答
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0:应答,1:非应答
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
void Init_pcf8591(unsigned char channel)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(channel);
IIC_WaitAck();
IIC_Stop();
}
unsigned char Read_pcf8591()
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return temp;
}
onewire.c文章来源地址https://www.toymoban.com/news/detail-412937.html
/*
程序说明: 单总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
日 期: 2011-8-9
*/
#include "STC15F2K60S2.h"
sbit DQ = P1^4; //单总线接口
//单总线延时函数
void Delay_OneWire(unsigned int t) //STC89C52RC
{
char i;
while(t--)
for(i=0;i<12;i++);
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
//DS18B20设备初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
unsigned int temp;
float rd_temperature(void)
{
unsigned char LSB,MSB;
float tempature;
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0x44);
while(!DQ);
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0xBE);
LSB= Read_DS18B20();
MSB= Read_DS18B20();
temp=MSB&0x0f;
temp=temp<<8;
temp=temp|LSB;
tempature=temp*0.0625;
return tempature;
}
到了这里,关于第十四届蓝桥杯单片机第二场模拟赛程序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!