CAN实验

CAN 寄存器

CAN实验_第1张图片CAN实验_第2张图片CAN实验_第3张图片CAN实验_第4张图片CAN实验_第5张图片CAN实验_第6张图片CAN实验_第7张图片CAN实验_第8张图片CAN实验_第9张图片CAN实验_第10张图片CAN实验_第11张图片CAN实验_第12张图片HAL库函数

CAN实验_第13张图片CAN实验_第14张图片CAN实验_第15张图片CAN实验_第16张图片CAN实验_第17张图片代码

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

CAN实验_第18张图片CAN实验_第19张图片

你可能感兴趣的:(stm32)