CAN 寄存器
HAL库函数
代码
#include "./BSP/CAN/can.h"CAN_HandleTypeDef g_can1_handle;
CAN_TxHeaderTypeDef g_can1_txheader;
CAN_RxHeaderTypeDef g_can1_rxheader;/* STM32F103 TS1 = 8 TS2 = 7 BRP = 3 波特率:36000 / [(9 + 8 + 1) * 4] = 500Kbps */
void can_init(void)
{g_can1_handle.Instance = CAN1;g_can1_handle.Init.Mode = CAN_MODE_LOOPBACK;/* 工作模式设置 环回模式:自发自收 *//* 波特率相关 */g_can1_handle.Init.Prescaler = 3 + 1;/* 分频系数 */g_can1_handle.Init.TimeSeg1 = CAN_BS1_9TQ;/* 时间段1 */g_can1_handle.Init.TimeSeg2 = CAN_BS2_8TQ;/* 时间段2 */g_can1_handle.Init.SyncJumpWidth = CAN_SJW_1TQ;/* 重新同步跳跃宽度 *//* CAN功能设置 */g_can1_handle.Init.AutoBusOff = DISABLE;/* 禁止自动离线管理 */g_can1_handle.Init.AutoRetransmission = DISABLE;/* 禁止自动重发 */g_can1_handle.Init.AutoWakeUp = DISABLE;/* 禁止自动唤醒 */g_can1_handle.Init.ReceiveFifoLocked = DISABLE;/* 禁止接收FIFO锁定 */g_can1_handle.Init.TimeTriggeredMode = DISABLE;/* 禁止时间触发通信模式 */g_can1_handle.Init.TransmitFifoPriority = DISABLE;/* 禁止发送FIFO优先级 */HAL_CAN_Init(&g_can1_handle);CAN_FilterTypeDef can_filterconfig = {0};/* 过滤器接收所有报文 不筛选 */can_filterconfig.FilterMode = CAN_FILTERMODE_IDMASK;can_filterconfig.FilterScale = CAN_FILTERSCALE_32BIT;can_filterconfig.FilterIdHigh = 0;can_filterconfig.FilterIdLow = 0;can_filterconfig.FilterMaskIdHigh = 0;can_filterconfig.FilterMaskIdLow = 0;can_filterconfig.FilterActivation = CAN_FILTER_ENABLE;can_filterconfig.FilterBank = 0;can_filterconfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;can_filterconfig.SlaveStartFilterBank = 14;HAL_CAN_ConfigFilter(&g_can1_handle, &can_filterconfig);HAL_CAN_Start(&g_can1_handle);
}void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan)
{GPIO_InitTypeDef gpio_init_struct = {0};__HAL_RCC_CAN1_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();gpio_init_struct.Pin = GPIO_PIN_11;gpio_init_struct.Mode = GPIO_MODE_AF_INPUT;/* 复用输入 */gpio_init_struct.Pull = GPIO_PULLUP;gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA, &gpio_init_struct);gpio_init_struct.Pin = GPIO_PIN_12;gpio_init_struct.Mode = GPIO_MODE_AF_PP;/* 复用推挽输出 */HAL_GPIO_Init(GPIOA, &gpio_init_struct);
}/* 发送消息数据函数 */
void can_send_message(uint32_t id, uint8_t *buf, uint8_t len)
{uint32_t tx_mail = CAN_TX_MAILBOX0;g_can1_txheader.ExtId = id;g_can1_txheader.DLC = len;g_can1_txheader.IDE = CAN_ID_EXT;g_can1_txheader.RTR = CAN_RTR_DATA;HAL_CAN_AddTxMessage(&g_can1_handle, &g_can1_txheader, buf, &tx_mail);while(HAL_CAN_GetTxMailboxesFreeLevel(&g_can1_handle) != 3);
}/* 接收数据函数 */
uint8_t can_receive_message(uint8_t *buf)
{if(HAL_CAN_GetRxFifoFillLevel(&g_can1_handle, CAN_RX_FIFO0) == 0){return 0;}HAL_CAN_GetRxMessage(&g_can1_handle, CAN_RX_FIFO0, &g_can1_rxheader, buf);return g_can1_rxheader.DLC;
}
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./BSP/CAN/can.h"int main(void)
{uint8_t canbuf[8];uint8_t t = 0;uint8_t cnt = 0;uint8_t key = 0;uint8_t i = 0;uint8_t rec_len = 0;uint8_t rec_buf[8];uint8_t x = 0;HAL_Init(); /* 初始化 HAL 库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72); /* 延时初始化 */usart_init(115200); /* 传口初始化 */led_init(); /* LED初始化 */lcd_init(); /* LCD初始化 */key_init(); /* KEY初始化 */can_init(); /* CAN初始化 */lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);lcd_show_string(30, 70, 200, 16, 16, "CAN TEST", RED);lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);lcd_show_string(30, 110, 200, 16, 16, "LoopBack Mode", RED);lcd_show_string(30, 130, 200, 16, 16, "KEY0:Send", RED); /* 显示提示信息 */lcd_show_string(30, 150, 200, 16, 16, "Count:", RED); /* 显示当前计数值 */lcd_show_string(30, 170, 200, 16, 16, "Send Data:", RED); /* 提示发送的数据 */lcd_show_string(30, 230, 200, 16, 16, "Receive Data:", RED); /* 提示接收到的数据 */while(1){key = key_scan(0);if(key == KEY0_PRES)/* KEY0按下一次,发送一次数据 */{for(i = 0; i < 8; i++){canbuf[i] = i + cnt;/* 填充发送缓冲区 */if (i < 4){lcd_show_xnum(30 + i * 32, 190, canbuf[i], 3, 16, 0X80, BLUE); /* 显示数据 */}else{lcd_show_xnum(30 + (i - 4) * 32, 210, canbuf[i], 3, 16, 0X80, BLUE); /* 显示数据 */}}can_send_message(0x12345678, canbuf, 8);/* ID = 0X12345678, 发送8个字节 */}rec_len = can_receive_message(rec_buf);/* 接收数据查询 */if(rec_len)/* 接收到有数据 */{for(x = 0; x < rec_len; x++){if (x < 4){lcd_show_xnum(30 + x * 32, 250, canbuf[x], 3, 16, 0X80, BLUE); /* 显示数据 */}else{lcd_show_xnum(30 + (x - 4) * 32, 270, canbuf[x], 3, 16, 0X80, BLUE); /* 显示数据 */}}}t++;if(t == 20){t = 0;LED1_TOGGLE();/* 提示系统正在运行 */cnt++;lcd_show_xnum(30 + 48, 150, cnt, 3, 16, 0X80, BLUE); /* 显示数据 */}delay_ms(10);}
}