STM庫是官方提供的,其已經做好了底層驅動的配置,用起來是相當簡單的;我們只需要了解其每個函數的功能,已經每個函數所使用流程即可!
整個框架就是下面這幅圖,我們只需在頂層做調用即可,跟現在做app的差不多!

注:摘自野火,希望大哥不要說我盜版
剛剛開始拿道庫,一看這么多函數,感覺有點棘手,無從下手;多虧stm官方也針對該庫提供了一個應用手冊,畫了兩天時間進行了探索和實踐,發現了一點比較方便的訣竅。
在此給大家分享分享,我們就拿今天的USART來說吧!
至于建工程,網上以及教程里面是非常多的,我也就不多說了!
任意一個外設都對應一個ppp.c和ppp.h文件,所以我們其實也不是無章可循的!同時,stm庫他有一套自己的縮寫定義,我們必須記住,不過這個很好記!

同時他的函數命名也有一定的規則:
名為PPP_Init的函數,其功能是根據PPP_InitTypeDef中指定的參數,初始化外設PPP,例如 ?TIM_Init.?
名為PPP_DeInit的函數,其功能為復位外設PPP的所有寄存器至缺省值,例如 ?TIM_DeInit.?
名為PPP_StructInit的函數,其功能為通過設置PPP_InitTypeDef 結構中的各種參數來定義外設的功能,例如:USART_StructInit
名為PPP_Cmd的函數,其功能為使能或者失能外設PPP,例如: ?SPI_Cmd.?
名為PPP_ITConfig的函數,其功能為使能或者失能來自外設PPP某中斷源,例如: ?RCC_ITConfig.?
名為PPP_DMAConfig的函數,其功能為使能或者失能外設PPP的DMA接口,例如:TIM1_DMAConfig.?
用以配置外設功能的函數,總是以字符串“Config”結尾,例如GPIO_PinRemapConfig.?
名為PPP_GetFlagStatus的函數,其功能為檢查外設PPP某標志位被設置與否,例如:I2C_GetFlagStatus.?
名為PPP_ClearFlag的函數,其功能為清除外設PPP標志位,例如:I2C_ClearFlag.?
名為PPP_GetITStatus的函數,其功能為判斷來自外設PPP的中斷發生與否,例如:I2C_GetITStatus.?
名為PPP_ClearITPendingBit 的函數 , 其功能 為 清除外 設PPP 中斷待處理標志位,例如:I2C_ClearITPendingBit.?
這些在官方給的庫說明里面都有,我只是特別說明下,有助于我么了解!
我們經常用的不多,如:PPP_Init,PPP_Cmd,PPP_ITConfig,PPP_DMAConfig,PPP_GetFlagStatus,PPP_ClearFlag
同時我們需要熟悉的結構體:PPP_InitTypeDef等
上面指出的都是常用的,不多6個函數,1個結構體,相信大家應該能很快記住,我比較笨,記了兩天才記的還不是很清!
下面我們先把USART1d的代碼附上去!
~~~
void usart_config()
{
USART_InitTypeDef usart;
NVIC_InitTypeDef nvic;
RCC->APB2ENR |= 1<<2;
RCC->APB2ENR |= 1<<14;
GPIOA->CRH &= ~(0xff<<4);
GPIOA->CRH |= 0x8b<<4;
usart.USART_BaudRate = 9600;
usart.USART_Parity = USART_Parity_No;
usart.USART_StopBits = USART_StopBits_1;
usart.USART_WordLength = USART_WordLength_8b;
usart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
usart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1,&usart);
USART_Cmd(USART1,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
nvic.NVIC_IRQChannel = USART1_IRQn;
nvic.NVIC_IRQChannelCmd = ENABLE;
nvic.NVIC_IRQChannelPreemptionPriority = 0x0f;
nvic.NVIC_IRQChannelSubPriority = 0x0f;
NVIC_Init(&nvic);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
}
~~~
怎么說呢,我是比較懶的!所以我比喜歡別人那種命名變量的方式,我以前是做linux的,我喜歡linux那套命名模式!
另外,我建議大家在做開發的時候用Keil4.0以上的版本,為啥呢?下面正式我想說的
我們在聲明一個結構體變量的時候,我們不知道結構題里面每個變量的名字,怎么辦?找嗎?很麻煩是吧?
如果我們用了mdk4.0以上的版本,他會自動匹配

可能有的人用過了,會說我多余,呵呵但是對那些沒有用過的人很有用,比如李想老師!呵呵,開個玩笑
這樣我們就不用一個一個輸入了!但是后面的變量賦值怎么辦?其實這些變量賦值都在ppp.h里面定義好了,我大致看了下ppp.h內容不是很多,所以很容易就找到,我有一個方法就是查找!
比如我們要找USART_Mode所對應的賦值:

切換到stm32f10x_usart.h,直接在上面輸入USART_Mode,按下Enter鍵,就找到了,那么我就直接把這個定義賦值過去,好了!
有人說我函數名記不住,那么我們還是在stm32f10x_usart.h直接一下子拉到最下面!是不是看到了所有的函數?

如果你細心看我代碼的話,你會發現,我對GPIO的初始化沒有用結構圖,我發現直接配置管腳的話很方便,代碼不多,我4行能解決他十幾行的代碼!
RCC->APB2ENR |= 1<<2;
RCC->APB2ENR |= 1<<14;
GPIOA->CRH &= ~(0xff<<4);
GPIOA->CRH |= 0x8b<<4;
這樣就把整個配置完了!有的人說我能記住嗎?這么多位!我只想呵呵!不信你自己對著寄存器看下
比如輸入模式:后兩位一定是00b,輸出模式一定是其他三種!在輸出中00,01為通用,10,11為復用,偶數為推挽,奇數為開漏,好記吧?
在輸入中,有三種模式,浮空就是復位的時候,還有模擬輸入,還有上拉下拉輸入!
我今天想寫中斷函數,怎么辦?記不住啊,我想既然是中斷函數,他一定在啟動代碼里面有定義,直接切換到startup_stm32f10x.md.s里面,直接搜索Handler
找到所有中斷函數的定義:

有了這些基本思想,我們在寫程序的時候方便多了,這次完成串口的配置就用了半個小時!我只能說庫用著好方便!
~~~
/*****************************************
* @file obj/main.c
* @author ieczw
* @version V1.0.1
* @date 24-11-2013
*****************************************/
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stdio.h"
#include "stm32f10x_conf.h"
void usart_config(void);
void led_init(void);
void msleep(u16 timeout);
void rs232_send_byte(u8 byte);
u16 systick = 0;
int main(void)
{
u8 ascii = 0;
SysTick_Config(72000); //Config DiDa = 1ms
/* Add your application code here */
usart_config();
led_init();
/* Infinite loop */
GPIOC->BRR |= 0xff<<8;
msleep(1000);
GPIOC->BSRR |= 0xff<<8;
while (1)
{
rs232_send_byte(ascii++);
msleep(1000);
}
}
void led_init()
{
RCC->APB2ENR |= 3<<4;
GPIOC->CRH = 0x33333333;
GPIOD->CRL &= ~(0xf<<2);
GPIOD->CRL |= 3<<2;
GPIOD->ODR &= ~(1<<2);
GPIOC->ODR |= 0xff<<8;
}
void usart_config()
{
USART_InitTypeDef usart;
NVIC_InitTypeDef nvic;
RCC->APB2ENR |= 1<<2;
RCC->APB2ENR |= 1<<14;
GPIOA->CRH &= ~(0xff<<4);
GPIOA->CRH |= 0x8b<<4;
usart.USART_BaudRate = 9600;
usart.USART_Parity = USART_Parity_No;
usart.USART_StopBits = USART_StopBits_1;
usart.USART_WordLength = USART_WordLength_8b;
usart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
usart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1,&usart);
USART_Cmd(USART1,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
nvic.NVIC_IRQChannel = USART1_IRQn;
nvic.NVIC_IRQChannelCmd = ENABLE;
nvic.NVIC_IRQChannelPreemptionPriority = 0x0f;
nvic.NVIC_IRQChannelSubPriority = 0x0f;
NVIC_Init(&nvic);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
}
void rs232_send_byte(u8 byte)
{
USART_SendData(USART1,byte);
while(RESET == USART_GetFlagStatus(USART1,USART_FLAG_TXE));
}
void USART1_IRQHandler(void)
{
static u8 flag = 0;
flag = ~flag;
if(flag)
GPIOC->BRR |= 0xff<<8;
else
GPIOC->BSRR |= 0xff<<8;
if(USART1->SR&(1<<5))
{
USART1->DR = USART1->DR;
while(0 == (USART1->SR&(1<<6)));
}
}
void msleep(u16 timeout)
{
systick = timeout;
while(systick);
}
~~~
今天就是說庫如何使用,原理請看[http://blog.csdn.net/ieczw/article/details/16118387](http://blog.csdn.net/ieczw/article/details/16118387)
希望各位指點!
- 前言
- 【菜鳥入門】stm32的第一個程序--LED
- 【菜鳥入門】stm32 之 掃描按鍵
- 【菜鳥入門】stm32 之 中斷按鍵
- 【菜鳥入門】stm32 之 USART
- 【菜鳥入門】stm32 之 iic
- 【菜鳥入門】stm32 之 eeprom
- 【菜鳥入門】stm32 之 pwm
- 【菜鳥入門】stm32 之 ADC 模數轉換
- 【菜鳥入門】stm32 之 實時時鐘
- 【菜鳥入門】stm32 之 DMA
- 【菜鳥入門】stm32 之 DAC
- 【STM庫應用】stm32 之 USART
- 中斷源去抖辦法
- stm32 啟動代碼應用技巧
- 【STM庫應用】stm32 之 IIC應用
- 【STM庫應用】stm32 之 中斷按鍵初始化(注意事項)
- 關于結構體初始化
- 【STM庫應用】stm32 之 TIM (詳解一 通用定時器)
- 【STM庫應用】stm32 之 TIM (詳解二 脈沖寬度、周期測量)
- 【stm32庫應用】SD驅動移植(基于SDIO外設)
- SD卡fat文件系統移植
- stm32 DMA初始化選項研究
- stm32 靈活靜態存儲控制器(FSMC)(NORFLASH\PSRAM)
- 【stm32+uC/OS-II】ucosii移植簡單詳細步驟
- STM32 加入調試信息來調試代碼
- NRF24L01 無線通信模塊使用