初識32

1、初識STM32

在學習51單片機後,對於寄存器、定時器、中斷、數碼管等有了基本的瞭解。知道其工作原理後。準備開始上手功能更強大的32單片機。相對於51單片機32單片機處理數據能力更強,一次可以處理32位數據,而51只能處理8位數據。STM32的內部RAM和ROM(flash)都比51大得多,STM32F103有64kRAM,512kROM,STM32F407有256Kram,1M ROM,主頻也很高,分別達72M和168M 因此運算能力要強大的多。
片上外設也比較豐富,定時器多達14個或17個,PWM 功能強大,其ADC精度也達到12位, 還有DA模塊 實時時鐘 較高檔次的還有浮點運算單元 DSP功能特別DMA控制器,將CPU從繁忙的數據中轉中解脫出來。
另外還有FMSC內存接口
它的外部接口也很豐富,多個串口 USB控制 SPI I2C 等一應俱全,高檔有的還有攝像頭接口,網絡接口等 。所以32的功能比51的功能更加強大。伴隨隨着強大的功能32單片機內部結構更加繁瑣、編碼複雜度更高。配置的寄存器更多。

2、STM32F10X的學習方法

1.跟着正點原子提供的視頻學習,瞭解基本的編碼規則和開發環境。
2.藉助正點原子提供的資料stm32開發指南進行開發編程。
3.查閱ST官方提供的stm32f10x中文手冊(或者英文版)
4.有問題可以去查閱相關的論壇找解決辦法。
5.實際用keil5來實現相關功能。
6.實戰編寫相關代碼,用32開發板製作一個智能小車。
7.做一個簡單的應用系統

3、STM32F10 IO口簡介

STM32的IO口由軟件配置爲8種模式:
1、 輸入浮空
2、 輸入上拉
3、 輸入下拉
4、 模擬輸入
5、 開漏輸出
6、 推輓輸出
7、 推輓式複用功能
8、 開漏複用功能
STM32 的每個 IO 端口都有 7 個寄存器來控制。他們分別是:配置模式的 2 個 32 位的端口配置寄存器 CRL 和 CRH; 2 個 32 位的數據寄存器 IDR 和 ODR; 1 個 32 位的置位/復位寄存器BSRR;一個 16 位的復位寄存器 BRR; 1 個 32 位的鎖存寄存器 LCKR;這裏我們僅介紹常用的幾個寄存器,我們常用的 IO 端口寄存器只有 4 個: CRL、 CRH、 IDR、 ODR。
CRLCRH 控制着每個 IO 口的模式輸出速率
STM32IO口配置表:
Alt
STM32輸出模式配置:
Alt
接下來我們看看端口低配置寄存器 CRL 的描述:
Alt
CRH 的作用和 CRL 完全一樣,只是 CRL 控制的是低 8 位輸出口,而 CRH 控制的是高 8位輸出口。給個實例,比如我們要設置 PORTC 的 11 位爲上拉輸入, 12 位爲推輓輸出。

GPIOC->CRH&=0XFFF00FFF; //清掉這 2 個位原來的設置,同時也不影響其他位的設置
GPIOC->CRH|=0X00038000; //PC11 輸入, PC12 輸出
GPIOC->ODR=1<<11; //PC11 上拉

通過這 3 句話的配置,我們就設置了 PC11 爲上拉輸入, PC12 爲推輓輸出。
IDR 是一個端口輸入數據寄存器,只用了低 16 位。該寄存器爲只讀寄存器,並且只能以16 位的形式讀出。
Alt
ODR 是一個端口輸出數據寄存器,也只用了低 16 位。該寄存器爲可讀寫,從該寄存器讀出來的數據可以用於判斷當前 IO 口的輸出狀態。而向該寄存器寫數據,則可以控制某個 IO 口的輸出電平。
Alt
瞭解這些寄存器以後就可以進行跑馬燈編程了。

代碼練習:

新建一個工程。在該工程文件夾下面新建一個 HARDWARE 的文件夾,用來存儲以後與硬件相關的代碼。然後在 HARDWARE 文件夾下新建一個 LED 文件夾,用來存放與 LED 相關的代碼。然後我們打開test.uvprojx 工程,新建一個文件,然後保存在HARDWARELED 文件夾下面,保存爲led.c在該文件中輸入如下代碼:

#include "led.h"
//初始化 PB5 和 PE5 爲輸出口.並使能這兩個口的時鐘
//LED IO 初始化
void LED_Init(void)
{
	RCC->APB2ENR|=1<<3; //使能 PORTB 時鐘
	RCC->APB2ENR|=1<<6; //使能 PORTE 時鐘
	GPIOB->CRL&=0XFF0FFFFF;
	GPIOB->CRL|=0X00300000;//PB.5 推輓輸出
	GPIOB->ODR|=1<<5; //PB.5 輸出高
	GPIOE->CRL&=0XFF0FFFFF;
	GPIOE->CRL|=0X00300000;//PE.5 推輓輸出
	GPIOE->ODR|=1<<5; //PE.5 輸出高
}

該代碼裏面就包含了一個函數 void LED_Init(void),該函數的功能就是用來實現配置 PB5和 PE5 爲推輓輸出。 這裏需要注意的是: 在配置 STM32 外設的時候,任何時候都要先使能該外設的時鐘!APB2ENR 是 APB2 總線上的外設時鐘使能寄存器,其各位的描述如下圖所示:
Alt
我們要使能的 PORTB 和 PORTE 的時鐘使能位,分別在 bit3 和 bit6,只要將這兩位置 1 就可以使能 PORTB 和 PORTE 的時鐘了。該寄存器還包括了很多其他外設的時鐘使能。在設置完時鐘之後就是配置完時鐘之後, LED_Init 配置了 PB5 和 PE5 的模式爲推輓輸出,並且默認輸出 1。這樣就完成了對這兩個 IO 口的初始化。保存 led.c 代碼,然後我們按同樣的方法,新建一個 led.h 文件,也保存在 LED 文件夾下面。
在 led.h 中輸入如下代碼:

#ifndef __LED_H
#define __LED_H
#include "sys.h"
//LED 端口定義
#define LED0 PBout(5) // DS0
#define LED1 PEout(5) // DS1
void LED_Init(void); //初始化
#endif

這段代碼裏面最關鍵就是 2 個宏定義:
#define LED0 PBout(5) // DS0
#define LED1 PEout(5) // DS1
這裏使用的是位帶操作來實現操作某個 IO 口的 1 個位的,關於位帶操作前面已經有介紹,
這裏不再多說。需要說明的是,這裏可以使用另外一種操作方式實現。如下:
#define LED0 (1<<5) //led0 PB5
#define LED1 (1<<5) //led1 PE5
#define LED0_SET(x) GPIOB->ODR=(GPIOB->ODR&~LED0)|(x ? LED0: 0)
#define LED1_SET(x) GPIOE->ODR=(GPIOE->ODR&~LED1)|(x ? LED1: 0)
後者通過 LED0_SET(0)和 LED0_SET(1)來控制 PB5 的輸出 0 和 1。而前者的類似操作爲:
LED0=0 和 LED0=1。顯然前者簡單很多,從而可以看出位帶操作帶來的好處。以後像這樣的IO 口操作,我們都使用位帶操作來實現,而不使用第二種方法。
將 led.h 也保存一下。接着,我們在 Manage Components 管理裏面新建一個 HARDWARE的組,並把 led.c 加入到這個組裏面.
將 led.h 頭文件包含路徑加入到工程裏面。回到主界面,在 main 函數裏面編寫如下代碼:

#include "sys.h"
#include "delay.h"
#include "led.h"
int main(void)
{
	Stm32_Clock_Init(9); //系統時鐘設置
	delay_init(72); //延時初始化
	LED_Init(); //初始化與 LED 連接的硬件接口
	while(1)
	{
		LED0=0;
		LED1=1;
		delay_ms(300);
		LED0=1;
		LED1=0;
		delay_ms(300);
	}
}

代碼包含了#include "led.h"這句,使得 LED0、 LED1、 LED_Init 等能在 main 函數裏被調用。接下來, main 函數先調用 Stm32_Clock_Init 函數, 配置系統時鐘爲 9 倍頻,也就是 8*9=72M(外部晶振是 8Mhz),然後調用 delay_init 函數,初始化延時函數。接着就是調用 LED_Init 來初始化 PE5 和 PB5 爲輸出。最後在死循環裏面實現 LED0 和 LED1 交替閃爍,間隔爲 300ms。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章