新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32F10x 學習筆記 1 (使用STM32F10x StdPeriph Driver)

        STM32F10x 學習筆記 1 (使用STM32F10x StdPeriph Driver)

        作者: 時間:2016-11-20 來源:網絡 收藏
        前段時間將Cortex-M3權威指南看完了,現在開始拿塊開發板練手。

        本文引用地址:http://www.104case.com/article/201611/318836.htm

        STM32F1xx本身并不難,不過因為第一次用KeilMDK,還有想在程序中使用最新的stm32f10x_stdperiph_libV3.5,最后讓程序跑通也經歷了一番周折。這里簡單的記錄一下,希望對剛剛開始學STM32的初學者有些幫助。(這篇的內容很初級,高手請繞道)

        首先介紹一下我這里的實驗環境,開發板是塊便宜貨“神舟IV號STM32F107VCT開發板”,聽這個名字就挺山寨,不過便宜倒是真的。仿真器是國內山寨的J-LinkV8,買開發板時送的。J-Link用的是V4.12版的驅動程序,segger網站上有新版的驅動,不過我試過了,新版的驅動添加了檢測J-Link是否是山寨的功能,裝上也不能用,在網上也沒有找到解決辦法,所以還是死心吧,4.12版的驅動也能支持挺多的ARM芯片型號了。

        IDE環境是KeiluVersionV4.10,工具鏈的版本為:RealViewMDK-ARM4.12,當然是D版的。

        總之,這一套從頭到腳都挺山寨。不過我這是非商業用途,僅供個人學習,想來ARM和segger也不會來難為我。

        不說廢話了。首先講一講如何在程序中使用STM32F10x_StdPeriph_Driver

        (1)新建一個文件夾存放項目文件,要注意路徑不能有中文,我這里目錄名取為stm32-test1。

        (2)打開KeiluVersion,新建一個項目“test.uvproj”,CPU選擇STM32F107VC。

        (3)KeiluVersion會提示是否添加啟動代碼,選擇否,因為我們要用STM32F10x_StdPeriph_Driver中提供的啟動代碼。

        (4)給ProjectTargets改名,我改的名為:STM32F107。這一步不是必須的,只是默認的名稱“Target1”太沒個性了。

        (5)Groups中我建立了三個組:Source、CMSIS、StdPeriphDriver。Source中存放我寫的代碼,另外兩個顧名思義存放相應的代碼。

        (6)stm32-test1目錄中也添加相應的三個文件夾:Source、CMSIS、StdPeriphDriver。這時stm32-test1目錄中應該有這些文件(文件夾):

        CMSIS

        Source

        StdPeriphDriver

        test.plg

        test.uvopt

        test.uvproj

        test_STM32F107.dep

        test_Target1.dep

        (7)網上下載的STM32F10x_StdPeriph_Lib_V3.5.0,解壓縮后“STM32F10x_StdPeriph_Lib_V3.5.0LibrariesCMSISCM3CoreSupport”和“STM32F10x_StdPeriph_Lib_V3.5.0LibrariesCMSISCM3DeviceSupportSTSTM32F10x”目錄中的c文件和h文件都拷貝到CMSIS目錄中。“STM32F10x_StdPeriph_Lib_V3.5.0LibrariesCMSISCM3DeviceSupportSTSTM32F10xstartuparm”目錄中“startup_stm32f10x_cl.s”也拷貝到CMSIS目錄中。這里多說一句,startup_stm32f10x_cl.s是STM32F105和STM32F107系列的啟動文件,cl指的是Connectivityline。如果用的是其他類型的STM32,需要換用合適的啟動文件。

        (8)“STM32F10x_StdPeriph_Lib_V3.5.0LibrariesSTM32F10x_StdPeriph_Driverinc”和“STM32F10x_StdPeriph_Lib_V3.5.0LibrariesSTM32F10x_StdPeriph_Driversrc”文件中的內容都拷貝到StdPeriphDriver目錄中。“STM32F10x_StdPeriph_Lib_V3.5.0ProjectSTM32F10x_StdPeriph_Templatestm32f10x_conf.h”拷貝到StdPeriphDriver目錄中。讀者可能注意到我將c文件和頭文件都混到了一個文件夾中了,之所以這樣管理文件,是為了讓項目的目錄結構看起來盡量的簡單。現在,CMSIS下的文件應該有這些:

        core_cm3.c

        core_cm3.h

        startup_stm32f10x_cl.s

        stm32f10x.h

        system_stm32f10x.c

        system_stm32f10x.h

        StdPeriphDriver目錄中文件應該有這些:

        misc.h

        stm32f10x_adc.c

        stm32f10x_adc.h

        stm32f10x_bkp.c

        stm32f10x_bkp.h

        stm32f10x_can.c

        stm32f10x_can.h

        stm32f10x_cec.c

        stm32f10x_cec.h

        stm32f10x_crc.c

        stm32f10x_crc.h

        stm32f10x_dac.c

        stm32f10x_dac.h

        stm32f10x_dbgmcu.c

        stm32f10x_dbgmcu.h

        stm32f10x_dma.c

        stm32f10x_dma.h

        stm32f10x_exti.c

        stm32f10x_exti.h

        stm32f10x_flash.c

        stm32f10x_flash.h

        stm32f10x_fsmc.c

        stm32f10x_fsmc.h

        stm32f10x_gpio.c

        stm32f10x_gpio.h

        stm32f10x_i2c.c

        stm32f10x_i2c.h

        stm32f10x_iwdg.c

        stm32f10x_iwdg.h

        stm32f10x_pwr.c

        stm32f10x_pwr.h

        stm32f10x_rcc.c

        stm32f10x_rcc.h

        stm32f10x_rtc.c

        stm32f10x_rtc.h

        stm32f10x_sdio.c

        stm32f10x_sdio.h

        stm32f10x_spi.c

        stm32f10x_spi.h

        stm32f10x_tim.c

        stm32f10x_tim.h

        stm32f10x_usart.c

        stm32f10x_usart.h

        stm32f10x_wwdg.c

        stm32f10x_wwdg.h

        stm32f10x_conf.h

        對于某個具體的項目,這些文件不一定都會用到,不過放在這里也沒什么壞處。

        (9)將.CMSIS;.StdPeriphDriver這兩個目錄加入到頭文件的搜索目錄中。

        (10)將startup_stm32f10x_cl.s添加到組CMSIS中,新建個main.c文件,加入到組Source中。

        (11)修改“stm32f10x.h”文件。在文件中找到這一段:

        1. #if!defined(STM32F10X_LD)&&!defined(STM32F10X_LD_VL)&&!defined(STM32F10X_MD)&&!defined(STM32F10X_MD_VL)&&!defined(STM32F10X_HD)&&!defined(STM32F10X_XL)&&!defined(STM32F10X_CL)
        2. /*#defineSTM32F10X_LD*//*!
        3. /*#defineSTM32F10X_LD_VL*//*!
        4. /*#defineSTM32F10X_MD*//*!
        5. /*#defineSTM32F10X_MD_VL*//*!
        6. /*#defineSTM32F10X_HD_VL*//*!
        7. /*#defineSTM32F10X_HD*//*!
        8. /*#defineSTM32F10X_XL*//*!
        9. /*#defineSTM32F10X_CL*//*!
        10. #endif

        將對“#defineSTM32F10X_CL”的注釋去掉。

        找到“#defineUSE_PERIPH_LIBRARY”將注釋去掉。

        (12)將“system_stm32f10x.c”加入到組“CMSIS”中,找到如下代碼:


        1. #ifdefined(STM32F10X_LD_VL)||(definedSTM32F10X_MD_VL)||(definedSTM32F10X_HD_VL)
        2. /*#defineSYSCLK_FREQ_HSEHSE_Value*/
        3. #defineSYSCLK_FREQ_24MHz24000000
        4. #else
        5. /*#defineSYSCLK_FREQ_HSEHSE_Value*/
        6. /*#defineSYSCLK_FREQ_24MHz24000000*/
        7. /*#defineSYSCLK_FREQ_36MHz36000000*/
        8. /*#defineSYSCLK_FREQ_48MHz48000000*/
        9. /*#defineSYSCLK_FREQ_56MHz56000000*/
        10. #defineSYSCLK_FREQ_72MHz72000000
        11. #endif

        根據板子上的使用的時鐘系統來確定SYSCLK的頻率。

        至此,該設置的都設置的差不多了,可以開始寫應用代碼了。我這里以閃燈程序為例吧。我的開發板上有四個LED,分別對應的GPIO端口D的PD2、PD3、PD4和PD7。

        下面先給一個不利用STM32F10x_StdPeriph_Driver中庫函數,只利用STM32F10x_StdPeriph_Driver中給出的外設寄存器的定義。下面是main.c的代碼。

        1. #include"stm32f10x.h"
        2. voiddelay(void)
        3. {
        4. uint32_ti;
        5. for(i=0;i<3000000L;i++)
        6. {
        7. }
        8. }
        9. intmain(void)
        10. {
        11. RCC->APB2ENR|=0x00000020;
        12. GPIOD->CRL=0x24422244;//PD2PD3PD4PD7SettoOutputmode
        13. for(;;)
        14. {
        15. GPIOD->ODR=0x00000000;
        16. delay();
        17. GPIOD->ODR=0x0000009C;
        18. delay();
        19. }
        20. }


        下面再給個利用TM32F10x_StdPeriph_Driver中庫函數的代碼。

        1. #include"stm32f10x.h"
        2. #defineRCC_GPIO_LEDRCC_APB2Periph_GPIOD
        3. #defineGPIO_LED_PORTGPIOD
        4. #defineGPIO_LED1GPIO_Pin_2
        5. #defineGPIO_LED2GPIO_Pin_3
        6. #defineGPIO_LED3GPIO_Pin_4
        7. #defineGPIO_LED4GPIO_Pin_7
        8. #defineGPIO_LED_ALLGPIO_LED1|GPIO_LED2|GPIO_LED3|GPIO_LED4
        9. voiddelay(void)
        10. {
        11. uint32_ti;
        12. for(i=0;i<3000000L;i++)
        13. {
        14. }
        15. }
        16. intmain(void)
        17. {
        18. GPIO_InitTypeDefGPIO_InitStructure;
        19. SystemInit();
        20. /*EnableGPIOB,GPIOCandAFIOclock*/
        21. RCC_APB2PeriphClockCmd(RCC_GPIO_LED|RCC_APB2Periph_AFIO,ENABLE);
        22. /*LEDspinsconfiguration*/
        23. GPIO_InitStructure.GPIO_Pin=GPIO_LED_ALL;
        24. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        25. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
        26. GPIO_Init(GPIO_LED_PORT,&GPIO_InitStructure);
        27. for(;;)
        28. {
        29. GPIO_SetBits(GPIO_LED_PORT,GPIO_LED_ALL);
        30. delay();
        31. GPIO_ResetBits(GPIO_LED_PORT,GPIO_LED_ALL);
        32. delay();
        33. }
        34. }

        編譯程序,在鏈接階段報錯了,錯誤信息如下:

        1. BuildtargetSTM32F107
        2. linking...
        3. test.axf:Error:L6218E:UndefinedsymbolGPIO_Init(referredfrommain.o).
        4. test.axf:Error:L6218E:UndefinedsymbolGPIO_ResetBits(referredfrommain.o).
        5. test.axf:Error:L6218E:UndefinedsymbolGPIO_SetBits(referredfrommain.o).
        6. test.axf:Error:L6218E:UndefinedsymbolRCC_APB2PeriphClockCmd(referredfrommain.o).
        7. test.axf:Notenoughinformationtolistimagesymbols.
        8. test.axf:Finished:1information,0warningand4errormessages.
        9. Targetnotcreated


        說的很明白,GPIO_Init、GPIO_ResetBits、GPIO_SetBits、RCC_APB2PeriphClockCmd這幾個函數的實現沒有找到。解決的辦法顯而易見,將“stm32f10x_gpio.c”和“stm32f10x_rcc.c”兩個文件加入到組“StdPeriphDriver”中,再編譯就通過了。將程序下載到板子上,一切正常。

        上面只說了個大概的流程,還有些如何設置J-Link一類的都略去了,因為介紹這些的文章實在是太多了。




        評論


        技術專區

        關閉
        主站蜘蛛池模板: 大厂| 汉寿县| 鄂伦春自治旗| 灯塔市| 澄迈县| 渑池县| 杭锦后旗| 监利县| 楚雄市| 历史| 循化| 神池县| 连城县| 龙口市| 祁阳县| 天全县| 遂宁市| 尼玛县| 罗平县| 南华县| 虞城县| 永修县| 河间市| 贵溪市| 门源| 桃源县| 南皮县| 来宾市| 林口县| 康定县| 鸡泽县| 金溪县| 普安县| 霍林郭勒市| 屯昌县| 石渠县| 甘洛县| 谢通门县| 交口县| 萍乡市| 呼玛县|