【OK210试用体验】车联网项目篇之二:CAN总线数据接收和转换的实现 - 在线问答 - 电子技术论坛 - 最好最受欢迎电子论坛!

【OK210试用体验】车联网项目篇之二:CAN总线数据接收和转换的实现

Jianjun ( 楼主 ) 2015-10-27 20:47:32  只看该作者 倒序浏览
本帖最后由 woriaty 于 2015-10-27 21:05 编辑

在上篇整体规划中已经介绍了车联网项目的基本结构,下面介绍第一部分功能,即CAN总线数据接收并转换为串口数据的实现方法:
1、硬件架构
       CAN总线接收采用带CAN通讯模块的飞思卡尔单片机MC9S12XS128实现,在接收时采用PCA82C251芯片作为CAN协议控制器和物理总线的接口,下图是自己做的带CAN总线收发器的飞思卡尔单片机最小系统:


       背面是PCA82C251芯片(纯手工焊接,不是很美观,哈哈^_^):


2、软件架构
       通过对飞思卡尔单片机寄存器配置实现单片机中断接收CAN总线数据的功能,具体配置代码如下:
  1. /*                        初始化CAN0                         */

  2. void INIT_CAN0(void)
  3. {
  4.   if(CAN0CTL0_INITRQ==0)      // 查询是否进入初始化状态   
  5.     CAN0CTL0_INITRQ =1;        // 进入初始化状态

  6.   while (CAN0CTL1_INITAK==0);  //等待进入初始化状态

  7.   CAN0BTR0_SJW = 0;            //设置同步
  8.   CAN0BTR0_BRP = 7;            //设置波特率  
  9.   CAN0BTR1 = 0x1c;       //设置时段1和时段2的Tq个数 ,总线频率为250kb/s

  10. // 关闭滤波器                                 
  11.   CAN0IDMR0 = 0xFF;
  12.   CAN0IDMR1 = 0xFF;
  13.   CAN0IDMR2 = 0xFF;
  14.   CAN0IDMR3 = 0xFF;
  15.   CAN0IDMR4 = 0xFF;
  16.   CAN0IDMR5 = 0xFF;
  17.   CAN0IDMR6 = 0xFF;
  18.   CAN0IDMR7 = 0xFF;

  19.   CAN0CTL1 = 0xC0;             //使能MSCAN模块,设置为一般运行模式、使用总线时钟源

  20.   CAN0CTL0 = 0x00;             //返回一般模式运行

  21.   while(CAN0CTL1_INITAK);      //等待回到一般运行模式

  22.   while(CAN0CTL0_SYNCH==0);    //等待总线时钟同步

  23.   CAN0RIER_RXFIE = 1;          //使能接收中断
  24. }
  25. /*                       CAN0接收                            */

  26. Bool MSCAN0GetMsg(struct can_msg *msg)
  27. {
  28.   unsigned char sp;

  29.   // 检测接收标志
  30.   if(!(CAN0RFLG_RXF))
  31.     return(FALSE);
  32.   
  33.   // 检测 CAN协议报文模式 (一般/扩展) 标识符
  34.   if(CAN0RXIDR1_IDE)
  35.     // IDE = Recessive (Extended Mode)
  36.     return(FALSE);

  37.   // 读标识符
  38.   msg->id = (unsigned int)(CAN0RXIDR0<<3) |
  39.             (unsigned char)(CAN0RXIDR1>>5);
  40.   
  41.   if(CAN0RXIDR1&0x10)
  42.     msg->RTR = TRUE;
  43.   else
  44.     msg->RTR = FALSE;
  45.   
  46.   // 读取数据长度
  47.   msg->len = CAN0RXDLR;
  48.   
  49.   // 读取数据
  50.   for(sp = 0; sp < msg->len; sp++)
  51.     msg->data[sp] = *((&CAN0RXDSR0)+sp);

  52.   // 清 RXF 标志位 (缓冲器准备接收)
  53.   CAN0RFLG = 0x01;

  54.   return(TRUE);
  55. }
复制代码
      在接受CAN总线数据时需要知道节点ID才能接受对应节点的数据,刚好公司现在在做新能源汽车变速箱实验,因此得到了变速箱控制器CAN总线节点ID,读取的CAN报文内容即为变速箱控制器共享至CAN总线网络中的档位、电机转速和电池电压数据,后面可以根据电机转速计算出对应的车速。
      接收到数据后使用SCI将其转化为串口数据发送,SCI配置如下:
  1. /*                       串口通信                            */

  2. /*                        初始化SCI                          */

  3. void INIT_SCI(void)
  4. {
  5.   SCI0BD = BUS_CLOCK/16/BAUD;   //设置SCI0波特率为9600
  6.   SCI0CR1 = 0x00;        //设置SCI0为正常模式,八位数据位,无奇偶校验
  7.   SCI0CR2 = 0x08;        //允许发送数据
  8. }


  9. /*                       串口发送函数                        */

  10. void SCI_send(unsigned char data)
  11. {
  12.   while(!SCI0SR1_TDRE);         //等待发送数据寄存器(缓冲器)为空
  13.   SCI0DRL = data;
  14. }

  15. /*                  串口发送数据函数                       */

  16. void send_string(unsigned char *putchar)
  17. {
  18.   unsigned char i;
  19.   for(i=0;i<8;i++)
  20.       SCI_send(*putchar++);
  21. }  

  22. /*                内容填写                    */
  23. void String_Init(void)         
  24. {
  25.     putstring[0]=0xaa;         //头校验文件
  26.     putstring[1]=Speed/256;    //转速信号拆分
  27.     putstring[2]=Speed%256;    //转速信号拆分
  28.     putstring[3]=D;            //档位
  29.     putstring[4]=Volt;         //电池电压
  30.     putstring[5]=0x55;         //尾校验文件   
  31. }
复制代码
          以上便实现了新能源汽车CAN总线数据读取和将其转化为SCI数据发送的功能。



3个回复

Jianjun 发表于 2015-10-27 20:55:06
本帖最后由 woriaty 于 2015-10-27 21:07 编辑

后面持续更新项目进度
燕小飞 发表于 2015-11-2 11:31:43
加油啊,后续的呢
回复

举报 使用道具

Jianjun 发表于 2015-11-2 11:37:39
燕小飞 发表于 2015-11-2 11:31
加油啊,后续的呢

第三篇已经发了,Android程序还在调试
您需要登录后才可以回帖 登录 | 注册

本版积分规则


关闭

站长推荐上一条 /6 下一条

小黑屋|手机版|Archiver|电子发烧友 ( 湘ICP备2023018690号 )

GMT+8, 2024-4-20 10:28 , Processed in 0.609983 second(s), Total 61, Slave 44 queries .

Powered by 电子发烧友网

© 2015 bbs.elecfans.com

微信扫描
快速回复 返回顶部 返回列表