第十四届蓝桥杯单片机第二场模拟赛程序(少量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.6LED指示灯功能
当前界面处于温度显示界面时,L1指示灯点亮,否则熄灭。
当前界面处于电压显示界面时,L2指示灯点亮,否则熄灭。
当前界面处于锁定状态时,L3指示灯以0.1s的时间间隔亮、灭,否则熄灭。
其余指示灯均处于熄灭状态。
3.7 继电器控制功能
继电器状态受温度控制,将采集的温度数据记为T,若当前采集的温度满足下列条件时,继电器吸合,否则,继电器断开。
T≥28℃
3.8 蜂鸣器控制功能
蜂鸣器状态受电压控制,将采集的电压数据记为V,若当前采集的电压满足下列条件时,蜂鸣器发声,否则蜂鸣器静音。
V>3.6V
3.9 初始化
上电数码管默认处于温度显示界面。
界面切换处于解锁状态。
指示灯全部熄灭。
程序 :
main.c
#include #include #include #include #define uchar unsigned char#define uint unsigned intsbit 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 灭 Uuchar 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,即12TAUXR &= 0xFE;//串口1选择定时器1为波特率发生器TMOD &= 0x0F;//设定定时器1为16位自动重装方式TL1 = 0xE6;//设定定时初值TH1 = 0xFF;//设定定时初值ET1 = 0;//禁止定时器1中断TR1 = 1;//启动定时器1ES = 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<=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
/* 程序说明: 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
/* 程序说明: 单总线驱动程序 软件环境: 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>= 1;}Delay_OneWire(5);}//从DS18B20读取一个字节unsigned char Read_DS18B20(void){unsigned char i;unsigned char dat; for(i=0;i>= 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;}