CanFestival移植到STM32F103
1.創建工程
?
?
2.將CanFestival源碼,拷貝到工程目錄
?
?
3.刪除其它架構和編譯器的代碼
查看include文件夾發現沒有cortex-m3架構,因此我們這里借鑒AVR架構進行修改
將AVR文件夾重命名為STM32,并刪除其它架構文件夾
打開STM32文件夾,將里面avr相關的文件刪除,我們用的開發環境是MDK,因此將iar相關文件也刪了
打開src文件夾,將其它架構、編譯器和系統的文件給刪了
?
?
4.將CanFestival文件添加進工程
添加好之后,編譯出現錯誤,config文件中包含了很多iar相關頭文件
將這些頭文件刪除
重新編譯,依然存在錯誤,提示有很多函數沒有定義
先解決start_and_seek_node和start_node的問題,打開def.c文件發現這兩個函數定義了
其實,這是MDK開發環境的問題,不要太糾結這個問題,把inline刪掉就好了
然后重新編譯,還剩下三個錯誤canSend、getElapsedTime和setTimer沒有定義。這三個接口是需要用戶移植程序的時候自己進行添加的。
?
?
5.添加接口
分別創建rcc.h、rcc.c、nvic.h、nvic.c、CANOpen_can.h、CANOpen_can.c、CANOpen_timeBase.h、CANOpen_timeBase.c文件
/************************************** 文件名: nvic.h* 作者: stone* 版本: V0.1* 日期: 2018-3-29* 描述: 設置中斷控制器************************************/ #ifndef __NVIC_H_ #define __NVIC_H_/* 功能: 中斷嵌套控制器配置參數: 無返回值:無*/ void nvic_config(void);#endif /************************************** 文件名: nvic.c* 作者: stone* 版本: V0.1* 日期: 2018-3-29* 描述: 設置中斷控制器************************************/ #include "stm32f10x.h" #include "nvic.h"/* 功能: 中斷嵌套控制器配置參數: 無返回值:無*/ void nvic_config(void) {/* 選擇中斷分組4 */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); } /************************************** 文件名:rcc.h* 作者: stone* 版本: V0.1* 日期: 2018-3-29* 描述: 配置時鐘源************************************/ #ifndef __RCC_H_ #define __RCC_H_/* 功能: RCC時鐘配置參數: 無返回值:無*/ void rcc_config(void);#endif /************************************** 文件名: rcc.c* 作者: stone* 版本: V0.1* 日期: 2018-3-29* 描述: 配置時鐘源************************************/ #include "stm32f10x.h" #include "stm32f10x_flash.h" #include "rcc.h"/* 功能: RCC時鐘配置參數: 無返回值:無*/ void rcc_config(void) { ErrorStatus HSEStartUpStatus;/* RCC寄存器設置為默認配置 */RCC_DeInit();/* 打開外部高速時鐘 */RCC_HSEConfig(RCC_HSE_ON);/* 等待外部高速時鐘穩定 */HSEStartUpStatus = RCC_WaitForHSEStartUp();if(HSEStartUpStatus == SUCCESS) { /* 設置HCLK = SYSCLK */RCC_HCLKConfig(RCC_SYSCLK_Div1);/* 設置PCLK2 = HCLK */RCC_PCLK2Config(RCC_HCLK_Div1);/* 設置PCLK1 = HCLK / 2 */RCC_PCLK1Config(RCC_HCLK_Div2);/* 設置FLASH代碼延時 */FLASH_SetLatency(FLASH_Latency_2);/* 使能預取址緩存 */FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);/* 設置PLL時鐘源為HSE倍頻9 72MHz */RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);/* 使能PLL */RCC_PLLCmd(ENABLE);/* 等待PLL穩定 */while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);/* 設置PLL為系統時鐘源 */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/* 等待系統時鐘源切換到PLL */while(RCC_GetSYSCLKSource() != 0x08);/* 設置系統節拍器時鐘源為FCLK */SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);} } /************************************** 文件名: CANOpen_timeBase.h* 作者: stone* 版本: V0.1* 日期: 2018-3-29* 描述: CANOPEN底層定時器接口文件************************************/ #ifndef __CANOPEN_TIMEBASE_H_ #define __CANOPEN_TIMEBASE_H_/* 功能: canopen時基配置參數: 無返回值:無*/ void canopen_timebase_config(void);#endif /************************************** 文件名: CANOpen_timeBase.c* 作者: stone* 版本: V0.1* 日期: 2018-3-29* 描述: CANOPEN底層定時器接口文件************************************/ #include "stm32f10x.h" #include "canfestival.h" #include "CANOpen_timeBase.h"/* 功能: 定時器配置參數: 無返回值:無*/ static void timer_config(void) {TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;/* 允許TIM2的時鐘 */RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);/* 將定時器2寄存器設為初始值 */TIM_DeInit(TIM2);/* 設置定時器2由內部時鐘 */TIM_InternalClockConfig(TIM2);/* 預分頻值 */TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;/* 時鐘分割 */TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;/* 向上計數 */TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;/* 自動重載值 */TIM_TimeBaseStructure.TIM_Period = 50000 - 1;/* 初始化定時器2 */TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);/* 清除溢出中斷標志 */TIM_ClearFlag(TIM2, TIM_FLAG_Update);/* 禁止ARR預裝載緩沖器 */TIM_ARRPreloadConfig(TIM2, DISABLE);/* 開啟TIM2的中斷 */TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);/* 開啟定時器2 */TIM_Cmd(TIM2, ENABLE); }/* 功能: 中斷配置參數: 無返回值:無*/ static void nvic_config(void) {NVIC_InitTypeDef NVIC_InitStructure;/* 選擇TIM2的中斷通道 */NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;/* 搶占式中斷優先級設置為2 */NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;/* 響應式中斷優先級設置為2 */NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;/* 使能中斷 */NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;/* 中斷初始化 */NVIC_Init(&NVIC_InitStructure); }/* 功能: canopen時基配置參數: 無返回值:無*/ void canopen_timebase_config(void) {/* 定時器配置 */timer_config();/* 中斷配置 */nvic_config(); }/* 功能: 設置定時器觸發時間參數: 定時器觸發時間返回值:無 */ void setTimer(TIMEVAL value) {TIM2->ARR = TIM2->CNT + value; }/* 功能: 獲取上次觸發到現在的流逝時間參數: 無返回值:獲取計數器值*/ TIMEVAL getElapsedTime(void) {return TIM2->CNT; }/* 定時器2中斷向量 */ void TIM2_IRQHandler(void) {/* 定時器2溢出標志位 */if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET){/* 定時器2清除溢出標志位 */TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);TimeDispatch();} } /************************************** 文件名: CANOpen_can.h* 作者: stone* 版本: V0.1* 日期: 2018-3-29* 描述: CANOPEN協議底層總線接口************************************/ #ifndef __CANOPEN_CAN_H_ #define __CANOPEN_CAN_H_/* 功能: can總線配置參數: 無返回值:無*/ void CANOpen_can_config(void);#endif /************************************** 文件名: CANOpen_can.c* 作者: stone* 版本: V0.1* 日期: 2018-3-29* 描述: CANOPEN協議底層總線接口************************************/ #include "stm32f10x.h" #include "CANOpen_can.h" #include "canfestival.h"/* CANOPEN字典 */ extern CO_Data masterObjdict_Data;/* 功能: GPIO配置參數: 無返回值:無*/ static void gpio_config(void) {GPIO_InitTypeDef GPIO_InitStructure;/* 開啟GPIO時鐘 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);/* CAN_RX */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(GPIOA, &GPIO_InitStructure);/* CAN_TX */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOA, &GPIO_InitStructure); }/* 功能: 中斷嵌套控制器配置參數: 無返回值:無*/ static void nvic_config(void) {NVIC_InitTypeDef NVIC_InitStructure;/* 設置CAN接收中斷,先占優先級2,從站優先級2 */NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;/* 初始化中斷 */NVIC_Init(&NVIC_InitStructure); }/* 功能: CAN總線過濾器配置參數: 無返回值:無*/ static void can_filter_config(void) {CAN_FilterInitTypeDef CAN_FilterInitStructure;/* 配置過濾器0組,配置成標準標識符且低7位都為0時接受 */CAN_FilterInitStructure.CAN_FilterNumber = 0; /* 設置過濾器組0 */CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; /* 屏蔽模式 */CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; /* 32位模式 */CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; /* 在CANOpen中標準標識符的低7位表示節點ID */CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0004; /* 在CANOpen中只用標準標識符,數據幀/遠程幀都有 */CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; /* 主節點ID為0 */CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; /* 標準幀 */CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; /* 過濾器關聯到FIFO0 */CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; /* 使能過濾器 */CAN_FilterInit(&CAN_FilterInitStructure); }/* 功能: can總線配置參數: 無返回值:無*/ void CANOpen_can_config(void) {CAN_InitTypeDef CAN_InitStructure;/* 配置IO */gpio_config();/* 中斷嵌套控制器配置 */nvic_config();/* 配置CAN總線時鐘 */RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);/* CAN1默認參數 */CAN_DeInit(CAN1);/* 將結構體填入默認參數 */CAN_StructInit(&CAN_InitStructure);/* 關閉時間觸發模式 */CAN_InitStructure.CAN_TTCM = DISABLE;/* 關閉自動離線管理 */CAN_InitStructure.CAN_ABOM = ENABLE;/* 關閉自動喚醒 */CAN_InitStructure.CAN_AWUM = ENABLE;/* 自動重傳 */CAN_InitStructure.CAN_NART = DISABLE;/* 禁止FIFO溢出時覆蓋原報文 */CAN_InitStructure.CAN_RFLM = DISABLE;/* 關閉優先級取決于ID */CAN_InitStructure.CAN_TXFP = DISABLE;/* 正常模式 */CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;/* 設置波特率:36MHz/9/(2+1+1)=1mbps */CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;CAN_InitStructure.CAN_BS1 = CAN_BS1_2tq;CAN_InitStructure.CAN_BS2 = CAN_BS2_1tq;CAN_InitStructure.CAN_Prescaler = 9;/* 初始化CAN總線 */CAN_Init(CAN1, &CAN_InitStructure);/* CAN總線過濾器配置 */can_filter_config();/* 接收掛起中斷 */CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); }/* can總線接收中斷回調函數 */ void USB_LP_CAN1_RX0_IRQHandler(void) {CanRxMsg message;Message Rx_Message;/* 接收消息 */CAN_Receive(CAN1, CAN_FIFO0, &message);/* 組裝canopen數據包 */Rx_Message.cob_id = message.StdId; /* 功能碼和節點ID */Rx_Message.rtr = (message.RTR == CAN_RTR_DATA) ? 0 : 1; /* 標識符類型 */Rx_Message.len = message.DLC; /* 數據包長度 */memcpy(Rx_Message.data, message.Data, message.DLC); /* 數據 *//* canopen數據包分配處理函數 */canDispatch(&masterObjdict_Data, &Rx_Message); }/* 功能: CAN發送數據函數參數: notused can總線端口message canopen數據包返回值: 0 成功1 失敗*/ uint8_t canSend(CAN_PORT notused, Message *message) {uint32_t i = 0xFFFFFF;CanTxMsg TxMessage;uint8_t TransmitMailbox = 0;/* 組裝CAN數據包 */TxMessage.DLC = message->len; /* 數據長度 */memcpy(TxMessage.Data, message->data, message->len); /* 數據 */TxMessage.IDE = CAN_ID_STD; /* 標準ID */TxMessage.StdId = message->cob_id; /* 標識符 */TxMessage.RTR = (message->rtr == CAN_RTR_DATA) ? 0 : 2; /* 數據幀 *//* 發送數據包 */TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);/* 等待發送成功 */while((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK) && --i);/* 成功0 超時1 */return (i != 0) ? 0 : 1; } /************************************** 文件名: main.c* 作者: stone* 版本: V0.1* 日期: 2018-3-29* 描述: 主文件************************************/ #include "stm32f10x.h" #include "rcc.h" #include "nvic.h" #include "CANOpen_timeBase.h" #include "CANOpen_can.h"/* 主函數 */ int main(void) {/* 時鐘配置 */rcc_config();/* 中斷嵌套控制器配置 */nvic_config(); /* canopen時基配置 */canopen_timebase_config();/* can總線配置 */CANOpen_can_config();while(1){} }添加好之后,重新編譯,提示沒有定義CANOpen字典
?
?
6.創建CANOpen字典
打開objdictedit,創建字典
分別得到masterObjdict.h和masterObjdict.c文件
?
?
7.將字典文件添加進工程
重新編譯,0錯誤,0警告
?
8.修改配置
按照CANOpen_timeBase.c的配置,定時器單位計數為1us。打開timerscfg.h。
AVR的例程定時器的單位計數時間為8us,我們這里做一個修改。
?
9.協議棧移植工作完成。下面要考慮的就是字典配置和協議棧使用的問題了。
總結
以上是生活随笔為你收集整理的CanFestival移植到STM32F103的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 功率驱动电路中元件的选择
- 下一篇: uboot主Makefile分析