stm32f1 CAN通讯 正常模式无法收发数据 环回模式正常接收

2019-03-23 15:48发布

本帖最后由 清风烈酒 于 2018-1-17 09:46 编辑

使用stm32f107芯片库函数,配置环回模式能够正常发送接收;
修改为正常模式,用单步调试查看到程序运行到这条语句 CANx->sTxMailBox[transmit_mailbox].TIR |= TMIDxR_TXRQ;

用示波器测试Tx引脚没有波形输出,发送三次后三个邮箱都占满了便不会发送数据了。

接收采用中断函数void USB_LP_CAN1_RX0_IRQHandler(void)接收。用CANalyst 发送数据下来,从单片机引脚Rx上能够检测到CANalyst发送过来数据的波形,但是程序中断函数没有触发。

不知道大家有没有遇到过这种情况,查了很久都不知道出现了什么问题。

请各位大神帮忙!!!谢谢!!!



  1. extern CanTxMsg TxMessage;
  2. extern CanRxMsg RxMessage;


  3. void GPIO_CAN_Configuration(void)
  4. {
  5.   GPIO_InitTypeDef GPIO_InitStructure;
  6.      
  7.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
  8.      
  9.     GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
  10.   
  11.   /* Configure CAN pin: RX */
  12.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  13.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  14.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  15.    
  16.   /* Configure CAN pin: TX */
  17.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  18.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  19.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  20.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  21. }


  22. void CAN_Interrupt(void)
  23. {
  24.     CAN_InitTypeDef        CAN_InitStructure;
  25.   CAN_FilterInitTypeDef  CAN_FilterInitStructure;
  26.      
  27.   /* CAN register init */
  28.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);            //使能CAN1时钟  
  29.   CAN_DeInit(CAN1);
  30.   CAN_StructInit(&CAN_InitStructure);
  31.   
  32.   /* CAN cell init */
  33.   CAN_InitStructure.CAN_TTCM = DISABLE;             // 时间触发通信禁止
  34.   CAN_InitStructure.CAN_ABOM = DISABLE;             // 离线退出是在中断置位清0后退出
  35.   CAN_InitStructure.CAN_AWUM = DISABLE;             // 自动唤醒模式:清零sleep
  36.      
  37.   CAN_InitStructure.CAN_NART = DISABLE;             // 自动重新传送报文,直到发送成功
  38.   CAN_InitStructure.CAN_RFLM = DISABLE;             // FIFO没有锁定,新报文覆盖旧报文
  39.      
  40.   CAN_InitStructure.CAN_TXFP = DISABLE;               // 发送报文优先级确定:标志符
  41.   CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
  42.     //CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;
  43.      
  44.   CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;          // 1tq、BS1、BS2的值跟波特率有关
  45.   CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq;
  46.   CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
  47.   CAN_InitStructure.CAN_Prescaler=4;              // 分频系数为1


  48.   CAN_Init(CAN1, &CAN_InitStructure);             // 初始化CAN1
  49.   
  50.   /* CAN filter init */
  51.   CAN_FilterInitStructure.CAN_FilterNumber = 0;
  52.   CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
  53.   CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
  54.   CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
  55.   CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
  56.   CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
  57.   CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
  58.   CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FilterFIFO0;
  59.   CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
  60.   CAN_FilterInit(&CAN_FilterInitStructure);
  61.   
  62.   
  63.   /* CAN FIFO0 message pending interrupt enable */
  64.   CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); //中断使能
  65.       
  66. }



  67. static void CAN_NVIC_Configuration(void)
  68. {
  69.   NVIC_InitTypeDef NVIC_InitStructure;
  70.   
  71.   /* Enable CAN1 RX0 interrupt IRQ channel */
  72.   NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
  73.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1
  74.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0
  75.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  76.   NVIC_Init(&NVIC_InitStructure);
  77. }


  78. void CAN_Config(void)
  79. {
  80.     GPIO_CAN_Configuration();
  81.     CAN_NVIC_Configuration();
  82.     CAN_Interrupt();
  83. }


  84. u8 CAN_SetMsg(void)
  85. {   
  86.     u8 mailBox;
  87.     u16 i = 0;
  88.      
  89.     TxMessage.StdId=0x00;                                                                                    //ID标识符
  90.     TxMessage.RTR = CAN_RTR_DATA;                                    //数据帧
  91.     TxMessage.IDE = CAN_ID_STD;                                      //标准帧格式
  92.     TxMessage.DLC=8;                                                                       //帧长度,单位:字节
  93.      
  94.     TxMessage.Data[0] = 0xF1;    //待传数据
  95.     TxMessage.Data[1] = 0xF2;
  96.     TxMessage.Data[2] = 0xF3;
  97.     TxMessage.Data[3] = 0xF4;
  98.     TxMessage.Data[4] = 0xF5;
  99.     TxMessage.Data[5] = 0xF6;
  100.     TxMessage.Data[6] = 0xF7;
  101.     TxMessage.Data[7] = 0xF8;
  102.      
  103.     mailBox = CAN_Transmit(CAN1, &TxMessage);
  104.      
  105.     while((CAN_TransmitStatus(CAN1, mailBox)==CANTXFAILED) && (i != 0XFF))
  106.     {
  107.             i++;    //等待发送结束        
  108.     }
  109. }


  110. void USB_LP_CAN1_RX0_IRQHandler(void)
  111. {
  112.     RxMessage.StdId=0x00;
  113.     RxMessage.IDE=CAN_ID_STD;
  114.     RxMessage.DLC=0;
  115.     RxMessage.FMI=0;
  116.     RxMessage.Data[0]=0x00;
  117.     RxMessage.Data[1]=0x00;
  118.     RxMessage.Data[2]=0x00;
  119.     RxMessage.Data[3]=0x00;
  120.     RxMessage.Data[4]=0x00;
  121.     RxMessage.Data[5]=0x00;
  122.     RxMessage.Data[6]=0x00;
  123.     RxMessage.Data[7]=0x00;
  124.       
  125.     CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
  126.          
  127.     //LED灯闪烁
  128.     if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1))
  129.     {
  130.             GPIO_ResetBits(GPIOA,GPIO_Pin_1);
  131.     }else
  132.     {
  133.             GPIO_SetBits(GPIOA,GPIO_Pin_1);
  134.     }   
  135. }
复制代码

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
huaiqiao
1楼-- · 2019-03-23 21:59
/ 楼主发现一个问题,在GPIO初始化的时候,我看到你用的是can1.  对应的IO分别是PA11,PA12.

但是,你仔细看了用户手册了吗?

11111111111111111111.png

我想GPIO初始化的时候。
  1. GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
复制代码

就不需要重映射了。

还有,如下时钟总线也不需要使能了。RCC_APB2Periph_AFIO 这个也不需要使能了
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
复制代码


其他没看出啥大的问题



清风烈酒
2楼-- · 2019-03-24 02:26
huaiqiao 发表于 2018-1-17 10:11
楼主发现一个问题,在GPIO初始化的时候,我看到你用的是can1.  对应的IO分别是PA11,PA12.

但是,你仔细 ...

那就不需要重映射了,像上面那个重映射就映射到PB8, PB9 了是吧?     我把这两个地方都屏蔽了,但是还是Tx引脚还是没有波形出来。有其他工程师说:这种情况最先检查的是波特率,麻烦帮我把波特率看下,波特率计算:36/(1+TS1+TS2)*BRP  ???
huaiqiao
3楼-- · 2019-03-24 04:58
 精彩回答 2  元偷偷看……
清风烈酒
4楼-- · 2019-03-24 10:20
本帖最后由 清风烈酒 于 2018-1-17 13:20 编辑
huaiqiao 发表于 2018-1-17 12:24
有关这个波特率的计算的。如下,这个在用户手册中有体现呢。。。



我感觉你不会计算波特率,不知道 ...

谢谢,非常感谢。我要配置的波特率为500kps,调用库函数配置是不是这样的。进入Dug模式后代码与BTR寄存器如下:C:UsersAdministratorDesktopESCI~HQZ_6PYYD0R0A}5(XV.png
huaiqiao
5楼-- · 2019-03-24 16:01
清风烈酒 发表于 2018-1-17 13:15
谢谢,非常感谢。我要配置的波特率为500kps,调用库函数配置是不是这样的。进入Dug模式后代码与BTR寄存器 ...

目测应该没有问题,你自己不会计算么?我不知道f107的Fpclk。  Fpclk我记得如果是F103的話,就是ABPB1的时钟频率。

一般,我们用就是波特率基本就是250k,500k比较常见。不知道其他人,怎么使用的。
清风烈酒
6楼-- · 2019-03-24 17:02
 精彩回答 2  元偷偷看……

一周热门 更多>