本帖最后由 lihuasoft 于 2019-10-23 20:50 编辑
3、CAN收发实验
作为车规级、目标定位在后装市场的MCU,CAN和LIN必不可少。
官方CAN例子,以及论坛版主早先发布的一个CAN实例,代码量都挺多的。
那么我就简化一下,免得像我一样喜欢简单的伙伴望而生畏。
首先,在板子上贴一个收发器芯片(我用的是TJA1050):
然后新建工程,参考官方和版主的代码,简化一下。波特率1MHz,CAN1。
mini板的收发器的standby引脚接在PB2上。
附件里有两个版本,一个是在main()循环里发报文,另一个是在接收中断里发报文。
贴出循环里发报文的:
#include "ac78xx.h"
#include "ac78xx_gpio.h"
#include "ac78xx_can.h"
#define PAout(n) BIT_ADDR(GPIOA_ODR_ADDR, n)
#define PAin(n) BIT_ADDR(GPIOA_IDR_ADDR, n)
#define PBout(n) BIT_ADDR(GPIOB_ODR_ADDR, n)
#define PBin(n) BIT_ADDR(GPIOB_IDR_ADDR, n)
#define LED0 PAout(0)
#define LED1 PAout(1)
#define PIN_LED0 (GPIO_PA0)
#define PIN_LED1 (GPIO_PA1)
#define CAN1_TX (GPIO_PC15)
#define CAN1_RX (GPIO_PC14)
#define CAN1_STB (GPIO_PB2)
#define CAN1_TRASCVER_NML do{GPIO_ResetPinBits(CAN1_STB);}while(0)
CAN_MSG_INFO sMsg = {0};
uint8_t receved = 0;
int32_t CanEventCallback(uint32_t event, uint32_t wparam, uint32_t lparam)
{
if (event & (uint32_t)CAN_EVENT_BUSERROR)
{
//printf("[CAN]ERROR: %x %x %x\r\n", event, wparam, lparam);
LED1=1;
}
if (event & (uint32_t)CAN_EVENT_RECVMSG)
{
//lparam==CAN1 or CAN2
if (!CAN_MessageRead((CAN_Type*)lparam, &sMsg))
{
receved = 1;
LED0 = !LED0;
}
}
return 0;
}
int main(void)
{
CAN_Config canConfig = {0};
CAN_FilterControl filter = {0};
GPIO_SetFunc(CAN1_TX, 1);//设置CAN1引脚复用功能
GPIO_SetFunc(CAN1_RX, 1);
GPIO_SetDir(CAN1_STB, 1);//设置CAN1收发器控制为IO控制
CAN1_TRASCVER_NML;//使能CAN收发器
filter.index = 1;
filter.code = 0x00000501;
filter.mask = 0x1fffffff;
filter.enable = 1;
canConfig.interruptEnable = 1;//使能中断
canConfig.TSSS = 1;//使用次发送缓冲区发送
canConfig.canMode = CAN_MODE_NORMAL;
canConfig.autoReset = 1;//CAN BUSOFF后,自动恢复
canConfig.filterList = &filter;//过滤器
CAN_SetEventCallBack(CAN1, CanEventCallback);
CAN_Initialize(CAN1, &canConfig, GetCommonBaudrate(CAN_BAUDRATE_1M));
GPIO_SetDir((uint32_t)PIN_LED0, 1);
GPIO_SetDir((uint32_t)PIN_LED1, 1);
LED0 = 0; LED1 = 0;
while (1)
{
if(receved)
{
if (!CAN_IsTransmitBusy(CAN1, TRANSMIT_SECONDARY))
{
sMsg.ID++;
CAN_MessageSend(CAN1, &sMsg, TRANSMIT_SECONDARY);
receved = 0;
}
}
}
}
用上位机每5ms发送一个报文,AC7811收到后ID加1再发出来,以下是效果:
CAN_ECHO.zip
(1013.12 KB, 下载次数: 59)
|