【蓝桥杯】第十二届单片机省赛
蓝桥杯省赛
题目
代码参考
#include "reg52.h"
#include "iic.h"
#include "onewire.h"
typedef unsigned char uint8;
typedef unsigned int uint32;
#define LED_Channel 4
#define BEEP_DELAY_Channel 5
#define COM_Channel 6
#define SMG_Channel 7
sfr P4 = 0xc0;
sfr AUXR = 0x8e;
//数码管编码
uint8 code TAB[19] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x7f,0x8c};
//带小数点
uint8 code Dot_TAB[16]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e} ;
//矩阵按键接口 J5:12
sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;
sbit C1 = P4^4;
sbit C2 = P4^2;
sbit C3 = P3^5;
sbit C4 = P3^4;
uint8 cnttemp = 0;
uint8 cntdac = 0;
uint8 cnttemp_flag = 0;
uint8 cntdac_flag = 0;
uint8 node = 0;//0 1 2
uint8 mode = 0;//0 1
uint32 temp = 0;
uint32 Vdac = 1;
uint8 default_temp = 25;
uint8 last_temp = 25;
//uint8 key_value = 0;
void Delay(uint32 ms);
void InitHC138(uint8 Channel);
void Init_System(void);
void Display_Bit(uint8 pos,uint8 date);
void Display_All(uint8 date);
void Dislpay(uint8 node);
void Key_Scan();
void Read_Temp(void);
void SMG_Delay(uint32 t);
void DAC_Hander(void);
void DAC(uint8 date);
void LED_Control(void);
void Timer0Init(void) //50毫秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初始值
TH0 = 0x4C; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
EA = 1;
}
void Time0_Hander(void) interrupt 1
{
cnttemp++;
cntdac++;
if(cnttemp == 10)//50*10
{
cnttemp = 0;
cnttemp_flag = 1;
//Read_Temp();
}
if(cntdac == 5)//50*5
{
cntdac = 0;
cntdac_flag = 1;
//DAC_Hander();
}
}
void main()
{
Init_System();
Timer0Init();
LED_Control();
while(1)
{
if(cnttemp_flag)
{
Read_Temp();
cnttemp_flag = 0;
}
Key_Scan();
Dislpay(node);
if(cntdac_flag)
{
DAC_Hander();
cntdac_flag = 0;
}
}
}
void LED_Control(void)
{
uint8 date = 0xff;
switch(node)
{
case 0://L2
date = ~(date & 0x02);
break;
case 1://L3
date = ~(date & 0x04);
break;
case 2://L4
date = ~(date & 0x08);
break;
}
if(!mode)
date&=0xfe;
InitHC138(LED_Channel);
P0 = date;
InitHC138(0);
}
void Delay(uint32 ms)
{
uint32 x,y;
for(x=0;x<ms;x++)
for(y=846;y>0;y--){}
}
void InitHC138(uint8 Channel)
{
switch(Channel)
{
case 4:P2 = (P2 & 0x1f) | 0x80;break;
case 5:P2 = (P2 & 0x1f) | 0xa0;break;
case 6:P2 = (P2 & 0x1f) | 0xc0;break;
case 7:P2 = (P2 & 0x1f) | 0xe0;break;
default:P2 &= 0x1f;
}
}
void Init_System(void)
{
InitHC138(BEEP_DELAY_Channel);
P0 = 0x00;
InitHC138(LED_Channel);
P0 = 0xff;
InitHC138(0);
}
void Display_Bit(uint8 pos,uint8 date)
{
InitHC138(COM_Channel);
P0 = 0x01<<pos;
InitHC138(SMG_Channel);
P0 = date;
InitHC138(0);
}
void Display_All(uint8 date)
{
InitHC138(COM_Channel);
P0 = 0xff;
InitHC138(SMG_Channel);
P0 = date;
InitHC138(0);
}
void SMG_Delay(uint32 t)
{
while(t--)
{
Dislpay(node);
}
}
void Dislpay(uint8 node)//不要忘记 Delay(1)
{
switch(node)
{
case 0:
Display_Bit(0,TAB[12]),Delay(1);
Display_Bit(1,0xff),Delay(1);
Display_Bit(2,0xff),Delay(1);
Display_Bit(3,0xff),Delay(1);
Display_Bit(4,TAB[temp/1000]),Delay(1);
Display_Bit(5,Dot_TAB[(temp%1000)/100]),Delay(1);
Display_Bit(6,TAB[(temp%100)/10]),Delay(1);
Display_Bit(7,TAB[temp%10]),Delay(1);
Display_All(0xff);
break;
case 1:
Display_Bit(0,TAB[18]),Delay(1);
Display_Bit(1,0xff),Delay(1);
Display_Bit(2,0xff),Delay(1);
Display_Bit(3,0xff),Delay(1);
Display_Bit(4,0xff),Delay(1);
Display_Bit(5,0xff),Delay(1);
Display_Bit(6,TAB[last_temp/10]),Delay(1);
Display_Bit(7,TAB[last_temp%10]),Delay(1);
Display_All(0xff);
break;
case 2:
if(mode == 0)
{
Display_Bit(0,TAB[10]),Delay(1);
Display_Bit(1,0xff),Delay(1);
Display_Bit(2,0xff),Delay(1);
Display_Bit(3,0xff),Delay(1);
Display_Bit(4,0xff),Delay(1);
Display_Bit(5,Dot_TAB[Vdac]),Delay(1);
Display_Bit(6,TAB[0]),Delay(1);
Display_Bit(7,TAB[0]),Delay(1);
Display_All(0xff);
}
else
{
Display_Bit(0,TAB[10]),Delay(1);
Display_Bit(1,0xff),Delay(1);
Display_Bit(2,0xff),Delay(1);
Display_Bit(3,0xff),Delay(1);
Display_Bit(4,0xff),Delay(1);
Display_Bit(5,Dot_TAB[Vdac/100]),Delay(1);
Display_Bit(6,TAB[(Vdac%100)/10]),Delay(1);
Display_Bit(7,TAB[Vdac%10]),Delay(1);
Display_All(0xff);
}
break;
default:Display_All(0xff);break;
}
}
void DAC_Hander(void)
{
if(mode==0)
{
if(temp<default_temp*100)
{
Vdac = 0;
DAC(0x00);
}
else
{
Vdac = 5;
DAC(0xff);
}
}
else
{
if(temp<=2000)
Vdac = 100;
else if(temp>=4000)
Vdac = 400;
else
Vdac = 0.15*temp-200;
DAC( (uint8)(Vdac*0.51) );
}
}
void DAC(uint8 date) // 输入值需要转换[0~255]
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x40);
IIC_WaitAck();
IIC_SendByte(date);
IIC_WaitAck();
IIC_Stop();
}
void Key_Scan()
{
R1=1,R2=1,R3=0,R4=1;
C1=1,C2=1,C3=1,C4=1;
if(C1==0&&node==2)//s5
{
Delay(10);
if(C1==0)
{
++mode;
if(mode>=2)
mode = 0;
while(C1==0)
{
Dislpay(node);
LED_Control();
}
}
}
if(C2==0&&node==1)//s9 +1
{
Delay(10);
if(C2==0&&node==1)
{
if(last_temp<99)
++last_temp;
while(C2==0)
{
Dislpay(node);
LED_Control();
}
}
}
R1=1,R2=1,R3=1,R4=0;
C1=1,C2=1,C3=1,C4=1;
if(C1==0)//s4
{
Delay(10);
if(C1==0)
{
++node;
if(node == 2)
{
default_temp = last_temp;
}
if(node>=3)
node = 0;
while(C1==0)
{
Dislpay(node);
LED_Control();
}
}
}
if(C2==0&&node==1)//s8 -1
{
Delay(10);
if(C2==0&&node==1)
{
if(last_temp>0)
--last_temp;
while(C2==0)
{
Dislpay(node);
LED_Control();
}
}
}
}
//初始化,跳过rom,操作
//前5位是符号位,后4位是小数位,小数存放在LSB(低位先读),//0.0625*10
void Read_Temp(void)
{
uint8 LSB,MSB;
init_ds18b20();
Write_DS18B20(0xcc); //跳过ROM指令
Write_DS18B20(0x44); //开始温度转换
SMG_Delay(50);
//Delay_OneWire(200); // 延时一段时间
init_ds18b20();
Write_DS18B20(0xcc); //跳过ROM指令
Write_DS18B20(0xbe); //读取高速暂存器
//SMG_Delay(400);
LSB =Read_DS18B20(); //读取第一个字节
MSB =Read_DS18B20(); //读取第二字节
temp = (MSB<<8)|LSB;
//包含小数 ,如果不包含小数,直接将temp右移4位即可
if((temp & 0xf800)== 0x0000) //判断高五位符号位是否为0 ,即是否为正数
{
temp = temp>>4;
temp = temp * 100;
temp = temp + (LSB & 0x0f)*6.25 ;
}
if(temp==8500)
temp = 0;
}
/*
float Read_Temp(void)
{
uint8 LSB,MSB;
uint32 result;
float ans;
init_ds18b20();
Write_DS18B20(0xcc); //跳过ROM指令
Write_DS18B20(0x44); //开始温度转换
//SMG_Delay(50);
Delay_OneWire(200); // 延时一段时间
init_ds18b20();
Write_DS18B20(0xcc); //跳过ROM指令
Write_DS18B20(0xbe); //读取高速暂存器
LSB =Read_DS18B20(); //读取第一个字节
MSB =Read_DS18B20(); //读取第二字节
result = ( (MSB&0x0f)<<8 )| LSB;
ans = result*0.0625;
return ans;
}
*/
总结
好久没看单片机,一开始数码管动态显示忘了加Delay(1),屏幕乱闪,翻了以前代码才看出bug,最后花了点时间写了一下也没细看,基本功能实现,优化和改错之后再弄。