原创 H8/300H的CAN通信程序

2011-2-25 14:08 1265 3 3 分类: MCU/ 嵌入式
来源:瑞萨单片机论坛

H8/300H系列带内部CAN控制器的单片机,广泛应用在各种环境恶劣的通信系统里,如炼油厂,汽车通信等。我们以Tiny系列为例,其内部集成一个TinyCAN控制器,其规格如下: 
BOSCH 2.0B active 
最高速率1Mbps 
数据长度:0~8bytes 
4个数据缓存mailbox(可配置为接收或者发送) 

CAN总线硬件电路组成: 
MCU + CAN控制器 + CAN的物理层收发器 
所以我们必须在外面加上一个CAN的收发器,典型的如飞利浦的TJA1050系列。不同的收发器支持不同的速率。如果你的CAN控制器支持1M的速率,那么相应的收发器必须支持1M的速率。 
CAN控制器根据2根线上的电位差来判断总线电平。总线电平分为显性电平和隐形电平,二者必居其一。发送方通过使总线电平发生变化,将消息发送给接受方。 
具体的CAN规格可以参考“瑞萨开发工具”板块里的《瑞萨提供的CAN通信入门手册》。 
下面以瑞萨产的HA13721收发器为例,典型电路如下: 
H8/300H的CAN通信程序 - 瑞沙 - 瑞萨产品世界


CAN通信编程介绍: 
首先我们来初始化CAN控制器。 
TinyCAN.MCR.BIT.RSTRQ = 1;    
while(TinyCAN.GSR.BIT.RESET == 0);          
TinyCAN.TCMSC.BIT.PMR97 = 1;   // 设置发送引脚 
TinyCAN.TCMSC.BIT.PMR96 = 1;   // 设置接收引脚 
TinyCAN.MCR.BIT.RSTRQ = 0;    
                                   
// TCIRR0 clear 
TinyCAN.TCIRR0.BIT.RHI = 1;       
                                 
// 设置接收中断源 
TinyCAN.TCIMR0.BIT.DFRIM = 0;   // 数据帧请求中断 
TinyCAN.TCIMR0.BIT.RFRIM = 0;          // 远程帧请求中断 
TinyCAN.MBIMR.BIT.MB3 = 0;   // 发送邮箱3中断 

// 设置发送中断源 
TinyCAN.TCIMR1.BIT.EMPIM = 0;       // Mailbox empty interrupt enable 

// 邮箱设置:设置为发送或者接收 
TinyCAN.MBCR.BIT.MB0 = 1;    // 该缓存默认为接收 
TinyCAN.MBCR.BIT.MB1 = 0;    // 设置为发送 
TinyCAN.MBCR.BIT.MB2 = 0;    // 设置为发送 
TinyCAN.MBCR.BIT.MB3 = 0;          // 设置为接收 

       // 下面我们用邮箱0作为接收,邮箱1作为发送。每个邮箱是一个CAN节点,分别设置这2个节点 

// MBOX0 setup Receive Mailbox 
TinyCAN.MC[0][0] = 8;        // 数据长度为8字节 
TinyCAN.MC[0][4] = 10;                // 设置低ID 
TinyCAN.MC[0][5] = 5;                 // 设置高ID 

        // MBOX3 setup Transmit Mailbox 
TinyCAN.MC[1][0] = 8;        // 数据长度为8字节 
TinyCAN.MC[1][4] = 11;                // 设置低ID 
TinyCAN.MC[1][5] = 6;                 // 设置高ID 

        // 下面设置CAN控制器的接收滤波器 
        // 如果设置为0的话,表示节点的ID匹配时,才接收数据 
TinyCAN.LAFM[0] = 0x00000000;       // Acceptance filter mask enable 
TinyCAN.LAFM[1] = 0x00000000; 

        // CAN通信波利率,这里我们设置为1Mbps 
TinyCAN.BCR1.BIT.TSG1 = 5;     // 6 Tq   
TinyCAN.BCR1.BIT.TSG2 = 2;     // 3 Tq 
TinyCAN.BCR0.BIT.SJW = 1;     // 2 time quantum 
TinyCAN.BCR0.BIT.BRP = 1;     // 2 system clocks XMB Added 2007.07.23 

while(TinyCAN.GSR.BIT.RESET != 0); // wait until GSR3 is reset 

OK,CAN控制器已经被初始化,下面我们就可以发送数据了。 
首先往数据缓存里填充要发送的数据,数据长度为8个字节。 
TinyCAN.MD[1][0] = 0x11; 
TinyCAN.MD[1][1] = 0x22; 
TinyCAN.MD[1][2] = 0x33; 
TinyCAN.MD[1][3] = 0x44; 
TinyCAN.MD[1][4] = 0x55; 
TinyCAN.MD[1][5] = 0x66;    
TinyCAN.MD[1][6] = 0x77; 
TinyCAN.MD[1][7] = 0x88; 
然后发送数据 
while(TinyCAN.TXACK.BIT.MB1); // 等待该标志 
TinyCAN.TXPR.BIT.MB1 = 1;    // 发送数据 

如果一桢数据全部发送完毕,则会产生一个发送中断,如下: 
__interrupt(vect=34) void INT_TinyCAN(void) 

    if(TinyCAN.TXACK.BIT.MB1) //发送数据完成 
    { 
      TinyCAN.TXACK.BIT.MB1 = 1; // 清除该标志 
    } 

这个CAN控制器的中断全部共享一个中断向量34,所以我们只能采用软件中断的方式来判断产生了哪个中断源。 
CAN接收的过程是在接收中断里读取接收缓冲的数据。 

总结: 
CAN通信是一种典型的串行通信协议,以抗干扰性强出名,适用于各种恶劣的环境。 
在应用上要注意一些问题,比如总线仲裁,广播,错误帧等。有兴趣的朋友可以深入研究一下。

文章评论0条评论)

登录后参与讨论
我要评论
0
3
关闭 站长推荐上一条 /3 下一条