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);
}
}