你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

st-img
chrome
st-img
firefox
st-img
safari
st-img
ie8及以上
shequ.stmicroelectronics.cn
  • ST意法半导体官网
  • STM32中文官网
  • ST全球论坛
登录/注册
  • 首页
  • 技术问答
  • 话题
  • 资源
  • 创客秀
  • 视频
  • 标签
  • 每日签到
  • STM32团队2
  • 论坛吐槽优化专区
  • 升级测试
zhangxm6

zhangxm6

 

回答数 0 关注数 0
关注 私信
  • 动态99
  • 提问
  • 回答0
  • 创客秀 0
  • 分享 0
  • 关注0
3 回答

stm32实现CAN发送邮箱空中断

未设置标签
hlt512 hlt512 回答时间: 2013-11-30 10:23

利用stm32实现了1个简单的CAN功能,使用了队列缓存 can.c 文件 #include "includes.h" #define GPIO_CAN                   GPIOB #define RCC_APB2Periph_GPIO_CAN    RCC_APB2Periph_GPIOB #define GPIO_Pin_RX                GPIO_Pin_8 #define GPIO_Pin_TX                GPIO_Pin_9 #define GPIO_Remap_CAN             GPIO_Remap1_CAN1 #define MAX_MAIL_NUM  3 static u8 CAN_msg_num[MAX_MAIL_NUM];   // 发送邮箱标记 // /**   * @brief  Configures the CAN, transmit and receive by polling   * @param  None   * @retval : PASSED if the reception is well done, FAILED in other case   */ void CAN_config_init(void) {   CAN_InitTypeDef        CAN_InitStructure;   CAN_FilterInitTypeDef  CAN_FilterInitStructure;   /* CAN register init */   CAN_DeInit(CAN1);   CAN_StructInit(&CAN_InitStructure);   /* CAN cell init */  // 36M 250k速率   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_InitStructure.CAN_SJW=CAN_SJW_1tq;   CAN_InitStructure.CAN_BS1=CAN_BS1_12tq;   CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;   CAN_InitStructure.CAN_Prescaler=9;   CAN_Init(CAN1, &CAN_InitStructure);   /* 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);   } void CAN_init(void) {        NVIC_InitTypeDef NVIC_InitStructure;     GPIO_InitTypeDef GPIO_InitStructure;          // 首先打开电源及时钟     /* GPIO for CAN and GPIO for LEDs clock enable */     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO |RCC_APB2Periph_GPIO_CAN, ENABLE);     /* CAN1 Periph clock enable */     RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);         /* Enable CAN1 RX0 interrupt IRQ channel */     NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     NVIC_Init(&NVIC_InitStructure);     /* Enable CAN1 TX0 interrupt IRQ channel */     NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     NVIC_Init(&NVIC_InitStructure);     // 然后配置pin     /* Configure CAN pin: RX */     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_RX;     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     GPIO_Init(GPIO_CAN, &GPIO_InitStructure);     /* Configure CAN pin: TX */     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_TX;     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     GPIO_Init(GPIO_CAN, &GPIO_InitStructure);     // 映射下     GPIO_PinRemapConfig(GPIO_Remap_CAN , ENABLE);     // 波特率过滤器初始化     CAN_config_init();     CAN_ITConfig(CAN1, CAN_IT_FMP0 | CAN_IT_FF0 | CAN_IT_FOV0, ENABLE);  // fifo0中断     CAN_ITConfig(CAN1, CAN_IT_FMP1 | CAN_IT_FF1 | CAN_IT_FOV1, ENABLE);  // fifo1中断     CAN_ITConfig(CAN1, CAN_IT_TME, DISABLE);                // 发送中断     CAN_ITConfig(CAN1, CAN_IT_EWG | CAN_IT_EPV | CAN_IT_BOF | CAN_IT_LEC                      | CAN_IT_ERR | CAN_IT_WKU | CAN_IT_SLK, ENABLE);  // ERR中断     // CAN缓存初始化     memset(CAN_msg_num,0,MAX_MAIL_NUM);     ClearCanQueue();     } int CAN_tx_msg(CanTxMsg TxMessage) {     uint8_t TransmitMailbox = 0;     OS_CPU_SR  cpu_sr = 0;     TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);     if(CAN_NO_MB == TransmitMailbox)     {         printf("tx can fail\r\n");         return 0;     }     else     {         OS_ENTER_CRITICAL();                  CAN_msg_num[TransmitMailbox] = 1;         OS_EXIT_CRITICAL();     }         CAN_ITConfig(CAN1, CAN_IT_TME, ENABLE);     return 1; } int CAN_tx_data(void) {     CanTxMsg TxMessage;     uint8_t TransmitMailbox = 0;     OS_CPU_SR  cpu_sr = 0;     /* transmit */     TxMessage.StdId=0x6f1;     TxMessage.RTR=CAN_RTR_DATA;     TxMessage.IDE=CAN_ID_STD;     TxMessage.DLC=4;     TxMessage.Data[0]=0x40;     TxMessage.Data[1]=0x02;     TxMessage.Data[2]=0x1a;     TxMessage.Data[3]=0x80;     TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);     if(CAN_NO_MB == TransmitMailbox)     {         printf("tx can fail\r\n");         return 0;     }     else     {         OS_ENTER_CRITICAL();                  CAN_msg_num[TransmitMailbox] = 1;         OS_EXIT_CRITICAL();     }         CAN_ITConfig(CAN1, CAN_IT_TME, ENABLE);     return 1; } // 发送中断 void USB_HP_CAN1_TX_IRQHandler(void) {     if(CAN_msg_num[0])     {         if(SET == CAN_GetITStatus(CAN1,CAN_IT_RQCP0))         {             CAN_ClearITPendingBit(CAN1,CAN_IT_RQCP0);             CAN_ITConfig(CAN1, CAN_IT_TME, DISABLE);             CAN_msg_num[0] = 0;         }     }         if(CAN_msg_num[1])     {         if(SET == CAN_GetITStatus(CAN1,CAN_IT_RQCP1))         {             CAN_ClearITPendingBit(CAN1,CAN_IT_RQCP1);             CAN_ITConfig(CAN1, CAN_IT_TME, DISABLE);             CAN_msg_num[1] = 0;         }     }         if(CAN_msg_num[2])     {         if(SET == CAN_GetITStatus(CAN1,CAN_IT_RQCP2))         {             CAN_ClearITPendingBit(CAN1,CAN_IT_RQCP2);             CAN_ITConfig(CAN1, CAN_IT_TME, DISABLE);             CAN_msg_num[2] = 0;         }     }     } /**   * @brief  This function handles USB Low Priority or CAN RX0 interrupts   *   requests.   * @param  None   * @retval : None   */ void USB_LP_CAN1_RX0_IRQHandler(void) {   //  u32 i;     CanRxMsg RxMessage;    if(SET == CAN_GetITStatus(CAN1,CAN_IT_FF0))    {         CAN_ClearITPendingBit(CAN1,CAN_IT_FF0);    }    else if(SET == CAN_GetITStatus(CAN1,CAN_IT_FOV0))    {         CAN_ClearITPendingBit(CAN1,CAN_IT_FOV0);    }    else    {         CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);         InsertCanQueue(RxMessage);      //   printf("CAN_FIFO0 RxMessage.StdId is 0x%x\r\n",RxMessage.StdId);      //   printf("RxMessage.DLC is 0x%x\r\n",RxMessage.DLC);          //  for(i = 0; i < RxMessage.DLC; i++)      //   {      //       printf("data[%d] is 0x%x\r\n",i,RxMessage.Data);       //  }      //   printf("\r\n");       }       } void CAN1_RX1_IRQHandler(void) {    // u32 i;     CanRxMsg RxMessage;    if(SET == CAN_GetITStatus(CAN1,CAN_IT_FF1))    {         CAN_ClearITPendingBit(CAN1,CAN_IT_FF1);    }    else if(SET == CAN_GetITStatus(CAN1,CAN_IT_FOV1))    {         CAN_ClearITPendingBit(CAN1,CAN_IT_FOV1);    }    else    {         CAN_Receive(CAN1, CAN_FIFO1, &RxMessage);         InsertCanQueue(RxMessage);             //  printf("CAN_FIFO1 RxMessage.StdId is 0x%x\r\n",RxMessage.StdId);       //  printf("RxMessage.DLC is 0x%x\r\n",RxMessage.DLC);          //  for(i = 0; i < RxMessage.DLC; i++)       //  {       //      printf("data[%d] is 0x%x\r\n",i,RxMessage.Data);       //  }       //  printf("\r\n");       }        } void CAN1_SCE_IRQHandler(void) {     } can.h文件 #ifndef __CAN_H__ #define __CAN_H__ void CAN_init(void); int CAN_tx_data(void); int CAN_tx_msg(CanTxMsg TxMessage); #endif can_queue.c文件 #include "includes.h" struct _CANQueue CANQueue; /******************************************************************* 作    者: 版    权:   函数名称: 函数功能: 清除通信队列 入口参数: 无 返 回 值: 无 相关调用: 备    注: 修改信息:          ********************************************************************/ void ClearCanQueue(void) {     int i;         for(i = 0; i < MAX_CAN_SIZE; i++)     {         memset(&CANQueue.Elem,0,sizeof(CanRxMsg));     }                  CANQueue.front = 0;     CANQueue.rear = 0; } /******************************************************************* 作    者: 版    权:   函数名称: 函数功能: 判断串口队列是否为空 入口参数: 返 回 值: 1: 空; 0:非空 相关调用: 备    注: 修改信息:          ********************************************************************/ u8 IsEmptyCanQueue(void) {         if(CANQueue.front == CANQueue.rear)              {         return 1;     }        else     {         return 0;        }     } /******************************************************************* 作    者: 版    权: 函数名称: 函数功能: 判队列是否满 入口参数: 返 回 值: 1: 满; 0:非满 相关调用: 备    注: 修改信息:          ********************************************************************/ u8 IsFullCanQueue(void) {         if( CANQueue.front == (CANQueue.rear+1) % MAX_CAN_SIZE)     {         return 1;     }        else     {         return 0;        }     } /******************************************************************* 作    者: 版    权:   函数名称: 函数功能: 将数据插入队列 入口参数: element:被插元素 返 回 值: 1: 成功; 0:失败 相关调用: 备    注: 修改信息:          ********************************************************************/ u8 InsertCanQueue(CanRxMsg element) {     if(!IsFullCanQueue())                               //是否为满     {         memcpy(&CANQueue.Elem[CANQueue.rear],&element,sizeof(CanRxMsg));                CANQueue.rear = (CANQueue.rear + 1) % MAX_CAN_SIZE;                        return 1;     }     else                       //队列满     {        // printf("CAN queue is full\r\n");         return 0;     } } /******************************************************************* 作    者: 版    权: 函数名称: 函数功能: 重新设置队列头指针 入口参数: head: 新头 返 回 值: 无 相关调用: 备    注: 修改信息:          ********************************************************************/ void SetHeadCanQueue(u16 head) {         if(CANQueue.front != CANQueue.rear)     {         CANQueue.front = head;     }          } /******************************************************************* 作    者: 版    权: 函数名称: 函数功能: 取对头 入口参数: head:对头;*element;数据 返 回 值: 1: 成功 0: 失败 相关调用: 备    注: 修改信息:          ********************************************************************/ u8 GetCanQueue(u16 head,CanRxMsg *element) {         if(head != CANQueue.rear)                //到队列尾     {         memcpy(element,&CANQueue.Elem[head],sizeof(CanRxMsg));//得到数据              return 1;     }     else     {         return 0;                               //无指定对头数据     }         } /******************************************************************* 作    者: 版    权: 函数名称: 函数功能: can数据处理 入口参数: 返 回 值: 相关调用: 备    注: 修改信息:          ********************************************************************/ void Can_data_process(void) {     u16 head; //   u32 i;     CanRxMsg RxMessage;       CanTxMsg TxMessage;             head = CANQueue.front;         if(1 == GetCanQueue(head,&RxMessage))     {         head = (head + 1) % MAX_CAN_SIZE;     //查询头前滚         SetHeadCanQueue(head);       //  printf("RxMessage.StdId is 0x%x\r\n",RxMessage.StdId);       //  printf("RxMessage.DLC is 0x%x\r\n",RxMessage.DLC);          //  for(i = 0; i < RxMessage.DLC; i++)       //  {       //      printf("data[%d] is 0x%x\r\n",i,RxMessage.Data);       //  }       //  printf("\r\n");         // 把接收到的数据发回去         /* transmit */       //  TxMessage.StdId=RxMessage.StdId;         TxMessage.StdId=0x5f1;         TxMessage.RTR=RxMessage.RTR;         TxMessage.IDE=RxMessage.IDE;         TxMessage.DLC=RxMessage.DLC;           memcpy(TxMessage.Data,RxMessage.Data,TxMessage.DLC);         CAN_tx_msg(TxMessage);                      }     else     {        // printf("CAN queue is empty\r\n");     }                  } can_queue.h文件 #ifndef CAN_QUEUE_H_ #define CAN_QUEUE_H_ #define MAX_CAN_SIZE 50 struct _CANQueue {     CanRxMsg Elem[MAX_CAN_SIZE];     u16 front;     u16 rear; }; void ClearCanQueue(void); u8 IsEmptyCanQueue(void); u8 IsFullCanQueue(void); u8 InsertCanQueue(CanRxMsg element); void SetHeadCanQueue(u16 head); u8 GetCanQueue(u16 head,CanRxMsg *element); void Can_data_process(void); #endif 参考一下吧!!

赞0
5 回答

如何用stm32 CAN实现stm32与电脑通信

未设置标签
zhangxm6 zhangxm6 回答时间: 2013-11-28 20:57

回复第 2 楼 于2013-08-31 10:07:37发表: PC机上没有CAN接口,直接通信不可行的,必须用一个转换模块,比如232转CAN接口, USB转CAN接口,这样才能让计算机和你的STM32 CAN接口通信,买了这样的接口后,只需要实现CAN协议代码即可 不好意思 很久没有进来了,这个问题已经解决了,谢谢!但是现在又出现一个新的问题了,STM32 CAN 通信中发送邮箱空中断,不管怎么样配置都进不去主要代码如下: void Can_Normal(void) {   CAN_InitTypeDef   CAN_InitStructure;   CAN_FilterInitTypeDef   CAN_FilterInitStructure;  CanTxMsg          TxMessage;   volatile    u8 TransmitMailbox = 0;     /* CAN register init */   CAN_DeInit(CAN1);   CAN_StructInit(&CAN_InitStructure);   /* CAN cell init */                                     CAN_InitStructure.CAN_TTCM=DISABLE; //???1ê±??′¥·¢í¨???£ê?   CAN_InitStructure.CAN_ABOM=DISABLE; //???1×??ˉà????£ê?   CAN_InitStructure.CAN_AWUM=DISABLE; //???1×??ˉ??D??£ê?   CAN_InitStructure.CAN_NART=DISABLE; //???1·?×??ˉ??′??£ê?   CAN_InitStructure.CAN_RFLM=DISABLE; //???1?óê?FIFO???¨?£ê?   CAN_InitStructure.CAN_TXFP=DISABLE; //???1·¢?íFIFOó??è??   CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;                         // CAN_Mode_Normal;           CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;   CAN_InitStructure.CAN_BS1=CAN_BS1_8tq; //ò??-????o?á?   CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;   CAN_InitStructure.CAN_Prescaler=5;   CAN_Init(CAN1,&CAN_InitStructure);   CAN_OperatingModeRequest( CAN1, CAN_OperatingMode_Normal);           /* 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=CAN_FIFO0;         CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;         CAN_FilterInit(&CAN_FilterInitStructure);                                     /* transmit 1 message */ /*          TxMessage.StdId=0x11;           //TxMessage.ExtId=0x1234;           TxMessage.IDE=CAN_ID_STD;  //à??1??ê?           TxMessage.RTR=CAN_RTR_DATA; //′?ê????¢μ???ààDí?aêy?Y??£¨?1óD??3ì??£?           TxMessage.DLC=6;                                     //        TxMessage.Data[0]='?';                      TxMessage.Data[0]=0x55;           TxMessage.Data[1]=0x55;           TxMessage.Data[2]=0x55;           TxMessage.Data[3]=0x55;           TxMessage.Data[4]=0x55;           TxMessage.Data[5]=0x55; */                    CAN_ITConfig(CAN1,CAN_IT_TME,ENABLE);       TransmitMailbox = CAN_Transmit(CAN1,&TxMessage); //        printf("receive data:0X%X,0X%X,0X%X,0X%X,0X%X,0X%X",TxMessage.Data[0], TxMessage.Data[1], TxMessage.Data[2], TxMessage.Data[3], TxMessage.Data[4], TxMessage.Data[5]);        } 是不是哪里配置错了呢?求指教  

赞0
zhangxm6 zhangxm6


阅读作者更多的帖子

所在话题

参与活动

  • 滴滴押注社区团购,明确“投入不设上限,要做市场第一”

    线下 2020-10-16
  • 滴滴押注社区团购,明确“投入不设上限,要做市场第一”

    网络 2020-10-16
  • 滴滴押注社区团购,明确“投入不设上限,要做市场第一”

    网络 2020-10-16
  • 滴滴押注社区团购,明确“投入不设上限,要做市场第一”

    网络 2020-10-16
  • 滴滴押注社区团购,明确“投入不设上限,要做市场第一”

    线下 2020-10-16
  • 滴滴押注社区团购,明确“投入不设上限,要做市场第一”

    线下 2020-10-16