第十四届蓝桥杯单片机第二场模拟赛程序(少量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;}