打印
[应用相关]

AT32F413 USB 和CAN同时使用案例

[复制链接]
2384|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
muyichuan2012|  楼主 | 2021-1-4 19:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
USB, CAN, pi, IO, gp


  Demo 实现功能:
  Demo 主要实现USB 和 CAN1 同时使用,USB 实现虚拟串口功能,CAN1使用Loopback模式自发自收.
  USB 和 CAN1使用了不同的中断号,具体参考USB_Interrupts_Config()里面的配置。
  如果要使用CAN2,按照CAN2的正常配置即可。


  Note:
  一、 USB 和 CAN1 同时使用主要问题
  1. 使用GPIO PA11 和 PA12 有冲突
     解决方法:CAN1 的 TX 和 RX 可以Remap 到另外一组GPIO上PB8,PB9
  2. 中断号有冲突。
     解决方法:AT32F13 给USB 分配了另外一组中断号,USB使用新的中断号,CAN1继续使用之前的中断号
         
  二、 USB 和 CAN2 同时使用不存在问题,按照正常使用即可

  三、 对于USB和CAN同时使用时SRAM的分配不需要软件配置





/**
  ******************************************************************************
  * @file    USB_Device/VirtualComPort_loopback/src/main.c
  * @author  Artery Technology
  * @version V1.1.2
  * @date    2019-01-04
  * @brief   VirtualComPort loopback Demo main file
  ******************************************************************************
  
#include "usb_lib.h"
#include "hw_config.h"
#include "usb_pwr.h"
#include "at32_board.h"

uint8_t usb_recvBuffer[256];
uint8_t usb_sendBuffer[256];
uint16_t recvLen, sendLen;

#define CANx     CAN1

/*Remap CAN TX & RX*/
#define CANx_TX    GPIO_Pins_9
#define CANx_RX    GPIO_Pins_8
#define CANx_TX_GPIO_CLK_ENABLE()       RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB, ENABLE);
#define CANx_RX_GPIO_CLK_ENABLE()       RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB, ENABLE);
#define CANx_TX_GPIO_PORT               GPIOB
#define CANx_RX_GPIO_PORT               GPIOB
#define CANx_CLK_ENABLE()                      RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_CAN1, ENABLE);
CanRxMsg RxMessage = {0};
void CAN1_Demo(void);
static void CAN_transmit_data(void);
void CAN_Rx_Data(void);


void CAN1_Demo(void)
{
  CAN_InitType                CAN_InitStructure;
  CAN_FilterInitType          CAN_FilterInitStructure = {0};
  GPIO_InitType GPIO_InitStructure;
  GPIO_StructInit(&GPIO_InitStructure);
        CAN_StructInit(&CAN_InitStructure);


  CANx_TX_GPIO_CLK_ENABLE();
        CANx_RX_GPIO_CLK_ENABLE();

  /*Remap*/
  GPIO_PinsRemapConfig(GPIO_Remap1_CAN1,ENABLE);

        GPIO_InitStructure.GPIO_Pins = CANx_TX;
        GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        
        GPIO_Init(CANx_TX_GPIO_PORT, &GPIO_InitStructure);        

        GPIO_InitStructure.GPIO_Pins = CANx_RX;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_PU;        
        GPIO_Init(CANx_RX_GPIO_PORT, &GPIO_InitStructure);
        CANx_CLK_ENABLE();

  CAN_InitStructure.CAN_TTC = DISABLE;                        
        CAN_InitStructure.CAN_ABO = ENABLE;                        
        CAN_InitStructure.CAN_AWU = ENABLE;                        
        CAN_InitStructure.CAN_NART = DISABLE;                        
        CAN_InitStructure.CAN_RFL = DISABLE;                        
        CAN_InitStructure.CAN_TFP = DISABLE;                        
        CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;
        CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;                                
        CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq;
        CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;        
        CAN_InitStructure.CAN_Prescaler = 2;
        CAN_Init(CANx, &CAN_InitStructure);    ///<SYSCLK=192M,  APB1CLK=24M, CAN Baudrate=(192/8)*1000K)/((1+1)*(3+7+2)) = 1000K

   CAN_FilterInitStructure.CAN_FilterNumber=0;        
        CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;         
        CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;         
        CAN_FilterInitStructure.CAN_FilterIdHigh=0x0;        
        CAN_FilterInitStructure.CAN_FilterIdLow=0x0;
        CAN_FilterInitStructure.CAN_FilterMskIdHigh=0x0;
        CAN_FilterInitStructure.CAN_FilterMskIdLow=0x0;
        CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;
        CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
        CAN_FilterInit(CANx, &CAN_FilterInitStructure);
        
  CAN_INTConfig(CANx,CAN_INT_RFP0,ENABLE);

}


/**
*        @brief  CAN transmit data.SID=0x400,Standard identifier,Data frame,data D0~D7 all 0xA5
*        @param  None
*        @retval None
*/
static void CAN_transmit_data(void)
{
    uint8_t TransmitMailbox;
    uint32_t i = 0;
    CanTxMsg TxMessage;
    TxMessage.Data[0] = 0xA5;
    TxMessage.Data[1] = 0xA5;
    TxMessage.Data[2] = 0xA5;
    TxMessage.Data[3] = 0xA5;
    TxMessage.Data[4] = 0xA5;
    TxMessage.Data[5] = 0xA5;
    TxMessage.Data[6] = 0xA5;
    TxMessage.Data[7] = 0xA5;

        TxMessage.StdId = 0x400;                        
        TxMessage.ExtId = 0;                        
        TxMessage.IDT = CAN_Id_Standard;
        TxMessage.RTR = CAN_RTR_Data;               
        TxMessage.DLC = 8;
    TransmitMailbox = CAN_Transmit(CANx, &TxMessage);
    while((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK) && (i != 0xFFFF))
    {
        i++;
    }
}


void CAN_Rx_Data(void)
{
    if (CAN_GetINTStatus (CANx,CAN_INT_RFOV0) == SET )
    {
        CAN_ClearINTPendingBit (CAN1, CAN_INT_RFOV0);
    }
    if (CAN_GetINTStatus (CANx,CAN_INT_RFFU0) == SET )
    {
        CAN_ClearINTPendingBit (CAN1, CAN_INT_RFFU0);
    }
    if (CAN_GetINTStatus (CANx,CAN_INT_RFP0) == SET )
    {
        CAN_Receive(CANx, CAN_FIFO0, &RxMessage);
        if ( RxMessage.StdId == 0X400 )
            AT32_LEDn_Toggle(LED2);
    }
}

/** @addtogroup AT32F413_StdPeriph_Examples
  * @{
  */

/** @addtogroup USB_VirtualComPort_loopback
  * @{
  */
int main(void)
{               
    /*AT START F4xx board initialize
    * Include LED, Button
    */
    AT32_Board_Init();

    /*USB GPIO configure*/
    AT32_USB_GPIO_init();


    /*Remap USB Interrupt*/
    RCC_USBINTRemap(ENABLE);

    /*初始化 USB Interrut
    USB 使用新的低优先级中断号:USB_LP_IRQn = 74
                高优先级中断号:USB_HP_IRQn = 73

    CAN1 中断号:
         TX: USB_HP_CAN1_TX_IRQn =  19
         RX:USB_LP_CAN1_RX0_IRQn =  20

     Note:中断初始化之后,中断处理函数需要一并修改。
    */
           USB_Interrupts_Config();   

    /*Set USB Clock, USB Clock must 48MHz*/
    Set_USBClock();

    /*Enable USB 768 Byte Mode*/
    Set_USB768ByteMode();

    /*Init CAN1*/
    CAN1_Demo();

    /* USB protocol and register initialize*/
           USB_Init();

           while(1)
          {
        recvLen = CDC_Receive_DATA(usb_recvBuffer, 256);
        if ( recvLen > 0 )
        {  /*recvive data from USB*/

            /*Send data to PC Host*/
            sendLen = CDC_Send_DATA(usb_recvBuffer, recvLen);
            AT32_LEDn_Toggle(LED3);

        }else
        {
            /*no data recv*/
            Delay_ms(500);
            AT32_LEDn_Toggle(LED4);
            CAN_transmit_data();
        }

          }                                                                                                                           
}

AT32F413_USB_CAN.zip

455.19 KB

使用特权

评论回复
评论
qinweixing 2022-4-3 17:30 回复TA
高手.................... 
沙发
pattywu| | 2021-1-4 19:47 | 只看该作者
本帖最后由 pattywu 于 2021-1-4 19:49 编辑

不错,先顶一下。看了一下,库版本旧了一点,是V1.0.5的,最新好像是V1.2.8。

使用特权

评论回复
板凳
hejiang1777| | 2021-1-15 10:03 | 只看该作者
学习了,不错

使用特权

评论回复
地板
单片小菜| | 2021-1-15 15:03 | 只看该作者
感谢楼主分享,不错,不错的。

使用特权

评论回复
5
123ycli| | 2021-1-17 19:49 | 只看该作者
Demo 主要实现USB 和 CAN1 同时使用,USB 实现虚拟串口功能,CAN1使用Loopback模式自发自收.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

198

主题

1910

帖子

29

粉丝