难点:如何控制pwm;已知频率为1kHZ,所以周期为1ms,使用100us的定时器,定义一个变量来记录过了多少时间,若想输出20%,前八个为0让第八个置1第十个置0;
main.c
#include <STC15F2K60S2.H>
#include <ONEWIRE.H>
void Timer2Init() //1毫秒@12.000MHz
{
AUXR &= 0xFB; //定时器时钟12T模式
T2L = 0x18; //设置定时初值
T2H = 0xFC; //设置定时初值
AUXR |= 0x10; //定时器2开始计时
IE2|=0X04;
EA=1;
}
void Timer0Init() //100微秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x9C; //设置定时初值
TH0 = 0xFF; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
}
void Device_ctrl(unsigned char p2date,unsigned char p0date)
{
P0=p0date;
P2=P2&0X1F|p2date;
P2&=0X1F;
}
unsigned char mode_display[8];
unsigned char temp_display[8];
unsigned char smg_du[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned int smg_count;
unsigned char display_mode;
unsigned char mode=1;
unsigned int time;
unsigned int time_count;
unsigned int temp;
unsigned int temp_count;
void temp_process()
{
if(temp_count>100)
{
temp_count=0;
temp=read_temp();
}
}
void smg_show()
{
unsigned char i;
Device_ctrl(0xc0,0);
if(display_mode==0)
{
Device_ctrl(0xe0,~mode_display[i]);
}
else
{
Device_ctrl(0xe0,~temp_display[i]);
}
Device_ctrl(0xc0,0x01<<i);
i=(i+1)%8;
}
void smg_process()
{
if(smg_count>3)
{
smg_count=0;
mode_display[0]=0x40;
mode_display[2]=0x40;
mode_display[3]=0x00;
temp_display[0]=0x40;
temp_display[1]=smg_du[4];
temp_display[2]=0x40;
temp_display[3]=0x00;
temp_display[4]=0x00;
temp_display[7]=0x39;
if(display_mode==0)
{
mode_display[1]=smg_du[mode];
mode_display[4]=smg_du[time/1000];
mode_display[5]=smg_du[time/100%10];
mode_display[6]=smg_du[time/10%10];
mode_display[7]=smg_du[time%10];
}
else
{
temp_display[5]=smg_du[temp/10];
temp_display[6]=smg_du[temp%10];
}
}
}
unsigned char Trig_btn;
unsigned char Cont_btn;
unsigned int key_count;
void key_btn()
{
unsigned char readdate=P3^0XFF;
Trig_btn=readdate&(Cont_btn^readdate);
Cont_btn=readdate;
}
void key_process()
{
if(key_count>=5)
{
key_btn();
key_count=0;
if(Trig_btn==0x08)//s4
{
if(display_mode==0)
{
mode++;
if(mode==4)
{
mode=1;
}
}
}
if(Trig_btn==0x04)//s5
{
if(display_mode==0)
{
if(time<9939)
{
time=time+60;
}
}
}
if(Trig_btn==0x02)//s6
{
if(display_mode==0)
{
time=0;
}
}
if(Trig_btn==0x01)//s7
{
display_mode++;
if(display_mode==2)
{
display_mode=0;
}
}
}
}
unsigned int led_count;
void led_process()
{
if(led_count>5)
{
led_count=0;
if(time)
{
if(mode==1)
{
Device_ctrl(0x80,~0x01);
}
else if(mode==2)
{
Device_ctrl(0x80,~0x02);
}
else
{
Device_ctrl(0x80,~0x04);
}
}
else
{
Device_ctrl(0x80,0xff);
}
}
}
void main()
{
Timer2Init();
Timer0Init();
Device_ctrl(0xa0,0x00);
while(1)
{
smg_process();
key_process();
led_process();
temp_process();
}
}
unsigned int mode_count;
void timer0service() interrupt 1
{
mode_count++;
if(mode==1)
{
if(mode_count==8)
{P34=1;}
if(mode_count==10)
{P34=0;}
}
else if(mode==2)
{
if(mode_count==7)
{P34=1;}
if(mode_count==10)
{P34=0;}
}
else
{
if(mode_count==3)
{P34=1;}
if(mode_count==10)
{P34=0;}
}
}
void timer2service() interrupt 12
{
smg_count++;
smg_show();
key_count++;
time_count++;
led_count++;
temp_count++;
if(time_count>=1000)
{
time_count=0;
if(time)
{
time--;
}
}
}
ONEWIRE.C
#include "onewire.h"
//单总线内部延时函数
void Delay_OneWire(unsigned int t)
{
t=t*12;
while(t--);
}
//单总线写操作
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;
}
//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;
}
float read_temp()
{
unsigned char low,high;
float date;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
low=Read_DS18B20();
high=Read_DS18B20();
date=(high<<8)|low;
date=date*0.0625;
return date;
}
ONEWIRE.H
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
#include <STC15F2K60S2.H>
sbit DQ = P1^4;
float read_temp();
#endif