色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > stm32 can總線通信[庫函數(shù)]

          stm32 can總線通信[庫函數(shù)]

          作者: 時間:2016-11-22 來源:網絡 收藏
          CAN是控制器局域網絡(Controller Area Network, CAN)的簡稱,是由研發(fā)和生產汽車電子產品著稱的德國BOSCH公司開發(fā)了的,并最終成為國際標準(ISO118?8)。近年來,其所具有的高可靠性和良好的錯誤檢測能力受到重視,被廣泛應用于汽車計算機控制系統(tǒng)和環(huán)境溫度惡劣、電磁輻射強和振動大的工業(yè)環(huán)境。相比于I2C和SPI總線結構,can總線定義了更為優(yōu)秀的物理層、數(shù)據鏈路層,并擁有種類豐富、繁簡不一的上層協(xié)議。
          CAN總線的物理連接只需要兩根線,通常稱為CAN_H和CAN_L,通常查分信號進行數(shù)據的傳輸。CAN總線有兩種電平,分為隱性電平和顯性電平,這兩種電平表現(xiàn)為“與”的關系。
          • 若隱性電平相遇,則總線表現(xiàn)為隱性電平。
          • 若顯性電平相遇,則總線表現(xiàn)為顯性電平。
          • 若隱性電平和顯性電平相遇,則總線表現(xiàn)為顯性電平。
          CAN總線網絡是一種多主機網絡,在總線處于空閑時,任何一個節(jié)點都可以申請成為主機,向總線發(fā)送消息,最先訪問總線的節(jié)點單元可以獲得總線的控制權。
          CAN總線的所有消息都是以固定的形式打包發(fā)送的。兩個以上的節(jié)點單元同時發(fā)送數(shù)據時,根據節(jié)點標志符決定各自優(yōu)先關系。CAN總線并沒有類似其他的總線上的地址的概念,在總線上增加節(jié)點時,連接節(jié)點的其他單元軟硬件什么都不需要改變。
          CAN總線的通信速率和總線長度有關,在總線長度小于40m的場合中,數(shù)據傳輸速率可以達到1Mbps,即便長度達到1000m,數(shù)據傳輸數(shù)率也可以達到50Kbps,無論在數(shù)率和傳輸距離上都由于常見的RS232、RS485和I2C總線。
          CAN總線在理論上節(jié)點數(shù)沒有上限,但是實際中受到總線上的時間延時和電氣負載的限制。降低節(jié)點數(shù)可以增大通信速率。
          Stm32 至少配備一個CAN總線控制器,最高速率可以達到1Mbps,支持11位的標準幀格式和29為的拓展幀格式的接收和發(fā)送,具備三個郵箱和2個接收FIFO,此外還有3級可編程濾波器。
          本例主要實現(xiàn)使用stm32的CAN總線實現(xiàn)數(shù)據的發(fā)送和接收,使用串口觀察數(shù)據。

          本文引用地址:http://cafeforensic.com/article/201611/319914.htm
          庫函數(shù)操作
          CAN 通信 過濾器 和 屏蔽器 :
          例如設置某接收濾波寄存器00000000001(11位),接收屏蔽寄存器11111111101(11位),則該對組合會拒絕接收00000000011和00000000001之外所有的標識符對應的CAN幀,因為屏蔽器規(guī)定第二位(為0)以外的所有標識符位要嚴格匹配(與濾波器值一致),第二位的濾波器值和收到的CAN標識符第二位值是否一致都可以.
          main.c
          view source
          print?
          001#include "stm32f10x.h"
          002#include "stdio.h"
          003
          004#define PRINTF_ON 1
          005
          006void RCC_Configuration(void);
          007void GPIO_Configuration(void);
          008void USART_Configuration(void);
          009void CAN_Configuration(void);
          010void NVIC_Configuration(void);
          011
          012u8 TransmitMailbox = 0;
          013CanTxMsg TxMessage;
          014CanRxMsg RxMessage;
          015
          016int main(void)
          017{
          018RCC_Configuration();
          019GPIO_Configuration();
          020USART_Configuration();
          021CAN_Configuration();
          022
          023
          024TxMessage.ExtId = 0x00AA0000;
          025TxMessage.RTR = CAN_RTR_DATA;
          026TxMessage.IDE = CAN_ID_EXT;
          027TxMessage.DLC = 8;
          028TxMessage.Data[0] = 0x00;
          029TxMessage.Data[1] = 0x12;
          030TxMessage.Data[2] = 0x34;
          031TxMessage.Data[3] = 0x56;
          032TxMessage.Data[4] = 0x78;
          033TxMessage.Data[5] = 0xAB;
          034TxMessage.Data[6] = 0xCD;
          035TxMessage.Data[7] = 0xEF;
          036
          037TransmitMailbox = CAN_Transmit(CAN1,&TxMessage);
          038while(CAN_TransmitStatus(CAN1,TransmitMailbox) != CANTXOK);
          039printf("rn The CAN has send data: %d ,%d,%d ,%d,%d ,%d,%d ,%d rn",
          040TxMessage.Data[0],
          041TxMessage.Data[1],
          042TxMessage.Data[2],
          043TxMessage.Data[3],
          044TxMessage.Data[4],
          045TxMessage.Data[5],
          046TxMessage.Data[6],
          047TxMessage.Data[7]
          048);
          049
          050while(CAN_MessagePending(CAN1,CAN_FIFO0) == 0);
          051
          052//RxMessage.StdId = 0x00;
          053RxMessage.IDE = CAN_ID_EXT;
          054RxMessage.DLC = 0;
          055RxMessage.Data[0] = 0x00;
          056RxMessage.Data[1] = 0x00;
          057RxMessage.Data[2] = 0x00;
          058RxMessage.Data[3] = 0x00;
          059RxMessage.Data[4] = 0x00;
          060RxMessage.Data[5] = 0x00;
          061RxMessage.Data[6] = 0x00;
          062RxMessage.Data[7] = 0x00;
          063
          064CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);
          065printf("rn The CAN has receive data : %d,%d,%d,%d,%d,%d,%d,%d rn",
          066RxMessage.Data[0],
          067RxMessage.Data[1],
          068RxMessage.Data[2],
          069RxMessage.Data[3],
          070RxMessage.Data[4],
          071RxMessage.Data[5],
          072RxMessage.Data[6],
          073RxMessage.Data[7]
          074);
          075
          076while(1);
          077}
          078
          079void CAN_Configuration(void)
          080{
          081CAN_InitTypeDef CAN_InitStructure;
          082CAN_FilterInitTypeDef CAN_FilterInitStructure;
          083
          084CAN_DeInit(CAN1);
          085CAN_StructInit(&CAN_InitStructure);
          086
          087CAN_InitStructure.CAN_TTCM = DISABLE;
          088CAN_InitStructure.CAN_ABOM = DISABLE;
          089CAN_InitStructure.CAN_AWUM = DISABLE;
          090CAN_InitStructure.CAN_NART = DISABLE;
          091CAN_InitStructure.CAN_RFLM = DISABLE;
          092CAN_InitStructure.CAN_TXFP = DISABLE;
          093CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;
          094CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
          095CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq;
          096CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq;
          097CAN_Init(CAN1,&CAN_InitStructure);
          098
          099CAN_FilterInitStructure.CAN_FilterNumber = 0;
          100CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
          101CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
          102CAN_FilterInitStructure.CAN_FilterIdHigh = 0x00AA << 3; //匹配過濾寄存器,因為數(shù)據標志符段 還有 IDE ,RTR 和一個補零位 所以左移三位
          103CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
          104CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x00FF << 3 ; //匹配屏蔽寄存器
          105CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
          106CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
          107
          108CAN_FilterInit(&CAN_FilterInitStructure);
          109
          110
          111}
          112
          113
          114void GPIO_Configuration(void)
          115{
          116GPIO_InitTypeDef GPIO_InitStructure;
          117
          118GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          119
          120GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
          121GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
          122GPIO_Init(GPIOB , &GPIO_InitStructure);
          123
          124GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
          125GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
          126GPIO_Init(GPIOB , &GPIO_InitStructure);
          127
          128
          129GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
          130GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
          131GPIO_Init(GPIOA , &GPIO_InitStructure);
          132
          133GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
          134GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
          135GPIO_Init(GPIOA , &GPIO_InitStructure);
          136}
          137
          138void RCC_Configuration(void)
          139{
          140
          141ErrorStatus HSEStartUpStatus;
          142
          143
          144RCC_DeInit();
          145
          146RCC_HSEConfig(RCC_HSE_ON);
          147
          148HSEStartUpStatus = RCC_WaitForHSEStartUp();
          149
          150if(HSEStartUpStatus == SUCCESS)
          151{
          152
          153RCC_HCLKConfig(RCC_SYSCLK_Div1);
          154
          155RCC_PCLK2Config(RCC_HCLK_Div1);
          156
          157RCC_PCLK1Config(RCC_HCLK_Div2);
          158
          159FLASH_SetLatency(FLASH_Latency_2);
          160
          161FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
          162
          163RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
          164
          165RCC_PLLCmd(ENABLE);
          166
          167while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
          168
          169RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
          170
          171while(RCC_GetSYSCLKSource() != 0x08);
          172}
          173
          174RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);
          175
          176//RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
          177
          178RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);
          179//RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP|RCC_APB1Periph_WWDG|RCC_APB1Periph_SPI2|RCC_APB1Periph_I2C1|RCC_APB1Periph_I2C2, ENABLE);
          180
          181}
          182
          183
          184void USART_Configuration(void)
          185{
          186USART_InitTypeDef USART_InitStructure;
          187USART_ClockInitTypeDef USART_ClockInitStructure;
          188
          189USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
          190USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
          191USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
          192USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
          193USART_ClockInit(USART1 , &USART_ClockInitStructure);
          194
          195USART_InitStructure.USART_BaudRate = 9600;
          196USART_InitStructure.USART_WordLength = USART_WordLength_8b;
          197USART_InitStructure.USART_StopBits = USART_StopBits_1;
          198USART_InitStructure.USART_Parity = USART_Parity_No;
          199USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
          200USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
          201USART_Init(USART1,&USART_InitStructure);
          202
          203USART_Cmd(USART1,ENABLE);
          204}
          205
          206#if PRINTF_ON
          207
          208int fputc(int ch,FILE *f)
          209{
          210USART_SendData(USART1,(u8) ch);
          211while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
          212return ch;
          213}
          214
          215#endif



          評論


          技術專區(qū)

          關閉