如果有用请点赞,还会继续更新的
题目:
思路:
总所周知,pwm的控制要用定时中断,而且倒计时也可以用定时中断来控制,所以就可以在一个定时中断中多套用几个if判断就OK了,但是要注意定时器的时间不要设置得太短了,不然很容易出现错误。(官方底层驱动已经给大家修改好了,可以直接使用了(也就是将那个延时扩大12倍就OK了))
源代码:
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;
}
main.c
#include"reg52.h"
#include"intrins.h"
#include"onewire.h"
void smg();
void key_board();
sfr AUXR=0x8e;
sbit Fen=P3^4;
sbit S4=P3^3;
sbit S5=P3^2;
sbit S6=P3^1;
sbit S7=P3^0;
int K4=1,K5=0,K7=0; //按键赋值
int last_time=60; //剩余时间
int count=0; //pwm间隔
int count_1=0;
int count_2=0; //时钟间隔
int pwm_num=0; //pwm
unsigned int temper; //温度
char code xianshi[13]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf,0xc6};
void choose573(int n)
{
switch(n)
{
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;
case(0):P2=(P2&0x1f)|0x00;break;
}
}
void clean()
{
choose573(4);
P0=0xff;
choose573(5);
P0=0x00;
choose573(0);
P0=0xff;
}
//----------------------------------------------wendu
void read_temper() //读取温度
{
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);
}
//----------------------------------------------
//----------------------------------------------pwm
void Timer0Init(void) //5毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初始值
TH0 = 0x28; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
}
void serverTimer0Init()interrupt 1
{
TL0 = 0x00; //设置定时初始值
TH0 = 0x28; //设置定时初始值
count++;
count_1++;
if(last_time!=0)
{
if(count_1>=200)
{
last_time--;
count_1=0;
}
else
{
if(count<pwm_num)
{
Fen=1;
}
else if(count<100&&count>pwm_num)
{
Fen=0;
}
else if(count>=100)
{
count=0;
}
}
}
}
//----------------------------------------------
//----------------------------------------------anjian
void Delay5ms() //@11.0592MHz
{
unsigned char i, j;
i = 54;
j = 199;
do
{smg();
while (--j);
} while (--i);
}
void key_board()
{
if(S4==0) //S4控制pwm的值
{
Delay5ms();
if(S4==0)
{
switch(K4)
{
case(1):pwm_num=20;K4=2;break;
case(2):pwm_num=30;K4=3;break;
case(3):pwm_num=70;K4=1;break;
}
}
while(!S4);
}
if(S5==0) //控制剩余时间的值
{
Delay5ms();
if(S5==0)
{
switch(K5)
{
case(0):last_time=60;K5=1;break;
case(1):last_time=120;K5=2;break;
case(2):last_time=0;K5=0;break;
}
}
while(!S5);
}
if(S6==0) //剩余时间清空
{
Delay5ms();
if(S6==0)
{
last_time=0;
K5=0;
}
while(!S6);
}
if(S7==0)
{
Delay5ms();
if(S7==0)
{
if(K7==1)
K7=0;
else
K7=1;
}
while(!S7);
}
}
//----------------------------------------------
//----------------------------------------------SMG
void Delay400us() //@11.0592MHz
{
unsigned char i, j;
i = 5;
j = 74;
do
{
while (--j);
} while (--i);
}
void SMG_display(int wei,int dat) //数码管显示选择
{
choose573(6);
P0=0x80>>(wei-1);
choose573(7);
P0=xianshi[dat];
}
void smg() //数码管显示
{
if(K7==0)
{
SMG_display(1,last_time%10);
Delay400us();
SMG_display(2,last_time/10-(last_time/100)*10);
Delay400us();
SMG_display(3,last_time/100);
Delay400us();
SMG_display(4,0);
Delay400us();
SMG_display(5,10);
Delay400us();
SMG_display(6,11);
Delay400us();
SMG_display(7,K4);
Delay400us();
SMG_display(8,11);
Delay400us();
}
if(K7==1)
{
SMG_display(1,12);
Delay400us();
SMG_display(2,temper%10);
Delay400us();
SMG_display(3,temper/10);
Delay400us();
SMG_display(4,10);
Delay400us();
SMG_display(5,10);
Delay400us();
SMG_display(6,11);
Delay400us();
SMG_display(7,4);
Delay400us();
SMG_display(8,11);
Delay400us();
}
}
//----------------------------------------------
//----------------------------------------------LED模块
void LED_display()
{
if(last_time==0)
{
choose573(4);
P0=0xff;
}
else
{
if(K4==1)
{
choose573(4);
P0=~(0x01);
}
if(K4==2)
{
choose573(4);
P0=~(0x02);
}
if(K4==3)
{
choose573(4);
P0=~(0x04);
}
}
}
//----------------------------------------------
void main()
{
clean();
Timer0Init();
while(1)
{
smg();
key_board();
read_temper();
LED_display();
}
}
**
码字不容易,点个赞再走!!!!
**