專注差異化嵌入式產(chǎn)品解決方案 給智能產(chǎn)品定制注入靈魂給予生命
提供開發(fā)工具、應用測試 完善的開發(fā)代碼案例庫分享
從全面的產(chǎn)品導入到強大技術支援服務 全程貼心伴隨服務,創(chuàng)造無限潛能!
深圳市英銳恩科技有限公司:臺灣麥肯單片機(Micon MDT單片機)亞太地區(qū)A級代理商
QLdsPIC3]CAN總線[C30+dsPIC30F6014A]
//實驗目的:CAN總線接收+LCD1602顯示
//軟件規(guī)劃:
// 1。通過CAN總線接收另一主機發(fā)送過來的溫度采集數(shù)據(jù)
// 2。接收到的數(shù)據(jù)轉(zhuǎn)換后送1602LCD顯示。
// 3。CAN模塊采用模塊C1,11位標識符的標準數(shù)據(jù)偵
//硬件規(guī)劃:
// 1。撥瑪開關S7全置ON
// 2。跳線J18全部接通
// 3。LCD1602插到座子上
// 4。接通CAN總線線纜
#include //dsPIC30F6014標準頭文件
_FOSC(0x0ffe5); //4倍頻晶振,F(xiàn)ailsafe 時鐘關閉
_FWDT(WDT_OFF); //關閉看門狗定時器
_FBORPOR(PBOR_OFF & MCLR_EN); //掉電復位禁止,MCLR復位使能。
_FGS(CODE_PROT_OFF); //代碼保護禁止
#define rs LATBbits.LATB4 //定義LCD控制位(注意這里只能用LATB寄存器,不能直接用PORTB寄存器)
#define rw LATBbits.LATB5
#define e LATBbits.LATB6
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ù)計數(shù)器
unsigned int buffer1; //定義CAN接收緩沖單元
unsigned int buffer2;
unsigned int buffer3;
unsigned int buffer4;
unsigned char __attribute__((address(0x930))) result[8]={0,0,0,'.',0,0,0,0};
unsigned long int i = 0;
//********************CAN模塊初始化函數(shù)*************************
void initcan()
{
C1CTRLbits.REQOP = 0x4; /進入配置模式
while (C1CTRLbits.OPMODE!=0x4){} //確認進入配置模式
C1TX0CON = 0x0003; //發(fā)送0郵箱配置,高優(yōu)先級
C1TX0SID = 0x0020; //發(fā)送0標準標識符,11位
C1TX0DLC = 0x01c0; //發(fā)送0數(shù)據(jù)長度,8字節(jié)
C1RX0CON = 0x0000; //接收0郵箱配置
C1RX0DLC = 0x0008; //接收0數(shù)據(jù)長度,8字節(jié)
C1RXF0SID = 0x0020; //接收濾波器0標準標識符,11位
C1RXM0SID = 0xffff; //接收屏蔽0標準標識符
C1CFG1bits.SJW=0; //SJW=1 x TQ
C1CFG1bits.BRP = 9; //125K
C1CFG2 = 0x03Ac; //SEG2PH=5;SEG1PH=6;PRSEG=4
C1CTRLbits.REQOP = 0x0; /進入正常模式
while (C1CTRLbits.OPMODE!=0x0){} //確認進入正常模式
return;
}
//****************延時函數(shù)**************************************
//延時函數(shù)(延時時間為(2+x)us)
void delay( char x)
{
unsigned char i;
for(i=0;i<x;i++);
}
//*****************寫一個字節(jié)數(shù)據(jù)函數(shù)***************************
//在電平發(fā)生改變后需要插入一段延時時間,否則LCD反應不過來。
void write(unsigned char x)
{
PORTD=x; //待顯示數(shù)據(jù)送PORTD口
delay(98);
rs=1; //該字節(jié)數(shù)據(jù)為數(shù)據(jù),而不是命令
delay(98);
rw=0; //此次操作為寫,而不是讀
delay(98);
e=0; //拉低使能信號
delay(98); //保持使能信號為低一段時間
e=1; //拉高使能信號,建立LCD操作所需要的上升沿
delay(98);
}
//******************LCD顯示設置函數(shù)*****************************
//在電平發(fā)生改變后需要插入一段延時時間,否則LCD反應不過來。
void lcd_enable()
{
delay(98);
rs=0; //該字節(jié)數(shù)據(jù)為命令,而不是數(shù)據(jù)
delay(98);
rw=0; //此次操作為寫,而不是讀
delay(98);
e=0; //拉低使能信號
delay(98); //保持使能信號為低一段時間
e=1; //拉高使能信號,建立LCD操作所需要的上升沿
delay(98);
}
//******************系統(tǒng)初始化函數(shù)******************************
void init()
{
TRISF=0X0000; //先設置18B20口方向為輸出
TRISB=0X0000; //設置B口方向為輸出
TRISD=0X0000; //設置D口方向為輸出
IFS0bits.T1IF=0; //先清除定時器中斷標志位
PR1=0XFFFF; //周期定最大
T1CON=0X0020; //分頻比為1:64
INTCON1=0x0000;
INTCON2=0x0000; //關閉所有中斷
}
//*******************LCD初始化函數(shù)*******************************
void lcd_init()
{
PORTD=0X1; //清除顯示
lcd_enable();
PORTD=0X38; //8位2行5*7點陣
lcd_enable();
PORTD=0X0e; //顯示開,光標開,閃爍
lcd_enable();
PORTD=0X06; //文字不動,光標右移
lcd_enable();
}
//*********************LCD顯示函數(shù)*******************************
void display()
{
PORTD=0X84; //顯示首地址
lcd_enable();
for(loop=0;loop<8;loop++) //共顯示8位
{
write(result[loop]); //查表并送顯示
delay(100); //插入一定延時
}
}
//******************啟動溫度轉(zhuǎn)換函數(shù)*****************************
void get_temp()
{
int i;
result[0]=(TZ/100)+0x30; //整數(shù)百位
result[1]=((TZ%100)/10)+0X30; //整數(shù)十位
result[2]=((TZ%100)%10)+0X30; //整數(shù)部分個位
wd=0;
if (TX & 0x80) wd=wd+5000;
if (TX & 0x40) wd=wd+2500;
if (TX & 0x20) wd=wd+1250;
if (TX & 0x10) wd=wd+625; //以上4條指令把小數(shù)部分轉(zhuǎn)換為BCD碼形式
result[4]=(wd/1000)+0x30; //十分位
result[5]=((wd%1000)/100)+0x30; //百分位
result[6]=((wd%100)/10)+0x30; //千分位
result[7]=(wd%10)+0x30; //萬分位
}
//**********************主函數(shù)***********************************
int main()
{
init(); //調(diào)用系統(tǒng)初始化函數(shù)
lcd_init(); //LCD初始化函數(shù)
initcan(); //調(diào)用CAN初始化函數(shù)
buffer1=buffer2=buffer3=buffer4=0;
while(1)
{
while(C1RX0CONbits.RXFUL==0); //等待接收到數(shù)據(jù)
buffer1 = C1RX0B1; //讀取接收到的數(shù)據(jù)
buffer2 = C1RX0B2;
buffer3 = C1RX0B3;
buffer4 = C1RX0B4;
C1RX0CONbits.RXFUL = 0;
TZ=buffer1;
TX=buffer2;
get_temp(); //調(diào)用溫度轉(zhuǎn)換函數(shù)
display(); //調(diào)用結果顯示函數(shù)
}
}