- 此文用于記錄學(xué)習(xí)STM32中所學(xué)習(xí)或者鞏固的知識(shí)蜻牢,主要圍繞但并不局限于STM32。
- 本次學(xué)習(xí)并非為了深入了解使用STM32,而是為了接觸其它嵌入式芯片打基礎(chǔ)载弄,因此學(xué)習(xí)中偏重于寄存器操作方法的學(xué)習(xí),庫(kù)函數(shù)方法依情況而定撵颊。
GPIO
General-purpose I/Os
<h6>推挽輸出與開(kāi)漏輸出</h6>
推挽輸出 (push-pull宇攻,TTL/CMOS反相器)
輸出驅(qū)動(dòng)能力有限
無(wú)法直接 “線與”
開(kāi)漏輸出 (OC門,即集電極開(kāi)路門)
必須有上拉電阻倡勇,否則只能輸出低電平
驅(qū)動(dòng)能力可由外接電源調(diào)節(jié)
可以直接 “線與”
<h6>寄存器聲明與定義</h6>
- C語(yǔ)言在給結(jié)構(gòu)體分配內(nèi)存空間時(shí)逞刷,會(huì)給每個(gè)成員依次分配連續(xù)的地址空間,而GPIO的七個(gè)寄存器在內(nèi)存映射中也被分配了連續(xù)的地址空間妻熊。所以只要在結(jié)構(gòu)體內(nèi)按照內(nèi)存映射中分配的順序聲明成員夸浅,每個(gè)寄存器的地址就能夠依次一一正確對(duì)應(yīng)扔役。
typedef struct
{
__IO uint32_t CRL;//volatile unsigned int CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;
<h6>volatile的使用</h6>
- 由于IO口的寄存器值隨時(shí)可能會(huì)變化帆喇,每次使用時(shí)應(yīng)重新讀取,故加上volatile防止編譯器對(duì)其進(jìn)行優(yōu)化厅目。
- 需要使用volatile的情況:
- 變量的值隨時(shí)可能會(huì)變化
- 變量的值會(huì)受到其它共享此變量的寄存器的影響
- 位帶操作中番枚,編譯器并不知道同一個(gè)bit有另一個(gè)別名區(qū)可以影響該比特的值,所以要用volatile使每次都重新讀值
<h6>上拉/下拉輸入 & 浮空輸入</h6>
- 上拉/下拉輸入表示IO口內(nèi)部已經(jīng)集成了上拉/下拉電阻损敷,外部輸入只需要提供上拉/下拉電壓即可葫笼;USART的RX端采用的即是上拉/下拉輸入模式。
- 浮空輸入則適合外部有提供上拉/下拉電阻的情況拗馒。例如作為按鍵檢測(cè)輸入端口使用路星。
時(shí)鐘和復(fù)位 RCC
Reset & Clock Control
<h6>右移操作符</h6>
- Eg:
while( ! (RCC->CR>>17) );//判斷RCC_CR第17位是否為 1
- RCC_CR是clock control register,第17位為外部高速時(shí)鐘就緒標(biāo)志位HSERDY诱桂,18-31位初始默認(rèn)為0洋丐,更保險(xiǎn)的寫法為:
while( (RCC->CR >> 17) & 0x0001 == 0 );
- 運(yùn)算操作符只在CPU的寄存器中進(jìn)行,不影響內(nèi)存的值挥等。所以對(duì)RCC_CR移位并不會(huì)影響RCC_CR對(duì)應(yīng)的映射內(nèi)存中的值友绝。
RCC->CR>>17;//不影響RCC_CR的值
RCC->CR = RCC->CR>>17;//會(huì)改變RCC_CR的值
- 第二條語(yǔ)句操作步驟為:
1.將內(nèi)存中RCC_CR的值復(fù)制到CPU寄存器中;
2.在CPU寄存器中右移17位肝劲;
3.將CPU寄存器中的值復(fù)制回內(nèi)存中
<h6>鎖相環(huán)PLL</h6>
-
u_d = u_i - u_o 的相位差迁客,通過(guò)相位差來(lái)控制VCO頻率的快慢郭宝,使輸出的頻率鎖定在輸入的頻率上。假使在反饋線上增加一個(gè)N分頻器掷漱,則 u_d = u_i - u_o/N粘室,那么輸出的頻率則會(huì)鎖定在 (N*輸入的頻率),即實(shí)現(xiàn)了N倍頻卜范∠瓮常可用作時(shí)鐘的倍頻。
- STM32中海雪,PLL最大輸出時(shí)鐘為72MHz
串口通信
CMOS輸入端不使用時(shí)不能夠懸空
MAX232電平轉(zhuǎn)換(TTL電平與串口的EIA-RS-232電平特性不匹配)
IC(Intergrated Circuit)芯片 datasheet 的作用:
1.芯片管腳的分配
2.典型應(yīng)用電路的接法
3.電氣特性锦爵,適用范圍,電壓極限等電荷泵:電荷泵可用于升壓喳魏、產(chǎn)生負(fù)壓等棉浸。典型的電荷泵電路由開(kāi)關(guān)控制部分和電容部分組成,利用電容能夠暫時(shí)保持電壓的特性反復(fù)充放電以達(dá)到疊加升壓的目的刺彩,或?qū)⒄姾啥私拥禺a(chǎn)生負(fù)壓迷郑。因此電路中至少要有2~3個(gè)電容(分別起搬運(yùn)、輸出的作用)创倔,并且產(chǎn)生的電壓并不是很穩(wěn)定嗡害。
電荷泵開(kāi)關(guān)控制部分集成在 IC 中,外圍只需要加電容就可以實(shí)現(xiàn)畦攘。(如max232芯片霸妹,開(kāi)關(guān)控制部分集成在max232內(nèi)部,從datasheet提供的典型應(yīng)用電路圖可看出知押,外部需連接若干1uF的電容)
二進(jìn)制小數(shù)轉(zhuǎn)十進(jìn)制:乘積取整法
USART 的波特率寄存器 USART_BRR 中由高到低存儲(chǔ)了12位的整數(shù)位叹螟,4位的小數(shù)位。將4位二進(jìn)制小數(shù)轉(zhuǎn)化為十進(jìn)制時(shí)台盯,可以按以下步驟進(jìn)行:
1.先將小數(shù)部分左移4位變成4位整數(shù)(相當(dāng)于乘以16)
2.將4位整數(shù)轉(zhuǎn)化成整數(shù)的十進(jìn)制數(shù)
3.再用16除十進(jìn)制整數(shù)即可得到十進(jìn)制的小數(shù)stm32f10x_usart.c 中罢绽,USART_ClearFlag函數(shù)為何清零代碼是
USARTx->SR = (uint16_t)~USART_FLAG;
而非
USARTx->SR &= (uint16_t)~USART_FLAG;
-
解答:經(jīng)過(guò)查閱手冊(cè),發(fā)現(xiàn)USART_SR寄存器如圖:
當(dāng)中僅有9静盅、8良价、6、5位可寫蒿叠,并且只能寫0明垢,因此置零某一位時(shí)只要將某位賦值為0,其它位賦值為1并不會(huì)影響其它位原本的狀態(tài)市咽。因此上面兩種代碼都是正確的痊银。(已調(diào)試驗(yàn)證了標(biāo)記了w0的bit只能寫0,寫1無(wú)效施绎。有些地方標(biāo)記為 wc溯革,即 wright clear 泌射。rc 同。)
USART_DR由2個(gè)寄存器 TDR & RDR 組成鬓照。可以進(jìn)行讀寫操作孤紧,讀的是 RDR 的值豺裆,寫的是 TDR 的值。
轉(zhuǎn)義字符 \r 與 \n 的區(qū)別
Mac | Linux | Windows | |
---|---|---|---|
\r | 換行+回到行首 | 回到行首 | / |
\n | / | 換行 | 換行+回到行首 |
- 重定向使printf輸出到串口
/*使用 Keil 的 MicroLIB号显,否則需要考慮 no semihosting 模式*/
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
//
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
USART_SendData(USART2, (uint8_t) ch);
/* Loop until the end of transmission */
while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
{
}
return ch;
}
中斷與事件
- 中斷優(yōu)先級(jí)分組
- 搶占式優(yōu)先級(jí)(PreemptionPriority) & 響應(yīng)優(yōu)先級(jí)(SubPriority)
待解決的問(wèn)題
- 為什么中斷標(biāo)志位通過(guò)寫'1'清零臭猜?(如 EXTI_PR 寄存器)