第十二届“蓝桥杯”单片机省赛(1)——程序设计题
个人编写,代码仅供参考
如有不足,多多指教
1.题目
2.代码
main.c程序
#include "reg52.h"
#include "onewire.h"
#include "iic.h"
//=============================参数定义
uchar code smg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0XFF,0xc1,0x8e,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x8c,0xc8,0xc6,0x88};
// 0 1 2 3 4 5 6 7 8 9 - mie U F 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. p n C A
sfr AUXR = 0X8E;
sfr P4 = 0XC0;
//sbit p32 = P3^2;
//sbit p33 = P3^3;
sbit c1 = P4^2;
sbit c2 = P4^4;
uchar xianshi = 0;//0 温度显示 1 参数设置 2 dac输出
uchar wengducanshu = 25;//温度参数初始化为25摄氏度
uchar wengducanshu_temp = 25;//温度参数(暂存)
uchar moshi = 0;//0 模式1 1 模式2
float vol_real;
unsigned short tempr = 0;//0~255的温度参数
//=============================函数声明
void select(uchar channel);
void cls_relay_buz_led_smg();
void key_scan();
void smg_delay(uint time);
void smg_dis(uchar pos,uchar val);
void smg_dis_all(uchar val);
void smg_show();
void read_tempr();
void dac_output();
void led_show();
//=============================主函数
void main()
{
cls_relay_buz_led_smg();
while(1)
{
read_tempr();
dac_output();
key_scan();
smg_show();
led_show();
}
}
//=============================初始化函数
void select(uchar 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;
case 0 : P2 = (P2 & 0X1F) | 0X00;break;
}
}
void cls_relay_buz_led_smg()
{
select(4);
P0 = 0XFF;
select(5);
P0 &= 0xaf;
select(0);
P0 = 0XFF;
select(6);
P0 = 0XFF;
select(7);
P0 = 0xff;
select(0);
}
//=============================按键扫描函数
void key_scan()
{
P3 = (P3 & 0XF0) | 0X07;
c1 = c2 = 1;
if(c2 == 0)//s4按下
{
smg_show();
if(c2 == 0)
{
while(c2 == 0)
{
smg_show();
}
switch(xianshi)
{
case 0 : xianshi = 1; break;
case 1 : xianshi = 2;wengducanshu = wengducanshu_temp; break;
case 2 : xianshi = 0; break;
}
}
}
else if(c1 == 0)
{
smg_show();
if(c1 == 0)//s8按下
{
while(c1 == 0)
{
smg_show();
}
if(xianshi == 1)
{
if(wengducanshu_temp == 0)
{
wengducanshu_temp = 0;
}
else
{
wengducanshu_temp--;
}
}
}
}
P3 = (P3 & 0XF0) | 0X0B;
c1 = c2 = 1;
if(c2 == 0)//s5按下
{
smg_show();
if(c2 == 0)
{
while(c2 == 0)
{
smg_show();
}
switch(moshi)
{
case 0 : moshi = 1;break;
case 1 : moshi = 0;break;
}
}
}
else if(c1 == 0)//s9按下
{
smg_show();
if(c1 == 0)
{
while(c1 == 0)
{
smg_show();
}
if(xianshi == 1)
{
if(wengducanshu_temp == 99)
{
wengducanshu_temp = 99;
}
else
{
wengducanshu_temp++;
}
}
}
}
}
//===================================数码管函数
void smg_delay(uint time)
{
while(time--);
}
void smg_dis(uchar pos,uchar val)
{
select(7);
P0 = 0XFF;
select(6);
P0 = 0x01 << pos;
select(7);
P0 = smg[val];
select(0);
smg_delay(500);
}
void smg_dis_all(uchar val)
{
select(7);
P0 = 0XFF;
select(6);
P0 = 0xff;
select(7);
P0 = smg[val];
select(0);
smg_delay(500);
}
void smg_show()
{
if(xianshi == 0)
{
smg_dis(0,26);
smg_dis(1,11);
smg_dis(2,11);
smg_dis(3,11);
smg_dis(4,tempr/1000);
smg_dis(5,(tempr/100)%10+14);
smg_dis(6,(tempr/10)%10);
smg_dis(7,tempr%10);
smg_dis_all(11);
}
else if(xianshi == 1)
{
smg_dis(0,24);
smg_dis(1,11);
smg_dis(2,11);
smg_dis(3,11);
smg_dis(4,11);
smg_dis(5,11);
smg_dis(6,wengducanshu_temp/10);
smg_dis(7,wengducanshu_temp%10);
smg_dis_all(11);
}
else if(xianshi == 2)
{
smg_dis(0,27);
smg_dis(1,11);
smg_dis(2,11);
smg_dis(3,11);
smg_dis(4,11);
smg_dis(5,(uint)(vol_real*100)/100+14);
smg_dis(6,((uint)(vol_real*100)/10)%10);
smg_dis(7,(uint)(vol_real*100)%10);
smg_dis_all(11);
}
}
//====================================温度读取
void read_tempr()
{
tempr = rd_tempreture_xiaoshuliangwei();
}
//====================================dac输出函数
void dac_output()
{
if(moshi == 0)
{
if(((float)tempr)/100 < (float)wengducanshu)
{
pcf_dac(0);
vol_real = 0.00;
}
else
{
pcf_dac(255);
vol_real = 5.00;
}
}
else if(moshi == 1)
{
if(((float)tempr)/100 < 20.00)
{
pcf_dac(51);
vol_real = 1.00;
}
else if(((float)tempr)/100 > 40.00)
{
pcf_dac(204);
vol_real = 4.00;
}
else
{
pcf_dac((uchar)((((float)tempr)/100*0.15 -2)*255/5));
vol_real = ((float)tempr)/100*0.15 -2;
}
}
}
//===========================================LED函数
void led_show()
{
if(moshi == 0)
{
select(4);
P0 &= 0xfe;
select(0);
}
else
{
select(4);
P0 |= 0x01;
select(0);
}
if(xianshi == 0)
{
select(4);
P0 = (P0 & 0xfd) | 0X0C;
select(0);
}
else if(xianshi == 1)
{
select(4);
P0 = (P0 & 0xFB) | 0X0A;
select(0);
}
else if(xianshi == 2)
{
select(4);
P0 = (P0 & 0xF7) | 0X06;
select(0);
}
}
onewire.c程序
#include "onewire.h"
//单总线内部延时函数
uchar i;
void Delay_OneWire(unsigned int t)
{
while(t--);
for(i=0;i<12;i++);
}
//单总线写操作
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(20);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//单总线读操作
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(20);
}
return dat;
}
//DS18B20初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(200);
DQ = 1;
Delay_OneWire(20);
initflag = DQ;
Delay_OneWire(100);
return initflag;
}
//==================================温度读取函数
unsigned short rd_tempreture_xiaoshuliangwei()
{
unsigned short temp = 0x0000;
uchar msb,lsb;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay_OneWire(200);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
lsb = Read_DS18B20();
msb = Read_DS18B20();
init_ds18b20();
temp = msb;
temp = (temp << 8) | lsb;
if((temp&0xf800)==0x0000)
{
temp >>= 4;
temp = temp *100;
temp = temp + (lsb & 0x0f) * 0.0625 * 100 ;
}
return temp;
}
onewire.h程序
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
#include "reg52.h"
sbit DQ = P1^4;
unsigned short rd_tempreture_xiaoshuliangwei();
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
#endif
iic.c程序
#include "iic.h"
#define DELAY_TIME 5
//I2C总线内部延时函数
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//I2C总线启动信号
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//I2C总线停止信号
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;
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;
}
//=============================pcf函数
void pcf_dac(uchar dat)//dat (0,255)
{
IIC_Start();
IIC_SendByte(0X90);
IIC_WaitAck();
IIC_SendByte(0X43);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
iic.h程序
#ifndef __IIC_H
#define __IIC_H
#include "reg52.h"
#include "intrins.h"
sbit SDA = P2^1;
sbit SCL = P2^0;
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
void pcf_dac(uchar dat);//dat (0,255)
#endif