?? temperature.c
字號:
#include "c8051f020.h"
#include "stdio.h"
#include "intrins.h"
#define READ_ROM 0x33 //讀ROM
#define MATCH_ROM 0x55 //匹配ROM
#define SKIP_ROM 0xcc //跳過ROM
#define SEARCH_ROM 0xf0 //搜索ROM
#define ALARM_SEARCH 0xec //ROM發(fā)出警告
#define CONVERT_T 0x44 //啟動溫度轉(zhuǎn)化
#define READ_SRAM 0xbe //讀暫存存儲器
#define WRITE_SRAM 0x4e //寫暫存存儲器
#define COPY_SRAM 0x48 //拷貝暫存存儲器內(nèi)容
#define RECALL_E2RAM 0xb8 //重新調(diào)用E2RAM
#define READ_POWER 0xb4 //讀電源方式
#define SYSCLK 25000000
#define BAUDRATE 9600 //波特率默認為9600
#define BUFSIZE 256
#define RX0BUFSIZE 256 //緩沖區(qū)默認為256字節(jié)
#define TX0BUFSIZE 256
bit symbol=0; //溫度的正負號 symbol=0 為正;symbol=1 為負
sbit Ds18b20_DQ=P0^4;
unsigned char SN[8];
unsigned char Rx0Buf[RX0BUFSIZE],Tx0Buf[TX0BUFSIZE];//串口0接收和發(fā)送緩沖區(qū)
int Rx0In, Rx0Out, Tx0In, Tx0Out; //循環(huán)緩沖區(qū)指針
int Tx0Count; //已發(fā)送的字節(jié)數(shù)
void Close_WDG(void);
void SYSCLK_Init(void);
void UART_Init(void);
void DispLED(char *DispBuf,char ShowDot);
void startConvertT(void);
unsigned int getT_matchDs18b20(char ID);
bit getSymbol();
void readSN(unsigned char SN[]);
void UART0_Init(void);
int ReadCom(char * buf, int num);
int WriteCom(char * buf, int num);
/*****************************************
*串口0讀取函數(shù)
*第一個參數(shù):指向讀回的字符串存放的位置的指針
*第二個參數(shù):要讀取的字符個數(shù)
*返回成功讀取的字符個數(shù)
*****************************************/
int ReadCom(unsigned char * buf, int num)
{
int count = 0;
while ((Rx0In != Rx0Out) && (count != num))
{
buf[count] = Rx0Buf[Rx0Out];
Rx0Out = (Rx0Out + 1) % RX0BUFSIZE;
count ++;
}
return count;
}
/*****************************************
*串口0發(fā)送函數(shù)
*第一個參數(shù):要發(fā)送的字符串的首地址(指向要發(fā)送的字符串的指針)
*第二個參數(shù):要發(fā)送的字節(jié)個數(shù)
*返回成功讀取的字符個數(shù)
*****************************************/
int WriteCom(unsigned char * buf, int num)
{
int count = 0;
long i = 0;
if(num != 0)
{
for (count = 0; count < num; count ++)
{
Tx0Buf[Tx0In] = buf[count];
if((Tx0In + 1) % TX0BUFSIZE == Tx0Out) //the buffer is full
Tx0Out = (Tx0Out + 1) % TX0BUFSIZE; //replace the oldest data
Tx0In = (Tx0In + 1) % TX0BUFSIZE;
}
//begin to transmit
REN0 = 0;
TI0 = 1;
Tx0Count = 0;
while((Tx0In != Tx0Out) && (i < 60000000)) //wait for all the datas in transmit buffer sent out; or overtime
i ++;
//transmit has completed
REN0 = 1;
}
else{}
return Tx0Count;
}
//串口0中斷服務程序
void UART0_ISR(void) interrupt 4
{
if (RI0 == 1) // handle receive function
{
RI0 = 0; // clear RX complete indicator
Rx0Buf[Rx0In] = SBUF0;
if((Rx0In + 1) % RX0BUFSIZE == Rx0Out) //如果滿 則覆蓋以前的數(shù)據(jù)
Rx0Out = (Rx0Out + 1) % RX0BUFSIZE; //保證有效數(shù)據(jù)的位數(shù)
Rx0In = (Rx0In + 1) % RX0BUFSIZE;
}
else if(TI0 == 1)
{
TI0 = 0;
if( Tx0Out != Tx0In ) //Transmit Buffer is not empty
{
SBUF0 = Tx0Buf[Tx0Out];
Tx0Out = (Tx0Out + 1) % TX0BUFSIZE;
Tx0Count ++; //calculate the number of the bytes having been sent
}
else{} //Transmit buffer is empty, do nothing
}
}
// 串口初始化函數(shù)
void UART0_Init()
{
//初始化緩沖區(qū)
Rx0In = Rx0Out = 0;
Tx0In = Tx0Out = 0;
//波特率初始化 使用timer1,兩個串口波特率相同
TMOD |= 0x20; // timer1, mode2, 8-bit reload
TH1 = -(SYSCLK/BAUDRATE/16);// set Timer1 reload value for baudrate
//TL1 = TH1;
CKCON |= 0x10; // Timer1 uses SYSCLK as time base
PCON |= 0x80; // SMOD0 = 1;禁止UART0波特率/2功能
TR1 = 1; // start Timer1
//交叉開關(guān)分配
XBR0 |= 0x04; //UART0允許 RX0,TX0連到兩端口上
XBR2 |= 0x40; //交叉開關(guān)允許
P0MDOUT |= 0x03;
P0 = 0;
SCON0 = 0x50; //UART0為方式1:8位,波特率由定時器1決定
T2CON &= ~(0x30); // use timer1 as bautrate generator
ES0 = 1; //允許串口0中斷
}
void main(void)
{
long temperature=0;
unsigned int feedbackT;
unsigned char led[6];
bit sign;
int i;
int count;
// unsigned char getchar[256];
Close_WDG();//關(guān)閉看門狗
SYSCLK_Init();//系統(tǒng)時鐘初始化
UART0_Init(); // 串口初始化函數(shù)
EA = 1;
UART_Init();//串口初始化
readSN(SN); //讀取DS18B20序列號,寫入SN[]
while(1)
{
temperature=0;
for(i=0;i<40;i++)
{
startConvertT(); //開始溫度轉(zhuǎn)換
feedbackT=getT_matchDs18b20(0);//獲取溫度值
sign =getSymbol();//獲取溫度的正、負
if(sign)
temperature -=feedbackT;
else
temperature +=feedbackT;
}
sprintf(led,"%6d",(int)(temperature/40));
count = WriteCom(led, sizeof(led));
DispLED(led,3);
}
}
void Delay1us(int us) //延時us毫秒
{
while (us)
{
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
--us;
}
}
//發(fā)復位脈沖
//返回: 0-有設(shè)備連接 1-無設(shè)備連接
bit resetDs18b20(void)
{
unsigned char i;
bit RstFlag;
RstFlag=1;
Ds18b20_DQ=0;
Delay1us(600);
Ds18b20_DQ=1;
Delay1us(60); //15us-60us
for (i=0;i<16;i++) //60us-240us
{
Delay1us(15);
if (Ds18b20_DQ==0) RstFlag=0;
}
Delay1us(240); //240us
return RstFlag;
}
//向DS18b20寫一個字節(jié)ch
void writeByteToDs18b20(unsigned char ch)
{
unsigned char i;
Ds18b20_DQ=1;
Delay1us(1);
for (i=0;i<8;i++)
{
Ds18b20_DQ=0;
Delay1us(15);
Ds18b20_DQ=ch&0x1;
Delay1us(45);
Ds18b20_DQ=1;
ch=ch>>1;
Delay1us(1);
}
}
//接收DS18b20傳送來的一個字節(jié)并返回
unsigned char readByteFromDs18b20(void)
{
unsigned char i,ch;
ch=0;
Ds18b20_DQ=1;
Delay1us(1);
for (i=0;i<8;i++)
{
Ds18b20_DQ=0;
Delay1us(10);
Ds18b20_DQ=1;
Delay1us(2);
ch=ch>>1;
if (Ds18b20_DQ==1)
{
ch=ch+0x80;
}
Delay1us(45);
}
return ch;
}
//跳過ROM區(qū)
void skipROMCode(void)
{
resetDs18b20();
writeByteToDs18b20(SKIP_ROM);
}
//啟動DS18b20的溫度轉(zhuǎn)化功能
void startConvertT(void)
{
resetDs18b20(); //復位
writeByteToDs18b20(SKIP_ROM); //廣播
writeByteToDs18b20(CONVERT_T); //啟動AD轉(zhuǎn)換12bit700ms
}
//讀取DS18b20的序列號,更新SN[]
void readSN(unsigned char SN[])
{
char i;
while(resetDs18b20());
writeByteToDs18b20(READ_ROM); //讀取ROM
for(i=0;i<8;i++)
{
SN[i]=readByteFromDs18b20();
}
}
//發(fā)送序列號并匹配
void matchDs18b20(char ID)
{
unsigned char i;
writeByteToDs18b20(MATCH_ROM); //匹配ROM
for ( i = 0; i < 8; i++ )
writeByteToDs18b20(SN[i]);
}
//獲取溫度值
unsigned int getTempValue(void)
{
unsigned char low,high;
unsigned int T;
writeByteToDs18b20(READ_SRAM);
low=readByteFromDs18b20();
high=readByteFromDs18b20();
T =low+high*256;
if((high & 0xf8)!=0)
symbol=1;
else symbol=0;
if(symbol) //溫度為負
T =-T;
T =T&0x07ff;
T =(T/16.0)*100;
return T;
}
//讀取與指定的DS18b20相匹配的溫度值
unsigned int getT_matchDs18b20(char ID)
{
unsigned int T;
int i;
for(i=0;i<30000;i++);//延時等待轉(zhuǎn)換結(jié)束
resetDs18b20(); //復位
skipROMCode();
writeByteToDs18b20(CONVERT_T);
Delay1us(2); //2us
resetDs18b20(); //復位
matchDs18b20(ID);
T=getTempValue();
return(T);
}
//返回溫度的正負號
bit getSymbol()
{
return symbol;
}
void UART_Init(void)
{
//初始化緩沖區(qū)
Rx0In = Rx0Out = 0;
Tx0In = Tx0Out = 0;
//波特率初始化 使用timer1,兩個串口波特率相同
TMOD |= 0x20; // timer1, mode2, 8-bit reload
TH1 = -(SYSCLK/BAUDRATE/16);// set Timer1 reload value for baudrate
//TL1 = TH1;
CKCON |= 0x10; // Timer1 uses SYSCLK as time base
PCON |= 0x80; // SMOD0 = 1;禁止UART0波特率/2功能
TR1 = 1; // start Timer1
XBR0=0x04;
XBR2=0x44;
SCON1=0x00;
P0MDOUT=0xFF;
SCON0 = 0x50; //UART0為方式1:8位,波特率由定時器1決定
T2CON &= ~(0x30); // use timer1 as bautrate generator
ES0 = 1; //允許串口0中斷
}
/*********************************************************
功能:在六位數(shù)碼管顯示要求的字符串 含標點
*DispBuf:要顯示的字符串,長度為6
ShowDot:標點的位置
0:不顯示
1~6:標點顯示在數(shù)碼管的對應位
*********************************************************/
unsigned char code table[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,
0xf6,0xee,0x3e,0x9a,0x7c,0x9e,0x8e,0x04,0x00};
void DispLED(char *DispBuf,char ShowDot)//ShowDot 顯示小數(shù)點位
{
char ch;
int i=0,j;
ShowDot=6-ShowDot; //顯示小數(shù)點
SCON1=0x20;
for(i=5;i>=0;i--)
{
ch=DispBuf[i];
if ((ch>='a') && (ch<='f')) //轉(zhuǎn)換ASCII碼為對應段碼
{ ch-='a';ch+=10;}
else if ((ch>='A') && (ch<='F'))
{ ch-='A';ch+=10;}
else if ((ch>='0') && (ch<='9'))
ch-='0';
else if (ch=='-') //顯示負號
ch=16;
else
ch=17;
if (i==ShowDot) //顯示小數(shù)點
SBUF1=table[ch]+1;
else
SBUF1=table[ch];
for(j=0;j<255;j++); //延時
if(i==0) //清除串口中斷
SCON1=0;
}
}
/*****************************************
Function:initiate the system clock
*****************************************/
void SYSCLK_Init(void)
{
int i;
OSCXCN=0x67; // start external oscillator with 22.1184MHz crystal
for(i=0;i<256;i++); // XTLVLD blanking interval (>1ms)
while(!(OSCXCN&0x80)); // Wait for crystal osc. to settle
OSCICN=0x88; // select external oscillator as SYSCLK
// source and enable missing clock
}
void Close_WDG()
{
WDTCN=0xde; // disable watchdog timer
WDTCN=0xad;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -