第十四屆藍(lán)橋杯單片機(jī)第二場(chǎng)模擬賽程序(少量bug)
題目來(lái)源于4T評(píng)測(cè)網(wǎng) www.4t.wiki
賽題:
一、基本要求
使用大賽組委會(huì)提供的國(guó)信長(zhǎng)天單片機(jī)競(jìng)賽實(shí)訓(xùn)平臺(tái),完成本試題的程序設(shè)計(jì)與調(diào)試。程序編寫、調(diào)試完成后,選手需通過(guò)考試系統(tǒng)提交以準(zhǔn)考證號(hào)命名的hex文件。不符合以上文件提交要求的作品將被評(píng)為零分或者被酌情扣分。
硬件設(shè)置:
將IAP15F2K61S2單片機(jī)內(nèi)部振蕩器頻率設(shè)定為12MHz,串口通信波特率為9600bps。
鍵盤工作模式跳線J5配置為KBD矩陣按鍵模式。
擴(kuò)展方式跳線J13配置為IO模式。
請(qǐng)注意:選手需嚴(yán)格按照以上要求配置競(jìng)賽板,編寫和調(diào)試程序,不符合以上配置要求的作品將被評(píng)為零分或者被酌情扣分。
二、硬件框圖
圖1 系統(tǒng)硬件框圖
三、功能描述?
3.1 基本功能描述
1)通過(guò)串口控制數(shù)碼管顯示界面:“溫度顯示界面”或“電壓顯示界面”;也可以返回當(dāng)前數(shù)碼管顯示的數(shù)據(jù)。 ?
2)通過(guò)讀取DS18B20溫度傳感器,獲取環(huán)境溫度。
3)通過(guò) PCF8591 的 ADC 通道測(cè)量電位器 RB2 的輸出電壓。
4)通過(guò)數(shù)碼管顯示獲取的溫度數(shù)據(jù)和采集的電壓數(shù)據(jù),顯示界面可以通過(guò)串口切換。
5)通過(guò)LED指示燈完成題目要求的指示功能。
6)根據(jù)題目要求完成繼電器和蜂鳴器的控制功能。
3.2?性能要求
1)按鍵動(dòng)作響應(yīng)時(shí)間:≤0.2 秒
2)指示燈動(dòng)作響應(yīng)時(shí)間:≤0.1 秒
3.3 顯示功能
溫度顯示界面
溫度顯示界面如圖2所示,顯示內(nèi)容包括界面提示符(U1)和溫度數(shù)據(jù),單位為℃。
圖2 溫度顯示界面(27.5℃)
使用3位數(shù)碼管顯示溫度數(shù)據(jù),溫度數(shù)據(jù)保留小數(shù)點(diǎn)后1位有效數(shù)字。
電壓顯示界面
電壓顯示界面如圖3所示,顯示內(nèi)容包括界面提示符(U2)和電壓數(shù)據(jù),單位為V。
圖3 電壓顯示界面(1.35V)
使用3位數(shù)碼管顯示溫度數(shù)據(jù),電壓數(shù)據(jù)保留小數(shù)點(diǎn)后2位有效數(shù)字。
3.4 按鍵功能
1)按鍵S4定義為“鎖定”按鍵,按下S4按鍵,能夠鎖定當(dāng)前界面“溫度顯示界面”或“電壓顯示界面”,串口切換界面指令失效。
2)按鍵S5定義為“解鎖”按鍵,在界面鎖定時(shí),按下S5按鍵,可取消界面鎖定,串口指令恢復(fù)控制。
3)按鍵S12定義為“發(fā)送”按鍵,每次按下,串口將當(dāng)前數(shù)碼管顯示的數(shù)據(jù)發(fā)送給PC端的串口調(diào)試工具。
注意:
(1)按鍵S5僅在界面鎖定時(shí)有效。
(2)判斷按鍵是否按下時(shí),需進(jìn)行消抖操作,避免單次按鍵操作,觸發(fā)多次結(jié)果。
3.5 串口功能
1)串口發(fā)送指令字符‘A’,進(jìn)入溫度顯示界面。
2)串口發(fā)送指令字符‘B’,進(jìn)入電壓顯示界面。
3)串口返回?cái)?shù)據(jù)格式:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?“TEMP:27.5℃”或“Voltage:1.35V”
注意:?注意區(qū)分字母大小寫。
3.6?LED指示燈功能
當(dāng)前界面處于溫度顯示界面時(shí),L1指示燈點(diǎn)亮,否則熄滅。
當(dāng)前界面處于電壓顯示界面時(shí),L2指示燈點(diǎn)亮,否則熄滅。
當(dāng)前界面處于鎖定狀態(tài)時(shí),L3指示燈以0.1s的時(shí)間間隔亮、滅,否則熄滅。
其余指示燈均處于熄滅狀態(tài)。
3.7 繼電器控制功能
繼電器狀態(tài)受溫度控制,將采集的溫度數(shù)據(jù)記為T,若當(dāng)前采集的溫度滿足下列條件時(shí),繼電器吸合,否則,繼電器斷開(kāi)。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? T≥28℃
3.8 蜂鳴器控制功能
蜂鳴器狀態(tài)受電壓控制,將采集的電壓數(shù)據(jù)記為V,若當(dāng)前采集的電壓滿足下列條件時(shí),蜂鳴器發(fā)聲,否則蜂鳴器靜音。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?V>3.6V
3.9 初始化
上電數(shù)碼管默認(rèn)處于溫度顯示界面。
界面切換處于解鎖狀態(tài)。
指示燈全部熄滅。
程序 :
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; //數(shù)碼管位選標(biāo)志位
uchar ad_value; //AD采集
uchar state=1; //界面切換標(biāo)志位
uchar x=0xff; //LED標(biāo)志
uint v_value; //AD顯示
uint intr=0,intr1=0,intr2=0;
float temperature; //溫度(浮點(diǎn)數(shù))
uint temper; //溫度(整數(shù))
code uchar s1[]={"TEMP:"};
code uchar s2[]={"Voltage:"};
code uchar s3[]={"℃"};
uchar str[20];
uchar str1[10];
uchar str_re='A';
uchar rxcnt=0; //串口標(biāo)志位
uchar Control;
bit flag,flag1,flag2;
bit rxc = 0; /數(shù)據(jù)接收標(biāo)志位
void InitAll() //初始化,關(guān)閉所有LED,蜂鳴器,繼電器
{
P2=(P2&0x1f)|0x80;
P0=0xff;
P2=(P2&0x1f)|0xa0;
P0=0x00;
P2=(P2&0x1f);
}
void Timer0Init(void) //2毫秒@12.000MHz 定時(shí)器初始化,軟件自動(dòng)生成
{
AUXR &= 0x7F; //定時(shí)器時(shí)鐘12T模式
TMOD &= 0xF0; //設(shè)置定時(shí)器模式
TL0 = 0x30; //設(shè)置定時(shí)初值
TH0 = 0xF8; //設(shè)置定時(shí)初值
TF0 = 0; //清除TF0標(biāo)志
TR0 = 1; //定時(shí)器0開(kāi)始計(jì)時(shí)
ET0=1;
EA=1;
}
void UartInit(void) //9600bps@12.000MHz 串口初始化,軟件自動(dòng)生成
{
SCON = 0x50; //8位數(shù)據(jù),可變波特率
AUXR &= 0xBF; //定時(shí)器1時(shí)鐘為Fosc/12,即12T
AUXR &= 0xFE; //串口1選擇定時(shí)器1為波特率發(fā)生器
TMOD &= 0x0F; //設(shè)定定時(shí)器1為16位自動(dòng)重裝方式
TL1 = 0xE6; //設(shè)定定時(shí)初值
TH1 = 0xFF; //設(shè)定定時(shí)初值
ET1 = 0; //禁止定時(shí)器1中斷
TR1 = 1; //啟動(dòng)定時(shí)器1
ES = 1;
EA = 1;
}
void SendDate(uchar dat) //串口發(fā)送字符
{
SBUF=dat;
while(TI==0);
TI=0;
}
void SendString(uchar *s) //串口發(fā)送字符串
{
unsigned char *p;
p = s;
while(*p != '\0')
{
SBUF = *p;
while(TI == 0); //等待發(fā)送標(biāo)志位置位
TI = 0;
p++;
}
}
void DisplaySMG() //數(shù)碼管顯示設(shè)置
{
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; //小數(shù)點(diǎn)
P2=P2&0x1f;
}
}
if(state==2)
{
if(dspcom==5)
{
P2=(P2&0x1f)|0xe0;
P0=tab[dspbuff[dspcom]]&0x7f; //小數(shù)點(diǎn)
P2=P2&0x1f;
}
}
if(++dspcom==8)
{
dspcom=0;
}
}
void displayWD() //數(shù)碼管溫度顯示
{
dspbuff[0]=11;
dspbuff[1]=1;
dspbuff[5]=temper/100;
dspbuff[6]=temper%100/10;
dspbuff[7]=temper%10;
}
void displayAD() //數(shù)碼管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 軟件延時(shí),自動(dòng)生成
{
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; //清除接收標(biāo)志位
str_re=SBUF;
ES = 0;
rxc = 1;
}
}
iic.c文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-412937.html
/*
程序說(shuō)明: IIC總線驅(qū)動(dòng)程序
軟件環(huán)境: Keil uVision 4.10
硬件環(huán)境: CT107單片機(jī)綜合實(shí)訓(xùn)平臺(tái) 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; /* 數(shù)據(jù)線 */
sbit SCL = P2^0; /* 時(shí)鐘線 */
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//總線啟動(dòng)條件
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);
}
//發(fā)送應(yīng)答
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0:應(yīng)答,1:非應(yīng)答
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待應(yīng)答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//通過(guò)I2C總線發(fā)送數(shù)據(jù)
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總線上接收數(shù)據(jù)
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文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-412937.html
/*
程序說(shuō)明: 單總線驅(qū)動(dòng)程序
軟件環(huán)境: Keil uVision 4.10
硬件環(huán)境: CT107單片機(jī)綜合實(shí)訓(xùn)平臺(tái)(外部晶振12MHz) STC89C52RC單片機(jī)
日 期: 2011-8-9
*/
#include "STC15F2K60S2.h"
sbit DQ = P1^4; //單總線接口
//單總線延時(shí)函數(shù)
void Delay_OneWire(unsigned int t) //STC89C52RC
{
char i;
while(t--)
for(i=0;i<12;i++);
}
//通過(guò)單總線向DS18B20寫一個(gè)字節(jié)
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讀取一個(gè)字節(jié)
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設(shè)備初始化
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;
}
到了這里,關(guān)于第十四屆藍(lán)橋杯單片機(jī)第二場(chǎng)模擬賽程序的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!