十二 蓝桥杯
problem:未使用AD/DA转化器,本题是运用温度与电压之间的关系转化出来的,给出了一次函数(嗯嗯,以后会了在补充),LED亮度不一致,L1比L2,L3,L4要亮(关于PWM,不是很会)
十二.c
#include"reg52.h"
#include"onewire.h"
#include"delay.h"
#define uchar unsigned char
#define uint unsigned int
sfr P4 = 0xc0;//将P3^7与P3^6引脚用P4^4与P4^2来完成
sbit a1 = P3^0;sbit a2 = P3^1;sbit a3 = P3^2;sbit a4 = P3^3;
sbit b1 = P4^4;sbit b2 = P4^2;sbit b3 = P3^5;sbit b4 = P3^4;
//将引脚重新定义名称
uchar code SMG_position[9] = {0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar code SMG_duanma[15] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0xc6,0x8c,0x88};
uchar yi,er,san,si,wu,liu,qi,ba;
uchar state=0;//显示数码管状态更换
uchar flag=0;//模式1与模式2状态更换
uchar x = 25;//初始化参数温度
uint v;//根据温度AD转化的电压值
void InitHC138(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;
}
}
void ShowSMG_Bit(uchar dat,uchar pos)
{
InitHC138(7);P0 = 0xff;//俗称“消影”
InitHC138(6);P0 = SMG_position[pos];
InitHC138(7);P0 = SMG_duanma[dat];
}
void ShowDotSMG_Bit(uchar dat,char pos)//带点段码数码管的位选
{
InitHC138(7);P0 = 0xff;
InitHC138(6);P0 = SMG_position[pos];
InitHC138(7);P0 = SMG_duanma[dat]&0x7f;
}
void InitSystem()
{
InitHC138(4);P0 = 0xff;
InitHC138(5);P0 = 0x00;
InitHC138(6);P0 = 0xff;
InitHC138(7);P0 = 0xff;
}
void control_SMG()
{
if(state == 0)
{
yi = 12;
er=san=si=11;
wu = temp/1000;
liu = temp%1000/100;
qi = temp%100/10;
ba = temp%10;
ShowDotSMG_Bit(liu,6);Delay2ms();
InitHC138(4);P0 = 0xfd;
}
if(state == 1)
{
yi = 13;
er=san=si=wu=liu=11;
qi = x/10;
ba = x%10;
ShowSMG_Bit(liu,6);Delay2ms();
InitHC138(4);P0 = 0xfb;
}
if(state == 2)
{
yi = 14;
er=san=si=wu=11;
liu = v/100;
qi = v%100/10;
ba = v%10;
ShowDotSMG_Bit(liu,6);Delay2ms();
InitHC138(4);P0 = 0xf7;
}
}
void All_SMG()
{
InitHC138(6);P0 = 0xff;
InitHC138(7);P0 = 0xff;
}
void Display_SMG()//单片机运行速度非常快,只要时间小于10ms,通过人的眼睛是识别不了变化的
{
control_SMG();
ShowSMG_Bit(yi,1);Delay2ms();
ShowSMG_Bit(er,2);Delay2ms();
ShowSMG_Bit(san,3);Delay2ms();
ShowSMG_Bit(si,4);Delay2ms();
ShowSMG_Bit(wu,5);Delay2ms();
ShowSMG_Bit(qi,7);Delay2ms();
ShowSMG_Bit(ba,8);Delay2ms();
All_SMG();Delay2ms();
}
void key_Cans()
{
a4=0;a2=a3=a1=1;
b1=b2=b3=b4=1;
if(b1==0)
{
Delay10ms();//消抖
if(b1==0)
{
switch(state)
{
case 0:state = 1;break;
case 1:state = 2;break;
case 2:state = 0;break;
}
}
while(b1==0)Display_SMG();
}
else if(b2==0)
{
Delay10ms();
if(b2==0)
{
if(state==1)
{
x--;
}
}
while(b2==0)Display_SMG();
}
a3=0;a1=a2=a4=1;
b1=b2=b3=b4=1;
if(b1==0)
{
Delay10ms();
if(b1==0)
{
switch(flag)
{
case 0:flag=1;break;
case 1:flag=0;break;
}
}
while(b1==0)Display_SMG();
}
else if(b2==0)
{
Delay10ms();
if(b2==0)
{
if(state==1)
{
x++;
}
}
while(b2==0)Display_SMG();
}
}
void Change_DA()
{
uint i;//0~65535
if(flag==0)
{
InitHC138(4);
P0 = 0xfe;
i = x*100;
if(temp<i)
{
v=0;
}
else if(temp>i)
{
v = 500;
}
}
if(flag==1)//初中数学一次函数推出温度与电压之间的关系
{
if(temp<=2000)
{
v=100;
}
else if(temp>2000&&temp<4000)
{
v = temp*0.15;
v = v-2;
}
else if(temp>=4000)
{
v = 400;
}
}
}
void main()
{
InitSystem();
while(1)
{
Read_T();
key_Cans();
Change_DA();
Display_SMG();
}
}
onewire.h
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
unsigned char rd_temperature(void);
bit init_ds18b20(void);
unsigned char Read_DS18B20(void);
void Write_DS18B20(unsigned char dat);
void Delay_OneWire(unsigned int t);
void Read_T();
extern unsigned int temp;//extern可以将temp存储至十二.c使用
#endif
onewire,c
//从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(20);
}
return dat;
}
//DS18B20设备初始化
bit init_ds18b20(void)
{
bit initflag = 0;
//DQ = 1;
//Delay_OneWire(5);
DQ = 0;
Delay_OneWire(200);
DQ = 1;
Delay_OneWire(20);
initflag = DQ;
Delay_OneWire(100);
return initflag;
}
void Read_T()
{
unsigned char LSB,MSB;
init_ds18b20();
Write_DS18B20(0xcc);//跳过ROM指令
Write_DS18B20(0x44);//温度转化
Delay_OneWire(100);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);//读取温度
LSB = Read_DS18B20();
MSB = Read_DS18B20();
init_ds18b20();
temp = 0x0000;
temp = MSB;
temp = temp<<8;
temp = temp | LSB;
if((temp&0xf800) == 0x0000)//判断温度正负,若违反取反加1
{
temp = temp>>4;//移出小数部分
temp = temp*100;
temp = temp+(LSB&0x0f)*6.25;//采用的是数码管直接点上点党的方式,若采用浮点数计算的话会影响单片机运行速度
}
}