求助STM32CAN收发PA11&12回环OK正常模式无数据发送

yangtianle   2010-6-14 10:28 楼主


问题如题,以下是我的源代码:请各位大侠帮帮忙!

源代码有两个部分,一个是main.c 一个是stm32f10x_it.c(此文件中我只使用了can接收中断和系统定时中断) (cantx和canrx都是一样的)

/******************** (C) COPYRIGHT 2007 STMicroelectronics ********************
* File Name          : main.c
* Author             : MCD Application Team
* Version            : V1.0
* Date               : 10/08/2007
* Description        : Main program body
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"

/* Local includes ------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;

/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
vu32 ret; /* for return of the interrupt handling */
volatile TestStatus TestRx;
ErrorStatus HSEStartUpStatus;
u16 TimingDelay;

/* Private functions ---------------------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
TestStatus CAN_Polling(void);
TestStatus CAN_Interrupt(void);
void SysTick_Configuration(void);

void delay_ms(u16 temp)
{
  TimingDelay = temp;
  while(TimingDelay != 0);
}

/*******************************************************************************
* Function Name  : SysTick_Configuration
* Description    : 系统时钟设置
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SysTick_Configuration(void)
{
        RCC_ClocksTypeDef         RCC_ClocksStatus;

        /* Return SysTick data */
        RCC_GetClocksFreq(&RCC_ClocksStatus);

        /* SysTick event each 1 ms with input clock equal to 9MHz (HCLK/8)*/         
        SysTick_SetReload(RCC_ClocksStatus.HCLK_Frequency/8/1000);
        
        /* Enable the SysTick Interrupt */
        SysTick_ITConfig(ENABLE);

        /* Enable the SysTick Counter */
          SysTick_CounterCmd(SysTick_Counter_Enable);
}
/*******************************************************************************
* Function Name  : main
* Description    : Main program
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int main(void)
{
   CanTxMsg TxMessage;
   u32 i = 0;
   u8 temp_data;

#ifdef DEBUG
  debug();
#endif

  /* System Clocks Configuration */
  RCC_Configuration();

  /* NVIC Configuration */
  NVIC_Configuration();
  
  /* GPIO ports pins Configuration */
  GPIO_Configuration();
  
  /* System Clocks */
  SysTick_Configuration();
  
  /* CAN transmit at 100Kb/s and receive by polling in loopback mode*/
  TestRx = CAN_Polling();

  while (1)
  {         
          /* transmit 1 message */
          TxMessage.StdId=0x12;
          TxMessage.ExtId=0x34;
          TxMessage.IDE=CAN_ID_EXT;
          TxMessage.RTR=CAN_RTR_DATA;
          TxMessage.DLC=2;
          TxMessage.Data[0]=0xDE;
          TxMessage.Data[1]=0xCA;
          temp_data = CAN_Transmit(&TxMessage);
          temp_data = CAN_TransmitStatus(temp_data);
          i = 0;
          while(( temp_data != CANTXOK) && (i != 0xFF))
          {
            i++;
                temp_data = CAN_TransmitStatus(temp_data);
          }

          GPIOA->ODR |= 0x0100;           //蜂鸣器响:
          if(temp_data == CANTXOK) delay_ms(600); //以不同声音区分发送状态;
          else delay_ms(100);
          GPIOA->ODR &= (~0x0100); //蜂鸣器关:
          delay_ms(900);
  }
}

/*******************************************************************************
* Function Name  : RCC_Configuration
* Description    : Configures the different system clocks.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RCC_Configuration(void)
{
  /* RCC system reset(for debug purpose) */
  RCC_DeInit();

  /* Enable HSE */
  RCC_HSEConfig(RCC_HSE_ON);

  /* Wait till HSE is ready */
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if(HSEStartUpStatus == SUCCESS)
  {
    /* Enable Prefetch Buffer */
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
   
    /* HCLK = SYSCLK */
    RCC_HCLKConfig(RCC_SYSCLK_Div1);
  
    /* PCLK2 = HCLK */
    RCC_PCLK2Config(RCC_HCLK_Div1);

    /* PCLK1 = HCLK/2 */
    RCC_PCLK1Config(RCC_HCLK_Div2);

    /* Select HSE as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);

    /* Wait till HSE is used as system clock source */
    while(RCC_GetSYSCLKSource() != 0x04)
    {
    }
  }

  /* GPIOA , GPIOB ,GPIOC , GPIOD and AFIO clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOD, ENABLE);

  /* CAN Periph clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);
}

/*******************************************************************************
* Function Name  : GPIO_Configuration
* Description    : Configures the different GPIO ports.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  //GPIO_PinRemapConfig(GPIO_Remap1_CAN, ENABLE);

  /* Configure PA.08 Output push-pull */   //蜂鸣器;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Configure CAN pin: RX */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  /* Configure CAN pin: TX */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

/*******************************************************************************
* Function Name  : NVIC_Configuration
* Description    : Configures the NVIC and Vector Table base address.
* 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

  /* enabling interrupt */
  NVIC_InitStructure.NVIC_IRQChannel=USB_LP_CAN_RX0_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

/*******************************************************************************
* Function Name  : CAN_Polling
* Description    : Configures the CAN and transmit and receive by polling
* Input          : None
* Output         : None
* Return         : PASSED if the reception is well done, FAILED in other case
*******************************************************************************/
TestStatus CAN_Polling(void)
{u8 Error;
  CAN_InitTypeDef        CAN_InitStructure;
  CAN_FilterInitTypeDef  CAN_FilterInitStructure;

  /* CAN register init */
  CAN_DeInit();
  CAN_StructInit(&CAN_InitStructure);

  /* CAN cell init */
  CAN_InitStructure.CAN_TTCM=DISABLE;
  CAN_InitStructure.CAN_ABOM=DISABLE;
  CAN_InitStructure.CAN_AWUM=DISABLE;
  CAN_InitStructure.CAN_NART=DISABLE;
  CAN_InitStructure.CAN_RFLM=DISABLE;
  CAN_InitStructure.CAN_TXFP=DISABLE;
  CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;//CAN_Mode_LoopBack;
  CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
  CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;
  CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;
  CAN_InitStructure.CAN_Prescaler=5;
  Error =CAN_Init(&CAN_InitStructure);
if (Error == 0)
        return FAILED;
  /* CAN filter init */
  CAN_FilterInitStructure.CAN_FilterNumber=0;
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
  CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);
  CAN_ITConfig(CAN_IT_TME, ENABLE);

  return PASSED; /* Test Passed */
}
/*******************************************************************************
* Function Name  : assert_failed
* Description    : Reports the name of the source file and the source line number
*                  where the assert_param error has occurred.
* Input          : - file: pointer to the source file name
*                  - line: assert_param error line source number
* Output         : None
* Return         : None
*******************************************************************************/
void assert_failed(u8* file, u32 line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}

/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/
//文件2:stm32f10x_it.c

/******************** (C) COPYRIGHT 2007 STMicroelectronics ********************
* File Name          : stm32f10x_it.c
* Author             : MCD Application Team
* Version            : V1.0
* Date               : 10/08/2007        
* Description        : Main Interrupt Service Routines.
*                      This file can be used to describe all the exceptions
*                      subroutines that may occur within user application.
*                      When an interrupt happens, the software will branch
*                      automatically to the corresponding routine.
*                      The following routines are all empty, user can write code
*                      for exceptions handlers and peripherals IRQ interrupts.
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
extern vu32 ret;
extern u16 TimingDelay;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/*******************************************************************************
* Function Name  : SysTickHandler
* Description    : This function handles SysTick Handler.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SysTickHandler(void)
{
    if(TimingDelay > 0) TimingDelay--;
}

/*******************************************************************************
* Function Name  : USB_HP_CAN_TX_IRQHandler
* Description    : This function handles USB High Priority or CAN TX interrupts
*                  requests.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void USB_HP_CAN_TX_IRQHandler(void)
{
    CAN_ITConfig(CAN_IT_TME, DISABLE);
}

/*******************************************************************************
* 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)
{
  vu8 temp_flag=0;        //用于在线调试的时候看数据所用
  CanRxMsg RxMessage;

  RxMessage.StdId=0x00;
  RxMessage.ExtId=0x00;
  RxMessage.IDE=0;
  RxMessage.DLC=0;
  RxMessage.FMI=0;
  RxMessage.Data[0]=0x00;
  RxMessage.Data[1]=0x00;

  CAN_Receive(CAN_FIFO0, &RxMessage);

  if((RxMessage.StdId==0x12) && (RxMessage.ExtId==0x34) && (RxMessage.IDE==CAN_ID_EXT)
     && (RxMessage.DLC==2) && ((RxMessage.Data[1]|RxMessage.Data[0]<<8)==0xDECA))
  {
    temp_flag = 1;
  }
  else
  {
    temp_flag = 0;
  }
  temp_flag = 0;
}

/*******************************************************************************
* Function Name  : CAN_RX1_IRQHandler
* Description    : This function handles CAN RX1 interrupt request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void CAN_RX1_IRQHandler(void)
{
}
/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/

回复评论 (13)

                                 版主主可否帮忙看看啊? 谢谢了!
点赞  2010-6-14 15:09
                                 香斑也挺郁闷的,咋天天看别人的source code呢
点赞  2010-6-14 15:22
                                 哈哈!我也不想,但是我坚持独自一个人搞了一周了还不见进展故来网上请教高手!就等不见高人回帖自得请版主了!
点赞  2010-6-14 16:55
                                 哈哈!我也不想,但是我坚持独自一个人搞了一周了还不见进展故来网上请教高手!久等不见高人回帖只得请版主了!
点赞  2010-6-14 16:56
1.CAN正常通信模式,需要至少2个节点
2.用示波器看看CAN_RX引脚的电平,正常应该是高电平
点赞  2010-6-14 17:14
我现在检测出一些现象,我改为正常模式后上电一开始检测到了一组波形从CANTX输出,之后就不在出现波形(使用回环模式结果是不停发送的,因为我的程序就是让他不停发送的)
第二个现象是,我使用回环模式下CANTX不停发送信号,我一路跟踪信号到MCP2551-I / SN的第一脚TXD波形仍然是正常,但是我此时用示波器量到MCP2551-I / SN输出引脚CANH和CANL的时候却没有了变化。这里有点晕呀!
点赞  2010-6-14 17:38
IJK,谢谢您的回复
我有点疑惑,
1、2个节点是要3个设备吧?
2、如果我现在只有两台一样的设备(都可收发,我使用一台收,一台发)可以发数据吗?
3、正常模式下用示波器测CAN_RX引脚的电平是3.4V左右正常吗?
点赞  2010-6-14 17:42
1、2个节点 2个设备就行了
2、如果只有两台一样的设备(都可收发,我使用一台收,一台发),可以发数据
3、正常模式下用示波器测CAN_RX引脚的电平是3.4V左右,基本正常

另外,看CAN初始化(CAN_Polling)是否成功,还要看CAN的状态寄存器。
点赞  2010-6-15 09:00
                                 CAN初始化成功,返回PASSED标志,还有就是发生后我检测发送状态寄存器返回值为CANTXPENDING 标志
点赞  2010-6-15 09:29
我修改了波特率和那个发送数据个数后发现
如果更改发送数据个数为8个
/* transmit 1 message */
          TxMessage.StdId=0x12;
          TxMessage.ExtId=0x34;
          TxMessage.IDE=CAN_ID_EXT;
          TxMessage.RTR=CAN_RTR_DATA;
          TxMessage.DLC=8;
          for(i=0;i<8;i++)
         {
             TxMessage.Data[i]=i;
         }


或者更改波特率设置为如下 CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
  CAN_InitStructure.CAN_BS1=CAN_BS1_9tq;
  CAN_InitStructure.CAN_BS2=CAN_BS2_8tq;
  CAN_InitStructure.CAN_Prescaler=200;

以上两种更改都会导致在回环模式下都无法发送正常。
点赞  2010-6-15 09:39
                                 哈哈!总算搞定了。我这只瞎猫总算碰上了死耗子!东猜西猜总算找到了问题,发送不成功是我一只稳压管有问题把它拉到地了。发送搞定了有出现接收到的ID出现全0的现象(不过那个程序不是这个,是我改过的精简版本),后来又改成这个OK了(是发送参数变量ID中途被清零了)。
点赞  2010-6-15 16:09
                                 谢谢各位的帮忙!谢谢了!
点赞  2010-6-15 16:10

STM32can通信

我也遇到了STM32can在回环模式下能够发送数据,而在正常模式下,尽在启动的时候示波器测得一帧数据的问题,请高手帮忙,留个QQ:455853630,
点赞  2012-4-24 14:43
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复