如果有用请点赞,还会继续更新的
题目:
思路:
用两个定时器来分别完成LED闪烁和读取温度
源代码:
main.c
#include"reg52.h"
#include"intrins.h"
#include"onewire.h"
int code xianshi[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}; //0,1,2,3,4,5,6,7,8,9,空,-
unsigned char temperature;
sfr P4=0xC0;
sfr AUXR=0x8e;
sbit R1=P3^0;
sbit R2=P3^1;
sbit R3=P3^2;
sbit R4=P3^3;
sbit C4=P3^4;
sbit C3=P3^5;
sbit C2=P4^2;
sbit C1=P4^4;
int set_number[4]={3,5,2,5}; //记录温度上下限 ,前两位为最大值,后两位为最小值
int set_wei=0; //用于set_number
int smg_mode=0; //数码管显示
void get_temperature() //获取温度
{
temperature=rd_temperature();
}
void choose_573(int i)
{
switch(i)
{
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;
}
}
void Init_system() //初始化系统
{
choose_573(4);
P0=0xff;
choose_573(5);
P0=0x00;
choose_573(0);
P0=0xff;
}
//---------------------------------按键
void Delay5ms() //@11.0592MHz
{
unsigned char i, j;
i = 54;
j = 199;
do
{
while (--j);
} while (--i);
}
void key_board()
{
R1=0;R2=R3=R4=1;
C1=C2=C3=C4=1;
if(C1==0)
{
Delay5ms();
if(C1==0)
{
set_number[set_wei]=0;
set_wei++;
}
while(!C1);
}
else if(C2==0)
{
Delay5ms();
if(C2==0)
{
set_number[set_wei]=1;
set_wei++;
}
while(!C2);
}
else if(C3==0)
{
Delay5ms();
if(C3==0)
{
set_number[set_wei]=2;
set_wei++;
}
while(!C3);
}
R2=0;R1=R3=R4=1;
C1=C2=C3=C4=1;
if(C1==0)
{
Delay5ms();
if(C1==0)
{
set_number[set_wei]=3;
set_wei++;
}
while(!C1);
}
else if(C2==0)
{
Delay5ms();
if(C2==0)
{
set_number[set_wei]=4;
set_wei++;
}
while(!C2);
}
else if(C3==0)
{
Delay5ms();
if(C3==0)
{
set_number[set_wei]=5;
set_wei++;
}
while(!C3);
}
R3=0;R1=R2=R4=1;
C1=C2=C3=C4=1;
if(C1==0)
{
Delay5ms();
if(C1==0)
{
set_number[set_wei]=6;
set_wei++;
}
while(!C1);
}
else if(C2==0)
{
Delay5ms();
if(C2==0)
{
set_number[set_wei]=7;
set_wei++;
}
while(!C2);
}
else if(C3==0)
{
Delay5ms();
if(C3==0)
{
set_number[set_wei]=8;
set_wei++;
}
while(!C3);
}
R4=0;R1=R3=R2=1;
C1=C2=C3=C4=1;
if(C1==0)
{
Delay5ms();
if(C1==0)
{
set_number[set_wei]=9;
set_wei++;
}
while(!C1);
}
else if(C2==0)
{
Delay5ms();
if(C2==0)
{
if(smg_mode==0)
{
int i;
smg_mode=1;
for(i=0;i<4;i++)
{
set_number[i]=0;
}
set_wei=0;
}
else
{
int i;
if((set_number[0]*10+set_number[1])<(set_number[2]*10+set_number[3]))
{
choose_573(4);
P0=0xfd;
choose_573(0);
for(i=0;i<4;i++)
{
set_number[i]=0;
}
set_wei=0;
}
else
{
choose_573(4);
P0=0xff;
choose_573(0);
smg_mode=0;
}
}
}
while(!C2 );
}
else if(C3==0&&smg_mode==1)
{
int i;
Delay5ms();
if(C3==0&&smg_mode==1)
{
for(i=0;i<4;i++)
{
set_number[i]=0;
set_wei=0;
}
}
while(!C3);
}
}
//---------------------------------
//---------------------------------数码管显示
void Delay400us() //@11.0592MHz
{
unsigned char i, j;
i = 5;
j = 74;
do
{
while (--j);
} while (--i);
}
void SMG(int wei,int dat)
{
choose_573(6);
P0=0x80>>(wei-1);
choose_573(7);
P0=xianshi[dat];
}
void SMG_display()
{
if(smg_mode==0)
{
Delay400us();
SMG(1,temperature%10);
Delay400us();
SMG(2,temperature/10);
Delay400us();
SMG(3,10);
Delay400us();
SMG(4,10);
Delay400us();
SMG(5,10);
Delay400us();
SMG(6,11);
Delay400us();
SMG(7,1);
Delay400us();
SMG(8,11);
Delay400us();
}
if(smg_mode==1)
{
Delay400us();
if(set_wei>3)
{
SMG(1,set_number[3]);
}
else
{
SMG(1,10);
}
Delay400us();
if(set_wei>2)
{
SMG(2,set_number[2]);
}
else
{
SMG(2,10);
}
Delay400us();
SMG(3,11);
Delay400us();
SMG(4,10);
Delay400us();
SMG(5,10);
Delay400us();
if(set_wei>1)
{
SMG(6,set_number[1]);
}
else
{
SMG(6,10);
}
Delay400us();
if(set_wei>0)
{
SMG(7,set_number[0]);
}
else
{
SMG(7,10);
}
Delay400us();
SMG(8,11);
Delay400us();
}
}
//---------------------------------
//---------------------------------判断
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初始值
TH0 = 0xD4; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
}
int i=0;
void Timer0Init_server()interrupt 1
{
TL0 = 0xCD; //设置定时初始值
TH0 = 0xD4; //设置定时初始值
i++;
if(smg_mode==0)
{
if(temperature<(set_number[2]*10+set_number[3]))
{
if(i>=800)
{
choose_573(4);
if(P0!=0xff)
{
P0=0xff;
}
else
{
P0=0xfe;
}
choose_573(0);
i=0;
}
}
else if(temperature<=(set_number[0]*10+set_number[1])&&(temperature>=set_number[2]*10+set_number[3]))
{
if(i>=400)
{
choose_573(4);
if(P0!=0xff)
{
P0=0xff;
}
else
{
P0=0xfe;
}
choose_573(0);
i=0;
}
}
else if(temperature>(set_number[0]*10+set_number[1]))
{
if(i>=200)
{
choose_573(4);
if(P0!=0xff)
{
P0=0xff;
}
else
{
P0=0xfe;
}
choose_573(0);
i=0;
}
}
}
}
//---------------------------------
void Timer1Init(void) //5毫秒@11.0592MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x00; //设置定时初始值
TH1 = 0x28; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1=1;
EA=1;
}
int nn=0;
void wendu() interrupt 3
{
nn++;
while(nn>=99)
{
get_temperature();
nn=0;
}
}
void main()
{
Init_system();
Timer0Init();
Timer1Init();
while(1)
{
key_board();
// get_temperature();
SMG_display();
}
}
onewire.h
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
unsigned char rd_temperature(void);
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
#endif
onewire.c
/*
程序说明: 单总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
日 期: 2011-8-9
*/
#include "reg52.h"
sbit DQ = P1^4; //单总线接口
//单总线延时函数
void Delay_OneWire(unsigned int t) //STC89C52RC
{
t=t*12;
while(t--);
}
//通过单总线向DS18B20写一个字节
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);
}
//从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(5);
}
return dat;
}
//DS18B20设备初始化
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;
}
unsigned char temper;
unsigned char rd_temperature(void)
{
int HBS,LBS;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay_OneWire(200);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LBS=Read_DS18B20();
HBS=Read_DS18B20();
temper=HBS<<4;
temper=temper|(LBS>>4);
return temper;
}
**
码字不容易,点个赞再走!!!!
**