【冉冰的成长日记001】
咕咕咕,鸽了17天我他喵终于写了一篇省赛。写这篇文章的目的是用以复习和留念一下,如若能帮助到他人和下一届的学弟学妹自然是极好的。QAQ话不多说,上代码。
#include
#include"onewire.h"
unsigned char LED[]={
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xBF,0xFF,0xC6
}; //定义数码管
unsigned char LEDbuff[]={
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
}; //数码管缓冲区
sbit S7=P3^0;
sbit S6=P3^1;
sbit S5=P3^2;
sbit S4=P3^3;
unsigned int num=0; //用于定时器0计数,每一秒获取一次温度和工作剩余时间倒计时
unsigned char Temp,cnt=0; //Temp用于获取DS18B20的温度。cnt用于风扇pwm输出占空比的计算
unsigned char S4_flag=1,S5_time=0; //S4_flag用于切换模式,S5_time用于S6按键计时和按键定时
bit MOTOR=0,Check_S4 = 0,Check_S5 = 0,Check_S6 = 0,Check_S7 = 0,S7_flag=0;
//MOTOR用于外设输出,Check_Sx用于检测按键按下,S7_flag用于切换模式四
void Initial(); //初始化函数
void KEY(); //按键
void Display(); //数码管显示
void Timer0Init(); //定时器0
void Timer1Init(); //定时器1
void main()
{
Initial();
Timer0Init();
Timer1Init();
while(1)
{
KEY();
if(num>=10000) //num每0.1ms加一,10000即1s
{
if(S5_time>0)
{
S5_time--;//工作剩余时间
}
num=0;
DS18B20_Start(); //每一秒获取一次温度
Temp=DS18B20_Get();
}
}
}
void Initial() //初始化函数
{
P2 = (P2&0x1F)|0x80;
P0 = 0xFF; //初始化LED
P2 = (P2&0x1F)|0xA0;
P0 = 0x00; //初始化继电器和蜂鸣器
P2 = (P2&0x1F)|0xC0;
P0 = 0xFF;
P2 = (P2&0x1F)|0xE0;
P0 = 0xFF; //初始化数码管
}
void Timer0Init(void) //100微秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xAE; //设置定时初值
TH0 = 0xFB; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA = 1;
ET0 = 1;
}
void Timer1Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xCD; //设置定时初值
TH1 = 0xD4; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
EA = 1;
ET1 = 1;
}
void delay(int ms) //某up debug测的1s我借用了,也可以用定时器来写delay函数
{
int X=0,Y=0;
for(X=0;X<ms;X++)
{
for(Y=846;Y>0;Y--);
}
}
void Display1() //控制高四位数码管
{
LEDbuff[7]=LED[10];
LEDbuff[6]=LED[S4_flag];
LEDbuff[5]=LED[10];
LEDbuff[4]=LED[11]; //不显示
}
void Display2() //控制低四位数码管
{
LEDbuff[3]=LED[0];
LEDbuff[2]=LED[S5_time/100];
LEDbuff[1]=LED[S5_time/10%10];
LEDbuff[0]=LED[S5_time%10];
}
void Display3()
{
LEDbuff[7]=LED[10];
LEDbuff[6]=LED[4];
LEDbuff[5]=LED[10];
LEDbuff[4]=LED[11];
LEDbuff[3]=LED[11];
LEDbuff[2]=LED[Temp/10];
LEDbuff[1]=LED[Temp%10];
LEDbuff[0]=LED[12]; //题干摄氏度的C
}
void Display()
{
Display1();
Display2();
}
void KEY_S4() //S4切换工作模式
{
if(S4==0)
{
delay(5);
if(S4==0)
Check_S4=1;
}
if((S4==1)&&(Check_S4==1))
{
Check_S4=0;
S4_flag++;
if(S4_flag>=4)
S4_flag=1;
}
}
//设置计时
void KEY_S5()
{
if(S5==0)
{
delay(5);
if(S5==0)
Check_S5=1;
}
if((S5==1)&&(Check_S5==1))
{
Check_S5=0;
S5_time = S5_time+60;
if(S5_time>=60&&S5_time<120) S5_time=60;
if(S5_time>=120&&S5_time<180) S5_time=120;
if(S5_time>=180) S5_time=0;
}
}
void KEY_S6() //清零
{
if(S6==0)
{
delay(5);
if(S6==0)
Check_S6=1;
}
if((S6==1)&&(Check_S6==1))
{
Check_S6=0;
S5_time=0;
MOTOR=0;
}
}
void KEY_S7() //显示温度
{
if(S7==0)
{
delay(5);
if(S7==0)
Check_S7=1;
}
if((S7==1)&&(Check_S7==1))
{
Check_S7=0;
S7_flag = ~S7_flag;
}
}
void KEY()
{
KEY_S4();
KEY_S5();
KEY_S6();
KEY_S7();
}
void Show1() //LED小灯随工作模式变化
{
if(S4_flag==1)
{
P2 = (P2&0x1F)|0x80;
P0 = 0xFE;
}
if(S4_flag==2)
{
P2 = (P2&0x1F)|0x80;
P0 = 0xFD;
}
if(S4_flag==3)
{
P2 = (P2&0x1F)|0x80;
P0 = 0xFB;
}
}
void Show2() //模式四关闭LED
{
P2 = (P2&0x1F)|0x80;
P0 = 0xFF;
}
void InterruptTimer0() interrupt 1
{
TL0 = 0xAE; //设置定时初值
TH0 = 0xFB; //设置定时初值
cnt++;
if(cnt>=10) {
cnt=0;} //各工作模式占空比
if(S4_flag==1)
{
if(cnt<=2) MOTOR=1;
else MOTOR=0;
}
if(S4_flag==2)
{
if(cnt<=3) MOTOR=1;
else MOTOR=0;
}
if(S4_flag==3)
{
if(cnt<=7) MOTOR=1;
else MOTOR=0;
}
num++;
}
void InterruptTimer1() interrupt 3
{
static unsigned char i = 0;
TL1 = 0xCD; //设置定时初值
TH1 = 0xD4; //设置定时初值
if(S7_flag==0) //S7切换温度显示页面
{
Display();
Show1();
}
if(S7_flag==1)
{
Display3();
Show2();
}
switch(i) //数码管动态刷新
{
case 0:P2=0xC0;P0=0x80;P2=0xE0;P0=LEDbuff[0];i++;break;
case 1:P2=0xC0;P0=0x40;P2=0xE0;P0=LEDbuff[1];i++;break;
case 2:P2=0xC0;P0=0x20;P2=0xE0;P0=LEDbuff[2];i++;break;
case 3:P2=0xC0;P0=0x10;P2=0xE0;P0=LEDbuff[3];i++;break;
case 4:P2=0xC0;P0=0x08;P2=0xE0;P0=LEDbuff[4];i++;break;
case 5:P2=0xC0;P0=0x04;P2=0xE0;P0=LEDbuff[5];i++;break;
case 6:P2=0xC0;P0=0x02;P2=0xE0;P0=LEDbuff[6];i++;break;
case 7:P2=0xC0;P0=0x01;P2=0xE0;P0=LEDbuff[7];i=0;break;
default :break;
}
}
以上是main,身边的人喜欢把main.c中的key和displsy部分拆出来写成新的c文件,方便他人阅读。各有各的好处吧,我更喜欢放一起,方便调用和查阅。各位看官多多担待吧。
/*
程序说明: 单总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
日 期: 2011-8-9
*/
#include
#include"onewire.h"
sbit DQ = P1^4; //单总线接口
//单总线延时函数
void Delay_OneWire(unsigned int t) //STC89C52RC
{
t=10*t; //stc的运行速度是传统51的7-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;
}
void DS18B20_Start()
{
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0x44);
Delay_OneWire(200);
}
unsigned char DS18B20_Get()
{
char temp = 0;
unsigned char low=0,high=0;
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0xBE);
low= Read_DS18B20();
high= Read_DS18B20();
temp = (high<<4);
temp |= (low>>4);
return temp;
}
以上是iic通信的c文件
#include
#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);
void DS18B20_Start();
unsigned char DS18B20_Get();
#endif
以上是.h文件
结束
立个flag,下一篇12号之前写出来,如果没发,请私信骂我,谢谢