打印
[CAN-bus/DeviceNet]

请教基于can的控制系统温度节点的程序

[复制链接]
1473|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kristen|  楼主 | 2007-8-21 15:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
     基于can的控制系统中温度节点的程序如下:
  包括单片机等的初始化还包括测温部分以及数据的传送,
  希望有谁能帮我看一下哪里还有些问题。
#include  <reg51.h>       
#include <absacc.h>

#define uchar unsigned char
#define uint unsigned int
uchar tplsb,tpmsb;      //温度值低位、高位字节
uint Temperature;


unsigned  char  xdata  Reg_CAN_MODE    _at_ 0xfd00;                             //模式寄存器的地址
unsigned  char  xdata  Reg_CAN_CMR     _at_ 0xfd01;                             //命令寄存器
unsigned  char  xdata  Reg_CAN_SR      _at_ 0xfd02;                             //状态寄存
unsigned  char  xdata  Reg_CAN_IR      _at_ 0xfd03;                             //中断寄存器
unsigned  char  xdata  Reg_CAN_IER     _at_ 0xfd04;                             //中断使能寄存器
unsigned  char  xdata  Reg_CAN_BTR0    _at_  0xfd06;                            //总线时序寄存器0
unsigned  char  xdata  Reg_CAN_BTR1    _at_  0xfd07;                            //总线时序寄存器1
unsigned  char  xdata  Reg_CAN_OCR     _at_ 0xfd08;                            //输出控制寄存器的地址
unsigned  char  xdata  Reg_CAN_TXB[1]  _at_  0xfd10;         //标准帧,数据字节长度为2,帧状态,节点号,
unsigned  char  xdata  Reg_CAN_AMR[1]   _at_ 0xfd14;                             //验收屏蔽寄存器
unsigned  char  xdata  Reg_CAN_RBSA     _at_ 0xfd1e;                             //接受缓冲器区起始地址寄存器 
unsigned  char  xdata  Reg_CAN_CDR      _at_ 0xfd1f;                            //时钟分频寄存器的地址
unsigned   char     data    Data_receive[5]={0x02,0x80,0x10,0x00,0x00};            // 存储收到的信息
unsigned     char   data    Data_send[5]={0x02,0x00,0x10,0x00,0x00};               //can下发数据信息
 
bit INT=0;    
sbit DQ=P1^5;                       //数据通信线                            
sbit p10=P1^0;
sbit  connect_ok=P1^1;
unsigned   char  data  judge=3;

                                                          //检查设备连接标志位
  /* sja1000初始化子程序*/
 void SJA1000_config_normal(void)                                            
  {  unsigned char  xdata *addr;
     unsigned char i;
     Reg_CAN_BTR0=0x00;
     Reg_CAN_BTR1=0x1C;                                                      //设置1M波特率
     Reg_CAN_MODE=0x01;                                                   //进入复位模式  
     Reg_CAN_IER=0x01;                                                   //接受中断使能
     Reg_CAN_CDR=0x88;                                                    //工作于PeliCAN模式下
     Reg_CAN_OCR=0xBA;                                                      //TX1下拉,TX0推挽 
     addr=&Reg_CAN_AMR;
     for(i=1;i<=4;i++)
        {*addr=0xff;
         addr++;
         }                                                     //屏蔽验收滤波器
     Reg_CAN_RBSA=0x00;                                           //设置接受缓冲寄存器FIFO的起始地址为0
     Reg_CAN_MODE=0x00;                                          //进入工作模式
  }
             /*SJA1000初始化完成*/
 
/*检查硬件连接*/
void    Work_test(void )
{ Reg_CAN_TXB[13]=0x11;               
  if(Reg_CAN_TXB[13]==0x11)
      connect_ok=1;                                                           //设备连接正常                         
      else    connect_ok=0;
      }
         /*硬件检查完成*/



  /*读缓冲数据区*/
void   CAN_read() interrupt 0
{   
    uint i;
    for(i=0;i<=4;i++)  Reg_CAN_TXB=Data_receive;
    Reg_CAN_CMR=0x01;
    INT=1;
 }


/*接收数据*/
void   RS_FROMCAN(void)      
    {
     uint i;
    for(i=0;i<=4;i++) Data_send=Reg_CAN_TXB;  
    if(Reg_CAN_TXB[2]==0x01)
       p10=1;
     else p10=0;
     }

//延时函数

void Delay6us(unsigned char delayDSTime)          //6us延时
{
     while(--delayDSTime);
}
void delay1ms(void)                 //1ms延时       
{
    unsigned char i,j,k;
    for(i=5;i>0;i--)
    for(j=4;j>0;j--)
    for(k=23;k>0;k--);
}
void delay1s(void)                    //1s延时
{
    unsigned char h,i,j,k;
    for(h=5;h>0;h--)
    for(i=4;i>0;i--)
    for(j=116;j>0;j--)
    for(k=214;k>0;k--);
}

//初始化函数
void Init_DS18B20(void)
{
 uchar x=0;
 DQ = 1;    //DQ复位
 Delay6us(8);  //稍做延时
 DQ = 0;    //单片机将DQ拉低
 Delay6us(250); //精确延时 大于 480us
 DQ = 1;    //拉高总线
 Delay6us(15);
 x=DQ;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
 Delay6us(125);
}


/*读取数据的一位,满足读时隙要求*/
bit RdBit(void)
{
 uint i;
 bit b;
 DQ=0;
 i++;              //保持低至少1us
 DQ=1;
 i++;  i++;         //延时15us以上,读时隙下降沿后15us,DS18B20输出数据才有效
 b=DQ;
 i=8;
 while(i>0) i--;   //读时隙不低于60us
 return(b);
}
/*读取数据的第一个字节*/
uchar RdByte(void)
{
 uchar i,j,b;
 b=0;
 for(i=1;i<=8;i++)
 {
  j=RdBit();
  b=(j<<7)|(b>>1);
 }
 return(b);
}

/*写数据的一个字节,满足写1和写0的实时隙要求*/
void WrByte(uchar b)
{
 uint i;
 uchar j;
 bit btmp;
 for(j=1;j<=8;j++)
 {
  btmp=b&0x01;     //取下一位(由低位向高位)
  b=b>>1;           //右移
  if (btmp)
  {
   /*写1*/
   DQ=0;
   i++;i++;        //延时,使得15us以内拉高
   DQ=1;
   i=8;
   while(i>0) i--;    //整个写1时隙不低于60us
  }
  else
  {
   /*写0*/
   DQ=0;
   i=8;
   while(i>0) i--;     //保持的电平在60us到120us之间
   DQ=1;
   i++;
   i++;
  }
 }
}
/*启动温度转换*/
void convert(void)
{
 Init_DS18B20();      //初始化DS18B20
 delay1ms();           //延时1ms
 WrByte(0xcc);       //skip rom命令
 WrByte(0x44);       //convert T命令
}

/*读取温度值*/
void RdTemp(void)
{
 Init_DS18B20();          //初始化DS18B20
 delay1ms();          //延时1ms
 WrByte(0xcc);      //skip rom命令
 WrByte(0xbe);      //read scratchpad命令
 tplsb=RdByte();    //温度值低位字节(其中低4位为二进制的"小数"部分)
 tpmsb=RdByte();    //温度值高位字节(其中高5位为符号位)  
}

/*主程序开始*/
void main()
{ INT=0;
 tpmsb=Data_receive[4];
  tplsb=Data_receive[3];    
  SJA1000_config_normal()    ;         //CAN控制器初始化子程序
   connect_ok=0; 
  while(connect_ok==0)
      Work_test();
 while(1)    
   while(connect_ok)                 //CAN控制器准备好则进入主程序
    {
      delay1ms();       //延时1ms
      convert();      //启动温度转换,需要750ms
      delay1s();    //延时1s
      RdTemp();       //读取温度
     if(INT)
         RS_FROMCAN() ;     //接收数据
   }

}

相关帖子

沙发
wxj1952| | 2007-8-22 22:17 | 只看该作者

相差甚远。

/* sja1000初始化子程序*/
void SJA1000_config_normal(void)                                            
  {  unsigned char  xdata *addr;
     unsigned char i;
     Reg_CAN_BTR0=0x00;
     Reg_CAN_BTR1=0x1C;                                                      //设置1M波特率
     Reg_CAN_MODE=0x01;                                                   //进入复位模式  
     Reg_CAN_IER=0x01;                                                   //接受中断使能
     Reg_CAN_CDR=0x88;                                                    //工作于PeliCAN模式下
     Reg_CAN_OCR=0xBA;                                                      //TX1下拉,TX0推挽 
     addr=&Reg_CAN_AMR;
     for(i=1;i<=4;i++)
        {*addr=0xff;
         addr++;
         }                                                     //屏蔽验收滤波器
     Reg_CAN_RBSA=0x00;                                           //设置接受缓冲寄存器FIFO的起始地址为0
     Reg_CAN_MODE=0x00;                                          //进入工作模式
  }
             /*SJA1000初始化完成*/

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

2

帖子

1

粉丝