打印
[STM32F1]

STM32的CAN通讯源程序

[复制链接]
5562|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
NYT369|  楼主 | 2016-5-29 17:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本程序调试完毕,并且制作了PCB电路板,程序运行正常。
       以下是有关CAN通讯部分的源程序设置:

#include "can.h"


extern CanTxMsg TxMessage;
void CAN_NVIC_Config(void)
{
           NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                   //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
                  
          NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; //CAN1 RX0中断
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);
}

void CAN_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
          
          /*外设时钟设置*/

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);//使能PORTA时钟       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟       

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽
    GPIO_Init(GPIOA, &GPIO_InitStructure);                //初始化IO

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化IO
}



void CAN_Mode_Config(void)
{
           CAN_InitTypeDef        CAN_InitStructure;
                 /************************CAN1通讯参数设置**********************************/
        /*CAN寄存器初始化*/
        CAN_DeInit(CAN1);
        CAN_StructInit(&CAN_InitStructure);
       
        /*CAN单元初始化*/
          CAN_InitStructure.CAN_TTCM=DISABLE;                           //MCR-TTCM   关闭时间触发通讯模式
    CAN_InitStructure.CAN_ABOM=ENABLE;                           //MCR-ABOM  自动离线管理
    CAN_InitStructure.CAN_AWUM=ENABLE;                           //MCR-AWUM  使用自动唤醒模式
    CAN_InitStructure.CAN_NART=DISABLE;                           //MCR-NART  非自动报文重传模式,DISABLE表示报文重传?
    CAN_InitStructure.CAN_RFLM=DISABLE;                           //MCR-RFLM  接收FIFO锁定模式,  DISABLE-溢出时新的报文覆盖原来的报文
    CAN_InitStructure.CAN_TXFP=DISABLE;                           //MCR-TXFP  使能FIFO发送优先级 DISABLE-发送时,优先级取决于报文的标识符
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;  //正常工作模式
    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;                   //BTR-SJW 同步跳跃1个时间单元
    CAN_InitStructure.CAN_BS1=CAN_BS1_6tq;                   //BTR-TS1 时间段1 占用6个时间单元
    CAN_InitStructure.CAN_BS2=CAN_BS2_1tq;                   //BTR-TS1 时间段2 占用1个时间单元
    CAN_InitStructure.CAN_Prescaler =225;                   ////BTR-BRP   波特率分频器,定义了时间单元的长度 36M/(1+6+1)/225=20 Kbps
          CAN_Init(CAN1, &CAN_InitStructure);
}

void CAN_Filter_Config(void)
{
   CAN_FilterInitTypeDef  CAN_FilterInitStructure;

        /*CAN滤波器初始化*/
        CAN_FilterInitStructure.CAN_FilterNumber=0;                                                                                      //过滤器组0
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;                                      //标识符屏蔽位模式
        CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;                                    //过滤器位宽是:单个32位
  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;                                        //需要过滤的ID高位
  CAN_FilterInitStructure.CAN_FilterIdLow=0x0000; //需要过滤的ID低位,标准帧,数据帧
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0x0000;                                                          //需要过滤的ID高位不必须匹配
  CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0x0000;                                                          //需要过滤的ID低位,必须匹配是:标准帧,数据帧
        CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0 ;                                                  //过滤器和FIFO0配套使用
        CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                                                          //使能过滤器
        CAN_FilterInit(&CAN_FilterInitStructure);
       
        CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);                                                    //FIFO0的消息挂号中断使能
}




void Can_Send_Msg(u16 Sff_Id,u8* msg,u8 len)
{       

  u16 send_i=0;


  TxMessage.StdId=Sff_Id;                                         // 标准标识符为Sff_Id,标准标识符是11位的,设置范围在0~0X7FF
  TxMessage.ExtId=0x12;                                     // 设置扩展标示符,后面使用标准标识符发送,这里只是设置,实际没有用到?
  TxMessage.IDE=CAN_ID_STD;                           // 使用标准标识符
  TxMessage.RTR=CAN_RTR_DATA;                   // 消息类型为数据帧
  TxMessage.DLC=len;                                                   // 发送两帧信息
  for(send_i=0;send_i<len;send_i++)
     {TxMessage.Data[send_i]=msg[send_i];}                           // 第一帧信息         
  CAN_Transmit(CAN1, &TxMessage);
        GPIO_WriteBit(GPIOA,GPIO_Pin_6, (BitAction)(1-(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_6))));
}

以下是中断部分设置:
// can1中断服务函数USB_LP_CAN1_RX0_IRQHandler
void USB_LP_CAN1_RX0_IRQHandler(void)
{

can1_Receive_flag=0xff; //接收中断标志位置位       
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);       
}

主程序部分就不列出了,因为每个工程师编写程序的功能差异很大。
可以技术交流,qq:531706356;13106551527      









沙发
NYT369|  楼主 | 2016-5-29 17:23 | 只看该作者

使用特权

评论回复
板凳
yklstudent| | 2016-5-29 17:30 | 只看该作者
楼主CAN跑的什么协议?

使用特权

评论回复
地板
NYT369|  楼主 | 2016-5-29 17:32 | 只看该作者
CAN2.0B

使用特权

评论回复
5
NYT369|  楼主 | 2016-5-29 17:33 | 只看该作者
给一家公司开发的远程控制自动窗户的程序,用到了CAN通讯,代替以前的485

使用特权

评论回复
6
yklstudent| | 2016-5-29 17:40 | 只看该作者
你的上层应用层协议是什么?

使用特权

评论回复
7
robter| | 2016-5-30 08:10 | 只看该作者
很好很好,感谢楼主的好资料

使用特权

评论回复
8
gbbfbaa| | 2016-5-30 11:02 | 只看该作者
mark

使用特权

评论回复
9
松哥无敌| | 2016-5-30 12:06 | 只看该作者
好厉害啊,膜拜,学习了

使用特权

评论回复
10
WANGDJ| | 2016-5-31 22:25 | 只看该作者
谢谢分享,学习了

使用特权

评论回复
11
NYT369|  楼主 | 2016-10-5 11:40 | 只看该作者

使用特权

评论回复
12
wdjz| | 2017-4-8 00:43 | 只看该作者
请问楼主要怎么实现CAN波特率自动匹配

使用特权

评论回复
13
dongnanxibei| | 2017-4-8 12:33 | 只看该作者
自从接触了Lua后,越来越觉得C语言不适合搞单片机了,

使用特权

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

本版积分规则

8

主题

38

帖子

1

粉丝