N32G430芯片CAN通信初始化

N32G430芯片CAN通信中断接收驱动程序,CAN引脚PA11,PA12,PA8是CAN芯片SIT1044T/3引脚STB控制,其他CAN芯片若不需要可以不用,另外CAN数据处理是WS2812灯带控制,实际应用移植时可以直接屏蔽,加入自己的控制程序,代码前面是头文件部分,后面是应用代码(已实测)。


#ifndef __CAN_H__
#define __CAN_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "main.h"

#define CAN_FILTER_STDID(STDID)       ((STDID&0x7FF)<<5)
#define CAN_STD_ID_H_MASK_DONT_CARE   0x0000
#define CAN_STD_ID_L_MASK_DONT_CARE   0x0000

enum CMD__    //CAN通信命令字
{
    CMD_POSITON = 0X01,                     //查询灯板位置信息
    CMD_ALARM,                             //报警
    CMD_RGB_LED_ALL = 0X80,              //打开所有RGB LED.        
    CMD_SET_RGB_LED,                     //设置单个RGB LED 工作
    CMD_SET_PARM,                         //设置灯板参数 
    CMD_INQUIRE_PARM,                     //查询灯板参数
    CMD_SET_LUMINANCE,                     //设置灯板参亮度    
    CMD_RESET,                           //重启单个灯板灯板ID为0是重启所有灯板,1-255时重启单个灯板

    CMD_TEST = 0XFF,                     //测试
    CMD_REV                                 //:备用
};
struct   CAN1__DATA_
{
    CanRxMessage RxMsg; 
    CanTxMessage TxMsg;
    u8  rxOk;//接收状态标记
    u8  ack;
    u16 rxLen;
    u8  rxDebug;
    u8  txDebug;
    u8  debug;
};

#define CAN_EN(n)    (n?GPIO_Pins_Reset(GPIOA, GPIO_PIN_8):GPIO_Pins_Set(GPIOA, GPIO_PIN_8))   

extern struct   CAN1__DATA_ Can1;  //can数据处理结构体

void can1Init(void);  //can1 初始化
void can1DataDeal(void);  //can 通信数据处理


#ifdef __cplusplus
}
#endif

#endif 

#include "can.h"
struct   CAN1__DATA_ Can1;  //can数据处理结构体
void can1Init(void)  //can1 初始化
{
    RCC_APB1_Peripheral_Clock_Enable(RCC_APB1_PERIPH_CAN);
    RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);
    RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA);

    GPIO_InitType GPIO_InitStructure;
    GPIO_Structure_Initialize(&GPIO_InitStructure);
    GPIO_InitStructure.Pin        = GPIO_PIN_8;  //CAN_CE
    GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_OUT_PP;
    GPIO_InitStructure.GPIO_Current   = GPIO_DS_4MA;
    GPIO_InitStructure.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST;
    GPIO_Peripheral_Initialize(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.Pin       = GPIO_PIN_11;         //CAN RX
    GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF2_CAN;
    GPIO_Peripheral_Initialize(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.Pin        = GPIO_PIN_12;        // CAN TX
    GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF2_CAN;
    GPIO_Peripheral_Initialize(GPIOA, &GPIO_InitStructure);    
    
    CAN_Reset(CAN);
    CAN_InitType        CAN_InitStructure;
    CAN_Structure_Initializes(&CAN_InitStructure);
    /* CAN cell init */
    CAN_InitStructure.TTCM          = DISABLE;
    CAN_InitStructure.ABOM          = ENABLE;
    CAN_InitStructure.AWKUM         = ENABLE;
    CAN_InitStructure.NART          = DISABLE;
    CAN_InitStructure.RFLM          = DISABLE;
    CAN_InitStructure.TXFP          = ENABLE;
    CAN_InitStructure.OperatingMode = CAN_NORMAL_MODE;
    //Baud rate calculation = CAN clock/(BaudRatePrescaler*(TBS1+TBS2+1)) RCC_APB1_PERIPH_CAN = 18Mhz  can波特率=18/1(1+9+2)=0.5Mhz=500Khz 
    CAN_InitStructure.RSJW          = CAN_RSJW_1TQ;
    CAN_InitStructure.TBS1          = CAN_TBS1_9TQ;
    CAN_InitStructure.TBS2          = CAN_TBS2_2TQ;   
    CAN_InitStructure.BaudRatePrescaler = 3;    
    /*Initializes the CAN */
    CAN_Initializes(CAN, &CAN_InitStructure); 
   
    // CAN_NVIC_Config();
    NVIC_InitType NVIC_InitStructure;                 //CAN中断设置。
    NVIC_Priority_Group_Set(NVIC_PER1_SUB3_PRIORITYGROUP);
    NVIC_InitStructure.NVIC_IRQChannel=CAN_RX0_IRQn; //开这个中断对应FIFO1
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Initializes(&NVIC_InitStructure);
    
    CAN_FilterInitType CAN_FilterInitStructure;  
    CAN_FilterInitStructure.Filter_Num            = 2;
    CAN_FilterInitStructure.Filter_Mode           = CAN_FILTER_IDLISTMODE;
    CAN_FilterInitStructure.Filter_Scale          = CAN_FILTER_16BITSCALE;
    CAN_FilterInitStructure.Filter_HighId         = CAN_FILTER_STDID(Parm.id);  
    CAN_FilterInitStructure.Filter_LowId          = CAN_FILTER_STDID(Parm.id);  
    CAN_FilterInitStructure.FilterMask_HighId     = CAN_STD_ID_H_MASK_DONT_CARE;  
    CAN_FilterInitStructure.FilterMask_LowId      = CAN_STD_ID_L_MASK_DONT_CARE;  
    CAN_FilterInitStructure.Filter_FIFOAssignment = CAN_FIFO0;  // CAN_FIFO0不行,原因未知。
    CAN_FilterInitStructure.Filter_Act            = ENABLE;  
     CAN_Filter_Initializes(&CAN_FilterInitStructure);
    /* IT Configuration for CAN */  
    CAN_Config_Interrupt_Enable(CAN, CAN_INT_FMP0);
    
    CAN_EN(true);
    // LED_GPIO_init();   //C13 LED工作灯控制。
    Can1.rxDebug = true;
    // Can1.rxDebug = false;

}
void CAN_RX0_IRQHandler(void)

    CanRxMessage RxMsg;   //CAN 接收缓存.
    CAN_Message_Receive(CAN,CAN_FIFO0, &RxMsg);  
    // CAN_ReleaseFIFO(CAN,CAN_FIFO1);
    Can1.RxMsg.StdId = RxMsg.StdId;
    // if ((RxMsg.StdId ==Parm.id)||(RxMsg.StdId ==0x0000))
    {    
        Can1.RxMsg.StdId = RxMsg.StdId;
        Can1.RxMsg.ExtId = RxMsg.ExtId;
        Can1.RxMsg.IDE = RxMsg.IDE;
        Can1.RxMsg.RTR = RxMsg.RTR;
        Can1.RxMsg.DLC = RxMsg.DLC;
        Can1.RxMsg.Data[0] = RxMsg.Data[0];
        Can1.RxMsg.Data[1] = RxMsg.Data[1];
        Can1.RxMsg.Data[2] = RxMsg.Data[2];
        Can1.RxMsg.Data[3] = RxMsg.Data[3];
        Can1.RxMsg.Data[4] = RxMsg.Data[4];
        Can1.RxMsg.Data[5] = RxMsg.Data[5];
        Can1.RxMsg.Data[6] = RxMsg.Data[6];
        Can1.RxMsg.Data[7] = RxMsg.Data[7];
        Can1.RxMsg.FMI = RxMsg.FMI;
        Can1.rxOk = true;        
    }    
}
void can1DataDeal(void)  //can 通信数据处理
{
    if (Can1.rxOk == true)
    {
        Can1.rxOk = false;
        if(Can1.rxDebug)printf("CAN RX:ID:%04X,data:%02x %02x %02x %02x %02x %02x %02x %02x.\r\n",
        Can1.RxMsg.StdId,Can1.RxMsg.Data[0],Can1.RxMsg.Data[1],Can1.RxMsg.Data[2],Can1.RxMsg.Data[3],Can1.RxMsg.Data[4],Can1.RxMsg.Data[5],Can1.RxMsg.Data[6],Can1.RxMsg.Data[7]);
        switch (Can1.RxMsg.Data[0]) //根据命令处理CAN数据
        {
            case CMD_POSITON:  //位置查询
            {
                Can1.TxMsg.StdId = Parm.id;  //
                Can1.TxMsg.ExtId   = 0; /* Extended ID(LSBs) */
                Can1.TxMsg.IDE     = CAN_STANDARD_ID;   /* 标准格式和扩展格式*/
                Can1.TxMsg.RTR     = CAN_RTRQ_DATA;   /* 远程帧或数据帧 */
                Can1.TxMsg.DLC     = 8;   /* 0 to 8 */
                for (u8 i = 0; i < 8; i++)
                {
                    Can1.TxMsg.Data[i] = Position.bitBuf[i]; //位置信息bit
                }  
                Can1.TxMsg.Data[0] = CMD_POSITON;   //赋值命令字                  
                CAN_Transmit_Message_initializes(CAN, &Can1.TxMsg); //发送CAN数据.
                break;
            }
            case CMD_ALARM:  //报警
            {
                break;
            }
            case CMD_RGB_LED_ALL:  //打开所有RGB LED.    
            {
                u32 colour = 0;        //灯珠颜色
                Can1.TxMsg.StdId = Parm.id;  //
                Can1.TxMsg.ExtId   = 0; /* Extended ID(LSBs) */
                Can1.TxMsg.IDE     = CAN_STANDARD_ID;   /* 标准格式和扩展格式*/
                Can1.TxMsg.RTR     = CAN_RTRQ_DATA;   /* 远程帧或数据帧 */
                Can1.TxMsg.DLC     = 8;   /* 0 to 8 */
                for (u8 i = 0; i < 8; i++)
                {
                    Can1.TxMsg.Data[i] = Position.bitBuf[i]; //位置信息bit
                } 
                Can1.TxMsg.Data[0] = CMD_SET_RGB_LED;   //赋值命令字        
                CAN_Transmit_Message_initializes(CAN, &Can1.TxMsg); //发送CAN数据.
                colour |= Can1.RxMsg.Data[1]<<16;
                colour |= Can1.RxMsg.Data[2]<<8;
                colour |= Can1.RxMsg.Data[3];
                // colour = 0XFF00; //This code just for test.
                for (u8 i = 0; i < RGB_LED_NUM; i++)
                {
                    setLedCorlor(i,colour,0xff,0xffff);
                }        
                break;
            }    
            case CMD_SET_RGB_LED:  //设置单个RGB LED 工作 
            {
                u8 serialNum = 0;      //灯珠序号
                u32 colour = 0;        //灯珠颜色
                u8  times = 0;         //灯珠闪烁次数0:灭  1-244闪烁次数,255:持续闪烁
                u16 period = 0;       //闪烁频率             
                serialNum = Can1.RxMsg.Data[1];   //灯珠序号
                colour |= Can1.RxMsg.Data[2]<<16; //灯珠颜色
                colour |= Can1.RxMsg.Data[3]<<8;
                colour |= Can1.RxMsg.Data[4];
                times = Can1.RxMsg.Data[5];       //灯珠闪烁次数0:灭  1-244闪烁次数,255:持续闪烁         
                period |= Can1.RxMsg.Data[6]<<8;  //闪烁频率
                period |= Can1.RxMsg.Data[7];           
                setLedCorlor(serialNum,colour,times,period);
                break;
            }
            case CMD_SET_PARM:  //设置灯板参数,灯板ID 灯珠数目
            {
                u32 id = 0;                  //灯板ID。           
                u8 num = 0;                  //灯珠数目
                id = Can1.RxMsg.Data[1];     //灯板ID
                num = Can1.RxMsg.Data[2];    //灯珠数目
                u8 * parmP = (u8 *)(&Parm);  //获取参数结构体地址。
                w25qxxRead(parmP,PARAMETER_ADDR,sizeof(Parm)); //read back the flash parameter.
                Parm.id = id;
                Parm.rgbLedNum = num;    
                w25qxxWrite(parmP,PARAMETER_ADDR,sizeof(Parm));  //Write system parameters to FLASH.            
                break;
            }
            case CMD_SET_LUMINANCE:  //设置灯板参亮度
            {
                RgbLed.luminance = Can1.RxMsg.Data[1];     //灯板亮度
                RgbLed.refresh = true;     //刷新显示。
                break;
            }
            case CMD_RESET:  //
            {
                printf("CAN通信重启:id=%d.\r\n",Can1.RxMsg.StdId); //                
                delay_ms(1000);      //
                NVIC_SystemReset();            
                break;
            }
            case CMD_REV:  //
            {
                break;
            }
            default:break;
        }
    }    
}

  • 29
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kevinpan2011

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值