#申请原创# @21小跑堂
8.CAN通讯实验
CAN 是控制器局域网络 Controller Area Network 的缩写,是德国BOSCH(博世)公司研发的一种串行通讯协议总线,它可以使用双绞线来传输信号,是世界上应用最广泛的现场总线之一。CAN协议主要用于汽车中各种不同元件之间的通信,以此取代昂贵而笨重的配电线束,该协议的健壮性使其同样适用于自动化和工业环境中。
APM32F407IG拥有2个CAN,支持 CAN 协议 2.0A 和 2.0B,例程中有个CAN的例程就是用这两个CAN互相发送接收数据,不过代码是针对MINI Board写的,修改一下让它适配TINY Board
先修改一下工程宏定义把MINI改成TINY
然后将main.c中的APM_MINI全部替换为APM_TINY
查看一下readme文件
先尝试直接连接PB8与PB13 PB9与PB12,测试结果失败,调换rx与tx的接法也还是失败,看来必须要用CAN模块才行
搞了2个TJA1050的CAN模块
按照上面readme里那个示意图进行连接,再次测试OK了
接下来尝试在自己的工程里实现一下,按下按键1 CAN1发送消息CAN2接收消息后打印出来,按下按键2 CAN2发送消息CAN1接收消息后打印出来
代码示例,CAN的相关初始化代码这里就不列举了,参考例程的就行
- uint8_t can1_rec_flag = 0;
- uint8_t can2_rec_flag = 0;
- CAN_RxMessage_T can1rxmsg;
- CAN_RxMessage_T can2rxmsg;
- void can_senddatas(uint8_t can)
- {
- CAN_TxMessage_T TxMessage;
- uint8_t x = 0;
- TxMessage.extID = 0x1234567;
- TxMessage.typeID = CAN_TYPEID_EXT;
- if(can == 2)
- {
- TxMessage.stdID = 0x123;
- TxMessage.typeID = CAN_TYPEID_STD;
- x = 0x80;
- }
- TxMessage.remoteTxReq = CAN_RTXR_DATA;
- TxMessage.dataLengthCode = 8;
- TxMessage.data[0] = 0x01|x;
- TxMessage.data[1] = 0x02|x;
- TxMessage.data[2] = 0x03|x;
- TxMessage.data[3] = 0x04|x;
- TxMessage.data[4] = 0x05|x;
- TxMessage.data[5] = 0x06|x;
- TxMessage.data[6] = 0x07|x;
- TxMessage.data[7] = 0x08|x;
- if(can == 1)
- CAN_TxMessage(CAN1, &TxMessage);
- else if(can == 2)
- CAN_TxMessage(CAN2, &TxMessage);
- }
- void can_print_rxmessage(CAN_RxMessage_T *msg)
- {
- uint8_t i = 0;
- printf("stdid: %08X\r\n",msg->stdID);
- printf("extid: %08X\r\n",msg->extID);
- printf("datalen: %d\r\n",msg->dataLengthCode);
- printf("data: ");
- while(i<msg->dataLengthCode)
- {
- printf("%02X ",msg->data[i]);
- i++;
- }
- printf("\r\n");
- }
- int main(void)
- {
- APM_TINY_LEDInit(LED2);
- APM_TINY_LEDInit(LED3);
- APM_TINY_PBInit(BUTTON_KEY1,BUTTON_MODE_GPIO);
- APM_TINY_PBInit(BUTTON_KEY2,BUTTON_MODE_GPIO);
- uart_init();
- can_init(CAN_BAUD_500K);
- CAN_EnableInterrupt(CAN1, CAN_INT_F0MP);
- CAN_EnableInterrupt(CAN2, CAN_INT_F0MP);
- NVIC_EnableIRQRequest(CAN1_RX0_IRQn, 0, 0);
- NVIC_EnableIRQRequest(CAN2_RX0_IRQn, 0, 0);
- while (1)
- {
- if(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET)
- {
- yuyy_delay_ms(30);
- if(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET)
- {
- while(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET);
- can_senddatas(1);
- }
- }
- if(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET)
- {
- yuyy_delay_ms(30);
- if(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET)
- {
- while(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET);
- can_senddatas(2);
- }
- }
- if(can1_rec_flag > 0)
- {
- printf("CAN1收到数据\r\n");
- can_print_rxmessage(&can1rxmsg);
- can1_rec_flag = 0;
- APM_TINY_LEDToggle(LED2);
- }
- if(can2_rec_flag > 0)
- {
- printf("CAN2收到数据\r\n");
- can_print_rxmessage(&can2rxmsg);
- can2_rec_flag = 0;
- APM_TINY_LEDToggle(LED3);
- }
- }
- }
- void CAN1_RX0_IRQHandler(void)
- {
- CAN_RxMessage(CAN1, CAN_RX_FIFO_0, &can1rxmsg);
- can1_rec_flag = 1;
- }
- void CAN2_RX0_IRQHandler(void)
- {
- CAN_RxMessage(CAN2, CAN_RX_FIFO_0, &can2rxmsg);
- can2_rec_flag = 1;
- }
运行结果
|