#include <STC15F2K60S2.H>
#include <onewire.H>
#include <stdio.H>
#include <iic.H>
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;
unsigned char F_SMG=1; //数码管标志位 1温度界面 2电压读取界面
unsigned char command; //获取下位机命令
unsigned int SMG_vlot; //数码管电压显示参数
unsigned int SMG_T; //数码管温度显示参数
unsigned int adc_value; //电压处理参数
unsigned char count_t; //T0 定时50ms 中断计数
float adc_vlot; //电压实际值
float b20_temp; //温度实际值
unsigned char code Nodat[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char code Isdat[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//=============================控制函数====================================
void SelctHC573(unsigned char n) //P2控制位HC573
{
switch(n)
{
case 0: P2=(P2 & 0x1f) |0x00; break;
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;
}
}
//========= P0输出控制位
void Output_P0(unsigned char pos,unsigned char value)
{
SelctHC573(pos);
P0=value; //控制完成后,取消位选,P0赋值为0x00
SelctHC573(0);
P0=0x00;
}
//======== 数码管专用延时 1-3ms
void Delay2ms()
{
unsigned char i, j;
i= 24;
j = 85;
do
{
while (--j);
} while (--i);
}
//======== 单个数码控制
void SMGBit(unsigned char pos,unsigned char value)
{
Output_P0(6,0x01<<pos); //位选————段选赋值————延时—————位选输出---—关闭数码管
Output_P0(7,value);
Delay2ms();
Output_P0(6,0x01<<pos);
Output_P0(7,0xff);
}
//======== 全部数码管控制
void SMGALL(unsigned char value)
{
Output_P0(6,0xff);
Output_P0(7,value);
}
//=============================显示函数====================================
void DisplaySMG()
{
switch(F_SMG)
{
case 1 : //温度界面
Output_P0(4,~0x01); //点亮L1灯
SMGBit(0,0xc1); //U
SMGBit(1,Nodat[1]); //界面1 or 2
SMGBit(2,0xff);
SMGBit(3,0xff);
SMGBit(4,0xff);
SMGBit(5, Nodat[SMG_T/100] ); // SMG_T=212 实际温度21.2扩大10倍
SMGBit(6, Isdat[(SMG_T/10)%10] ); //十位
SMGBit(7, Nodat[SMG_T%10] ); // 各位
SMGALL(0xff); // 全部数码管静止显示
break;
case 2 :
Output_P0(4,~0x02);
SMGBit(0,0xc1);
SMGBit(1,Nodat[2]);
SMGBit(2,0xff);
SMGBit(3,0xff);
SMGBit(4,0xff);
SMGBit(5, Isdat[SMG_vlot/100] ); // SMG_vlot=129 实际电压1.29.扩大100倍
SMGBit(6, Nodat[(SMG_vlot/10)%10] );
SMGBit(7, Nodat[SMG_vlot%10] );
SMGALL(0xff);
break;
}
}
//======== 刷新数码管的延时函数
void Delay1ms(unsigned char t)
{
while(t--)
{
DisplaySMG(); //总延时==8*数码专用延时*T ms
}
}
//=============================初始化函数====================================
void Initsystem()
{
Output_P0(4,0xff); //关闭LED灯、蜂鸣器、继电器
Output_P0(5,0x00); //打开串行中断允许位
ES=1;
}
//======== Uart1初始化
void IintUart()
{
SCON = 0x50; //8位数据,可变波特率
AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xE6; //设定定时初值
TH1 = 0xFF; //设定定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
EA = 1; //打开总中断 ******自己添加***
}
//======== T0初始化
void Timer0Init() //50毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0xB0; //设置定时初值
TH0 = 0x3C; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1; //********EA ET0 自己添加********
ET0=1;
}
//=============================中断请求函数====================================
void ServiceTimber0() interrupt 1
{
TL0 = 0xB0; //设置定时初值
TH0 = 0x3C; //设置定时初值
count_t++;
if(count_t==2)
{
count_t=0; // 定时到0.1s 判断串行口是否关闭
if(ES==0)
{
Output_P0(4,~0x04); // L3点亮
} }
}
//======== Uart中断
void ServiceUart() interrupt 4
{
if(RI==1)
{
command=SBUF; //下位机命令读取
RI=0;
}
}
//=============================printf函数初始化====================================
//======== 发送一个字节数据
void sendByte(unsigned char dat){
SBUF = dat; //写入发送缓冲寄存器
while(!TI); //等待发送完成,TI发送溢出标志位 置1
TI = 0; //对溢出标志位清零
}
//======== 输出重定向到串口
char putchar(char c)
{
sendByte(c);
return c; //返回给函数的调用者printf
}
//=============================下位机命令处理====================================
void Command_mange ()
{
if(command=='A')
{
F_SMG=1; command='\0';
}
if(command=='B')
{
F_SMG=2; command='\0';
}
}
//=============================温度电压数据读取====================================
//======== 温度读取
unsigned int Read_temp ()
{
unsigned int medium;
unsigned char LSB,MSB;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay1ms(31); //****750ms*******
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB=Read_DS18B20();
MSB=Read_DS18B20();
medium=MSB;
medium <<=8;
medium |= LSB;
if((medium & 0xf800)==0x0000)
{
medium=medium>>4;
medium=medium*10;
medium=(medium+(LSB&0x0f)*0.625);
}
return medium; //返回值 为实际温度的10倍
}
//======== 电压读取
unsigned char Read_AD()
{
unsigned char medium;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Stop();
DisplaySMG(); //****几毫秒足够*******
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
medium=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return medium; //返回值 为未处理的AD值
}
//=============================温度电压数据处理====================================
void Date_mange()
{
char i;
SMG_T=Read_temp();
adc_value=0;
for(i=0;i<3;i++)
{
adc_value +=Read_AD();
}
adc_value=adc_value/3; //三次采样取平均的电压值
adc_vlot=adc_value*(5.0/255); //实际电压值
SMG_vlot=adc_vlot*100; //数码管电压值
//======== 温度电压判断
if(SMG_T>=240)
{
Output_P0(5,(P0&0x40)|0x10); // 温度电压判断
DisplaySMG();
}
if(adc_vlot>=3.6)
{
Output_P0(5,(P0&0x10)|0x40);
}
else{Output_P0(5,0x00);}
}
//=============================键盘扫描====================================
void Scankey()
{
R4 = 0;
R2 = R3 = R1 = 1;
C1 = C2 = C3 = C4 = 1;
if(C1 == 0) //S4
{
Delay1ms(1);
if(C1 == 0)
{
ES = 0; //关闭串行中断
}
while(C1==0)
{
DisplaySMG();
}
}
else if(C3 == 0) //S12
{
Delay1ms(1);
if(C3 == 0)
{
if(F_SMG==1) //判断当前界面是
{
b20_temp=SMG_T*0.1; //实际温度
printf("TEMP: %.1f℃ \r\n",b20_temp);
}
if(F_SMG==2)
{
printf("Vlotage:%.2fV\r\n",adc_vlot);
}
}
while(C3==0)
{
DisplaySMG();
}
}
R3 = 0;
R4 = R2 = R1 = 1;
C1 = C2 = C3 = C4 = 1;
if(C1 == 0) //S4
{
Delay1ms(1);
if(C1 == 0)
{
ES = 1; //打开串行中断
}
while(C1==0)
{
DisplaySMG();
}
}
}
//=============================主函数====================================
void main()
{
Initsystem();
Timer0Init();
IintUart();
while(1)
{
Command_mange ();
Scankey();
Date_mange();
DisplaySMG();
}
}
十四届蓝桥杯单片机模拟赛第二套题 自撸程序
于 2023-03-07 23:13:55 首次发布
该代码实现了一个基于STM15F2K60S2单片机的程序,用于控制数码管显示温度和电压信息。程序中包括了对OneWire协议的支持,IIC通信,以及串行中断处理。同时,它还包含了温度传感器DS18B20的数据读取和ADC值转换,用于获取实时的温度和电压数据。此外,还包括了键盘扫描功能,允许用户交互切换显示界面。
摘要由CSDN通过智能技术生成