<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > STM32--CAN總線應運

          STM32--CAN總線應運

          作者: 時間:2016-11-28 來源:網(wǎng)絡 收藏
          CAN 總線在控制領域使用的非常廣泛,如今大多數(shù)CPU芯片外圍都擴展CAN接口。本文重點介紹以STM32F103E系列芯片為基礎介紹CAN 總線的使用方法。

          1. 硬件基礎

          CAN總線工作需要兩根數(shù)據(jù)線,RX和TX,即為輸入總線和輸出總線。一般CPU與外界通信需要接一個驅動芯片(這點很像UART接口),常用的CAN芯片主要有:SN65VHD230、PCA82C250T等,本系統(tǒng)使用SN65VHD230作為CAN接口芯片。而CPU提供的CAN接口為CAN_L和CAN_H。

          2. 軟件設計

          在進行軟件設計時,我們首先來看這樣的一個結構體:

          typedef struct
          {
          uint32_t StdId;

          uint32_t ExtId;

          uint8_t IDE;

          uint8_t RTR;

          uint8_t DLC;

          uint8_t Data[8];
          } CanTxMsg;

          這是定義一個can數(shù)據(jù)包的結構體,即一個CAN數(shù)據(jù)包包含以上幾個部分。

          現(xiàn)在我們思考一個問題:由于can可連接多個節(jié)點,如果一個系統(tǒng)為星形網(wǎng)絡連接方式,那么主機應該怎樣區(qū)別這些從機發(fā)送的信息呢?

          答案在上面那個結構體中,我們可以給每個分機定義一個ID,那么主機在接收到分機發(fā)送的數(shù)據(jù)后,通過ID號判別接收到的信息是那個從機發(fā)送的。

          注意: DLC定義發(fā)送數(shù)據(jù)的長度,其范圍為:0~8。

          下面我們來編寫CAN驅動:



          對CAN模塊初始化

          void CAN_CfgInit(void)
          {
          CAN_InitTypeDefCAN_InitStructure;
          CAN_FilterInitTypeDefCAN_FilterInitStructure;

          CAN_PortInit();
          CAN_DeInit(CAN1);
          CAN_StructInit(&CAN_InitStructure);

          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_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;
          CAN_Init(CAN1, &CAN_InitStructure);

          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_FilterFIFOAssignment=CAN_FIFO0;
          CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
          CAN_FilterInit(&CAN_FilterInitStructure);

          CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
          }

          這里為can 定義一個專門的結構體,便于數(shù)據(jù)處理:

          typedef struct CAN_Socket CAN;
          struct CAN_Socket {
          INT32U u32_StdId;
          INT32U u32_ExtId;
          INT8Uu8_IDE;
          INT8Uu8_RTR;
          INT8Uu8_DLC;
          INT8Uu8_FMI;
          INT8Uu8_data[8];
          };

          數(shù)據(jù)打包,并且發(fā)送

          void CAN_TxSocket( CAN *can_Socket )
          {
          INT8U i = 0;
          CanTxMsg TxMessage;

          CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);// CAN FIFO0 message pending interrupt enable
          // Transmit a message
          TxMessage.StdId=can_Socket->u32_StdId;
          TxMessage.ExtId=can_Socket->u32_ExtId;
          TxMessage.IDE=can_Socket->u8_IDE;
          TxMessage.RTR= can_Socket->u8_RTR;
          TxMessage.DLC=can_Socket->u8_DLC;
          for( i =0; i
          TxMessage.Data= can_Socket->u8_data;
          }
          CAN_Transmit(CAN1, &TxMessage);
          CAN_ITConfig(CAN1, CAN_IT_FMP0, DISABLE);// Disable interrupt handling
          }



          接收函數(shù)放在中斷程序中處理:



          void USB_LP_CAN1_RX0_IRQHandler(void)
          {
          CanRxMsg RxMessage;
          INT8U i = 0;
          INT8U u8_RxLen = 0;

          RxMessage.StdId = 0x00;
          RxMessage.ExtId = 0x00;
          RxMessage.IDE = 0;
          RxMessage.RTR = 0;
          RxMessage.DLC = 0;
          RxMessage.FMI = 0;
          for( i=0;i<8;i++){
          RxMessage.Data=0x00;
          }

          CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
          u8_RxLen = RxMessage.DLC;
          if((RxMessage.ExtId==0x12) && (RxMessage.IDE==CAN_ID_EXT)){
          for( i=0;i
          CAN_ReceiveBuff= RxMessage.Data;
          }
          }
          }



          這里只介紹CAN使用方法和主要驅動程序,測試程序可自行設計。

          本人的測試程序:

          ~INT8U SendBuff1[]="Hello";
          INT8U SendBuff2[]="World";
          INT8U SendBuff3[]="ADC= 255";
          void main(void)
          {
          System_HardwareInit();
          while (1)
          {
          CAN_Tx(SendBuff1);
          Disp_CanReceveData();
          CAN_Tx(SendBuff2);
          Disp_CanReceveData();
          CAN_Tx(SendBuff3);
          Disp_CanReceveData();
          }
          }



          接收數(shù)據(jù),并在液晶上打印出來!

          void Disp_CanReceveData( void )
          {
          INT8U u8_CanRecBuff[64];

          if(CAN_ReceiveBuff[0] == H){
          sprintf(( char *)u8_CanRecBuff,"CAN receve buff1 is : %s",CAN_ReceiveBuff);
          GCLDASC_PutChar16x16Str(10,30,u8_CanRecBuff, Red, Green, 1);
          }
          if(CAN_ReceiveBuff[0] == W){
          sprintf(( char *)u8_CanRecBuff,"CAN receve buff2 is : %s",CAN_ReceiveBuff);
          GCLDASC_PutChar16x16Str(10,50,u8_CanRecBuff, Red, Green, 1);
          }
          if(CAN_ReceiveBuff[0] == A){
          sprintf(( char *)u8_CanRecBuff,"CAN receve buff3 is : %s",CAN_ReceiveBuff);
          GCLDASC_PutChar16x16Str(10,70,u8_CanRecBuff, Red, Green, 1);
          }
          }


          關鍵詞: STM32CAN總

          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();