|
|
#include "SWM221.h"
|
|
|
|
|
|
|
|
|
/* 测试条件:SWM221 <==CAN_RX/TX==> CAN 收发器(如 TJA1050)<==CAN_H/L==> CAN 分析仪
|
|
|
* 错误处理演示:
|
|
|
* 1、将 CAN 收发器与 CAN 分析仪断开,触发 ACK 错误,CAN->TXERR 从 0 递增到 128,然后保持不变
|
|
|
* 2、将 SWM221 与 CAN 收发器断开,触发位错误,CAN->TXERR 继续递增到 255,触发 Bus Off,CAN->CR.RST 自动置 1,CAN 模块处于复位状态
|
|
|
* 3、ISR 中在检测到 Bus Off 后执行 CAN_Open(CAN0) 使 CAN 模块退出复位状态,此时将上面断开的连接恢复,CAN->TXERR 将逐渐递减到0,CAN 模块恢复正常工作
|
|
|
*/
|
|
|
|
|
|
|
|
|
void SerialInit(void);
|
|
|
|
|
|
int main(void)
|
|
|
{
|
|
|
CAN_InitStructure CAN_initStruct;
|
|
|
|
|
|
SystemInit();
|
|
|
|
|
|
SerialInit();
|
|
|
|
|
|
PORT_Init(PORTC, PIN2, PORTC_PIN2_CAN0_RX, 1);
|
|
|
PORT_Init(PORTC, PIN3, PORTC_PIN3_CAN0_TX, 0);
|
|
|
|
|
|
CAN_initStruct.Mode = CAN_MODE_NORMAL;
|
|
|
CAN_initStruct.CAN_bs1 = CAN_BS1_5tq;
|
|
|
CAN_initStruct.CAN_bs2 = CAN_BS2_4tq;
|
|
|
CAN_initStruct.CAN_sjw = CAN_SJW_2tq;
|
|
|
CAN_initStruct.Baudrate = 50000;
|
|
|
CAN_initStruct.RXNotEmptyIEn = 1;
|
|
|
CAN_initStruct.ArbitrLostIEn = 0;
|
|
|
CAN_initStruct.ErrPassiveIEn = 1;
|
|
|
CAN_Init(CAN0, &CAN_initStruct);
|
|
|
|
|
|
CAN_INTEn(CAN0, CAN_IT_ERR_WARN | CAN_IT_RX_OVERFLOW);
|
|
|
|
|
|
CAN_SetFilter32b(CAN0, CAN_FILTER_1, 0x00122122, 0x1FFFFFFE); //接收ID为0x00122122、0x00122123的扩展包
|
|
|
CAN_SetFilter16b(CAN0, CAN_FILTER_2, 0x122, 0x7FE, 0x101, 0x7FF); //接收ID为0x122、123、0x101的标准包
|
|
|
|
|
|
CAN_Open(CAN0);
|
|
|
|
|
|
while(1)
|
|
|
{
|
|
|
uint8_t tx_data[8] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
|
|
|
|
CAN_Transmit(CAN0, CAN_FRAME_STD, 0x133, tx_data, 8, 1);
|
|
|
while(CAN_TXComplete(CAN0) == 0) __NOP();
|
|
|
|
|
|
printf("\r\nCAN->TXERR: %d\r\n", CAN0->TXERR);
|
|
|
|
|
|
for(int i = 0; i < SystemCoreClock / 16; i++) __NOP();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void CAN0_Handler(void)
|
|
|
{
|
|
|
uint32_t can_if = CAN_INTStat(CAN0);
|
|
|
|
|
|
if(can_if & CAN_IF_RXDA_Msk)
|
|
|
{
|
|
|
CAN_RXMessage msg;
|
|
|
|
|
|
CAN_Receive(CAN0, &msg);
|
|
|
|
|
|
if(msg.size > 0)
|
|
|
{
|
|
|
printf("\r\nReceive %s: %08X, ", msg.format == CAN_FRAME_STD ? "STD" : "EXT", msg.id);
|
|
|
for(int i = 0; i < msg.size; i++) printf("%02X, ", msg.data[i]);
|
|
|
printf("\r\n");
|
|
|
}
|
|
|
else if(msg.remote == 1) //远程帧
|
|
|
{
|
|
|
printf("\r\nReceive %s Remote Request\r\n", msg.format == CAN_FRAME_STD ? "STD" : "EXT");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if(can_if & CAN_IF_RXOV_Msk)
|
|
|
{
|
|
|
printf("\r\nCAN RX Overflow\r\n");
|
|
|
|
|
|
CAN_Close(CAN0);
|
|
|
for(int i = 0; i < CyclesPerUs; i++) __NOP();
|
|
|
CAN_Open(CAN0);
|
|
|
}
|
|
|
|
|
|
if(can_if & CAN_IF_ERRWARN_Msk)
|
|
|
{
|
|
|
if(CAN0->SR & CAN_SR_BUSOFF_Msk)
|
|
|
{
|
|
|
printf("\r\nCAN Bus Off\r\n");
|
|
|
printf("\r\nCAN->CR.RST = %d\r\n", CAN0->CR & CAN_CR_RST_Msk ? 1 : 0);
|
|
|
|
|
|
CAN_Open(CAN0); //Bus Off recovery
|
|
|
}
|
|
|
else if(CAN0->SR & CAN_SR_ERRWARN_Msk)
|
|
|
{
|
|
|
printf("\r\nCAN Error Warning\r\n");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if(can_if & CAN_IF_ERRPASS_Msk)
|
|
|
{
|
|
|
printf("\r\nCAN Error Passive\r\n");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void SerialInit(void)
|
|
|
{
|
|
|
UART_InitStructure UART_initStruct;
|
|
|
|
|
|
PORT_Init(PORTA, PIN0, PORTA_PIN0_UART0_RX, 1); //GPIOA.0配置为UART0 RXD
|
|
|
PORT_Init(PORTA, PIN1, PORTA_PIN1_UART0_TX, 0); //GPIOA.1配置为UART0 TXD
|
|
|
|
|
|
UART_initStruct.Baudrate = 57600;
|
|
|
UART_initStruct.DataBits = UART_DATA_8BIT;
|
|
|
UART_initStruct.Parity = UART_PARITY_NONE;
|
|
|
UART_initStruct.StopBits = UART_STOP_1BIT;
|
|
|
UART_initStruct.RXThreshold = 3;
|
|
|
UART_initStruct.RXThresholdIEn = 0;
|
|
|
UART_initStruct.TXThreshold = 3;
|
|
|
UART_initStruct.TXThresholdIEn = 0;
|
|
|
UART_initStruct.TimeoutTime = 10;
|
|
|
UART_initStruct.TimeoutIEn = 0;
|
|
|
UART_Init(UART0, &UART_initStruct);
|
|
|
UART_Open(UART0);
|
|
|
}
|
|
|
|
|
|
/******************************************************************************************************************************************
|
|
|
* 函数名称: fputc()
|
|
|
* 功能说明: printf()使用此函数完成实际的串口打印动作
|
|
|
* 输 入: int ch 要打印的字符
|
|
|
* FILE *f 文件句柄
|
|
|
* 输 出: 无
|
|
|
* 注意事项: 无
|
|
|
******************************************************************************************************************************************/
|
|
|
int fputc(int ch, FILE *f)
|
|
|
{
|
|
|
UART_WriteByte(UART0, ch);
|
|
|
|
|
|
while(UART_IsTXBusy(UART0));
|
|
|
|
|
|
return ch;
|
|
|
}
|