void Set_HC573(unsigned char channel, unsigned char dat)
{
P0 = dat; //待设置数据
switch(channel) //选通锁存器
{
case 4:
P2 = (P2 & 0x1f) | 0x80; //Y4输出0,LED控制
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0; //Y5输出0,蜂鸣器和继电器控制
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0; //Y6输出0,数码管位选
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0; //Y7输出0,数码管段码
break;
case 0:
P2 = (P2 & 0x1f) | 0x00; //所有锁存器不选择
break;
}
P2 = (P2 & 0x1f) | 0x00; //设置完成,关闭全部锁存器
}
//===================系统初始化===================
void Init_sys()
{
Set_HC573(0, 0x00); //关闭所有锁存器
Set_HC573(5, 0x00); //关闭蜂鸣器和继电器
Set_HC573(4, 0xff); //关闭全部LED灯
DisplaySMG_All(0xff); //关闭全部数码管
Init_DS1302_Param(); //初始化DS1302
}
//选择YNC与P0输入
void outputP0(unsigned char channel,unsigned char date)
{
HC138_init(channel);
P0= date;
}
//开启继电器与蜂鸣器
outputP0(5,0x10);//开继电器P04,0x10为0001 0000,对应的为P04
outputP0(5,0x40);//开启蜂鸣器P06,0x40为0100 0000,从左往右分别为P07 P06 P05 P04 | P03 P02 P01 P00
单个数码管动态显示
void DisplaySMG_Bit(unsigned char pos, unsigned char value)
{
Set_HC573(6, 0x01 << pos); //数码管的段位
Set_HC573(7, value); //数码管显示内容
DelaySMG(TSMG); //数码管点亮时长
Set_HC573(6, 0x01 << pos);
Set_HC573(7, 0xff); //消隐
}
全部数码管静态显示(常用于关闭所有)
void DisplaySMG_All(unsigned char value)
{
Set_HC573(6, 0xff); //使能所有数码管
Set_HC573(7, value); //数码管显示内容
}
动态显示段码
void dynamic_display()
{
dispalySMG_bit(SMG_duanma[2],0);
delay(500);
dispalySMG_bit(SMG_duanma[0],1);
delay(500);
dispalySMG_bit(SMG_duanma[1],2);
delay(500);
dispalySMG_bit(SMG_duanma[8],3);
delay(500);
dispalySMG_bit(SMG_duanma[16],4);
delay(500);
dispalySMG_bit(SMG_duanma[16],5);
delay(500);
dispalySMG_bit(SMG_duanma[month/10],6);
delay(500);
dispalySMG_bit(SMG_duanma[month%10],7);
delay(500);
}
//数码管延时时,需在延时中加dynamic_display();否则延时时数码管不显示
void delay_show(unsigned char t)
{
while(t--)
{
dynamic_display();
}
}
void scan_key()
{
if(S7 == 0)
{
delay(100);
if(S7 == 0)
{
if(sta==0)
{
L1=0;
sta=1;
}
else if(sta==1)
{
L1=1;
sta=0;//释放状态
}
}
}
if(S6 == 0)
{
delay(100);
if(S6 == 0)
if(sta==0)
{
L2=0;
sta=2;
}
else if(sta==2)
{
L2=1;
sta=0;
}
}//等等
}
//定义初始化
sfr P4 = 0xC0
sbit HC138_C=P2^7;
sbit HC138_B=P2^6;
sbit HC138_A=P2^5;
sbit row1=P3^0;
sbit row2=P3^1;
sbit row3=P3^2;
sbit row4=P3^3;
sbit col1=P4^4;
sbit col2=P4^2;
sbit col3=P3^5;
sbit col4=P3^4;
//按键检测
void key_scan()
{
row1=0;//第一行0~3
row2=row3=ro4=1;
col1=col2=col3=col4=1;
if(col1==0)
{
delay(500);
if(col1==0)
{
while(col1==0);
keynum=0;
display_keynum(SMG_duanma[keynum]);
}
}
else if(col2==0)
{
delay(500);
if(col2==0)
{
while(col2==0);
keynum=1;
display_keynum(SMG_duanma[keynum]);
}
}
else if(col3==0)
{
delay(500);
if(col3==0)
{
while(col3==0);
keynum=2;
display_keynum(SMG_duanma[keynum]);
}
}
else if(col4==0)
{
delay(500);
if(col4==0)
{
while(col4==0);
keynum=3;
display_keynum(SMG_duanma[keynum]);
}
}
row2=0;//第二行4~7
row1=row3=ro4=1;
col1=col2=col3=col4=1;
//。。。。同上
void Init_INT0()
{
IT0=1;//下降沿触发
EX0=1;//外部中断0使能
EA =1;//总开关使能
}
unsigned char num=0;
void Interrupt() interrupt 0
{
num=1;//即按下S5即可给下降沿触发中断,中断执行标志即为num=1,由此进行if语句执行
}
////////////////////定时器初始化函数//////////////
void Init_Timer0()
{
TMOD=0x01;//0x01为第四位的定时器0,TR0软启动加16为定时计数器
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;//定时50ms
ET0=1;//使能
EA=1;//使能
TR0=1;//开启
}
//////////////////////////////////////////////
/////////////////定时器服务函数////////////////
unsigned char n=0;
void Timer0Serve() interrupt 1//定时器0中断号为1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;//定时50ms(无自动重装,只得重新设置定时器初值)
n++;
if(n%10==0)
{
L1=~L1;
}
if(n==100)
{
L8=~L8;
n=0;
}
}
/////////////////////////////////////////////
////////////定时器相关/////////////
void Init_Timer0()
{
TMOD=0x01;//16位Timer0
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
ET0=1;
EA=1;
TR0=1;
}
void ServiceTimer0() interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
t_005s++;
if(t_005s==20)
{
t_s++;
t_005s=0;
if(t_s++==60)
{
t_min++;
t_s=0;
}
if(t_min==99)
{
t_min=0;
}
}
}
///////////////////////////////////
unsigned char tim=0;
unsigned char duty=0;
void Init_Timer0()
{
TMOD=0x01;
TH0=(65535-100)/256;
TL0=(65535-100)%256;
ET0=1;
EA=1;
}
void ServiceTimer0() interrupt 1
{
TH0=(65535-100)/256;
TL0=(65535-100)%256;
tim++;
if(tim==duty)
{
L1=1;
}
else if(tim==100)
{
L1=0;
tim=0;
}
}
unsigned char n=0;//状态机参数
void delay(unsigned int t)
{
while(t--);
}
void key_scan()
{
if(S7==0)
{
delay(100);
if(S7==0)
{
switch(n)//检测按键按下后直接进入状态机
{
case 0:L1=0;duty=10;TR0=1;n=1;
case 1:duty=50;n=2;
case 2:duty=90;n=3;
case 3:L1=1;TR0=0;n=0;
}
while(S7==0);//按下之后的松手检测
}
}
}
sfr AUXR=0x8e;
void Init_UART()
{
TMOD=0x20;//定时器1自动重装8位产生波特率
TH1=0xFD;
TH1=0xFD;//重装时一样
TR0=1;
SCON=0x50;//8位UART,允许接收
AUXR=0x00;//特殊寄存器置0才可发送与接收
ES=1;//使能串口
EA=1;
}
void sent_date(unsigned char dat)
{
SBUF=dat;
while(TI==0);//0为一直发送
TI=0;
}
unsigned char uart_dat;
void Service_UART() interrupt 4//4号为串口中断
{
if(RI==1)
{
RI=0;
SBUF=uart_dat;
sent_date(uart_dat);
}
}
需包含源文件onewire.c和头文件onewire.h
//=================温度值显示函数=================
void DisplaySMG_Temp()
{
switch(mode)
{
//2位小数显示模式
case 1:
smg_ds18b20 = temp_ds18b20 * 100;
DisplaySMG_Bit(7,SMG_NoDot[smg_ds18b20 % 10]);
DisplaySMG_Bit(6,SMG_NoDot[(smg_ds18b20 / 10) % 10]);
DisplaySMG_Bit(5,SMG_Dot[(smg_ds18b20 / 100) % 10]);
if(smg_ds18b20 / 1000 != 0)
{
DisplaySMG_Bit(4,SMG_NoDot[smg_ds18b20 / 1000]);
}
break;
//1位小数显示模式
case 2:
smg_ds18b20 = temp_ds18b20 * 10;
DisplaySMG_Bit(7,SMG_NoDot[smg_ds18b20 % 10]);
DisplaySMG_Bit(6,SMG_Dot[(smg_ds18b20 / 10) % 10]);
if(smg_ds18b20 / 100 != 0)
{
DisplaySMG_Bit(5,SMG_NoDot[smg_ds18b20 / 100]);
}
break;
//整数显示模式
case 3:
smg_ds18b20 = temp_ds18b20;
DisplaySMG_Bit(7,SMG_NoDot[smg_ds18b20 % 10]);
if(smg_ds18b20 / 10 != 0)
{
DisplaySMG_Bit(6,SMG_NoDot[smg_ds18b20 / 10]);
}
break;
}
}
//==============DS18B20温度读出与显示==============
void Read_Dsiplay_DS18B20()
{
unsigned char LSB,MSB;
unsigned int temp = 0;
init_ds18b20(); //初始化DS18B20
DisplaySMG_Temp(); //动态刷新数码管
Write_DS18B20(0xcc); //忽略ROM操作
Write_DS18B20(0x44); //启动温度转换
DisplaySMG_Temp(); //动态刷新数码管
init_ds18b20(); //初始化DS18B20
DisplaySMG_Temp(); //动态刷新数码管
Write_DS18B20(0xcc); //忽略ROM操作
Write_DS18B20(0xbe); //读出内部存储器
LSB = Read_DS18B20(); //第0字节:温度低8位
MSB = Read_DS18B20(); //第1字节:温度高8位
DisplaySMG_Temp(); //动态刷新数码管
//上述程序中插入多处数码管刷新,可使显示亮度充足
temp = MSB; //合成16位温度原始数据
temp = (temp << 8) | LSB;
if((temp & 0xf800) == 0x0000) //处理正温度
{
temp_ds18b20 = temp * 0.0625; //计算实际温度值
}
DisplaySMG_Temp(); //动态刷新数码管
}
//=================初始化DS1302的参数=================
void Init_DS1302_Param()
{
unsigned char i;
Write_Ds1302_Byte(0x8E,0x00); //解除写保护
for(i = 0; i < 7; i++) //依次写入7个参数
{
Write_Ds1302_Byte(WRITE_RTC_ADDR[i],TIME[i]);
}
Write_Ds1302_Byte(0x8E,0x80); //使能写保护
}
//===============设置DS1302中的时分秒=================
void Set_DS1302_Time()
{
Write_Ds1302_Byte(0x8E,0x00); //解除写保护
Write_Ds1302_Byte(0x80,sec); //设置:秒
Write_Ds1302_Byte(0x82,min); //设置:分
Write_Ds1302_Byte(0x84,hour); //设置:时
Write_Ds1302_Byte(0x8E,0x80); //使能写保护
}
//===============读取DS1302中的时分秒=================
void Read_DS1302_Time()
{
if(F_pause == 0) //在非暂停模式中
{
sec = Read_Ds1302_Byte(0x81);
min = Read_Ds1302_Byte(0x83);
hour = Read_Ds1302_Byte(0x85);
}
DisplaySMG_RTC(); //显示最新的时分秒
}
本文章使用limfx的vscode插件快速发布