1.题目
本次题目模块较多,难度较大
2.底层代码
2.1三个常用模块
2.1.1 按键
本次省赛采用了NE555模块,要用P34引脚,在按键底层中,要把P34相关的代码注释掉,并且要将P34引脚用跳线帽(可以用超声波模块的跳线帽)与SIGNAL相连
Key.c
#include <Key.h>
unsigned char Key_Read()
{
unsigned char temp=0;
ET0 = 0;//用于串口优化
P44=0;
P42=1;
P35=1;
//P34=1;
if(P33==0) temp=4;
if(P32==0) temp=5;
if(P31==0) temp=6;
if(P30==0) temp=7;
P44=1;
P42=0;
P35=1;
//P34=1;
if(P33==0) temp=8;
if(P32==0) temp=9;
if(P31==0) temp=10;
if(P30==0) temp=11;
P44=1;
P42=1;
P35=0;
//P34=1;
if(P33==0) temp=12;
if(P32==0) temp=13;
if(P31==0) temp=14;
if(P30==0) temp=15;
//P44=1;
//P42=1;
//P35=1;
//P34=0;
//if(P33==0) temp=12;
//if(P32==0) temp=13;
//if(P31==0) temp=14;
//if(P30==0) temp=15;
ET0 = 1;
P3=0xff;
return temp;
}
2.1.2 数码管
Seg.c
#include <Seg.h>
code unsigned char Dulu[18]={
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0xff, //熄灭
0xbf, //-
0xc6, //C
0x89, //H
0x8e, //F
0x8c, //P
0x86, //E
0x88 //A
};
code unsigned char Wulu[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
void Seg_Disp(unsigned char addr,dat,point)
{
//用段选消隐
P0=0xff;
P2=P2&0x1f|0xe0;
P2&=0x1f;
//位选
P0=Wulu[addr];
P2=P2&0x1f|0xc0;
P2&=0x1f;
//段选
P0=Dulu[dat];
if(point)
P0&=0x7f;
P2=P2&0x1f|0xe0;
P2&=0x1f;
}
2.1.3 Led
我使用的是Led灯1亮,0灭的逻辑,所有P0取了一下反
Led.c
#include <Led.h>
void Led_Disp(unsigned char addr,unsigned char flag)
{
static unsigned char temp=0x00;
static unsigned char temp_old=0xff;
if(flag)
temp|=0x01<<addr;
else
temp&=~(0x01<<addr);
if(temp!=temp_old)
{
P0=~temp;
P2=P2&0x1f|0x80;
P2&=0x1f;
temp_old=temp;
}
}
2.1.4 初始化
关闭了Led和数码管,防止在烧录过程在乱叫
Init.c
#include <Init.h>
void System_Init(void)
{
P0=0xff;
P2=P2&0x1f|0x80;
P2&=0x1f;
P0=0x00;
P2=P2&0x1f|0xa0;
P2&=0x1f;
}
准备工作做好了,接下来我们开始写题目要求的底层代码
2.2 题目要求底层
由于第十四届只提供了.c文件,所有我们需要自己写.h文件
2.2.1 PCF88591
题目中只要求ADC转换,所以我只写了这个部分。
iic.c
/* # I2C代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <iic.h>
#include <intrins.h>
#define DELAY_TIME 5
sbit scl=P2^0;
sbit sda=P2^1;
//
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);
}
unsigned char AD_Read(unsigned char addr)
{
unsigned char temp;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
temp=I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return temp;
}
iic.h
#include <STC15F2K60S2.H>
static void I2C_Delay(unsigned char n);
void I2CStart(void);
void I2CStop(void);
void I2CSendByte(unsigned char byt);
unsigned char I2CReceiveByte(void);
unsigned char I2CWaitAck(void);
void I2CSendAck(unsigned char ackbit);
unsigned char AD_Read(unsigned char addr);
//void DA_Read(unsigned char dat);
2.2.2 DS18B20
该模块一次只能读取8位,所以要读两次,采用float型数据
onewire.c
/* # 单总线代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <onewire.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;
}
//读取温度
float Read_Temperature(void)
{
unsigned char high,low;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
low=Read_DS18B20();
high=Read_DS18B20();
return ((high<<8)|low)/16.0;
}
onewire.h
#include <STC15F2K60S2.H>
void Delay_OneWire(unsigned int t) ;
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
float Read_Temperature(void);
2.2.3 DS1302
该模块读取数据是16进制,不要忘记数码管表示时除或者取余16
ds1302.c
/* # DS1302代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <ds1302.h>
#include <intrins.h>
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST=P1^3;
//
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK = 0;
SDA = temp&0x01;
temp>>=1;
SCK=1;
}
}
//
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
Write_Ds1302(dat);
RST=0;
}
//
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
return (temp);
}
void Set_Rtc(unsigned char *ucRtc)
{
unsigned char i;
Write_Ds1302_Byte(0x8e,0);//关闭写保护
for(i=0;i<3;i++)
Write_Ds1302_Byte(0x84-i*2,ucRtc[i]);
Write_Ds1302_Byte(0x8e,1);//打开写保护
}
void Read_Rtc(unsigned char *ucRtc)
{
unsigned char i;
for(i=0;i<3;i++)
ucRtc[i]=Read_Ds1302_Byte(0x85-i*2);
}
ds1302.h
#include <STC15F2K60S2.H>
void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte ( unsigned char address );
void Set_Rtc(unsigned char *ucRtc);
void Read_Rtc(unsigned char *ucRtc);
2.2.4 NE555
NE555模块我放在main.c里面写的,采用定时器0,可以用STC烧录工具生成代码
加上一句TMOD|=0x05;就ok了
//NE555必须使用定时器0 且要加入(TMOD|=0x05;)这段代码
//定时器0初始化
void Timer0Init(void) //0毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x05; //设置计时方式
TL0 = 0x00; //设置定时初始值
TH0 = 0x00; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
3.main.c文件
3.1 定时器
因为NE555采用定时器0,所以我采用定时器1来计时
/利用STC工具生成后要加入(ET1=1,EA=1)两段代码
//定时器1初始化
void Timer1Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x18; //设置定时初始值
TH1 = 0xFC; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1=1;
EA=1;
}
//定时器1
void Timer1Sever(void) interrupt 3
{
if(++Key_Slow==10) Key_Slow=0;
if(++Seg_Slow==500) Seg_Slow=0;
if(++Seg_Pos==8) Seg_Pos=0;
if(++Timer_1000ms==1000)
{
TR0=0;//停止计时
Timer_1000ms=0;
Freq=(TH0<<8)|TL0;
TH0=TL0=0;
TR0=1;//开始计时
}
if(Find_Flag==1)
{
if(++Timer_3000ms==3000)
{
Timer_3000ms=3001;
}
}
if(S9_Flag==1)
{
if(++Timer_2000ms==2000)
Timer_2000ms=2001;
}
else
Timer_2000ms=0;
if(++Timer_1000ms==1000)
{
Timer_1000ms=0;
Led_Star_Flag=!Led_Star_Flag;
}
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
}
3.2 void main()
DS18B20上电后会先显示85,所以要延时750ms,STC生成
对应DS1302模块,要先设置时间
//main()函数
void main()
{
//读取DS18B20要在main()函数里面先读取延时750ms。
Read_Temperature();
Delay750ms();
//读书DS1302的时间要先在main()函数里面先设置。
Set_Rtc(ucRtc);
//用定时器要先初始化
Timer0Init();
Timer1Init();
//板子要先初始化
System_Init();
while(1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
}
}
3.3 完整代码
main.c
#include <STC15F2K60S2.H>
#include <intrins.h>
#include <iic.h>
#include <onewire.h>
#include <ds1302.h>
#include <Seg.h>
#include <Key.h>
#include <Led.h>
#include <Init.h>
//变量定义区
/*按键*/
unsigned char Key_Slow;//10
unsigned char Key_Val,Key_Down,Key_Up,Key_Old;
/*数码管*/
unsigned int Seg_Slow;//500
unsigned Seg_Pos;
unsigned Seg_Buf[8]={10,10,10,10,10,10,10,10};
unsigned Seg_Point[8]={0,0,0,0,0,0,0,0};
/*Led*/
unsigned ucLed[8]={0,0,0,0,0,0,0,0};
/*自定义变量*/
unsigned char Seg_Disp_Mode;//界面:0-时间,1-回显,2-参数
/*时间界面*/
unsigned char ucRtc[3]={0x13,0x03,0x05};//时-分-秒,写出0x的形式
/*回显界面*/
unsigned char Re_Disp_Mode;//回显:0-温度,1-湿度,2-时间
//温度回显·
unsigned char Max_Temperature;//最大温度
float Aver_Temperature;//平均温度
//湿度回显
unsigned char Max_Humidity;//最大湿度
float Aver_Humidity;//平均湿度
//时间回显
unsigned char trigger_Inedx;//触发次数
unsigned char trigger_Time[3];//触发时间
/*参数界面*/
unsigned char Temperature_Set=30;
/*温湿度界面*/
unsigned int Freq;//实时频率
unsigned int Timer_1000ms;
/*S9长短按*/
unsigned int Timer_2000ms;//用于S9长按
bit S9_Flag;//记录是否按下S9;
/*温湿度界面*/
bit Tem_And_Hum_Flag;//温湿度界面和其他界面的区分标志
unsigned char Temperature_Disp;//温湿度界面的温度
unsigned char Humidity_Disp;//温湿度界面的湿度
unsigned char Temperature_Disp_Old;//上一次温湿度界面的温度
unsigned char Humidity_Disp_Old;//上一次温湿度界面的湿度
bit Error_Humidity;//湿度是否有效
bit Led6_Flag;//判断本次采集的温湿度是否均升高
/*判断是否进入采集*/
bit flag;//判断湿度数据是否有效,有效为0,无效为1;
unsigned char Voltage;
unsigned char Voltage_Old;
unsigned int Timer_3000ms;//3s
bit Find_Flag;
/*报警指示灯*/
bit Led_Star_Flag;//控制亮灭
bit Led_Flag;//表明采集温度大于温度参数的状态
unsigned int Timer_1000ms;//1000ms
//清空数据函数
void Clear_Data(void)
{
unsigned char i=0;
Max_Temperature=0;
Aver_Temperature=0;
Max_Humidity=0;
Aver_Humidity=0;
trigger_Inedx=0;
for(i=0;i<3;i++)
trigger_Time[i]=0;
}
//按键处理函数
void Key_Proc()
{
if(Key_Slow) return;
Key_Slow=1;
Key_Val = Key_Read();
Key_Down = Key_Val & (Key_Old ^ Key_Val);
Key_Up = ~ Key_Val & (Key_Old ^ Key_Val);
Key_Old = Key_Val;
//时间回显界面
if(Re_Disp_Mode==2&&Seg_Disp_Mode==1)
{
if(Key_Down==9)
S9_Flag=1;//开始计时
if(Key_Up==9)//S9抬起
{
if(Timer_2000ms>=2000&&S9_Flag==1)
{
Clear_Data();
S9_Flag=0;//停止计时
}
else
S9_Flag=0;//停止计时
}
}
switch(Key_Down)
{
case 4:
if(++Seg_Disp_Mode==3)
Seg_Disp_Mode=0;
Re_Disp_Mode=0;
break;
case 5:
if(Seg_Disp_Mode==1)
{
if(++Re_Disp_Mode==3)
Re_Disp_Mode=0;
}
break;
case 8:
if(Seg_Disp_Mode==2)
{
if(++Temperature_Set==100)
Temperature_Set=99;
}
break;
case 9:
//参数界面
if(Seg_Disp_Mode==2)
{
if(--Temperature_Set==255)
Temperature_Set=0;
}
break;
}
}
//湿度处理函数
bit Read_Humidity(void)
{
if(Freq<200||Freq>2000)
Error_Humidity=0;//无效数据
else
{
Error_Humidity=1;
Humidity_Disp=(unsigned char)(2/45*(Freq-200)+10);
}
return Error_Humidity;
}
//清除数码管
void Clear_Seg(void)
{
unsigned char i;
for(i=0;i<8;i++)
{
Seg_Buf[i]=10;
Seg_Point[i]=0;
}
}
//信息处理函数
void Seg_Proc()
{
unsigned char i;
if(Seg_Slow) return;
Seg_Slow=1;
Read_Rtc(ucRtc);
Temperature_Disp=(unsigned char)Read_Temperature();
//判断是否进入温湿度界面
Voltage=AD_Read(0x41);
//由亮到暗,避免重复进入
if((Voltage_Old>50&&Voltage<50)&&Tem_And_Hum_Flag==0)
{
Find_Flag=1;//开始计时
Tem_And_Hum_Flag=1;
if(Read_Humidity()==1)
{
if(++trigger_Inedx==100) trigger_Inedx=99;
for(i=0;i<3;i++)
trigger_Time[i]=ucRtc[i];
}
}
//是否间隔3s
else if(Tem_And_Hum_Flag==1&&Timer_3000ms>=3000)
{
Find_Flag=0;//停止计时·
Timer_3000ms=0;
Tem_And_Hum_Flag=0;
}
Voltage_Old=Voltage;
//处于温湿度界面
if(Tem_And_Hum_Flag==1)
{
Seg_Buf[0]=16;//E
Seg_Buf[1]=Seg_Buf[2]=10;//熄灭
Seg_Buf[3]=Temperature_Disp/10;
Seg_Buf[4]=Temperature_Disp%10;
Seg_Point[6]=0;
if(Temperature_Disp>Temperature_Set)
Led_Flag=1;
else
Led_Flag=0;
/*用于读取最大温度,平均温度*/
Max_Temperature=(Max_Temperature>Temperature_Disp)?Max_Temperature:Temperature_Disp;
//平均温度等于(前几次采集的次数乘上平均值+本次采集的温度)/采集次数
Aver_Temperature=((trigger_Inedx-1)*Aver_Temperature+Temperature_Disp)/trigger_Inedx;
Seg_Buf[5]=11;//-
//采集有效
if(Error_Humidity==1)
{
flag=0;//进行了温湿度采集,且采集有效
Seg_Buf[6]=Humidity_Disp/10;
Seg_Buf[7]=Humidity_Disp%10;
/*用于读取最大温度,平均温度*/
Max_Humidity=(Max_Humidity>Humidity_Disp)?Max_Humidity:Humidity_Disp;
//平均温度等于(前几次采集的次数乘上平均值+本次采集的温度)/采集次数
Aver_Humidity=((trigger_Inedx-1)*Aver_Humidity+Humidity_Disp)/trigger_Inedx;
if(trigger_Inedx>=2)
{
Led6_Flag=(Temperature_Disp>Temperature_Disp_Old)&(Humidity_Disp>Humidity_Disp_Old);
Temperature_Disp_Old=Temperature_Disp;
Humidity_Disp_Old=Humidity_Disp;
}
}
else
{
flag=1;//进行了温湿度采集,且采集有效
Seg_Buf[6]=Seg_Buf[7]=17;//A
}
}
else
{
switch(Seg_Disp_Mode)
{
//时间
case 0:
Seg_Buf[0]=ucRtc[0]/16;
Seg_Buf[1]=ucRtc[0]%16;
Seg_Buf[2]=11;//-
Seg_Buf[3]=ucRtc[1]/16;
Seg_Buf[4]=ucRtc[1]%16;
Seg_Buf[5]=11;//-
Seg_Buf[6]=ucRtc[2]/16;
Seg_Buf[7]=ucRtc[2]%16;
Seg_Point[6]=0;
break;
//回显
case 1:
switch(Re_Disp_Mode)
{
//温度
case 0:
if(trigger_Inedx==0)
Clear_Seg();
Seg_Buf[0]=12;//C
Seg_Buf[1]=10;//熄灭
if(trigger_Inedx>0)
{
Seg_Buf[2]=Max_Temperature/10;
Seg_Buf[3]=Max_Temperature%10;
Seg_Buf[4]=11;//-
Seg_Buf[5]=(unsigned char)Aver_Temperature/10;
Seg_Buf[6]=(unsigned char)Aver_Temperature%10;
Seg_Buf[7]=(unsigned int)(Aver_Temperature*100)%10;
Seg_Point[6]=1;
}
break;
//湿度
case 1:
if(trigger_Inedx==0)
Clear_Seg();
Seg_Buf[0]=13;//H
Seg_Buf[1]=10;//熄灭
if(trigger_Inedx>0)
{
Seg_Buf[2]=Max_Humidity/10;
Seg_Buf[3]=Max_Humidity%10;
Seg_Buf[4]=11;//-
Seg_Buf[5]=(unsigned char)Aver_Humidity/10;
Seg_Buf[6]=(unsigned char)Aver_Humidity%10;
Seg_Buf[7]=(unsigned int)(Aver_Humidity*100)%10;
Seg_Point[6]=1;
}
break;
//时间
case 2:
if(trigger_Inedx==0)
Clear_Seg();
Seg_Buf[0]=14;//F
Seg_Buf[1]=trigger_Inedx/10;
Seg_Buf[2]=trigger_Inedx%10;
if(trigger_Inedx>0)
{
Seg_Buf[3]=trigger_Time[0]/16;
Seg_Buf[4]=trigger_Time[0]%16;
Seg_Buf[5]=11;//-
Seg_Buf[6]=trigger_Time[1]/16;
Seg_Buf[7]=trigger_Time[1]%16;
Seg_Point[6]=0;
}
break;
}
break;
//参数
case 2:
Seg_Buf[0]=15;//P
Seg_Buf[1]=Seg_Buf[2]=Seg_Buf[3]=Seg_Buf[4]=Seg_Buf[5]=10;//熄灭
Seg_Buf[6]=Temperature_Set/10;
Seg_Buf[7]=Temperature_Set%10;
Seg_Point[6]=0;
break;
}
}
}
//其他处理函数
void Led_Proc()
{
unsigned char i;
for(i=0;i<2;i++)
ucLed[i]=(i==Seg_Disp_Mode);
ucLed[2]=Tem_And_Hum_Flag;
ucLed[3]=(Led_Star_Flag&Led_Flag);
ucLed[4]=flag;
ucLed[5]=Led6_Flag;
}
//NE555必须使用定时器0 且要加入(TMOD|=0x05;)这段代码
//定时器0初始化
void Timer0Init(void) //0毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x05; //设置计时方式
TL0 = 0x00; //设置定时初始值
TH0 = 0x00; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
//利用STC工具生成后要加入(ET1=1,EA=1)两段代码
//定时器1初始化
void Timer1Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x18; //设置定时初始值
TH1 = 0xFC; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1=1;
EA=1;
}
//定时器1
void Timer1Sever(void) interrupt 3
{
if(++Key_Slow==10) Key_Slow=0;
if(++Seg_Slow==500) Seg_Slow=0;
if(++Seg_Pos==8) Seg_Pos=0;
if(++Timer_1000ms==1000)
{
TR0=0;//停止计时
Timer_1000ms=0;
Freq=(TH0<<8)|TL0;
TH0=TL0=0;
TR0=1;//开始计时
}
if(Find_Flag==1)
{
if(++Timer_3000ms==3000)
{
Timer_3000ms=3001;
}
}
if(S9_Flag==1)
{
if(++Timer_2000ms==2000)
Timer_2000ms=2001;
}
else
Timer_2000ms=0;
if(++Timer_1000ms==1000)
{
Timer_1000ms=0;
Led_Star_Flag=!Led_Star_Flag;
}
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
}
void Delay750ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 35;
j = 51;
k = 182;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
//main()函数
void main()
{
//读取DS18B20要在main()函数里面先读取延时750ms。
Read_Temperature();
Delay750ms();
//读书DS1302的时间要先在main()函数里面先设置。
Set_Rtc(ucRtc);
//用定时器要先初始化
Timer0Init();
Timer1Init();
//板子要先初始化
System_Init();
while(1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
}
}
4.结束语
我是初学者,可能有些BUG,希望大家可以指出了。
标签:Disp,char,void,unsigned,Seg,蓝桥,单片机,省赛,Buf From: https://blog.csdn.net/weixin_62267326/article/details/137207739