新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > stm32 can總線通信[庫函數]

        stm32 can總線通信[庫函數]

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

        本文引用地址:http://www.104case.com/article/201611/319914.htm
        庫函數操作
        CAN 通信 過濾器 和 屏蔽器 :
        例如設置某接收濾波寄存器00000000001(11位),接收屏蔽寄存器11111111101(11位),則該對組合會拒絕接收00000000011和00000000001之外所有的標識符對應的CAN幀,因為屏蔽器規定第二位(為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; //匹配過濾寄存器,因為數據標志符段 還有 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



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 清徐县| 涡阳县| 库车县| 丹棱县| 舒兰市| 清水县| 丰都县| 苍山县| 鄂托克旗| 东丽区| 富阳市| 托里县| 鄂尔多斯市| 剑川县| 堆龙德庆县| 从化市| 清新县| 治多县| 响水县| 太谷县| 大庆市| 虎林市| 瓦房店市| 黑山县| 新竹县| 高碑店市| 环江| 海阳市| 潜山县| 绥棱县| 保定市| 抚州市| 久治县| 武穴市| 固安县| 县级市| 浙江省| 五指山市| 彰化市| 调兵山市| 渝中区|