[活动专区] 【AutoChips MCU评测报告】+CAN驱动实现

[复制链接]
2373|11
 楼主| caizhiwei 发表于 2020-6-3 17:15 | 显示全部楼层 |阅读模式

  1. #include "bsp_can.h"

  2. stc_can_rxframe_t       stcRxFrame;
  3. stc_can_txframe_t       stcTxFrame;
  4. uint8_t                 u8RxFlag = FALSE;

  5. static void Can_Gpio_Init(void)
  6. {
  7.     stc_gpio_cfg_t stcGpioCfg;

  8.     Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);

  9.     ///< 端口方向配置->输入
  10.     stcGpioCfg.enDir = GpioDirIn;
  11.     ///< 端口驱动能力配置->高驱动能力
  12.     stcGpioCfg.enDrv = GpioDrvL;
  13.     ///< 端口上下拉配置->无
  14.     stcGpioCfg.enPu = GpioPuDisable;
  15.     stcGpioCfg.enPd = GpioPdDisable;
  16.     ///< 端口开漏输出配置->开漏输出关闭
  17.     stcGpioCfg.enOD = GpioOdDisable;
  18.     ///< 端口输入/输出值寄存器总线控制模式配置->AHB
  19.     stcGpioCfg.enCtrlMode = GpioAHB;

  20.     Gpio_Init(EVB_CAN_RX_PORT, EVB_CAN_RX_PIN, &stcGpioCfg);
  21.     stcGpioCfg.enDir = GpioDirOut;
  22.     Gpio_Init(EVB_CAN_TX_PORT, EVB_CAN_TX_PIN, &stcGpioCfg);
  23.     Gpio_Init(EVB_CAN_STB_PORT, EVB_CAN_STB_PIN, &stcGpioCfg);

  24.     ///<CAN RX\TX复用功能配置
  25.     Gpio_SetAfMode(EVB_CAN_RX_PORT, EVB_CAN_RX_PIN, GpioAf1);
  26.     Gpio_SetAfMode(EVB_CAN_TX_PORT, EVB_CAN_TX_PIN, GpioAf1);

  27.     ///<STB 低-PHY有效
  28.     Gpio_ClrIO(EVB_CAN_STB_PORT, EVB_CAN_STB_PIN);
  29. }


  30. void BSP_Can_Init(void)
  31. {
  32.     stc_can_init_config_t   stcCanInitCfg;
  33.     stc_can_filter_t        stcFilter;

  34.         Can_Gpio_Init();
  35.        
  36.     Sysctrl_SetPeripheralGate(SysctrlPeripheralCan, TRUE);

  37.     //<<CAN 波特率配置
  38.         // 手册page884.exp: bt = (PRESC+1)((SEG_1+2) + (SEG_2+1))*(1/8M) = 1us (1000k)

  39. #ifdef CAN_CONFIG_48MHZ_500K         
  40.        
  41.         stcCanInitCfg.stcCanBt.PRESC = 6-1;
  42.         stcCanInitCfg.stcCanBt.SEG_1 = 9-2;
  43.         stcCanInitCfg.stcCanBt.SEG_2 = 7-1;       
  44.         stcCanInitCfg.stcCanBt.SJW   = 3-1;       
  45.        
  46. //        stcCanInitCfg.stcCanBt.PRESC = 8-1;
  47. //  stcCanInitCfg.stcCanBt.SEG_1 = 7-2;
  48. //  stcCanInitCfg.stcCanBt.SEG_2 = 5-1;
  49. //  stcCanInitCfg.stcCanBt.SJW   = 5-1;
  50.        
  51. #endif

  52.     stcCanInitCfg.stcWarningLimit.CanErrorWarningLimitVal = 10;
  53.     stcCanInitCfg.stcWarningLimit.CanWarningLimitVal = 16-1;

  54.     stcCanInitCfg.enCanRxBufAll  = CanRxNormal;
  55.     stcCanInitCfg.enCanRxBufMode = CanRxBufNotStored;
  56.     stcCanInitCfg.enCanSTBMode   = CanSTBFifoMode;

  57.     CAN_Init(&stcCanInitCfg);

  58.     //<<CAN 滤波器配置
  59.     stcFilter.enAcfFormat = CanAllFrames;
  60.     stcFilter.enFilterSel = CanFilterSel1;
  61.     stcFilter.u32CODE     = 0x00000236;
  62.     stcFilter.u32MASK     = 0x1FFFFFFF; /*0x1FFFFFFF is all received*/
  63.     CAN_FilterConfig(&stcFilter, TRUE);

  64.     //<<Can Irq Enable
  65.     CAN_IrqCmd(CanRxIrqEn, TRUE); /* 接收中断使能 */
  66.         CAN_IrqCmd(CanBusErrorIrqEn, TRUE); /*总线错误中断使能*/
  67.                
  68.     EnableNvic(CAN_IRQn, IrqLevel0, TRUE);
  69. }



  70. /********************************************************************************************************
  71. **函数信息 :void CAN_send_Frame()
  72. **功能描述 :CAN发送一帧报文
  73. **输入参数 :stcTxFrame
  74. **输出参数 :None
  75. **    备注  目前只考虑标准帧
  76. ********************************************************************************************************/
  77. void CAN_send_Frame(stc_can_txframe_t *TxFrame, uint32_t Can_ID,uint8_t frame_len)
  78. {
  79.         TxFrame->StdID = Can_ID;
  80.         TxFrame->Control_f.DLC = frame_len;
  81.         TxFrame->Control_f.IDE = 0; /*标准帧 or 扩展帧*/
  82.         TxFrame->Control_f.RTR = 0; /*数据帧 or 远程帧*/
  83.         TxFrame->enBufferSel = (en_can_buffer_sel_t)0U; /*使用主缓冲器*/
  84.         CAN_SetFrame(TxFrame); /*数据塞进fifo缓冲器*/       
  85.         CAN_TransmitCmd(CanPTBTxCmd);
  86. }
  87.        

  88. void Can_IRQHandler(void)
  89. {
  90.     if(TRUE == CAN_Irq**Get(CanRxIrq**))
  91.     {
  92.         CAN_Irq**Clr(CanRxIrq**);
  93.         CAN_Receive(&stcRxFrame);
  94.         u8RxFlag = TRUE;
  95.     }
  96.          if(TRUE == CAN_Irq**Get(CanBusErrorIrq**))  /*当总线短路时,进入此中断*/
  97.          {          
  98.                   CAN_Irq**Clr(CanBusErrorIrq**);         
  99.                 // M0P_CAN->CFG_STAT = 0x00; /* 清除由硬件置位的Reset 标志位,必须在中断外部执行*/                 
  100.          }
  101. }


头文件:
  1. #ifndef __BSP_CAN_H__
  2. #define __BSP_CAN_H__

  3. #include "can.h"
  4. #include "gpio.h"


  5. #define CAN_CONFIG_48MHZ_500K

  6. void BSP_Can_Init(void);

  7. void CAN_send_Frame(stc_can_txframe_t *TxFrame, uint32_t Can_ID,uint8_t frame_len);

  8. extern uint8_t      u8RxFlag ;
  9. extern stc_can_rxframe_t       stcRxFrame;
  10. extern stc_can_txframe_t       stcTxFrame;

  11. #endif


xddfandy 发表于 2020-6-3 21:33 | 显示全部楼层
 楼主| caizhiwei 发表于 2020-6-4 09:42 | 显示全部楼层

过江啦,大家一起学习,这个驱动可以直接用的
JasonLee27 发表于 2020-6-8 14:46 | 显示全部楼层
看上去像是从st移植过来的驱动,不需要修改一下底层实现吗?
wangchong1 发表于 2020-7-4 11:54 | 显示全部楼层
你好,大神,我在使用华大072CAN的时候,用例程收发数据都正常,就是我把CAN H和CAN L两条线断开后,再连上,就无法收发数据了,必须把单片机复位一下,又可以收发了,不知道什么原因?能指点一下吗?我以前没用过CAN
 楼主| caizhiwei 发表于 2020-7-4 19:36 | 显示全部楼层
wangchong1 发表于 2020-7-4 11:54
你好,大神,我在使用华大072CAN的时候,用例程收发数据都正常,就是我把CAN H和CAN L两条线断开后,再连上 ...

问得好,总线错误了呢,参考我之前的帖子
 楼主| caizhiwei 发表于 2020-7-4 19:38 | 显示全部楼层
caizhiwei 发表于 2020-7-4 19:36
问得好,总线错误了呢,参考我之前的帖子

https://bbs.21ic.com/icview-2970238-1-1.html
wangchong1 发表于 2020-7-7 11:12 | 显示全部楼层
caizhiwei 发表于 2020-7-4 19:38
https://bbs.21ic.com/icview-2970238-1-1.html

大神,我看你说的清这个标志位必须放到中断外部,我感觉没什么区别吧,我是在中断里面写的,试了一下暂时也没什么问题,你能不能帮忙看看,我这样写有什么问题吗?多谢了?
这个是你的:// M0P_CAN->CFG_STAT = 0x00; /* 清除由硬件置位的Reset 标志位,必须在中断外部执行*/
下面是我写的,还请大神指点一下
void Can_IRQHandler(void)
{
    if(TRUE == CAN_Irq**Get(CanRxIrq**))
    {
        CAN_Irq**Clr(CanRxIrq**);
        CAN_IrqCmd(CanRxIrqEn, FALSE);

        CAN_Receive(&stcRxFrame);

        u8RxFlag = TRUE;
    }
               
                 if(TRUE == CAN_Irq**Get(CanBusErrorIrq**))
                 {
               
                         
                   CAN_Irq**Clr(CanBusErrorIrq**);
              
                         M0P_CAN->CFG_STAT = 0x01;//总线关闭状态
                         M0P_CAN->CFG_STAT = 0x00;//清除由硬件置位的Reset标志位
                 }

}

评论

@caizhiwei :好的,多谢了!  发表于 2020-7-7 13:26
看了,这样也没问题,主要目的是让总线能恢复。  发表于 2020-7-7 12:32
lvhaoguang 发表于 2021-3-12 10:31 | 显示全部楼层
cr315 发表于 2021-3-12 11:03 | 显示全部楼层
楼主厉害了,赞
您需要登录后才可以回帖 登录 | 注册

本版积分规则

100

主题

856

帖子

16

粉丝
快速回复 在线客服 返回列表 返回顶部