3本人参加15届蓝桥杯单片机组,目前仍然在学习,关于第12届省赛这是我写的解答代码,欢迎大家评论区指正。
学习于小蜜蜂老师
1.主函数(main.c)
#include "reg52.h"
#include "onewire.h"
#include "smgh.h"
#include "iic.h"
sfr P4=0xC0;
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;
float get_DS18B20=0;
unsigned int smg_DS18B20=0;
unsigned char mode=1;
unsigned char x_mode=1;
unsigned char hot=25;
unsigned int smg_v=0;
void DA_Write(unsigned char dat)
{
IIC_Start();
IIC_SendByte(0x90); //PCF8591的写设备地址
IIC_WaitAck();
IIC_SendByte(0x41); //输出DAC,转换AIN3
IIC_WaitAck();
IIC_SendByte(dat); //设置DAC电压输出参数
IIC_WaitAck(); //产生非应答信号
IIC_Stop();
}
void Display()
{
switch(mode)
{
case 1:
smg_DS18B20=get_DS18B20*100;
DisplaySMG_Bit(0,0xc6);
DisplaySMG_Bit(4,SMGNoDot_CA[smg_DS18B20/1000]);
DisplaySMG_Bit(5,SMGDot_CA[smg_DS18B20/100%10]);
DisplaySMG_Bit(6,SMGNoDot_CA[smg_DS18B20/10%10]);
DisplaySMG_Bit(7,SMGNoDot_CA[smg_DS18B20%10]);
select573(4,0xfd);
break;
case 2:
smg_DS18B20=get_DS18B20*10;
DisplaySMG_Bit(0,0x8c);
DisplaySMG_Bit(6,SMGNoDot_CA[hot/10]);
DisplaySMG_Bit(7,SMGNoDot_CA[hot%10]);
select573(4,0xfb);
break;
case 3:
smg_DS18B20=get_DS18B20*100;
switch(x_mode)
{
case 1:
if(smg_DS18B20<hot*100)
{
DA_Write(0);
DisplaySMG_Bit(0,0x88);
DisplaySMG_Bit(5,SMGDot_CA[0]);
DisplaySMG_Bit(6,SMGNoDot_CA[0]);
DisplaySMG_Bit(7,SMGNoDot_CA[0]);
}
else if(smg_DS18B20>hot*100)
{
DA_Write(255);
DisplaySMG_Bit(0,0x88);
DisplaySMG_Bit(5,SMGDot_CA[5]);
DisplaySMG_Bit(6,SMGNoDot_CA[0]);
DisplaySMG_Bit(7,SMGNoDot_CA[0]);
}
select573(4,0xfe);
break;
case 2:
if(smg_DS18B20<2000)
{
DA_Write(51);
DisplaySMG_Bit(0,0x88);
DisplaySMG_Bit(5,SMGDot_CA[1]);
DisplaySMG_Bit(6,SMGNoDot_CA[0]);
DisplaySMG_Bit(7,SMGNoDot_CA[0]);
}
else if(smg_DS18B20>2000||smg_DS18B20<4000)
{
smg_v=(smg_DS18B20*0.15)-200;
DA_Write((smg_v*51)/100);
DisplaySMG_Bit(0,0x88);
DisplaySMG_Bit(5,SMGDot_CA[smg_v/100]);
DisplaySMG_Bit(6,SMGNoDot_CA[smg_v/10%10]);
DisplaySMG_Bit(7,SMGNoDot_CA[smg_v%10]);
}
else if(smg_DS18B20>4000)
{
DA_Write(210);
DisplaySMG_Bit(0,0x88);
DisplaySMG_Bit(5,SMGDot_CA[4]);
DisplaySMG_Bit(6,SMGNoDot_CA[0]);
DisplaySMG_Bit(7,SMGNoDot_CA[0]);
}
select573(4,0xf7);
break;
}
break;
}
}
void GetDS18B20()
{
unsigned char low,high;
unsigned int temp=0;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Display();
init_ds18b20();
Display();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
Display();
low=Read_DS18B20();
high=Read_DS18B20();
temp=(high<<8)|low;
Display();
if((temp&0xf800)==0x0000)
{
get_DS18B20=temp*0.0625;
}
Display();
}
void Scankennys()
{
R4=0;
R1=R2=R3=1;
C1=C2=C3=C4=1;
if(C1==0)
{
delay(100);
if(C1==0)
{
switch(mode)
{
case 1:
mode=2;
break;
case 2:
mode=3;
break;
case 3:
mode=1;
break;
}
while(C1==0)
{
if(mode==1)
{
GetDS18B20();
}
Display();
}
}
}
if(mode==2)
{
R3=0;
R1=R2=R4=1;
C1=C2=C3=C4=1;
if(C2==0)
{
delay(100);
if(C2==0)
{
hot++;
}
while(C2==0)
{
Display();
}
}
R4=0;
R1=R2=R3=1;
C1=C2=C3=C4=1;
if(C2==0)
{
delay(100);
if(C2==0)
{
hot--;
}
while(C2==0)
{
Display();
}
}
}
R3=0;
R1=R2=R4=1;
C1=C2=C3=C4=1;
if(C1==0)
{
delay(100);
if(C1==0)
{
switch(x_mode)
{
case 1:
x_mode=2;
break;
case 2:
x_mode=1;
break;
}
while(C1==0)
{
Display();
}
}
}
}
void main()
{
initsystem();
while(1)
{
Scankennys();
GetDS18B20();
}
}
-
2.onewire.c(单总线底层驱动代码)
#include "onewire.h"
//单总线延时函数
void Delay_OneWire(unsigned int t)
{
while(t--);
}
//DS18B20芯片初始化
bit init_dS18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(144);
DQ = 0;
Delay_OneWire(960);
DQ = 1;
Delay_OneWire(120);
initflag = DQ;
Delay_OneWire(60);
return initflag;
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(60);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(60);
}
//从DS18B20读取一个字节
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(60);
}
return dat;
}
3.iic.c
#include "reg52.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);
}
//发送应答
//等待应答
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总线上接收数据
4.iic.h
#ifndef _IIC_H
#define _IIC_H
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);
#endif
5.onewire.h
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
#include "reg52.h"
sbit DQ = P1^4;
bit init_ds18b20(void);
unsigned char Read_DS18B20(void);
void Write_DS18B20(unsigned char dat);
#endif
6.smgc.c(这是我的模版,控制数码管以及573锁存器的选择,应用起来比较方便)
#include "reg52.h"
sbit S7=P3^6;
sbit S6=P3^5;
sbit S5=P3^4;
sbit S4=P3^3;
void select573(unsigned char n,dat)
{
P0=dat;
switch(n)
{
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;
}
P2 = (P2 & 0x1f) | 0x00;
}
void delay(unsigned int t)
{
while(t--);
}
void DisplaySMG_Bit(unsigned char pos, unsigned char value)
{
select573(6, 0x01 << pos); //数码管的段位
select573(7, value); //数码管显示内容
delay(500); //数码管点亮时长
select573(6, 0x01 << pos);
select573(7, 0xff); //消隐
}
void Displayall(unsigned char dat)
{
select573(6,0xff);
select573(7,dat);
}
void initsystem()
{
select573(4,0xff);
select573(5,0x00);
Displayall(0xff);
}
7.smgh.h(模板头文件)
#ifndef _SMGH_H
#define _SMGH_H
code unsigned char SMGNoDot_CA[10] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
code unsigned char SMGDot_CA[10] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
void select573(unsigned char n,dat);
void DisplaySMG_Bit(unsigned char pos , value);
void delay(unsigned int t);
void Displayall(unsigned char dat);
void initsystem();
#endif
应该是把所有功能都实现了,我觉得这个写法可能没有全部模块儿化那么简洁结构条理。
但是非常适合新手小白理解。如有不懂可以私信提问,看到了就回。同时恳请大佬指正改进!