📄 复件 tempercontrol.c
字号:
#include<pic.h>
#define uchar unsigned char
#define nop() asm("nop")
//继电器脚
#define Relay1 RC1 //常闭点 50吸合 65断开 加热
#define Relay1_DIR TRISC1
#define Relay2 RC2 //常开点 30断开 40闭合 风扇
#define Relay2_DIR TRISC2
//DS1820 管脚定义
#define DQ RC0
#define DQ_DIR TRISC0
#define DQ RC0 /* ds18b20 */
#define DQ_DIR TRISC0
/* DS1820 command */
#define SKIPROM 0XCC
#define READSCRACHPAD 0XBE
#define TCONVERT 0X44
const uchar LedNum[]={
0X6F,//0
0X09,//1
0X75,//2
0X3D,//3
0X1B,//4
0X3E,//5
0X7E,//6
0X2B,//7
0X7F,//8
0X3F,//9
0X7B,//A
0X5E,//b
0X66,//C
0X5D,//d
0X76,//E
0XE2,//F
0X50,//r
0X00,
0XFF
};//0--1,灭,亮
unsigned int Temperature,InitT;
unsigned char Tcount,ReadFlag;
union{
char c[2];
int x;
}temp;
void delay (int t){
while (t--);
}
unsigned long hextobcd(unsigned long hexs)
{
unsigned long va,bcds=0;
unsigned char i,disp_buffer[10];
va = 1000000000; //最大数级
for (i=9;i;i--) {
disp_buffer[i] = 0; //目标数组清零
while ((hexs>=va)&&(va>9)) {
hexs -= va; //减除数
disp_buffer[i]++; //商位加1
}
va /= 10; //除数除10,指向低一位
}
disp_buffer[0]=hexs;
va = 1;
for(i=0;i<8;i++)
{ bcds=bcds+ disp_buffer[i]*va;
va=va*0x10;
}
return(bcds);
}
/* DS1820
This file working with 16F876A using
RA0 pin to communate */
/* INIT */
void dsinit(){
DQ_DIR=0;
DQ=0;
delay(36); /* keep DSDQ low for 10*50 us, to reset the DS1820 */
DQ_DIR=1;
nop();
// delay(5); /* here we can only use delay(1), more then one may go out of the sample window */
// if (!DSDQ) /* sample window between min end:15+60, max begin,60 */
/* garrente sample window is between 60 to 75 us */
// print(dsfound);
// else
// print(dsnotfound);
//delay(10);
delay(20);
delay(30); /* wait for more then 480us, as required by the DS18B20 */
//delay(40);
}
/* write command to DS1820*/
void wdscmd(char cmd){
char tmp;
DQ_DIR=0;
for(tmp=8;tmp>0;tmp--) {
DQ_DIR=0;
DQ= 0;
nop();
if (cmd & 0x01) {
DQ_DIR=1; /* release the bus */
delay(3); /* wait for more than 60 us */
for (i=5;i>0;i--);
}
else {
DQ=0 ;
delay(3);
for (i=5;i>0;i--);
DQ_DIR=1;
}
cmd=cmd>>1;
}
}
/* READ temperature */
unsigned int dsread () {
char tmp=0x01;
unsigned int t;
temp.x=0;
while (tmp){ // read first 8 bits
DQ_DIR=0;
DQ=0;
asm("NOP");
DQ_DIR=1; // release the bus
if (DQ) // "1" presented
{temp.c[0] |= tmp;}
else nop();
tmp=tmp<<1;
delay(6);
}
tmp=1;
while (tmp){ // read first 8 bits
DQ_DIR=0;
DQ=0;
asm("NOP");
DQ_DIR=1; // release the bus
// asm("NOP");
if (DQ) // "1" presented
temp.c[1] |= tmp;
tmp=tmp<<1;
delay(6);
}
t=temp.x ;
//t=(t*10)>>4; //此时t为实际的带一位小数的温度值
t=(t>>1); //此时返回温度的整数部分
t=(t>>1);
t=(t>>1);
t=(t>>1);
nop();
return t;
}
ReadTemp() //函数处理后Teperature值为BCD码温度,如1234表示1234度。
{
unsigned int Temp;
dsinit();asm("clrwdt");
wdscmd(SKIPROM);asm("clrwdt");
wdscmd(TCONVERT);asm("clrwdt");
DQ_DIR=0;
DQ=0;
DQ_DIR=1;
while(1) { //test if the conversion finished
asm("clrwdt");
if (DQ)
break;
else
continue;
}
dsinit();
wdscmd(SKIPROM);asm("clrwdt");
wdscmd(READSCRACHPAD);asm("clrwdt");
Temp=dsread();asm("clrwdt"); /* read temperature */
Temperature=hextobcd(Temp);
}
void Relay() //常闭点Relay1 50吸合 65断开;常开点 Relay2 30断开 40吸合
{
Relay1_DIR = 0;Relay2_DIR = 0;
if(Temperature<=0x30) {Relay2 = 0;Relay1=0;delay(10);return;}
if(Temperature>=0x40) {Relay2 = 1;delay(10);} //继电器2闭合
if(Temperature<=0x50) {Relay1 = 0;delay(10);return;}
if(Temperature>=0x64) {Relay1 = 1; delay(10);} //继电器1断开
}
void timer()//
{
if (TMR1IF)
{ TMR1IF=0;TMR1H = 0x4F;TMR1L=0xD3;//TMR1H=time1_hi;TMR1L=time1_lo;//
Tcount++;
if(Tcount>40&&!ReadFlag)
{ReadTemp();
ReadFlag=1;Tcount=0;}
if(Tcount<40) ReadFlag=0;
}
}
//***************************
//初始化MCU
//****************************
void init_mcu(void)
{
T1CON = 0;TMR1H = 0x4F;TMR1L=0xD3;
CCP1CON = 0;
CCP2CON = 0;
INTCON = 0; //关闭与PORTC复用功能相关的寄存器
PIE1 = 0;
PIE2 = 0;
PIR1 = 0;
PIR2 = 0;
ADCON0 = 0;
ADCON1 = 0x07; //端口A为数字IO口
T1CON=0x1;
CCP1CON = 0;
CCP2CON = 0;
INTCON = 0; //关闭与PORTC复用功能相关的寄存器
PIE1 = 0; //外围中断寄存器关闭
PIE2 = 0;
PIR1 = 0; //中断标志
PIR2 = 0;
ADCON0 = 0;
ADCON1 = 0x0f; //端口A为数字IO口
asm("clrwdt");
InitT = 20;
OPTION=0x0F; //给wdt时钟,预分频128
//Relay1_DIR = 0;Relay2_DIR = 0;
Relay1 = 0;Relay2 = 0;
}
void display(unsigned int data)
{
unsigned int Disdata;unsigned char i,data1,data2,data0,Com;
Disdata = data&0xfff;
for(i=0;i<3;i++)
{
if(data>0x125) //超限 显示Err
{if(i==0){data0 = 0x50;}
if(i==1){data0 = 0x50;}
if(i==2){data0 = 0x76;}
}
else{data0 = LedNum[Disdata&0x0f]; Disdata=Disdata>>4;}
data1 = data0&0xDC;
data2 = (data0&0x20)+((data0&0x03)<<3);
if(i==0)Com=0x22; //Com1 RB0
if(i==1)Com=0x03; //Com2 RB5
if(i==2)Com=0x21; //Com3 RB1
PORTB = PORTB|0x23;//共阴,全部置一,然后将待显位置零
PORTC &= 0xC7;
PORTB = (PORTB &Com)|data1;PORTC = (PORTC&0xC7)|data2;
delay(100);
}
}
void InitDisplay()//显示端口初始化函数
{
TRISB=0;TRISC =TRISC^0x38;
PORTC |=0x38;PORTB =0xDC;
}
//主程序
void main(void)
{
unsigned int t1,t2;
//init_mcu();
//InitDisplay();
delay(65530);delay(65530);
init_mcu();
delay(65530);delay(65530);
init_mcu();
ReadTemp();
InitDisplay();ReadTemp();Temperature=0x26;
while(1)
{
asm("clrwdt");//ReadTemp();
timer();
display(Temperature);
Relay();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -