基于can的控制系统中温度节点的程序如下:<br /> 包括单片机等的初始化还包括测温部分以及数据的传送,<br /> 希望有谁能帮我看一下哪里还有些问题。<br />#include <reg51.h> <br />#include <absacc.h><br /><br />#define uchar unsigned char<br />#define uint unsigned int<br />uchar tplsb,tpmsb; //温度值低位、高位字节<br />uint Temperature;<br /><br /><br />unsigned char xdata Reg_CAN_MODE _at_ 0xfd00; //模式寄存器的地址<br />unsigned char xdata Reg_CAN_CMR _at_ 0xfd01; //命令寄存器<br />unsigned char xdata Reg_CAN_SR _at_ 0xfd02; //状态寄存<br />unsigned char xdata Reg_CAN_IR _at_ 0xfd03; //中断寄存器<br />unsigned char xdata Reg_CAN_IER _at_ 0xfd04; //中断使能寄存器<br />unsigned char xdata Reg_CAN_BTR0 _at_ 0xfd06; //总线时序寄存器0<br />unsigned char xdata Reg_CAN_BTR1 _at_ 0xfd07; //总线时序寄存器1<br />unsigned char xdata Reg_CAN_OCR _at_ 0xfd08; //输出控制寄存器的地址<br />unsigned char xdata Reg_CAN_TXB[1] _at_ 0xfd10; //标准帧,数据字节长度为2,帧状态,节点号,<br />unsigned char xdata Reg_CAN_AMR[1] _at_ 0xfd14; //验收屏蔽寄存器<br />unsigned char xdata Reg_CAN_RBSA _at_ 0xfd1e; //接受缓冲器区起始地址寄存器 <br />unsigned char xdata Reg_CAN_CDR _at_ 0xfd1f; //时钟分频寄存器的地址<br />unsigned char data Data_receive[5]={0x02,0x80,0x10,0x00,0x00}; // 存储收到的信息<br />unsigned char data Data_send[5]={0x02,0x00,0x10,0x00,0x00}; //can下发数据信息<br /> <br />bit INT=0; <br />sbit DQ=P1^5; //数据通信线 <br />sbit p10=P1^0;<br />sbit connect_ok=P1^1;<br />unsigned char data judge=3;<br /><br /> //检查设备连接标志位<br /> /* sja1000初始化子程序*/<br /> void SJA1000_config_normal(void) <br /> { unsigned char xdata *addr;<br /> unsigned char i;<br /> Reg_CAN_BTR0=0x00;<br /> Reg_CAN_BTR1=0x1C; //设置1M波特率<br /> Reg_CAN_MODE=0x01; //进入复位模式 <br /> Reg_CAN_IER=0x01; //接受中断使能<br /> Reg_CAN_CDR=0x88; //工作于PeliCAN模式下<br /> Reg_CAN_OCR=0xBA; //TX1下拉,TX0推挽 <br /> addr=&Reg_CAN_AMR;<br /> for(i=1;i<=4;i++)<br /> {*addr=0xff;<br /> addr++;<br /> } //屏蔽验收滤波器<br /> Reg_CAN_RBSA=0x00; //设置接受缓冲寄存器FIFO的起始地址为0<br /> Reg_CAN_MODE=0x00; //进入工作模式<br /> }<br /> /*SJA1000初始化完成*/<br /> <br />/*检查硬件连接*/<br />void Work_test(void )<br />{ Reg_CAN_TXB[13]=0x11; <br /> if(Reg_CAN_TXB[13]==0x11)<br /> connect_ok=1; //设备连接正常 <br /> else connect_ok=0;<br /> }<br /> /*硬件检查完成*/<br /><br /><br /><br /> /*读缓冲数据区*/<br />void CAN_read() interrupt 0<br />{ <br /> uint i;<br /> for(i=0;i<=4;i++) Reg_CAN_TXB=Data_receive;<br /> Reg_CAN_CMR=0x01;<br /> INT=1;<br /> }<br /><br /><br />/*接收数据*/<br />void RS_FROMCAN(void) <br /> {<br /> uint i;<br /> for(i=0;i<=4;i++) Data_send=Reg_CAN_TXB; <br /> if(Reg_CAN_TXB[2]==0x01)<br /> p10=1;<br /> else p10=0;<br /> }<br /><br />//延时函数<br /><br />void Delay6us(unsigned char delayDSTime) //6us延时<br />{<br /> while(--delayDSTime);<br />}<br />void delay1ms(void) //1ms延时 <br />{<br /> unsigned char i,j,k;<br /> for(i=5;i>0;i--)<br /> for(j=4;j>0;j--)<br /> for(k=23;k>0;k--);<br />}<br />void delay1s(void) //1s延时<br />{<br /> unsigned char h,i,j,k;<br /> for(h=5;h>0;h--)<br /> for(i=4;i>0;i--)<br /> for(j=116;j>0;j--)<br /> for(k=214;k>0;k--);<br />}<br /><br />//初始化函数<br />void Init_DS18B20(void)<br />{<br /> uchar x=0;<br /> DQ = 1; //DQ复位<br /> Delay6us(8); //稍做延时<br /> DQ = 0; //单片机将DQ拉低<br /> Delay6us(250); //精确延时 大于 480us<br /> DQ = 1; //拉高总线<br /> Delay6us(15);<br /> x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败<br /> Delay6us(125);<br />}<br /><br /><br />/*读取数据的一位,满足读时隙要求*/<br />bit RdBit(void)<br />{<br /> uint i;<br /> bit b;<br /> DQ=0;<br /> i++; //保持低至少1us<br /> DQ=1;<br /> i++; i++; //延时15us以上,读时隙下降沿后15us,DS18B20输出数据才有效<br /> b=DQ;<br /> i=8;<br /> while(i>0) i--; //读时隙不低于60us<br /> return(b);<br />}<br />/*读取数据的第一个字节*/<br />uchar RdByte(void)<br />{<br /> uchar i,j,b;<br /> b=0;<br /> for(i=1;i<=8;i++)<br /> {<br /> j=RdBit();<br /> b=(j<<7)|(b>>1);<br /> }<br /> return(b);<br />}<br /><br />/*写数据的一个字节,满足写1和写0的实时隙要求*/<br />void WrByte(uchar b)<br />{<br /> uint i;<br /> uchar j;<br /> bit btmp;<br /> for(j=1;j<=8;j++)<br /> {<br /> btmp=b&0x01; //取下一位(由低位向高位)<br /> b=b>>1; //右移<br /> if (btmp)<br /> {<br /> /*写1*/<br /> DQ=0;<br /> i++;i++; //延时,使得15us以内拉高<br /> DQ=1;<br /> i=8;<br /> while(i>0) i--; //整个写1时隙不低于60us<br /> }<br /> else<br /> {<br /> /*写0*/<br /> DQ=0;<br /> i=8;<br /> while(i>0) i--; //保持的电平在60us到120us之间<br /> DQ=1;<br /> i++;<br /> i++;<br /> }<br /> }<br />}<br />/*启动温度转换*/<br />void convert(void)<br />{<br /> Init_DS18B20(); //初始化DS18B20<br /> delay1ms(); //延时1ms<br /> WrByte(0xcc); //skip rom命令<br /> WrByte(0x44); //convert T命令<br />}<br /><br />/*读取温度值*/<br />void RdTemp(void)<br />{<br /> Init_DS18B20(); //初始化DS18B20<br /> delay1ms(); //延时1ms<br /> WrByte(0xcc); //skip rom命令<br /> WrByte(0xbe); //read scratchpad命令<br /> tplsb=RdByte(); //温度值低位字节(其中低4位为二进制的"小数"部分)<br /> tpmsb=RdByte(); //温度值高位字节(其中高5位为符号位) <br />}<br /><br />/*主程序开始*/<br />void main()<br />{ INT=0;<br /> tpmsb=Data_receive[4];<br /> tplsb=Data_receive[3]; <br /> SJA1000_config_normal() ; //CAN控制器初始化子程序<br /> connect_ok=0; <br /> while(connect_ok==0)<br /> Work_test();<br /> while(1) <br /> while(connect_ok) //CAN控制器准备好则进入主程序<br /> {<br /> delay1ms(); //延时1ms<br /> convert(); //启动温度转换,需要750ms<br /> delay1s(); //延时1s<br /> RdTemp(); //读取温度<br /> if(INT)<br /> RS_FROMCAN() ; //接收数据<br /> }<br /><br />} |
|