您好,歡迎進入深圳市穎特新科技有限公司官方網(wǎng)站!
很多學(xué)習(xí)stm32的,為什么學(xué)習(xí)stm32他也不知道,我們所知道的就是各個論壇討論stm32的很多,而我們很多人之所以學(xué)習(xí)stm32是很多的淘寶賣家做了大量的圖片文字宣傳,于是我們經(jīng)不住誘惑就買了板子,然后我們就開始了我們的學(xué)習(xí)之旅。
在淘寶賣家的眼里有著齊全的入門資料是板子的最大的賣點,于是當(dāng)我們拿到開發(fā)板的時候,我們感覺我們永遠不能和別人說自己熟悉stm32,因為脫離了網(wǎng)絡(luò)的資料我們什么都做不了,這是我們最害怕的事情。
今天我就就像在這里記錄下自己一無所有建立stm32工程的過程,是我自己的一個探索過程,同時也是大家互相交流的過程。
第一步:當(dāng)然是新建一個工程我把它命名為small(這個隨便你,青菜蘿卜各有所愛……)
第二部:就是選擇芯片的型號了,這個按照每個人手上的板子的不同就選擇不同的芯片型號。
選擇完了之后按確認(rèn),然后會出來一個對話框,是問你要不要添加啟動文件的,這個簡單我們都是白手起家了,別人好不容易送你點東西我們當(dāng)然照單全收,直接點是。」。。。。。
點完是后我們的工程就是差不多建立好了,大家可以看到里面就一個代碼文件,是以.s結(jié)尾的,是一個啟動文件里面的代碼全是匯編的,看了有點暈死。。。。,以后再說吧這個。。。。
要不我們編譯了看看結(jié)果?
一串鳥文的錯誤,看不怎么懂,但是好像是說什么沒有main函數(shù)。想想也是啊,自己確實沒寫main函數(shù),要不我們自己建立一個.c文件,然后寫一個main函數(shù)?說做就做。。。。。
直接點擊file下面的新建圖標(biāo),然后寫一個名字保存,注意別忘保存好之后在工程里面“add files to group”,然后我們再自己寫一個空的main函數(shù),大家看看我做的對不對?
這下可以編譯了吧?
編譯有警告說什么main函數(shù)的返回值必須是int。。。。不知道為什么?
百度看了下好像是編譯器和c語言標(biāo)準(zhǔn)規(guī)范的問題,沒辦法那就修改下main函數(shù)的返回值吧,把前面的main前面的void變成int就好了。
編譯通過了。。。
要不我們接下來設(shè)置工程屬性看看?這個是很多教程中有的,我不想多少,大家自己找找吧。。。。
你看都可以仿真,哈哈那就說明系統(tǒng)運行起來了。。。。但是我們什么都看不到,接下來我們的任務(wù)就是想辦法點亮一個led燈。
首先我們要控制燈的話就要操作寄存器,還記得我們在51里面要操作P0口嗎?是用P0=0x00,這里面簡單的說下51里面操作IO口的原理,我們看到這里有一個P0,這個P0是哪里來的?顯然不像是int一樣是是c語言本身自帶的,也不是某一個變量是我們自己定的,其實這個是在reg52.h里面定義的,有圖有真相。
可以看到在我們一直使用reg52.h里面他做了這樣一件事情,就是把我們的真實物理地址是0x90的這個P1寄存器和P1這個代名詞相互聯(lián)系了,其實P1只是一個代名詞,假如我在reg52.h里面修改 把sfr P1 = 0x90;修改為sfr XX = 0x90;這樣也是可以用的,只不過下一次你要對P1口進行操作的時候要寫XX=0x00;了,所以為了好記我們就把名字取成P1,現(xiàn)在我們知道了51的原理,我們可以依葫蘆畫瓢來操作stm32的GPIO,先不管我們要操作什么寄存器,我們要接解決的第一個問題怎么使用c語言操作單片機中知道絕對物理地址的寄存器,比如我們通過查資料RM0008的179頁知道了關(guān)于IO操作的一個寄存器GPIOA_CRL的絕對地址是0x40010800+0x00(其中0x40010800是起始地址,0x00是偏移地址),接下來我們怎么操作他呢?用 sfr?好像sfr是51匯編特有的指令,在arm里面沒有。。。這時候我們是否想到c語言的一個和地址緊密相關(guān)的內(nèi)容----指針,我們在上課的時候知道指針的本質(zhì)就是地址,這樣我們是否可以通過它來把實際的物理地址和c語言變量建立關(guān)系呢?首先我們要把絕地地址變?yōu)橹羔樧兞?,肯定是強制類型轉(zhuǎn)換了(int*(0x40010800+0x00))通過這一步我們已經(jīng)有一個int類型的指針,這個指針指向的地址就是我們GPIOA_CRL的絕對地址(0x40010800+0x00),有了指針之后我們要取變量,那么很簡單只要一個簡單的*取變量運算符就可以了(int*(0x40010800+0x00)),這下變量有了那么我們是不是需要給變量取一個名字?
那就這樣#define GPIOA_CRL *((int*)(0x40010800+0x00)) 好了完成了我們終于可以再c語言的環(huán)境中操作我們的寄存器了,接下來我們只要給GPIOA_CRL 這個變量賦值就是我們在給GPIOA_CRL 這個寄存器賦值,先休息下再說。。。。。
這篇文章其實我是一邊寫代碼做測試一邊寫的,就在上面我想要控制IO的時候花了好長的時間,就是因為自己的不仔細吧!犯了幾個小錯誤。先看我的最終代碼。
代碼非常的簡單,但是為了這幾行代碼花了我好久的時間,我已經(jīng)在代碼后面寫了注釋了,具體的怎么來的讓我婉婉道來,首先是上面那幾行的define的機構(gòu)我在上面已經(jīng)介紹過了,具體的地址是怎么知道的?下面我來簡單的說下,在stm32的
RM0008
Reference manual
STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx
and STM32F107xx advanced ARM-based 32-bit MCUs
這個開發(fā)文檔中的44頁內(nèi)存映射表,如下圖
我截圖的只是上半部分,還有下半部分,在下半部分我們可以看到
從這里可以看到和GPIOA相關(guān)的寄存器的起始地址是0x40010400所以代碼中的一開始的基址是這個,然后我們需要知道不同的寄存器的偏移地址,這個是在后面的跳轉(zhuǎn)的鏈接可以看到的,跳轉(zhuǎn)到179頁,偏移地址的表格
這樣的話上面的幾個define的計算也就水落石出了。
這里簡單的說下自己當(dāng)時犯的一個錯誤。我一開始寫的#define GPIOA_CRL *((int*)0x40010800+0x00) 是這樣的,調(diào)試后死活不是我想要的工作效果,后來花了好大的力氣才想起來原來是宏定義的括號的問題,大家仔細比對下我在代碼中的寫的和我上面的寫法,發(fā)現(xiàn)什么端倪沒?#define GPIOA_CRL *((int*)(0x40010800+0x00)) 看到紅色的括號沒?就是因為一個小小的括號耽誤了很長時間。
花了這么長的時間我們終于可以操作IO口了,那怎么操作呢?在學(xué)過51的人的眼里那是很簡單的,就是直接把我們要IO口輸出的值送到數(shù)據(jù)寄存器中不就好了,但是畢竟他是高級的stm32,所以要復(fù)雜點,首先我們要開啟GPIOA的端口時鐘,這也許大家會疑惑了,怎么還和時鐘有關(guān)系了。。。。還是看資料吧!
可以看到GPIOA是掛載在AHB2總線上面的,他們都有自己的時鐘信號的控制端,這是由stm32的機構(gòu)決定的,我想之所以這樣做,一方面可以降低系統(tǒng)功耗,讓工作的模塊的時鐘使能,不工作的就不使能,其實這里的時鐘信號就好比是模塊的心臟一樣,只有先讓他工作了我們才可以去對他進行操作,這就是代碼上 RCC_APB2ENR=0x00000004;//開啟GPIOA的端口時鐘這一句的作用,我嘗試過,假如去掉這一句話的話,即使我后面對寄存器賦值了,也是沒有作用的。所以這一句很重要,而且與下面的順序是不好交換的。接下來就是設(shè)置GPIO的工作方式什么輸入輸出 模式之類的,對于只學(xué)過51的人來說有點新鮮感覺,如果學(xué)過其他高級點單片機的 估計已經(jīng)習(xí)以為常了,就那么回事,具體的寄存器的每一位我就多說了,直接看stm32f10XXXX參考手冊的113頁上滿寫的很清楚了。
這里再順便解釋下下我看到的一個現(xiàn)象,先看文檔
從這里面我們知道任何IO在復(fù)位之后都處于浮空輸入狀態(tài),這是PDF上說的通過我的代碼大家看到我只是改變GPIOA0這位的狀態(tài)所以其他IO口應(yīng)該還是浮空輸入的模式,但是實際上是的嗎?
看仿真截圖:
大家可以看到其他幾個口還是聽話的就是PA12 PA13 PA14 PA15不怎么對勁,怎么回事呢?一開始我也疑惑,后來突然想起來了,這不是我們仿真用的jtag口嗎?這樣的話就對了,于是為了驗證我的想法,我查看jtag用的其他IO口的情況,都不是默認(rèn)的浮空輸入模式,這樣的話就應(yīng)該是這個原因了。(提醒大家一下以后設(shè)計硬件的時候盡量避免使用jtag口,如果實在避免不了的話在設(shè)計程序的時候就要注意關(guān)閉jtag模式釋放那幾個IO口,在此做一個友情提醒因為被坑過幾次。。。)
代碼寫完了,然后編譯下載,不出意外的話就可以看到PA0上面接的led燈亮了,這是必然的結(jié)果,這一次入門教程也就差不多了。。。,謝謝!
相關(guān)代碼的下載鏈接是:http://files.cnblogs.com/51mcu/small_9.20.zip
如果有什么錯誤的話歡迎批評指正!
這篇文章是我轉(zhuǎn)載的,雖然時間很久了,不過真的感謝這篇文章,解決了我很多的疑問和困惑。
明天是美好的,每天進步一點點,經(jīng)過時間的累積那也是種巨大的收獲。
一分辛苦一分才,我相信自己的努力。
掃碼關(guān)注我們
傳真:0755-82591176
郵箱:vicky@yingtexin.net
地址:深圳市龍華區(qū)民治街道民治大道973萬眾潤豐創(chuàng)業(yè)園A棟2樓A08