十四届省赛模拟题2题目:
示例代码(reg52.h):
main.c
#include <REG52.H>
#include "stdio.h"
#include "onewire.h"
#include "IIC.h"
sfr P4=0xc0;
sfr AUXR=0x8e;
sbit L1=P3^0;
sbit L2=P3^1;
sbit L3=P3^2;
sbit L4=P3^3;
sbit R1=P4^4;
sbit R2=P4^2;
sbit R3=P3^5;
sbit R4=P3^4;
sbit LED3=P0^2;
sbit Buzzer=P0^6;
sbit jidian=P0^4;
void HC573(unsigned char channel,unsigned char value);
void Nixie(unsigned char column,unsigned char value);
void Delay(unsigned int x);
void System_init();
unsigned char code Array[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
0xbf,0x7f};
unsigned char code Array_pot[]={0x40,0x79,0X24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//小数点数组
unsigned int temperature=0;//温度
unsigned int voltage=0;//电压
float T_V=0;//电压计算
unsigned char Mode=0;//模式
unsigned char Data=0;//串口接受数据
unsigned char lock=0;//s4锁定标志位
unsigned char Send_Data=0;//S12按键控制位
unsigned char LED_stat=0xff;//LED控制
unsigned int Count=0;//0.1s计数
unsigned char Flag=0;//LED3翻转标志位
//温度读取
unsigned int Read_temperature()
{
unsigned char LSB,MSB;
unsigned int temp;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xBE);
LSB=Read_DS18B20();
MSB=Read_DS18B20();
temp=(MSB<<8)|LSB;
temp=temp>>4;
temp*=10;
temp=temp+(LSB&0x0f)*0.625;
return temp;
}
//温度显示
void Display_temp()
{
Nixie(1,0xc1);
Nixie(2,Array[1]);
Nixie(3,0xff);
Nixie(4,0xff);
Nixie(5,0xff);
Nixie(6,Array[temperature/100%10]);
Nixie(7,Array_pot[temperature/10%10]);
Nixie(8,Array[temperature%10]);
}
//电压读取
void PCF8591_Read()
{
unsigned char t;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x43);
I2CWaitAck();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
t=I2CReceiveByte();
I2CWaitAck();
I2CStop();
T_V=t*(5.0/255);
voltage=T_V*100;
}
//电压显示
void Display_V()
{
Nixie(1,0xc1);
Nixie(2,Array[2]);
Nixie(3,0xff);
Nixie(4,0xff);
Nixie(5,0xff);
Nixie(6,Array_pot[voltage/100%10]);
Nixie(7,Array[voltage/10%10]);
Nixie(8,Array[voltage%10]);
}
//串口
void UartInit(void) //9600bps@12.000MHz
{
SCON = 0x50;
AUXR &= 0xBF;
AUXR &= 0xFE;
TMOD &= 0x0F;
TL1 = 0xE6;
TH1 = 0xFF;
ET1 = 0;
TR1 = 1;
EA=1;
ES=1;
}
//串口发送
void Send_Byte(unsigned char Dat)
{
SBUF=Dat;
while(TI==0);
TI=0;
}
//按键扫描
void Key_Scan()
{
L4=0;
L1=L2=L3=1;
R1=R2=R3=R4=1;
if(R1==0)
{
if(lock==0)lock=1;
while(R1==0)
{
if(Mode==0)
{
Display_temp();
}
else if(Mode==1)
{
Display_V();
}
}
}
else if(R3==0)
{
if(Send_Data==0)Send_Data=1;
while(R3==0)
{
if(Mode==0)
{
Display_temp();
}
else if(Mode==1)
{
Display_V();
}
}
}
L3=0;
L1=L2=L4=1;
R1=R2=R3=R4=1;
if(R1==0)
{
if(lock==1)lock=0;
while(R1==0)
{
if(Mode==0)
{
Display_temp();
}
else if(Mode==1)
{
Display_V();
}
}
}
}
//串口发送数据
void Send_uart()
{
if(Send_Data==1)
{
if(Mode==0)
{
printf("TEMP(温度):%.1F°C\r\n",(float)temperature/10);
}
else if(Mode==1)
{
printf("Voltage(电压):%.2fV\r\n",(float)voltage/100);
}
Send_Data=0;
}
}
//灯光控制
void LED_Run()
{
P0=0xff;//防止继电器部分干扰
if(Mode==0)
{
LED_stat=P0&0xfe;
HC573(4,LED_stat);
}
else if(Mode==1)
{
LED_stat=P0&0xfd;
HC573(4,LED_stat);
}
//LED3控制
if(lock==1)
{
TR0=1;//锁定状态下开启定时器0.1s计数
LED3=Flag;//通过定时器翻转引脚
P2=(P2&0x1f)|0x80;
P2=(P2&0x1f)|0x00;
}
else
{
TR0=0;
LED3=1;
P2=(P2&0x1f)|0x80;
P2=(P2&0x1f)|0x00;
}
}
//定时器0初始化
void Time_init()
{
TMOD=0x01;
TH0=(65535-1000)/256;
TL0=(65535-1000)%256;
TF0=0;
ET0=1;
EA=1;
}
//继电器蜂鸣器控制
void Buzzer_ctrl()
{
if(temperature>=280)
{
P2=(P2&0x1f)|0xa0;
jidian=1;
P2=(P2&0x1f)|0x00;
}
else if(temperature<280)
{
P2=(P2&0x1f)|0xa0;
jidian=0;
P2=(P2&0x1f)|0x00;
}
if(voltage>=360)
{
P2=(P2&0x1f)|0xa0;
Buzzer=1;
P2=(P2&0x1f)|0x00;
}
else if(voltage<360)
{
P2=(P2&0x1f)|0xa0;
Buzzer=0;
P2=(P2&0x1f)|0x00;
}
}
void main()
{
System_init();
while(1)
{
temperature=Read_temperature();//温度读取
PCF8591_Read();//电压读取
if(Mode==0)
{
Display_temp();
}
else if(Mode==1)
{
Display_V();
}
Send_uart();
Key_Scan();
Buzzer_ctrl();
LED_Run();
}
}
void Time0() interrupt 1
{
TH0=(65535-1000)/256;
TL0=(65535-1000)%256;
if(lock==1)//锁定情况下计数,和上面开启定时器双重判断
{
Count++;
if(Count>100)
{
Flag++;
Flag%=2;
Count=0;
}
}
}
void UART() interrupt 4
{
if(RI)
{
Data=SBUF;
if(lock==0)//未锁定情况下执行命令
{
if(Data=='A')
{
Mode=0;
}
else if(Data=='B')
{
Mode=1;
}
}
RI=0;
}
}
void System_init()
{
HC573(5,0x00);
HC573(4,0xff);
Read_temperature();
Delay(700);//上电之前延时700ms,将初始85读取掉
Time_init();
UartInit();
}
void HC573(unsigned char channel,unsigned char value)
{
P2=(P2&0x1f)|0x00;
P0=value;
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;
}
P2=(P2&0x1f)|0x00;
}
void Delay(unsigned int x)
{
unsigned char i,j;
while(x--)
{
i=11;
j=190;
do
{
while(--j);
}while(--i);
}
}
void Nixie(unsigned char column,unsigned char value)
{
HC573(6,0x01<<(column-1));
HC573(7,value);
Delay(2);
HC573(6,0x01<<(column-1));
HC573(7,0xff);
}
//printrf重定向
char putchar(char ch)
{
Send_Byte(ch);
return ch;
}
iic.h
#ifndef __IIC_H_
#define __IIC_H_
void I2CStart(void);
void I2CStop(void);
void I2CSendByte(unsigned char byt);
unsigned char I2CReceiveByte(void);
unsigned char I2CWaitAck(void);
#endif
iic.c
#include "reg52.h"
#include "intrins.h"
sbit scl=P2^0;
sbit sda=P2^1;
#define DELAY_TIME 5
//
static void I2C_Delay(unsigned char n)
{
do
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
while(n--);
}
//
void I2CStart(void)
{
sda = 1;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 0;
I2C_Delay(DELAY_TIME);
scl = 0;
}
//
void I2CStop(void)
{
sda = 0;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 1;
I2C_Delay(DELAY_TIME);
}
//
void I2CSendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++){
scl = 0;
I2C_Delay(DELAY_TIME);
if(byt & 0x80){
sda = 1;
}
else{
sda = 0;
}
I2C_Delay(DELAY_TIME);
scl = 1;
byt <<= 1;
I2C_Delay(DELAY_TIME);
}
scl = 0;
}
//
unsigned char I2CReceiveByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++){
scl = 1;
I2C_Delay(DELAY_TIME);
da <<= 1;
if(sda)
da |= 0x01;
scl = 0;
I2C_Delay(DELAY_TIME);
}
return da;
}
//
unsigned char I2CWaitAck(void)
{
unsigned char ackbit;
scl = 1;
I2C_Delay(DELAY_TIME);
ackbit = sda;
scl = 0;
I2C_Delay(DELAY_TIME);
return ackbit;
}
//
//void I2CSendAck(unsigned char ackbit)
//{
// scl = 0;
// sda = ackbit;
// I2C_Delay(DELAY_TIME);
// scl = 1;
// I2C_Delay(DELAY_TIME);
// scl = 0;
// sda = 1;
// I2C_Delay(DELAY_TIME);
//}
onewire.h
#ifndef __ONEWIRE_H_
#define __ONEWIRE_H_
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
#endif
onewire.c
#include "reg52.h"
sbit DQ=P1^4;
//
void Delay_OneWire(unsigned int t)
{
unsigned char i;
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(5);
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(5);
}
return dat;
}
//
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}