自己的钱包,然后哭了199 2023-07-22 01:11 采纳率: 0%
浏览 69
已结题

CAN通信中如何按要求传输数据

在 STM32F1 上配置 CAN 通信,实现以下功能:

  1. 将 CAN 配置为回环模式,波率为 500Kbps,并按 ID 优先级发送消息。
  2. 当口发送数据以"C0x1234"格式,发送扩展帧为 0x1234 的报文。数据只能使
    用 FIFO0 接收,并且接收数据 ID 必须为 0x5301。发送的数据由上位机输入。
  3. 当串口发送数据以"K0x1234"格式时,发送扩展帧为 0x1234 的报文。数据只能
    使用 FIFO1 接收,并且接收的数据 ID 必须为 0x5201。发送的数据由上机输入。
  4. 当串口发送数据以"F0x1234"格式时,发送扩展帧为 0x1234 的报文。数据可
    以使用 FIFO0 或 FIFO1 接,并且接收的数据 ID 必须为 0x5300。发送的数据由上
    位机输入。
  5. 请使用标准库。
    1234的部分可以为任意数字。
    要求:
  • 使用中断方式接收 FIFO0 和 FIFO1 的数据。
  • 接收成功后,在中断处理函数中发送"FIFOx 接收成功"消息,并将收到的数据
    打印出来。
    请编写相关代码实现以上功能。
  • 写回答

13条回答 默认 最新

  • 「已注销」 2023-07-22 08:46
    关注
    
    #include "stm32f10x.h"  
    #include "stm32f10x_can.h"  
    #include "stm32f10x_rcc.h"  
    #include "stm32f10x_gpio.h"  
    #include "stm32f10x_spi.h"  
    #include "stm32f10x_usart.h"  
    #include "stm32f10x_tim.h"  
    #include "stdio.h"  
      
    #define CANSpeed 500000 // CAN波特率  
      
    // CAN配置结构体  
    typedef struct {  
        uint8_t ID;  
        uint8_t FIFO;  
        uint8_t Data[8];  
    }CanMsg, *pCanMsg;  
      
    CanMsg RxMsg, TxMsg;  
      
    // CAN中断处理函数  
    void CAN_IRQ(void)  
    {  
        if (CAN_GetITStatus(CAN_IT_RXOK)) { // 接收OK中断  
            uint32_t RxMail;  
            CAN_GetRxMessage(CAN1, 0, &RxMsg.ID, &RxMsg.FIFO, RxMsg.Data);  
            switch (RxMsg.ID) {  
                case 0x5301: // FIFO0接收成功  
                    printf("FIFO0 receive success:\n");  
                    printf("Data: ");  
                    for (int i = 0; i < 8; i++) {  
                        printf("%02X ", RxMsg.Data[i]);  
                    }  
                    printf("\n");  
                    break;  
                case 0x5201: // FIFO1接收成功  
                    printf("FIFO1 receive success:\n");  
                    printf("Data: ");  
                    for (int i = 0; i < 8; i++) {  
                        printf("%02X ", RxMsg.Data[i]);  
                    }  
                    printf("\n");  
                    break;  
                case 0x5300: // FIFO0或FIFO1接收成功  
                    printf("FIFO0 or FIFO1 receive success:\n");  
                    printf("Data: ");  
                    for (int i = 0; i < 8; i++) {  
                        printf("%02X ", RxMsg.Data[i]);  
                    }  
                    printf("\n");  
                    break;  
            }  
        }  
    }  
      
    int main(void)  
    {  
        // 时钟配置  
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);  
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);  
      
        // GPIO配置CAN收发器使能引脚  
        GPIO_InitTypeDef GPIO_InitStructure;  
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  
        GPIO_Init(GPIOA, &GPIO_InitStructure);  
      
        // CAN配置  
        CAN_InitTypeDef CAN_InitStructure;  
        CAN_InitStructure.CAN_TTCM = DISABLE;  
        CAN_InitStructure.CAN_ABOM = DISABLE;  
        CAN_InitStructure.CAN_AWUM = DISABLE;  
        CAN_InitStructure.CAN_NART = DISABLE;  
        CAN_InitStructure.CAN_RFLM = DISABLE;  
        CAN_InitStructure.CAN_TDLAR = DISable;  
        CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;  
        CAN_InitStructure.CAN_SJW = CAN_SJW_1sample;  
        CAN_InitStructure.CAN_BS1 = CAN_BS1_4sample;  
        CAN_InitStructure.CAN_BS2 = CAN_BS2_3sample;  
        CAN_InitStructure.CAN_Prescaler = SystemCoreClock / (2 * (16 + CANSpeed / 50)); // 根据系统时钟和要求波特率计算出Prescaler
    
    评论

报告相同问题?

问题事件

  • 系统已结题 7月30日
  • 修改了问题 7月22日
  • 创建了问题 7月22日