找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5225|回复: 0
打印 上一主题 下一主题
收起左侧

STM32 can总线代码 带详细注射

[复制链接]
跳转到指定楼层
楼主
ID:140343 发表于 2016-10-21 23:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1.     #include "sysdef.h"

  2.     #define MAX_MAIL_NUM  3
  3.     //CAN总线调试:0=运行 1=自环调试
  4.     #define CAN_DEBUG     0
  5.     //CAN总线波特率:0=250kbps,1=500kbps,2=1Mbps
  6.     #define CAN1_BPS      0

  7.     unsigned char can1_addr = 0;

  8.     unsigned short  Can1_Tx_Count =0;
  9.     unsigned short  Can1_Rx_Count =0;

  10.     unsigned short  Can1_Send_Delay =0;

  11.     unsigned char   Can1_Send_Buf[10]={0xeb,0x90,0x01,0x55,0xAA};
  12.     unsigned char   Can1_Recv_Buf[10]={0};
  13.     extern int  angle_num ;
  14.     extern unsigned int  angle_data ;

  15.     static  u8 CAN_msg_num[MAX_MAIL_NUM];   // 发送邮箱标记

  16.     void CAN1_Config_init(void)
  17.     {
  18.          CAN_InitTypeDef        CAN_InitStructure;
  19.          CAN_FilterInitTypeDef  CAN_FilterInitStructure;

  20.          /* CAN register init */
  21.          CAN_DeInit(CAN1);
  22.          CAN_StructInit(&CAN_InitStructure);
  23.       
  24.          /* CAN cell init */ //36MHz 500Kbps
  25.          CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式
  26.          CAN_InitStructure.CAN_ABOM=DISABLE;//软件对CAN_MCR寄存器的INRQ位进行置1随后清0后,一旦硬件检测
  27.                                             //到128次11位连续的隐性位,就退出离线状态
  28.          CAN_InitStructure.CAN_AWUM=DISABLE;//睡眠模式通过清除CAN_MCR寄存器的SLEEP位,由软件唤醒
  29.          CAN_InitStructure.CAN_NART=DISABLE;//CAN报文是否只发1次,不管发送的结果如何(成功/出错或仲裁丢失)
  30.          CAN_InitStructure.CAN_RFLM=DISABLE;//在接收到溢出时FIFO未被锁定,当接收到FIFO报文未被读出,下一个收到的报文会覆盖原有的报文
  31.          CAN_InitStructure.CAN_TXFP=DISABLE;//发送的FIFO优先级由报文的标识符来决定
  32.          
  33.     #if CAN_DEBUG
  34.          CAN_InitStructure.CAN_Mode= CAN_Mode_LoopBack;
  35.     #else
  36.          CAN_InitStructure.CAN_Mode= CAN_Mode_Normal;
  37.     #endif
  38.          //传输波特率

  39.          if(CAN1_BPS ==  0)
  40.          {
  41.             CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;//重新同步跳跃宽度1个时间单位
  42.             CAN_InitStructure.CAN_BS1=CAN_BS1_12tq;//时间段1为9个时间单位
  43.             CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;//时间段2为8个时间单位
  44.             CAN_InitStructure.CAN_Prescaler= 9;//36M/(1+12+3)/9= 250kbps
  45.                                                 //36M/(1+5+2)/9 = 500kbps
  46.                                                //36M(1+2+1)/9 = 1M
  47.          }
  48.          else if(CAN1_BPS == 1)
  49.          {
  50.             CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;//重新同步跳跃宽度1个时间单位
  51.             CAN_InitStructure.CAN_BS1=CAN_BS1_5tq;//时间段1为9个时间单位
  52.             CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;//时间段2为8个时间单位
  53.             CAN_InitStructure.CAN_Prescaler= 9;//36M/(1+12+3)/9= 250kbps
  54.             
  55.          }
  56.          else
  57.          {
  58.             CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;//重新同步跳跃宽度1个时间单位
  59.             CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;//时间段1为9个时间单位
  60.             CAN_InitStructure.CAN_BS2=CAN_BS2_1tq;//时间段2为8个时间单位
  61.             CAN_InitStructure.CAN_Prescaler= 9;//36M/(1+12+3)/9= 250kbps
  62.             
  63.          }
  64.          CAN_Init(CAN1,&CAN_InitStructure);
  65.                                              
  66.          /* CAN filter init */
  67.          CAN_FilterInitStructure.CAN_FilterNumber=0;  //指定了待初始化的过滤器0
  68.          CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定了过滤器将被初始化到的模式为标识符屏蔽位模式
  69.          CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;;//给出了过滤器位宽1个32位过滤器
  70.          CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;//用来设定过滤器标识符(32位位宽时为其高段位,16位位宽时为第一个)
  71.          CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;;//用来设定过滤器标识符(32位位宽时为其低段位,16位位宽时为第二个)
  72.          CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//用来设定过滤器屏蔽标识符或者过滤器标识符(32位位宽时为其高段位,16位位宽时为第一个)
  73.          CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;//用来设定过滤器屏蔽标识符或者过滤器标识符(32位位宽时为其低段位,16位位宽时为第二个)
  74.          CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;;//设定了指向过滤器的FIFO0
  75.          CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//使能过滤器
  76.          CAN_FilterInit(&CAN_FilterInitStructure);

  77.     }

  78.     // ***************************************************************
  79.     //       BaudRate = 1 / NominalBitTime
  80.     //       NominalBitTime = 1tq + tBS1 + tBS2
  81.     //       tq = (BRP[9:0] + 1) x tPCLK
  82.     //       tPCLK = CAN's clock = APB1's clock
  83.     //   1Mbps 速率下,采用点的位置在6tq位置处,BS1=5, BS2=2
  84.     //   500kbps 速率下,采用点的位置在8tq位置处,BS1=7, BS2=3
  85.     //   250kbps 速率下,采用点的位置在14tq位置处,BS1=13, BS2=2
  86.     //   125k, 100k, 50k, 20k, 10k 的采用点位置与 250K 相同
  87.     // ****************************************************************

  88.     void  CAN1_Com_init(void)
  89.     {
  90.           GPIO_InitTypeDef GPIO_InitStruct;
  91.           NVIC_InitTypeDef NVIC_InitStructure;
  92.          
  93.           /* Enable CAN RX0 interrupt IRQ channel */
  94.           NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
  95.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  96.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  97.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  98.           NVIC_Init(&NVIC_InitStructure);
  99.          
  100.           NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;
  101.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  102.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  103.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  104.           NVIC_Init(&NVIC_InitStructure);
  105.          
  106.           NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn;
  107.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  108.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  109.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  110.           NVIC_Init(&NVIC_InitStructure);
  111.          
  112.          
  113.           RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  114.           RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
  115.           //Can Rx
  116.           GPIO_InitStruct.GPIO_Pin  =  GPIO_Pin_11;
  117.           GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  118.           GPIO_InitStruct.GPIO_Mode =  GPIO_Mode_IPU;
  119.           GPIO_Init(GPIOA,&GPIO_InitStruct);
  120.          
  121.           //Can Tx
  122.           GPIO_InitStruct.GPIO_Pin  =  GPIO_Pin_12;
  123.           GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  124.           GPIO_InitStruct.GPIO_Mode =  GPIO_Mode_AF_PP;
  125.           GPIO_Init(GPIOA,&GPIO_InitStruct);
  126.          
  127.           CAN1_Config_init();
  128.          
  129.           CAN_ITConfig(CAN1,CAN_IT_FMP0 | CAN_IT_FF0 | CAN_IT_FOV0, ENABLE);  // fifo0中断
  130.           CAN_ITConfig(CAN1,CAN_IT_FMP1 | CAN_IT_FF1 | CAN_IT_FOV1, ENABLE);  // fifo1中断
  131.           CAN_ITConfig(CAN1,CAN_IT_TME, DISABLE);                // 发送中断
  132.           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中断

  133.           // CAN缓存初始化
  134.           memset(CAN_msg_num,0,MAX_MAIL_NUM);   
  135.     }


  136.     int CAN1_Tx_msg(CanTxMsg TxMessage)
  137.     {
  138.         u8 TransmitMailbox = 0;
  139.       
  140.         TransmitMailbox = CAN_Transmit(CAN1,&TxMessage);
  141.         if(CAN_NO_MB == TransmitMailbox)
  142.         {
  143.             //发送失败
  144.             return 0;
  145.         }
  146.         else
  147.         {         
  148.             CAN_msg_num[TransmitMailbox] = 1;
  149.          
  150.         }
  151.         CAN_ITConfig(CAN1,CAN_IT_TME, ENABLE);
  152.          
  153.         return 1;
  154.     }


  155.     u16 angle=0,angle_h=0,angle_l=0;
  156.     extern unsigned char angle_dir;
  157.     int CAN1_Tx_data(void)
  158.     {
  159.         CanTxMsg TxMessage;
  160.         u8 TransmitMailbox = 0,i=0;
  161.       
  162.         /* transmit */
  163.         TxMessage.StdId=0x6f1;//设定标准标识符
  164.         TxMessage.ExtId=0x1234;//设置扩展标识符
  165.         TxMessage.RTR=CAN_RTR_DATA;//设定待传输消息的帧类型
  166.         TxMessage.IDE=CAN_ID_STD;//设定消息标识符的类型
  167.         TxMessage.DLC=6; //数据长度
  168.          
  169.         angle=angle_data/10;
  170.         if(angle>9999) angle=9999;
  171.         angle_h=angle/100;
  172.         angle_h=angle_h/10*16+angle_h%10;
  173.         angle_l=angle%100;
  174.         angle_l=angle_l/10*16+angle_l%10;
  175.         Can1_Send_Buf[0]=angle_num;  //圈数
  176.         Can1_Send_Buf[1]=angle_h; //总角度
  177.         Can1_Send_Buf[2]=angle_l;
  178.         Can1_Send_Buf[3]=0;
  179.         Can1_Send_Buf[4]=0;
  180.         Can1_Send_Buf[5]=angle_dir;
  181.          
  182.         for(i=0;i < TxMessage.DLC;i++)
  183.         {
  184.            TxMessage.Data[i] = Can1_Send_Buf[i];
  185.         }
  186.          
  187.         TransmitMailbox = CAN_Transmit(CAN1,&TxMessage);
  188.         if(CAN_NO_MB == TransmitMailbox)
  189.         {
  190.             //发送失败,没有空邮箱
  191.             return 0;
  192.         }
  193.         else
  194.         {         
  195.             CAN_msg_num[TransmitMailbox] = 1;   
  196.         }
  197.         CAN_ITConfig(CAN1,CAN_IT_TME, ENABLE);
  198.          
  199.         Can1_Tx_Count++;
  200.         if(Can1_Tx_Count > 10000)
  201.            Can1_Tx_Count =0;
  202.          
  203.         Can1_Send_Delay =200;
  204.         return 1;
  205.     }

  206.     //解析数据
  207.     void  CAN1_Rx_Data(CanRxMsg RxMessage)
  208.     {     
  209.           u8  i =0;
  210.           if((RxMessage.StdId==0x6f1) && (RxMessage.IDE==CAN_ID_STD) && ((RxMessage.Data[1]|RxMessage.Data[0]<<8)==0xEB90))
  211.           {
  212.                
  213.               for(i=0;i < RxMessage.DLC;i++)
  214.               {
  215.                   Can1_Recv_Buf[i] =  RxMessage.Data[i];
  216.               }
  217.             
  218.               Can1_Rx_Count++;
  219.               if(Can1_Rx_Count > 10000)
  220.                  Can1_Rx_Count =0;
  221.           }
  222.     }
  223.     //发送完中断函数
  224.     void CAN1_Send(void)
  225.     {
  226.          if(CAN_msg_num[0])
  227.          {
  228.             if(CAN_GetITStatus(CAN1,CAN_IT_RQCP0))
  229.             {
  230.                 CAN_ClearITPendingBit(CAN1,CAN_IT_RQCP0);
  231.                 CAN_ITConfig(CAN1,CAN_IT_TME, DISABLE);
  232.                 CAN_msg_num[0] = 0;
  233.             }
  234.          }
  235.          if(CAN_msg_num[1])
  236.          {
  237.             if(CAN_GetITStatus(CAN1,CAN_IT_RQCP1))
  238.             {
  239.                 CAN_ClearITPendingBit(CAN1,CAN_IT_RQCP1);
  240.                 CAN_ITConfig(CAN1,CAN_IT_TME, DISABLE);
  241.                 CAN_msg_num[1] = 0;
  242.             }
  243.          }  
  244.         if(CAN_msg_num[2])
  245.         {
  246.             if(CAN_GetITStatus(CAN1,CAN_IT_RQCP2))
  247.             {
  248.                 CAN_ClearITPendingBit(CAN1,CAN_IT_RQCP2);
  249.                 CAN_ITConfig(CAN1,CAN_IT_TME, DISABLE);
  250.                 CAN_msg_num[2] = 0;
  251.             }
  252.         }
  253.     }
  254.     //接收中断函数
  255.     void CAN1_Recv(unsigned char num)
  256.     {
  257.          CanRxMsg RxMessage;
  258.          switch(num)
  259.          {
  260.          case 0:
  261.               if(CAN_GetITStatus(CAN1,CAN_IT_FF0))
  262.               {
  263.                  CAN_ClearITPendingBit(CAN1,CAN_IT_FF0);
  264.               }
  265.               else if(CAN_GetITStatus(CAN1,CAN_IT_FOV0))
  266.               {
  267.                  CAN_ClearITPendingBit(CAN1,CAN_IT_FOV0);
  268.               }
  269.               else
  270.               {
  271.                  CAN_Receive(CAN1,CAN_FIFO0, &RxMessage);
  272.                  //解析数据:
  273.                  CAN1_Rx_Data(RxMessage);
  274.               }
  275.               break;
  276.          case 1:
  277.               if(CAN_GetITStatus(CAN1,CAN_IT_FF1))
  278.               {
  279.                  CAN_ClearITPendingBit(CAN1,CAN_IT_FF1);
  280.               }
  281.               else if(CAN_GetITStatus(CAN1,CAN_IT_FOV1))
  282.               {
  283.                  CAN_ClearITPendingBit(CAN1,CAN_IT_FOV1);
  284.               }
  285.               else
  286.               {
  287.                  CAN_Receive(CAN1,CAN_FIFO1, &RxMessage);
  288.                 //解析数据
  289.                  CAN1_Rx_Data(RxMessage);
  290.               }
  291.               break;
  292.          }
  293.     }

  294.     void  CAN1_Main(unsigned char flg )
  295.     {
  296.           if(flg)
  297.           {
  298.             if(Can1_Send_Delay == 0)
  299.                CAN1_Tx_data();
  300.           }
  301.     }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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