標(biāo)題:
dsPIC30F6014控制DS18B20溫度+CAN總線的發(fā)送程序
[打印本頁(yè)]
作者:
xiaos
時(shí)間:
2015-4-2 23:16
標(biāo)題:
dsPIC30F6014控制DS18B20溫度+CAN總線的發(fā)送程序
dsPIC30F6014控制DS18B20溫度+CAN總線的發(fā)送程序
// 1。DS18B20定時(shí)采集溫度
// 2。溫度采集時(shí)間間隔用T1定時(shí)器控制
// 3。采集到的溫度通過(guò)CAN總線送另一主機(jī)處理
#include <p30f6014.h> //dsPIC30F6014標(biāo)準(zhǔn)頭文件
_FOSC(0x0ffe5); //4倍頻晶振,F(xiàn)ailsafe 時(shí)鐘關(guān)閉
_FWDT(WDT_OFF); //關(guān)閉看門(mén)狗定時(shí)器
_FBORPOR(PBOR_OFF & MCLR_EN); //掉電復(fù)位禁止,MCLR復(fù)位使能。
_FGS(CODE_PROT_OFF); //代碼保護(hù)禁止
unsigned long int i = 0;
#define uch unsigned char //給unsigned char起別名 uch
# define DQ PORTFbits.RF6 //定義18B20數(shù)據(jù)端口
# define DQ_DIR TRISFbits.TRISF6 //定義18B20D口方向寄存器
# define DQ_HIGH() DQ_DIR =1 //設(shè)置數(shù)據(jù)口為輸入
# define DQ_LOW() DQ = 0; DQ_DIR = 0 //設(shè)置數(shù)據(jù)口為輸出
#define rs LATBbits.LATB4 //定義LCD控制位(注意這里只能用LATB寄存器,不能直接用PORTB寄存器)
#define rw LATBbits.LATB5
#define e LATBbits.LATB6
unsigned char __attribute__((address(0x900))) TLV; //采集到的溫度高8位
unsigned char __attribute__((address(0x902))) THV; //采集到的溫度低8位
unsigned char __attribute__((address(0x904))) TZ; //轉(zhuǎn)換后的溫度值整數(shù)部分
unsigned char __attribute__((address(0x906))) TX; //轉(zhuǎn)換后的溫度值小數(shù)部分
unsigned int __attribute__((address(0x908))) wd; //轉(zhuǎn)換后的溫度值BCD碼形式
unsigned char __attribute__((address(0x9a0))) loop; //LCD顯示次數(shù)計(jì)數(shù)器
//**********************CAN總線初始化*************************
void initcan()
{
C1CTRLbits.REQOP = 0x4; //請(qǐng)求進(jìn)入配置模式
while (C1CTRLbits.OPMODE!=0x4){} //確認(rèn)進(jìn)入配置模式
C1TX0CON = 0x0003; //發(fā)送0郵箱配置
C1TX0SID = 0x0020; //發(fā)送0標(biāo)準(zhǔn)標(biāo)識(shí)符,11位
C1TX0DLC = 0x01c0; //發(fā)送0數(shù)據(jù)長(zhǎng)度,8字節(jié)
C1RX0CON = 0x0000; //接收0郵箱配置
C1RX0DLC = 0x0008; //接收0數(shù)據(jù)長(zhǎng)度,8字節(jié)
C1RXF0SID = 0x0020; //接收濾波器0標(biāo)準(zhǔn)標(biāo)識(shí)符,11位
C1RXM0SID = 0xffff; //接收屏蔽0標(biāo)準(zhǔn)標(biāo)識(shí)符
C1CFG1bits.SJW=0; //SJW=1 x TQ
C1CFG1bits.BRP = 9; //125K
C1CFG2 = 0x03Ac; //SEG2PH=5;SEG1PH=6;PRSEG=4
C1CTRLbits.REQOP = 0x0; //請(qǐng)求進(jìn)入正常模式
while (C1CTRLbits.OPMODE!=0x0){} //確認(rèn)進(jìn)入正常模式
return;
}
//**********************延時(shí)函數(shù)**************************
//延時(shí)函數(shù)(延時(shí)時(shí)間為(2+x)us)
void delay( char x)
{
unsigned char i;
for(i=0;i<x;i++);
}
//********************系統(tǒng)初始化函數(shù)**********************
void init()
{
TRISF=0X0000; //先設(shè)置18B20口方向?yàn)檩敵?br />
TRISB=0X0000; //設(shè)置B口方向?yàn)檩敵?br />
TRISD=0X0000; //設(shè)置D口方向?yàn)檩敵?br />
IFS0bits.T1IF=0; //先清除定時(shí)器中斷標(biāo)志位
PR1=0XFFFF; //周期定最大
T1CON=0X0020; //分頻比為1:64
INTCON1=0x0000;
INTCON2=0x0000; //關(guān)閉所有中斷
}
//******************復(fù)位DS18B20函數(shù)*****************************
//主控制器(dsPIC30F6014A)先拉低總線480us,然后釋放總線回到高電平
//18B20檢測(cè)到上升沿后先等待15-60us,然后拉低總線做為復(fù)位的應(yīng)答信號(hào)
//主控制器釋放總線后到復(fù)位結(jié)束時(shí)間應(yīng)為480US
reset(void)
{
char presence=1;
while(presence)
{
DQ_LOW() ; //主機(jī)拉至低電平
delay(100);
delay(100);
delay(100);
delay(100);
delay(78); //以上5條共延時(shí)480us
DQ_HIGH(); //釋放總線等電阻拉高總線,并保持15~60us
delay(38); //延時(shí)40us
if(DQ==1) presence=1; //沒(méi)有接收到應(yīng)答信號(hào),繼續(xù)復(fù)位
else presence=0; //接收到應(yīng)答信號(hào)
delay(100);
delay(100);
delay(100);
delay(100);
delay(38); //以上5條共延時(shí)440us
}
}
//****************寫(xiě)18b20寫(xiě)字節(jié)函數(shù)*****************************
//主控制器寫(xiě)數(shù)據(jù)1:先把總線拉低,然后在15us內(nèi)釋放總線
//主控制器寫(xiě)數(shù)據(jù)0:把總線拉低至少60us
//寫(xiě)一位數(shù)據(jù)至少需要60us
//兩位數(shù)據(jù)之間至少延時(shí)1us
void write_byte(uch val)
{
uch i;
uch temp;
for(i=8;i>0;i--)
{
temp=val&0x01; //最低位移出
DQ_LOW();
delay(3); //保持拉低5us
if(temp==1) DQ_HIGH(); //如果寫(xiě)1,拉高電平
delay(58); //延時(shí)60us
DQ_HIGH();
delay(1); //在兩位之間插入3us延時(shí)
val=val>>1; //右移一位
}
}
//****************18b20讀字節(jié)函數(shù)********************************
//主控制器把總線拉低至少1US,然后釋放
//主控制器讀數(shù)據(jù)1:18B20保持總線狀態(tài)不變
//主控制器讀數(shù)據(jù)0:18B20檢測(cè)到總線拉低后繼續(xù)拉低總線至少60ms
//主控制器在拉低總線后的15us讀取總線上的狀態(tài)
//讀取1位數(shù)據(jù)至少需要60us
uch read_byte(void)
{
uch i;
uch value=0; //讀出溫度
for(i=8;i>0;i--)
{
value>>=1;
DQ_LOW();
delay(1); //保持總線拉低3us
DQ_HIGH(); //拉至高電平
delay(5); //釋放總線后保持7us再讀取數(shù)據(jù)
if(DQ) value|=0x80;
delay(48); //延時(shí)50us,保證每1位的60us延時(shí)
}
return(value);
}
//*****************啟動(dòng)溫度轉(zhuǎn)換函數(shù)***************************
void get_temp()
{
int i;
DQ_HIGH();
reset(); //復(fù)位等待從機(jī)應(yīng)答
write_byte(0XCC); //忽略ROM匹配
write_byte(0X44); //發(fā)送溫度轉(zhuǎn)化命令
for(i=0;i<8;i++)
{
delay(98); //確保溫度轉(zhuǎn)換完成所需要的時(shí)間
}
reset(); //再次復(fù)位,等待從機(jī)應(yīng)答
write_byte(0XCC); //忽略ROM匹配
write_byte(0XBE); //發(fā)送讀溫度命令
TLV=read_byte(); //讀出溫度低8
THV=read_byte(); //讀出溫度高8位
DQ_HIGH(); //釋放總線
TZ=(TLV>>4)|(THV<<4)&0X3f; //溫度整數(shù)部分
TX=TLV<<4; //溫度小數(shù)部分
}
//************************主函數(shù)********************************
int main(void)
{
init(); //調(diào)用系統(tǒng)初始化函數(shù)
initcan();
LATDbits.LATD0=1;
LATDbits.LATD1=0;
while(1)
{
TMR1=0XC2F6; //定時(shí)器初值
T1CONbits.TON=1; //啟動(dòng)定時(shí)器
while(!IFS0bits.T1IF); //等待0.1s定時(shí)到
IFS0bits.T1IF=0;
get_temp(); //調(diào)用溫度轉(zhuǎn)換函數(shù)
C1TX0B1 = TZ;
C1TX0B2 = TX;
C1TX0B3 = 0x5A5A; //B3跟B4四字節(jié)數(shù)據(jù)無(wú)效,也可做效驗(yàn)用
C1TX0B4 = 0xa5a5;
C1TX0CONbits.TXREQ = 1; //啟動(dòng)發(fā)送
while (C1TX0CONbits.TXREQ==1){} //等待發(fā)送完成
for (i=0;i<2;i++){}
}
}
復(fù)制代碼
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1