查看: 2962|回复: 1
打印 上一主题 下一主题

STM32F103RBT6平台两个相同开发板CAN收发程序无法正常通信

[复制链接]
跳转到指定楼层
沙发
发表于 2016-7-22 21:04:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我想实现的功能是:
1、开发板1烧发送程序:
(1)按键1(PC0引脚)下降沿触发EXTI_Line0中断
(2)中断程序中添加
       LED1_ON程序点亮LED1灯(PB9引脚);
       CAN_Transmit(&TxMessage)函数发送数据 ;

2、开发板2烧接收程序:
(1)使能CAN接收中断,进入USB_LP_CAN_RX0_IRQHandler()中断函数
(2)中断函数中添加LED2_Flash程序,使LED2(PB7引脚)闪烁

我运行的结果是按开发板1的按键,开发板1的LED1亮,开发板2的LED2不闪烁!求解,以下是程序!


3、keil uvision4界面添加的程序文件目录


4、开发板1发送程序:
(1)stm32f103rbt6_can.c
#include "led.h"
#include "key.h"
#include "can.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_it.h"

CanTxMsg TxMessage;

/*******************************************************************************
* Function Name  : main
* Description       : main body function
* Input              : None
* Output           : None
* Return            : None
*******************************************************************************/
int main()
{   
                        LED_GPIO_INIT();
                         KEY_INIT();
                         CAN_Config();
                         CAN_SendMsgStructure();                        
                         LED1_OFF;
                         while(1)
                                  {
                                  }

}
(2)led.h
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stdint.h"

#define   LED1_ON       GPIO_SetBits(GPIOB, GPIO_Pin_9)
#define   LED1_OFF          GPIO_ResetBits(GPIOB, GPIO_Pin_9)


void LED_GPIO_INIT(void);
(3)led.c
#include "led.h"
GPIO_InitTypeDef LED_GPIO_Inistructure;

void LED_GPIO_INIT()
{   
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        LED_GPIO_Inistructure.GPIO_Pin=GPIO_Pin_9;
        LED_GPIO_Inistructure.GPIO_Speed=GPIO_Speed_50MHz;
        LED_GPIO_Inistructure.GPIO_Mode=GPIO_Mode_Out_PP;
        GPIO_Init(GPIOB, &LED_GPIO_Inistructure);
}

(4)key.h
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_nvic.h"

void KEY_GPIO_INIT(void);
void KEY_EXTI_INIT(void);
void NVIC_Configuration(void);
void KEY_INIT(void);

(5)key.c
#include "key.h"

GPIO_InitTypeDef KEY_GPIO_Inistructure;
void KEY_GPIO_INIT()
{
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);
        KEY_GPIO_Inistructure.GPIO_Pin=GPIO_Pin_0;
        KEY_GPIO_Inistructure.GPIO_Speed=GPIO_Speed_50MHz;
        KEY_GPIO_Inistructure.GPIO_Mode=GPIO_Mode_IPU;
        GPIO_Init(GPIOC, &KEY_GPIO_Inistructure);
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource0);

}

EXTI_InitTypeDef  KEY_EXIT_Inistructure;

void KEY_EXTI_INIT()
{
        KEY_EXIT_Inistructure.EXTI_Line=EXTI_Line0;
        KEY_EXIT_Inistructure.EXTI_Mode=EXTI_Mode_Interrupt;
        KEY_EXIT_Inistructure.EXTI_Trigger=EXTI_Trigger_Falling;
        KEY_EXIT_Inistructure.EXTI_LineCmd=ENABLE;
        EXTI_Init(&KEY_EXIT_Inistructure);

}

/*******************************************************************************
* Function Name  : NVIC_Configuration
* Description    : Configure the nested vectored interrupt controller.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  
#ifdef  VECT_TAB_RAM  
  /* Set the Vector Table base location at 0x20000000 */
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */
  /* Set the Vector Table base location at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
#endif

  /* Configure one bit for preemption priority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
  /* Enable the EXTI0 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

}

void KEY_INIT()
{
  KEY_GPIO_INIT();
  KEY_EXTI_INIT();
  NVIC_Configuration();
}
(6)can.h
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_nvic.h"
#include "stm32f10x.h"
#include "stm32f10x_can.h"

void CAN_GPIO_Config(void);
void CAN_Mode_Config(void);
void CAN_Filter_Config(void);
void CAN_Config(void);
void CAN_SendMsgStructure(void);
(7)can.c
#include "can.h"

extern   CanTxMsg TxMessage;
/********************************************************************************************
* 函数名:CAN_GPIO_Config
* 描述  :CAN的GPIO 配置,PA11上拉输入,PA12推挽输出
* 输入  :无
* 输出  : 无
* 调用  :内部调用
*********************************************************************************************/
void CAN_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
           
          /*外设时钟设置*/
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);

          /*IO设置*/
        /* Configure CAN pin: RX */                                                                         // PA11
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                                        // 上拉输入
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* Configure CAN pin: TX */                                                                         // PA12
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                                        // 复用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
    GPIO_Init(GPIOA, &GPIO_InitStructure);
        
}

/******************************************************************************************
* 函数名:CAN_Mode_Config
* 描述  :CAN的模式 配置
* 输入  :无
* 输出  : 无
* 调用  :内部调用
******************************************************************************************/
void CAN_Mode_Config(void)
{
           CAN_InitTypeDef        CAN_InitStructure;
                 /************************CAN通信参数设置**********************************/
        /*CAN寄存器初始化*/
        CAN_DeInit();
        CAN_StructInit(&CAN_InitStructure);
        /*CAN单元初始化*/
        CAN_InitStructure.CAN_TTCM=DISABLE;                           //MCR-TTCM  关闭时间触发通信模式使能
       CAN_InitStructure.CAN_ABOM=DISABLE;                           //MCR-ABOM  自动离线管理
       CAN_InitStructure.CAN_AWUM=DISABLE;                           //MCR-AWUM  使用自动唤醒模式
       CAN_InitStructure.CAN_NART=ENABLE;                           //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 重新同步跳跃宽度 2个时间单元
       CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;                   //BTR-TS1 时间段1 占用了6个时间单元
       CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;                   //BTR-TS1 时间段2 占用了3个时间单元
       CAN_InitStructure.CAN_Prescaler =5;                       //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+2+3)/6=1Mbps
      CAN_Init(&CAN_InitStructure);
}

/*******************************************************************************************
* 函数名:CAN_Filter_Config
* 描述  :CAN的过滤器 配置
* 输入  :无
* 输出  : 无
* 调用  :内部调用
*******************************************************************************************/
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位。
        /* 使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。 */

       CAN_FilterInitStructure.CAN_FilterIdHigh=0x00AA<<3;                                //要过滤的ID高位  地址设置的地方
       CAN_FilterInitStructure.CAN_FilterIdLow= 0x0000;                                   //要过滤的ID低位  地址设置的地方
       CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0x00FF<<3;                        //过滤器高16位每位必须匹配
       CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0x0000;                                //过滤器低16位每位必须匹配
       CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FilterFIFO0;               //过滤器被关联到FIFO0
       CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                               //使能过滤器
       CAN_FilterInit(&CAN_FilterInitStructure);
        /*CAN通信中断使能*/
    CAN_ITConfig(CAN_IT_FMP0, ENABLE);
}

/*******************************************************************************************
* 函数名:CAN_Config
* 描述  :完整配置CAN的功能
* 输入  :无
* 输出  : 无
* 调用  :外部调用
*******************************************************************************************/
void CAN_Config(void)
{
  CAN_GPIO_Config();
  CAN_Mode_Config();
  CAN_Filter_Config();   
}

/*******************************************************************************************
* 函数名:CAN_SendMsgStructure
* 描述  :CAN通信报文内容设置
* 输入  :无
* 输出  : 无
* 调用  :外部调用
*******************************************************************************************/         
void CAN_SendMsgStructure(void)
{                                                           
  TxMessage.ExtId=0x00AA0000;                                         //使用的扩展ID
  TxMessage.IDE=CAN_ID_EXT;                                         //扩展模式
  TxMessage.RTR=CAN_RTR_DATA;                                 //发送的是数据
  TxMessage.DLC=1;                                                         //数据长度为1字节
  TxMessage.Data[0]=0x16;
}
(8)stm32f10x_it.c
略去该文件中的其它函数
/*******************************************************************************
* Function Name  : EXTI0_IRQHandler
* Description    : This function handles External interrupt Line 0 request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void EXTI0_IRQHandler(void)
{
  
  LED1_ON;
  CAN_Transmit(&TxMessage);
  EXTI_ClearFlag(EXTI_Line0);
   
}

5、开发板2接收程序
(1)stm32f103_can.c
#include "led.h"
#include "can.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_it.h"

CanRxMsg RxMessage;                                                 //接收缓冲区

/*******************************************************************************
* Function Name  : main
* Description    : main body function
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int main()
{   
                         LED_GPIO_INIT();
                         CAN_Config();
                         CAN_ReceiveMsgStructure();                        
                         LED2_OFF;
                         while(1)
                                  {
                                   }

}
(2)led.h
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stdint.h"

#define   LED2_ON       GPIO_SetBits(GPIOB, GPIO_Pin_7)
#define   LED2_OFF          GPIO_ResetBits(GPIOB, GPIO_Pin_7)

void LED_GPIO_INIT(void);
void Delay(volatile uint32_t nCount);
void LED2_flash(void);
(3)led.c
#include "led.h"
GPIO_InitTypeDef LED_GPIO_Inistructure;
void LED_GPIO_INIT()
{
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        LED_GPIO_Inistructure.GPIO_Pin=GPIO_Pin_7;
        LED_GPIO_Inistructure.GPIO_Speed=GPIO_Speed_50MHz;
        LED_GPIO_Inistructure.GPIO_Mode=GPIO_Mode_Out_PP;
        GPIO_Init(GPIOB, &LED_GPIO_Inistructure);
}

/*******************************************************************************
* Function Name  : Delay
* Description    : Time delays.
* Input          : nCount
* Output         : None
* Return         : None
*******************************************************************************/
void Delay(volatile uint32_t nCount)
{
   for(; nCount != 0; nCount--);
}

/*******************************************************************************
* Function Name  : LED2_flash
* Description    : LED2 flashes.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void LED2_flash()
{
        LED2_ON;
        Delay(0xAFFFF);
        LED2_OFF;
        Delay(0xAFFFF);
}
(4)can.h
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_nvic.h"
#include "stm32f10x.h"
#include "stm32f10x_can.h"

void CAN_GPIO_Config(void);
void CAN_NVIC_Config(void);
void CAN_Mode_Config(void);
void CAN_Filter_Config(void);
void CAN_Config(void);
void CAN_ReceiveMsgStructure(void);
(5)can.c
#include "can.h"

extern   CanRxMsg RxMessage;
/********************************************************************************************
* 函数名:CAN_GPIO_Config
* 描述  :CAN的GPIO 配置,PA11上拉输入,PA12推挽输出
* 输入  :无
* 输出  : 无
* 调用  :内部调用
*********************************************************************************************/
void CAN_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
           
          /*外设时钟设置*/
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);

          /*IO设置*/
        /* Configure CAN pin: RX */                                                                         // PA11
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                                        // 上拉输入
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* Configure CAN pin: TX */                                                                         // PA12
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                                 // 复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        
}

/*******************************************************************************************
* 函数名:CAN_NVIC_Config
* 描述  :CAN的NVIC 配置,第1优先级组,0,0优先级
* 输入  :无
* 输出  : 无
* 调用  :内部调用
*******************************************************************************************/
void CAN_NVIC_Config(void)
{
           NVIC_InitTypeDef NVIC_InitStructure;
                /* Configure one bit for preemption priority */
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
                 /*中断设置*/
        NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN_RX0_IRQChannel;           //CAN1 RX0中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;                                   //抢占优先级0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                                          //子优先级为0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

/******************************************************************************************
* 函数名:CAN_Mode_Config
* 描述  :CAN的模式 配置
* 输入  :无
* 输出  : 无
* 调用  :内部调用
******************************************************************************************/
void CAN_Mode_Config(void)
{
           CAN_InitTypeDef        CAN_InitStructure;
                 /************************CAN通信参数设置**********************************/
        /*CAN寄存器初始化*/
        CAN_DeInit();
        CAN_StructInit(&CAN_InitStructure);
        /*CAN单元初始化*/
        CAN_InitStructure.CAN_TTCM=DISABLE;                           //MCR-TTCM  关闭时间触发通信模式使能
       CAN_InitStructure.CAN_ABOM=DISABLE;                                   //MCR-ABOM  自动离线管理
       CAN_InitStructure.CAN_AWUM=DISABLE;                           //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 重新同步跳跃宽度 2个时间单元
       CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;                           //BTR-TS1 时间段1 占用了6个时间单元
       CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;                           //BTR-TS1 时间段2 占用了3个时间单元
       CAN_InitStructure.CAN_Prescaler =5;                                  //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+2+3)/6=1Mbps
       CAN_Init(&CAN_InitStructure);
}

/*******************************************************************************************
* 函数名:CAN_Filter_Config
* 描述  :CAN的过滤器 配置
* 输入  :无
* 输出  : 无
* 调用  :内部调用
*******************************************************************************************/
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位。
        /* 使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。 */

        CAN_FilterInitStructure.CAN_FilterIdHigh=0x00AA<<3;                                                                       //要过滤的ID高位  地址设置的地方
        CAN_FilterInitStructure.CAN_FilterIdLow= 0x0000;                                                                         //要过滤的ID低位  地址设置的地方
        CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0x00FF<<3;                                                              //过滤器高16位每位必须匹配
        CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0x0000;                                                                      //过滤器低16位每位必须匹配
        CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FilterFIFO0;                                                      //过滤器被关联到FIFO0
        CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                                                                      //使能过滤器
        CAN_FilterInit(&CAN_FilterInitStructure);
        /*CAN通信中断使能*/
        CAN_ITConfig(CAN_IT_FMP0, ENABLE);
}

/*******************************************************************************************
* 函数名:CAN_Config
* 描述  :完整配置CAN的功能
* 输入  :无
* 输出  : 无
* 调用  :外部调用
*******************************************************************************************/
void CAN_Config(void)
{
  CAN_GPIO_Config();
  CAN_NVIC_Config();
  CAN_Mode_Config();
  CAN_Filter_Config();
  CAN_ReceiveMsgStructure();   
}

/*******************************************************************************************
* 函数名:CAN_ReceiveMsgStructure
* 描述  :CAN通信报文内容设置
* 输入  :无
* 输出  : 无
* 调用  :外部调用
*******************************************************************************************/         
void CAN_ReceiveMsgStructure(void)
{                                                           
  RxMessage.ExtId=0x00;                                //使用的扩展ID
  RxMessage.IDE=0x00;                                //扩展模式
  RxMessage.RTR=0x00;                                //接收的数据类型
  RxMessage.DLC=0x00;                                //数据长度
  RxMessage.Data[0]=0x00;                //数据内容
}
(6)stm32f10x_it.h
该文件为库文件,我只添加了“include”,和声明一个外部变量
#include "stm32f10x_lib.h"
#include "led.h"
extern CanTxMsg TxMessage;
(7)stm32f10x_it.c
该文件为库文件,我只使用了其中的CAN接收中断函数,其它的文件内容略
/*******************************************************************************
* Function Name  : USB_LP_CAN_RX0_IRQHandler
* Description    : This function handles USB Low Priority or CAN RX0 interrupts
*                  requests.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void USB_LP_CAN_RX0_IRQHandler(void)
{
   LED2_flash();
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入中科因仑

本版积分规则

快速回复 返回顶部 返回列表