#申请原创# @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;
}
运行结果
|