18級(jí)嵌入式系統(tǒng)復(fù)習(xí)提綱
第1講 STM32F4體系結(jié)構(gòu)
1、嵌入式系統(tǒng)的概念
以應(yīng)用為中心、以計(jì)算機(jī)技術(shù)為基礎(chǔ)、軟硬件可裁剪,適應(yīng)應(yīng)用系統(tǒng)對(duì)功能、可靠性、成本、體積、功耗嚴(yán)格要求的專用計(jì)算機(jī)系統(tǒng)。
2、了解ARM體系結(jié)構(gòu)的演變進(jìn)程
1991年開(kāi)始共推出7個(gè)版本,V1~V3未用于商業(yè)授權(quán)。V4T開(kāi)始商業(yè)授權(quán),T表示16位Thumb指令,ARM7TDMI,馮諾依曼結(jié)構(gòu),三級(jí)流水線,0.9MIPS/MHz。V5增強(qiáng)ARM和Thumb指令切換的支持,增加了DSP指令支持(后綴E)、Java支持(后綴J)V6版增強(qiáng)DSP和多媒體處理指令,增加SIMD指令擴(kuò)展,對(duì)音、視頻處理性能有極大提升,Thumb-2指令。2004年發(fā)布V7版,ARM首次為其體系結(jié)構(gòu)命名,命名為Cortex,分為A(應(yīng)用)、R(實(shí)時(shí))、M(微控制器)三個(gè)系列
3、掌握STM32F4的時(shí)鐘樹(shù):有哪幾個(gè)時(shí)鐘源、特點(diǎn),正點(diǎn)原子戰(zhàn)艦開(kāi)發(fā)板時(shí)鐘配置
5個(gè)時(shí)鐘源
LSI:低速內(nèi)部時(shí)鐘,RC 振蕩器,頻率為 32kHz 左右。供獨(dú)立看門(mén)狗、RTC、自動(dòng)喚醒單元使用
LSE:低速外部時(shí)鐘,接頻率為32.768kHz 的石英晶體。主要是 RTC 的時(shí)鐘源
HSI:高速內(nèi)部時(shí)鐘,RC 振蕩器,頻率為 16MHz。可以直接作為系統(tǒng)時(shí)鐘或者用作 PLL輸入
HSE:高速外部時(shí)鐘,可接石英/陶瓷諧振器,或者接外部時(shí)鐘源,頻率范圍4MHz~26MHz。開(kāi)發(fā)板接8M晶振。HSE也可以直接做為系統(tǒng)時(shí)鐘或者 PLL 輸入。
PLL:鎖相環(huán)倍頻輸出 。主 PLL:由 HSE 或者 HSI 提供時(shí)鐘信號(hào),并具有兩個(gè)不同的輸出時(shí)鐘。PLLP:生成高速的系統(tǒng)時(shí)鐘(最高168MHz)PLLQ:生成 USB OTG FS 的時(shí)鐘(48MHz)、隨機(jī)數(shù)發(fā)生器的時(shí)鐘和 SDIO時(shí)鐘。專用 PLL(PLLI2S):生成精確時(shí)鐘,從而在 I2S 接口實(shí)現(xiàn)高品質(zhì)音頻性能
PLL輸出頻率計(jì)算方法:輸入時(shí)鐘先
M
M
M分頻再
N
N
N倍頻最后
P
P
P(或
Q
Q
Q分頻)
f
o
u
t
=
f
i
n
?
N
M
?
P
f_{out}=\frac{f_{in}*N}{M*P}
fout?=M?Pfin??N?
開(kāi)發(fā)板時(shí)鐘配置:
f
i
n
=
8
M
H
z
f_{in}=8MHz
fin?=8MHz,設(shè)置
M
=
8
,
N
=
336
,
P
=
2
M=8,N=336,P=2
M=8,N=336,P=2
4、時(shí)鐘相關(guān)函數(shù)在哪個(gè).h和.c文件定義(其他模塊同樣),時(shí)鐘源使能函數(shù)、外設(shè)時(shí)鐘使能函數(shù)(要知道哪個(gè)外設(shè)掛在哪個(gè)總線上,截圖打印下來(lái)參考)、時(shí)鐘源選擇函數(shù),分頻因子配置函數(shù),外設(shè)復(fù)位函數(shù)
文件:stm32f4xx_rcc.h、stm32f4xx_rcc.c
時(shí)鐘源使能函數(shù):
void RCC_HSICmd(FunctionalState NewState);
void RCC_LSICmd(FunctionalState NewState);
void RCC_PLLCmd(FunctionalState NewState);
void RCC_PLLI2SCmd(FunctionalState NewState);
void RCC_PLLSAICmd(FunctionalState NewState);
void RCC_RTCCLKCmd(FunctionalState NewState);
外設(shè)時(shí)鐘使能函數(shù):
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
void RCC_APB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
void RCC_APB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
使能:ENABLE.失能:DISABLE
時(shí)鐘源選擇函數(shù):
void RCC_HSEConfig(uint8_t RCC_HSE);
void RCC_LSEConfig(uint8_t RCC_LSE);
void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ);//分頻因子配置
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);//系統(tǒng)時(shí)鐘源選擇
void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
void RCC_PCLK1Config(uint32_t RCC_HCLK);//外設(shè)(APB1)配置
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);//設(shè)置系統(tǒng)時(shí)鐘源為HSI
RCC_PCLK1Config(RCC_HCLK_Div2);//設(shè)置APB1時(shí)鐘為HCLK的2分頻
外設(shè)復(fù)位函數(shù):
void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
void RCC_APB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
void RCC_APB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
狀態(tài)參數(shù)獲取清除函數(shù)
uint8_t RCC_GetSYSCLKSource(void);
void RCC_GetClocksFreq(RCC_ClocksTypeDef*RCC_Clocks);
FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG);
void RCC_ClearFlag(void);
5、ARM存儲(chǔ)空間,大端排序、小端排序
ARM體系的存儲(chǔ)空間:
2
32
B
2^{32}B
232B的單一、線性地址空間。地址:
0
~
2
32
?
1
0 \sim 2^{32}-1
0~232?1.可以看作由
2
30
2^{30}
230個(gè)32位的字組成的字地址空間.也可以看作由
2
31
2^{31}
231個(gè)16位的半字組成的半字地址空間
ARM體系的存儲(chǔ)器格式:大端格式(Big Endian)高字節(jié)存儲(chǔ)在低地址中,低字節(jié)則存放在高地址中;小端格式(Little Endian)高字節(jié)存儲(chǔ)在高地址中,低字節(jié)則存放在低地址.
6、位帶操作的含義、哪些區(qū)域可以進(jìn)行位帶操作,位帶地址計(jì)算方法
含義:使用普通的加載/存儲(chǔ)指令(字)對(duì)單一比特(位)進(jìn)行讀寫(xiě)的方式
區(qū)域:內(nèi)部SRAM的最低1MB(0x20000000 ~ 0x200FFFFF)片內(nèi)外設(shè)的最低1MB(0x40000000 ~ 0x400FFFFF)
內(nèi)存SRAM區(qū):
A
l
i
a
s
A
d
d
r
=
0
x
22000000
+
(
(
A
?
0
x
20000000
)
×
8
+
n
)
×
4
=
0
x
22000000
+
(
A
?
0
x
20000000
)
×
32
+
n
×
4
AliasAddr=0x2200 0000+((A-0x2000 0000)×8+n)×4\\ =0x2200 0000+(A-0x2000 0000)×32+n×4
AliasAddr=0x22000000+((A?0x20000000)×8+n)×4=0x22000000+(A?0x20000000)×32+n×4
外設(shè)區(qū):
A
l
i
a
s
A
d
d
r
=
0
x
42000000
+
(
(
A
?
0
x
40000000
)
×
8
+
n
)
×
4
=
0
x
42000000
+
(
A
?
0
x
40000000
)
×
32
+
n
×
4
AliasAddr=0x4200 0000+((A-0x4000 0000)×8+n)×4\\ =0x4200 0000+(A-0x4000 0000)×32+n×4
AliasAddr=0x42000000+((A?0x40000000)×8+n)×4=0x42000000+(A?0x40000000)×32+n×4
A:SRAM或外設(shè)地址;AliasAddr:別名地址
n:位序號(hào),若A為字節(jié)地址,則n為0…7,若A為字地址,則n為0…31
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr&0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr,bitnum))
第2講 GPIO
1、STM32F4ZGT6共有多少組多少位GPIO(其他資源也同樣,比如有多少USART,這個(gè)知識(shí)點(diǎn)后面就不單獨(dú)列了)
7組16位IO端口(GPIOAGPIOG,PAPG)
1組2位端口GPIOH(GPIOH.0/PH0、GPIOH.1/PH1)
7×16+2=114
2、GPIO的工作方式、特點(diǎn)
4種輸入模式
浮空輸入:輸出關(guān)閉,上下拉關(guān)閉
上拉輸入:下拉電阻關(guān)閉,上拉電阻打開(kāi)。無(wú)輸入時(shí),默認(rèn)高電平。
下拉輸入:上拉電阻關(guān)閉,下拉電阻打開(kāi)。無(wú)輸入時(shí),默認(rèn)低電平。
模擬輸入:一定是浮空輸入,不能上下拉。
4種輸出模式
開(kāi)漏輸出、推挽式輸出、開(kāi)漏復(fù)用功能、推挽式復(fù)用功能(均可上、下拉)
上電復(fù)位后,GPIO默認(rèn)為浮空狀態(tài)(上下拉電阻都不加),部分特殊功能引腳為特定狀態(tài)。
推挽輸出:可以輸出強(qiáng)高、低電平,連接數(shù)字器件
開(kāi)漏輸出:只可以輸出強(qiáng)低電平,高電平得靠外部電阻拉高。輸出端相當(dāng)于三極管的集電極,要得到高電平狀態(tài)需要上拉電阻才行。適合于做電流型的驅(qū)動(dòng),其吸收電流的能力相對(duì)強(qiáng)(一般20mA以內(nèi))
復(fù)用輸出:數(shù)據(jù)來(lái)自復(fù)用外設(shè)的輸出腳
3、打開(kāi)相應(yīng)GPIO的時(shí)鐘(其他資源同樣要求,后面不單獨(dú)列出)RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
4、GPIO相關(guān)寄存器的作用
端口模式寄存器(GPIOx_MODER)、端口輸出類型寄存器(GPIOx_OTYPER)、端口輸出速度寄存器(GPIOx_OSPEEDR)、端口上拉下拉寄存器(GPIOx_PUPDR)、端口輸入數(shù)據(jù)寄存器(GPIOx_IDR)、端口輸出數(shù)據(jù)寄存器(GPIOx_ODR)、端口置位/復(fù)位寄存器(GPIOx_BSRR)、端口配置鎖存寄存器(GPIOx_LCKR)、復(fù)用功能寄存器(GPIOx_AFRL & GPIOx_AFRH)
5、庫(kù)函數(shù)的操作方法:GPIO初始化;輸出0、1;讀取等
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能時(shí)鐘
//GPIOF9,F(xiàn)10初始化設(shè)置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;//IO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通輸出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIOF9,F10
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//輸出1
GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10);//調(diào)用示例
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//輸出0
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,BitAction BitVal);//按位輸出
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);//輸出
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);//按位讀輸入
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);//讀取輸入
GPIO_ReadlnputDataBit(GPIOF,GPIO_Pin_9);//示例
GPIO_ReadlnputData(GPIOF);//示例
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);//按位讀輸出
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);//讀取輸出
6、寄存器方式操作方法
RCC->AHB1ENR|= 1<<5;//打開(kāi)GPIOF時(shí)鐘,RCC_AHB1ENR.5
GPIOF->MODER &= ~(3<<2*9);//GPIOF.9通用輸出模式
GPIOF->MODER |= 1<<(2*9);
GPIOF->OSPEEDR &= ~(3<<2*9);//GPIOF.9速度100MHz
GPIOF->OSPEEDR |= 3<<(2*9);
GPIOF->PUPDR &= ~(3<<2*9);//GPIOF.9上拉
GPIOF->PUPDR |=1<<(2*9);
GPIOF->OTYPER &= ~(1<<9);//GPIOF.9推挽輸出模式
GPIOF->OTYPER |=0<<9;
GPIOF->ODR|= 1<<9;//GPIOF.9=1,熄滅DS0
GPIOF->ODR&=~(1<<9); //第九位輸出0
GPIOF->ODR|=1<<9; //第九位輸出1
GPIOF->BSRRH = 0x0200; //第9位輸出0
GPIOF->BSRRL = 0x0400; //第10位輸出1
uint32_t data=GPIOF->IDR //讀取輸入
uint32_t data=GPIOF->ODR //讀取輸出
7、位帶操作
//位帶區(qū)別名地址計(jì)算公式的c語(yǔ)言宏定義
#define BITBAND(addr, bitnum) ((addr&0xF0000000)+0x2000000+((addr&0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射
#define GPIOA_ODR_Addr (GPIOA_BASE+20) //0x40020014
#define GPIOF_ODR_Addr (GPIOF_BASE+20) //0x40021414
#define GPIOA_IDR_Addr (GPIOA_BASE+16) //0x40020010
#define GPIOF_IDR_Addr (GPIOF_BASE+16) //0x40021410
//IO口位帶操作的c語(yǔ)言宏定義
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //位帶輸出(寫(xiě))
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //位帶輸入(讀)
PFout(9)=1;//輸出1
PFout(9)=0;//輸出0
8、寄存器開(kāi)發(fā)與固件庫(kù)開(kāi)發(fā)的優(yōu)缺點(diǎn)
寄存器開(kāi)發(fā)方式的特點(diǎn)
運(yùn)行速度快、占用存儲(chǔ)空間?。恍枰獙W(xué)習(xí)、記憶各寄存器的功能、格式、每位作用含義,STM32F4有數(shù)百個(gè)寄存器
固件庫(kù)開(kāi)發(fā)方式的特點(diǎn)
直接調(diào)用固件庫(kù)函數(shù),無(wú)須深入了解各寄存器的具體格式
運(yùn)行速度較慢、占用存儲(chǔ)空間較大
9、理解CMSIS標(biāo)準(zhǔn)
使不同芯片公司Cortex-M4內(nèi)核的芯片在軟件上基本兼容。Cortex Microcontroller Software Interface Standard,Cortex微控制器軟件接口標(biāo)準(zhǔn)
10、GPIO與其他模塊結(jié)合的應(yīng)用
驅(qū)動(dòng)LED、按鍵,中斷,USART等
11、GPIO端口復(fù)用:
注意初始化GPIO時(shí)一定選擇****復(fù)用功能****,即GPIO_InitStructure.GPIO_Mode = ****GPIO_Mode_AF;*并用*GPIO_PinAFConfig();****進(jìn)行復(fù)用功能配置。要知道哪個(gè)資源可以復(fù)用哪些引腳,把我們學(xué)過(guò)的資源都整理出來(lái)備查
第3講NVIC與EXTI
EXTI掛載在APB2上。
1、NVIC與EXTI的概念
NVIC:Nested Vectored Interrupt Controller,嵌入向量中斷控制器
EXTI:External Interrupt/event controller,外部中斷/事件控制器
2、NVIC相對(duì)VIC的優(yōu)點(diǎn)
快,ns級(jí)響應(yīng)速度,實(shí)時(shí)性強(qiáng)。標(biāo)準(zhǔn),只要是Cortex內(nèi)核,不同公司用法一樣。
3、NVIC的中斷管理規(guī)模(多少級(jí)中斷、內(nèi)核中斷、外部中斷各多少)、STM32F407的中斷管理規(guī)模
256級(jí)可編程中斷設(shè)置(8位),16個(gè)內(nèi)核中斷,240個(gè)可屏蔽中斷,每個(gè)IO口都可以作為中斷源。
管理中斷:非屏蔽請(qǐng)求NMI、可屏蔽請(qǐng)求IRQ。中斷源是IO口、外設(shè)、內(nèi)核中斷、系統(tǒng)異常中斷
stm32只支持92個(gè)(10個(gè)內(nèi)核中斷,82個(gè)可屏蔽中斷)4位16級(jí)優(yōu)先管理,5組分組(沒(méi)有使用Cortex內(nèi)核IP的全部8位)
4、NVIC中斷的優(yōu)先級(jí)管理規(guī)則,理解搶占優(yōu)先級(jí)、響應(yīng)優(yōu)先級(jí),中斷優(yōu)先順序、中斷嵌套規(guī)則、中斷優(yōu)先級(jí)分組。STM32F4對(duì)NVIC中斷優(yōu)先管理上的實(shí)現(xiàn)
優(yōu)先級(jí)分為搶占優(yōu)先級(jí)(主優(yōu)先級(jí))、響應(yīng)優(yōu)先級(jí)(從優(yōu)先級(jí))。
中斷嵌套規(guī)則:高搶占優(yōu)先級(jí)嵌套低搶占優(yōu)先級(jí),同級(jí)不可嵌套,小號(hào)優(yōu)先。
響應(yīng)優(yōu)先級(jí)不嵌套,只決定多個(gè)相同搶占優(yōu)先級(jí)、不同響應(yīng)優(yōu)先級(jí)同時(shí)申請(qǐng)時(shí)的相應(yīng)順序,小號(hào)優(yōu)先。
兩種優(yōu)先級(jí)都相同的多個(gè)中斷源同時(shí)申請(qǐng)時(shí),首先響應(yīng)中斷地址(向量)低(小號(hào))
優(yōu)先級(jí)規(guī)則針對(duì)中斷通道而非中斷源。
中斷優(yōu)先級(jí)分組:9種組合。
分組0:8位全用于響應(yīng)優(yōu)先級(jí)(0:8)
分組x:x位搶占優(yōu)先級(jí),8-x位響應(yīng)優(yōu)先級(jí)(x:8-x)
STM32對(duì)NVIC中斷優(yōu)先管理實(shí)現(xiàn):只用高4位,16個(gè)可編程優(yōu)先級(jí)
5、NVIC相關(guān)寄存器的含義
在core_cm4.hISER[8]
:中斷使能寄存器組ICER[8]
:中斷失能寄存器組ISPR[8]
:中斷掛起寄存器組ICPR[8]
:中斷解掛寄存器組IABR[8]
:中斷激活標(biāo)志位寄存器組
(stm32只用3個(gè))IP[240]
:中斷優(yōu)先級(jí)寄存器組(stm32只用82個(gè),高4位)STIR
:軟件觸發(fā)中斷寄存器組
6、固件庫(kù)方式對(duì)NVIC初始化、中斷優(yōu)先級(jí)分組設(shè)定方法
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
typedef struct {
uint8_t NVIC_IRQChannel; //通道
uint8_t NVIC_IRQChannelPreemptionPriority; //搶占優(yōu)先級(jí)
uint8_t NVIC_IRQChannelSubPriority; //響應(yīng)優(yōu)先級(jí)
FunctionalState NVIC_IRQChannelCmd //使能、失能
} NVIC_InitTypeDef;
//示例
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 分組2
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //EXTI0通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x00;//0搶占優(yōu)先級(jí)
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x02;//2響應(yīng)優(yōu)先級(jí)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能
NVIC_Init(&NVIC_InitStructure);//NVIC初始化
中斷分組配置在寄存器SCB->AIRCR[10..8]
中進(jìn)行。
固件庫(kù)函數(shù):void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
例如:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2)
(在初始化時(shí)配置一次,一般不改)
7、中斷與事件區(qū)別
中斷:需CPU執(zhí)行ISR(中斷服務(wù)程序)完成相關(guān)操作
事件:靠脈沖發(fā)生器產(chǎn)生一個(gè)脈沖,不需CPU干預(yù),由硬件自動(dòng)完成相關(guān)操作,如觸發(fā)AD轉(zhuǎn)換
可以這樣簡(jiǎn)單認(rèn)為,事件機(jī)制提供了一個(gè)完全由硬件自動(dòng)完成觸發(fā)到產(chǎn)生結(jié)果的通道,不要軟件的參與,降低了CPU的負(fù)荷,節(jié)省了中斷資源,提高了響應(yīng)速度,是利用硬件來(lái)提升CPU芯片處理能力的一個(gè)有效方法。
8、EXTI中斷線的映射規(guī)則
23根(23個(gè)通道,16個(gè)針對(duì)輸入輸出端口,每個(gè)I/O都可以映射為外部中斷線,同一編號(hào)的I/O口同時(shí)只能由一個(gè)映射為外部中斷線)
配置:SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource2)
//PE幾連到中斷線幾
9、外部中斷、內(nèi)部中斷的中斷服務(wù)函數(shù)名
(固定的,編程用到,外部中斷線9-5、10-15共用一個(gè))
在stm32f4xx_it.c定義void EXTI0_IRQHandler(void)
void EXTI1_IRQHandler(void)
void EXTI9_5_IRQHandler(void)
void EXTI15_10_IRQHandler(void)
外部中斷:0~4各一個(gè),5~9共用,10~15共用
10、EXTI相關(guān)寄存器含義
中斷屏蔽寄存器 (EXTI_IMR)
事件屏蔽寄存器 (EXTI_EMR)
上升沿觸發(fā)選擇寄存器 (EXTI_RTSR)
下降沿觸發(fā)選擇寄存器 (EXTI_FTSR)
軟件中斷事件寄存器 (EXTI_SWIER)
掛起寄存器 (EXTI_PR)
11、EXTI固件庫(kù):stm32f4xx_exti.h,stm32f4xx_exti.c
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
//初始化中斷線類型、觸發(fā)方式ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
//判斷中斷線中斷狀態(tài)是否發(fā)生EXTI_ClearITPendingBit()
//清除中斷線上標(biāo)志位
EXTI_InitStructure.EXTI_Line = EXTI_Line2;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
中斷服務(wù)函數(shù)。EXTIx_IRQHandler();
中斷服務(wù)函數(shù)最后一步:清除中斷標(biāo)志位void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
示例:
void EXTI3_IRQHandler(void){
if (EXTI_GetITStatus(EXTI_Line3)!=RESET){//判斷某個(gè)中斷是否發(fā)生
//中斷邏輯
EXTI_ClearITPendingBit(EXTI_Line3); //清除LINE上的中斷標(biāo)志位
}
}
12、根據(jù)電路連接圖判別外部中斷的觸發(fā)方式
按鍵連接高電平,按下接通電路。則需要默認(rèn)輸出低電平,下拉,高有效,上升沿觸發(fā)。
按鍵連接低電平,按下接通電路,則需要默認(rèn)輸出高電平,上拉,低有效,下降沿觸發(fā)。
第4講WDG
窗口看門(mén)狗掛在APB1。獨(dú)立看門(mén)狗內(nèi)部自帶時(shí)鐘,不掛載總線。
1、WDG的作用
遞減器計(jì)數(shù)(定時(shí)器),溢出時(shí),使系統(tǒng)復(fù)位
2、IWDG、WWDG的特點(diǎn)、工作原理
IWDG(獨(dú)立看門(mén)狗):由專用的低速時(shí)鐘(LSI,32kHz)驅(qū)動(dòng),即使主時(shí)鐘發(fā)生故障它仍有效,但精度不高(15~47kHz )應(yīng)用于需要看門(mén)狗作為一個(gè)在主程序之外能夠完全獨(dú)立工作,并且對(duì)時(shí)間精度要求較低的場(chǎng)合。
在鍵值寄存器(IWDG_KR)中寫(xiě)入0xCCCC(啟動(dòng)),開(kāi)始啟用獨(dú)立看門(mén)狗。此時(shí)計(jì)數(shù)器開(kāi)始從其復(fù)位值0xFFF遞減,當(dāng)計(jì)數(shù)器值計(jì)數(shù)到尾值0x000時(shí)會(huì)產(chǎn)生一個(gè)復(fù)位信號(hào)(IWDG_RESET)。無(wú)論何時(shí),只要往鍵值寄存器IWDG_KR中寫(xiě)入0xAAAA(俗稱喂狗), 自動(dòng)重裝載寄存器IWDG_RLR的值就會(huì)重新加載到計(jì)數(shù)器,從而避免看門(mén)狗復(fù)位。如果程序異常,就無(wú)法正常喂狗,則導(dǎo)致系統(tǒng)復(fù)位。
WWDG(窗口看門(mén)狗):由APB1分頻(4096)后的時(shí)鐘驅(qū)動(dòng),精度高。通過(guò)可配置的時(shí)間窗口來(lái)檢測(cè)應(yīng)用程序非正常的過(guò)遲或過(guò)早操作。最適合那些要求看門(mén)狗在精確計(jì)時(shí)窗口起作用的程序??捎|發(fā)中斷(提前喚醒中斷)
3、IWDG、WWDG寄存器的含義IWDG_KR
:鋼鐵雄心4mod KaiserReich鍵值寄存器,只寫(xiě)IWDG_RLR
:每次喂狗時(shí)重載入計(jì)數(shù)器的初值,具有寫(xiě)保護(hù)。IWDG_SR
:狀態(tài)寄存器,為1時(shí)表示正在更新,為0時(shí)表示復(fù)位IWDG_PR
:預(yù)分頻寄存器。
WWDG_CR
:控制寄存器,第7位為激活位,低位為計(jì)數(shù)器WWDG_CFR
:第9位為是否使能提前喚醒中斷EWI(在計(jì)數(shù)值0x40時(shí)喚醒并用中斷服務(wù)程序提醒主程序去喂狗),第8位第7位為定時(shí)器時(shí)基,低7位為上窗口值。WWDG_SR
:提前喚醒中斷標(biāo)志,計(jì)數(shù)器值達(dá)到0x40時(shí)硬件置1
4、IWDG幾個(gè)鍵值的作用:
aaaah:喂狗
5555h:去除寫(xiě)保護(hù),使能對(duì)IWDG_PR和IWDG_RLR訪問(wèn)
cccch:?jiǎn)?dòng)(使能)看門(mén)狗
0000h:加寫(xiě)保護(hù)對(duì)IWDG_PR和IWDG_RLR
5、了解IWDG、WWDG庫(kù)函數(shù)、配置流程
IWDG庫(kù)函數(shù):
void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);//寫(xiě)保護(hù):0x5555使能寫(xiě);0x0000失能寫(xiě)
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);//設(shè)置預(yù)分頻系數(shù):寫(xiě)PR
void IWDG_SetReload(uint16_t Reload);//設(shè)置重裝載值:寫(xiě)RLR
void IWDG_ReloadCounter(void);//喂狗:寫(xiě)0xAAAA到KR
void IWDG_Enable(void);//使能(啟動(dòng))看門(mén)狗:寫(xiě)0xCCCC到KR
FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);//狀態(tài):重裝載/預(yù)分頻 更新
配置流程:
IWDG_WriteAccessCmd();//取消寄存器寫(xiě)保護(hù):
IWDG_SetPrescaler(prer);//設(shè)置獨(dú)立看門(mén)狗的預(yù)分頻系數(shù),確定時(shí)鐘:
IWDG_SetReload(rlr);//設(shè)置看門(mén)狗重裝載值,確定溢出時(shí)間:
IWDG_Enable();//使能(啟動(dòng))看門(mén)狗
IWDG_ReloadCounter(); //應(yīng)用程序喂狗
獨(dú)立看門(mén)狗溢出時(shí)間
T
o
u
t
=
(
4
?
2
p
r
e
r
?
r
l
r
)
/
32
T_{out}=(4*2^{prer}*rlr)/32
Tout?=(4?2prer?rlr)/32
WWDG庫(kù)函數(shù):
溢出時(shí)間 T w w d g = t p c l k 1 ? 4096 ? 2 w d g t b ? ( T [ 5 : 0 ] + 1 ) ( m s ) T_{wwdg}=t_{pclk1}*4096*2^{wdgtb}*(T[5:0]+1)(ms) Twwdg?=tpclk1??4096?2wdgtb?(T[5:0]+1)(ms),其中 t p c l k 1 t_{pclk1} tpclk1?為APB1時(shí)鐘周期, w d g t b wdgtb wdgtb為預(yù)分頻系數(shù), T [ 5 : 0 ] T[5:0] T[5:0]為WWDG計(jì)數(shù)值低6位
void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);//預(yù)分頻
void WWDG_SetWindowValue(uint8_t WindowValue); //窗口設(shè)置
void WWDG_EnableIT(void);//使能EWI中斷
void WWDG_SetCounter(uint8_t Counter);//設(shè)置計(jì)數(shù)值,喂狗
void WWDG_Enable(uint8_t Counter);//使能WWDG,并寫(xiě)入計(jì)數(shù)值
FlagStatus WWDG_GetFlagStatus(void);//獲取EWIF
void WWDG_ClearFlag(void);//清除EWIF
配置步驟:
RCC_APB1PeriphClockCmd();//使能看門(mén)狗時(shí)鐘
WWDG_SetPrescaler(fprer);//設(shè)置分頻系數(shù)
WWDG_SetWindowValue(wr);//設(shè)置上窗口值
WWDG_EnableIT();NVIC_Init();//開(kāi)啟提前喚醒中斷并對(duì)NVIC初始化(可選):
WWDG_Enable(WWDG_CNT);//使能看門(mén)狗:
WWDG_SetCounter();//喂狗,一般放在ISR(中斷服務(wù)程序)
WWDG_IRQHandler();//編寫(xiě)中斷服務(wù)函數(shù)
第5-7講TIM
TIM1和TIM8在APB2,TIM2~TIM5在APB1,TIM9~TIM11在APB2,TIM12~TIM14、TIM6和TIM7在APB1
1、STM32F4有哪幾類定時(shí)器、特點(diǎn)、計(jì)數(shù)模式
STM32F40x系列總共有最多14個(gè)定時(shí)器:
通用定時(shí)器TIM2~TIM5
通用定時(shí)器TIM9~TIM14
基本定時(shí)器TIM6、TIM7
高級(jí)定時(shí)器TIM1、TIM8
看門(mén)狗(IWDG、WWDG)本質(zhì)上也是定時(shí)器
TIM2、TIM5為32位,其他16位
Cortex內(nèi)核的SysTick計(jì)時(shí)器(24位遞減)
2、定時(shí)器原理(基本定時(shí)模塊、輸入捕捉模塊、輸出比較模塊)、輸入捕捉通道數(shù)量、產(chǎn)生PWM的通道數(shù)量
16/32位向上、向下、向上/向下(中心對(duì)齊)計(jì)數(shù)模式,自動(dòng)重裝載計(jì)數(shù)器。16位可編程預(yù)分頻器,分頻系數(shù)為1~65536,可實(shí)時(shí)修改。4個(gè)獨(dú)立通道(TIMx_CH1 ~4),可用作:輸入捕獲/輸出比較/PWM生成/單脈沖輸出,可對(duì)外部信號(hào)(TIMx_ETR)計(jì)數(shù),可以定時(shí)器級(jí)連.
輸入捕捉通道數(shù)量:TIM6、7無(wú)此功能,10、11、13、14一個(gè)通道,9、12二個(gè)通道,其他4個(gè)通道
PWM輸出通道數(shù)量:TIM1/TIM8產(chǎn)生7路PWM輸出,TIM2~5同時(shí)4路PWM輸出。TIM9、TIM12同時(shí)2路PWM輸出,TIM10/11/13/14產(chǎn)生1路PWM輸出
3、定時(shí)時(shí)間的計(jì)算
若APB1的分頻系數(shù)是1,則TIMx的時(shí)鐘等于APB1時(shí)鐘(×1),否則TIMx的時(shí)鐘等于APB1時(shí)鐘的2倍(×2)。
(T1/T8/T9~11時(shí)鐘信號(hào)來(lái)自APB2)
CK_PSC為時(shí)鐘周期。
CK_INT=84M
f
C
K
_
I
N
T
=
f
C
K
_
P
S
C
/
(
P
S
C
[
15
:
0
]
+
1
)
f_{CK\_INT} = f_{CK\_PSC} / (PSC[15:0] + 1)
fCK_INT?=fCK_PSC?/(PSC[15:0]+1)
T
=
(
T
I
M
_
P
e
r
i
o
d
+
1
)
?
(
T
I
M
_
P
r
e
s
c
a
l
e
r
+
1
)
/
f
C
K
_
P
S
C
T=(TIM\_Period+1)*(TIM\_Prescaler+1)/f_{CK\_PSC}
T=(TIM_Period+1)?(TIM_Prescaler+1)/fCK_PSC?
4、相關(guān)寄存器的含義、作用TIMx_CNT
:實(shí)現(xiàn)計(jì)數(shù)功能TIMx_PSC
:對(duì)CK_PSC預(yù)分頻,TIMx_ARR
:自動(dòng)重載寄存器。TIMx_CR1
:控制寄存器TIMx_DIER
:中斷控制TIMx_SR
:狀態(tài)寄存器,低位表示中斷,其他位用于捕獲/比較TIMx_CCER
:捕獲比較使能寄存器TIMx_CCMR1
:PWM輸出模式
5、庫(kù)函數(shù)的使用、各方式的配置流程
stm32f4xx_tim.c、stm32f4xx_tim.h
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);//定時(shí)器參數(shù)(基本定時(shí)功能)初始化
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);//定時(shí)器使能函數(shù)
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);//定時(shí)器中斷使能函數(shù)
//狀態(tài)標(biāo)志位獲取和清除
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);//獲取中斷標(biāo)志位
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);//中斷標(biāo)志位掛起清除
TIM_TimeBaseStructure.TIM_Prescaler=7199;//預(yù)分頻
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//計(jì)數(shù)模式
TIM_TimeBaseStructure.TIM_Period = 4999;//周期(重裝載值)
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
定時(shí)器中斷
RCC_APBxPeriphClockCmd();//使能定時(shí)器時(shí)鐘
TIM_TimeBaseInit();//配置ARR、PSC、CR1,初始化定時(shí)器
TIM_ITConfig()、NVIC_Init();//開(kāi)啟定時(shí)器中斷,配置NVIC
TIM_Cmd(); //配置CR1的CEN位,使能定時(shí)器
TIMx_IRQHandler();//編寫(xiě)中斷服務(wù)函數(shù)
輸入捕獲通道初始化void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
TIM5_ICInitStructure.TIM_Channel=TIM_Channel_1;//通道
TIM5_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//邊沿選擇
TIM5_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI; //通道映射
TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//預(yù)分頻(DIV1不分頻)
TIM5_ICInitStructure.TIM_ICFilter = 0x00;//不濾波
TIM_ICInit(TIM5, &TIM5_ICInitStructure);
通道極性設(shè)置獨(dú)立函數(shù)void TIM_OCxPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
獲取通道捕獲值函數(shù)uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx);
輸入捕獲的一般配置步驟
//1.使能定時(shí)器和通道對(duì)應(yīng)IO的時(shí)鐘。
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
//2.初始化IO口,模式為復(fù)用:GPIO_Init();
GPIO_PinAFConfig();//3.設(shè)置引腳復(fù)用映射
TIM_TimeBaseInit();//4.初始化定時(shí)器ARR,PSC
TIM_ICInit();//5.初始化輸入捕獲通道(time的時(shí)基和輸入捕獲都要初始化)
TIM_ITConfig(); NVIC_Init();
NVIC_PriorityGroupConfig();//6.如果要開(kāi)啟捕獲中斷
TIM_Cmd();//7.使能定時(shí)器
TIMx_IRQHandler();//8.編寫(xiě)中斷服務(wù)函數(shù)
PWM輸出通道初始化函數(shù):void TIM_OCxInit(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
示例:
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
TIM_OCInitStructure. TIM_Pulse=100;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高(CC1P)
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //初始化TIM3_OC2
設(shè)置比較值函數(shù)void TIM_SetCompareX(TIM_TypeDef* TIMx, uint16_t Comparex);
使能輸出比較預(yù)裝載void TIM_OCxPreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
使能自動(dòng)重裝載的預(yù)裝載寄存器允許位void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
PWM輸出配置步驟
RCC_APB1PeriphClockCmd();
RCC_AHB1PeriphClockCmd ();//使能定時(shí)器14和相關(guān)IO口時(shí)鐘。
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//初始化IO口為復(fù)用功能輸出。//復(fù)用功能
GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);//GPIOF9復(fù)用映射到定時(shí)器14
TIM_TimeBaseInit();//初始化定時(shí)器時(shí)基:ARR,PSC等:
TIM_OC1Init();//初始化輸出比較參數(shù)
TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);//使能預(yù)裝載寄存器:
TIM_ARRPreloadConfig(TIM14,ENABLE);//使能自動(dòng)重裝載的預(yù)裝載寄存器允許位
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)//使能定時(shí)器
TIM_SetCompare1();//不斷改變比較值CCRx,達(dá)到不同的占空比效果:
6、輸入捕捉的原理,如何測(cè)量脈沖的寬度和周期
輸入階段:消除抖動(dòng)、邊沿選擇、通道選擇、分頻,得到的信號(hào)直接控制主電路。得到捕獲控制信號(hào)后,讀取捕獲值。
上升沿捕獲得到計(jì)數(shù)值1,下降沿捕獲得到計(jì)數(shù)值2,計(jì)算得到脈寬。(中間可能有多次溢出)
T
=
n
?
T
溢出
+
(
C
N
T
下降
?
C
N
T
上升
)
?
T
計(jì)數(shù)
T=n*T_{溢出}+(CNT_{下降}-CNT_{上升})*T_{計(jì)數(shù)}
T=n?T溢出?+(CNT下降??CNT上升?)?T計(jì)數(shù)?
捕獲到上升沿立即清除cnt時(shí),
T
=
n
?
T
溢出
+
C
N
T
下降
?
T
計(jì)數(shù)
T=n*T_{溢出}+CNT_{下降}*T_{計(jì)數(shù)}
T=n?T溢出?+CNT下降??T計(jì)數(shù)?
7、輸入捕捉中的硬件濾波原理
在CK_INT的DTS時(shí)鐘下控制濾波。假如DTS采樣頻率=計(jì)數(shù)器的時(shí)鐘(CK_INT)頻率,采樣次數(shù)N=4,則在上升沿時(shí)采樣信號(hào)進(jìn)行倒計(jì)數(shù),沒(méi)記到N次時(shí)電平又低了,則不認(rèn)為是有效信號(hào)。若上升沿持續(xù)了N個(gè)DTS周期,認(rèn)為有效。在輸入信號(hào)變低后,經(jīng)過(guò)N個(gè)DTS周期,濾波后的信號(hào)也變低。時(shí)間延遲了N個(gè)DTS周期,寬度不變。
8、PWM的原理、作用,占空比、周期如何改變
PWM(Pulse Width Modulation)即脈沖寬度調(diào)制,也就是占空比和周期均可變的脈沖波形。
原理:沖量相等而形狀不同的窄脈沖加在具有慣性的環(huán)節(jié)上時(shí),其效果基本相同。
作用:PWM脈沖寬度調(diào)制是利用微處理器的數(shù)字輸出來(lái)對(duì)模擬電路進(jìn)行控制的一種非常有效的技術(shù),廣泛應(yīng)用在從測(cè)量、通信到功率控制與變換的許多領(lǐng)域中。
改變周期可達(dá)到調(diào)頻效果,改變脈寬或占空比可達(dá)到調(diào)壓效果。故采用適當(dāng)?shù)目刂品椒纯墒闺妷弘娏髋c頻率協(xié)調(diào)變化。
改變重載值A(chǔ)RR可以改變周期,改變比較值CCRx可以改變脈寬(占空比)
PWM頻率=計(jì)數(shù)頻率/重裝載值
9、影子寄存器與原寄存器的關(guān)系,作用
物理上對(duì)應(yīng)兩個(gè)寄存器(緩沖作用),一個(gè)程序可直接操作的,另一個(gè)叫影子寄存器(真正起作用的).由TIMx_CR1.APRE控制,APRE=0兩者直通,APRE=1,每次更新事件(UEV)時(shí)接通。void TIM_ARRPreloadConfig(TIM_TypeDef *TIMx,FunctionalState NewState);
第9講USART
USART1、USART6掛在APB2,其他APB1。
1、幾種常見(jiàn)串行通信標(biāo)準(zhǔn)(UART、USART、SPI、I2C、1-wire)的特點(diǎn)
USART:引腳同UART,異步通信,全雙工。
2、USART主要寄存器
USART_SR:狀態(tài)寄存器
TXE:發(fā)送數(shù)據(jù)寄存器的數(shù)據(jù)是否傳到移位寄存器,1表示完成
TC:0表示發(fā)送未完成,1表示發(fā)送完成
RXNE:0表示未接受,1表示已準(zhǔn)備好讀取接收到的數(shù)據(jù)
USART_DR:數(shù)據(jù)寄存器
USART_CR:控制寄存器
USART_BRR:波特率寄存器
15~4位存儲(chǔ)USARTDIV的整數(shù)部分(PPT有誤),3~0存放USART小數(shù)。小數(shù)部分的數(shù)值*16后以二進(jìn)制存儲(chǔ)。
3、波特率計(jì)算,
波特率
=
f
P
C
L
K
8
?
(
2
?
O
V
E
R
8
)
?
U
S
A
R
T
D
I
V
f
C
L
K
為串口總線上的時(shí)鐘頻率
,
O
V
E
R
8
為過(guò)采樣率
波特率=\frac{f_{PCLK}}{8*(2-OVER8)*USARTDIV}\\ f_{CLK}為串口總線上的時(shí)鐘頻率, OVER8為過(guò)采樣率
波特率=8?(2?OVER8)?USARTDIVfPCLK??fCLK?為串口總線上的時(shí)鐘頻率,OVER8為過(guò)采樣率
4、常用庫(kù)函數(shù),中斷方式工作、查詢方式工作,接收、發(fā)送方法(含庫(kù)函數(shù)與寄存器兩種方式)
void USART_Init();//串口初始化:波特率、數(shù)據(jù)字長(zhǎng)、奇偶校驗(yàn)、硬件流、收發(fā)使能
void USART_Cmd();//串口使能
void USART_ITConfig();//相關(guān)中斷使能
查詢
FlagStatus USART_GetFlagStatus(); //獲取狀態(tài)標(biāo)志位
void USART_ClearFlag(); //清除狀態(tài)標(biāo)志位
while(USART_GetFlagStatus(USART1, UART_FLAG_TC) == RESET); //等待發(fā)送完成
while((USART1->SR&0x40)==0);//等待發(fā)送完成(寄存器方式)
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
while(USART1->SR & Ox20 == 0);//等待接收完成
中斷
if(USART_GetITStatus(USART1,USART_IT_RXNE)){
res=USART_ReceiveData(USART1);//讀取接收到的數(shù)據(jù)
//USART_SendData(USART1,res);//把接收到的數(shù)據(jù)發(fā)回去
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
}
ITStatus USART_GetITStatus(); //獲取中斷狀態(tài)標(biāo)志位
void USART_ClearFlag();//清楚狀態(tài)標(biāo)志位
void USART_ClearITPendingBit(); //清除中斷狀態(tài)標(biāo)志位
接收
uint16_t USART_ReceiveData(); //接受數(shù)據(jù),讀DR(RDR)
ch=USART_ReceiveData(USART1);//讀取一個(gè)數(shù)據(jù)存到ch
ch=USART1->DR;//寄存器方式
發(fā)送
void USART_SendData(); //發(fā)送數(shù)據(jù),庫(kù)函數(shù)
USART_SendData(USART1,ch);//發(fā)送ch
USART1->DR=ch;//寄存器方式發(fā)送庫(kù)函數(shù)
5、USART的應(yīng)用,與主機(jī)串口調(diào)試助手通信,結(jié)合其他模塊,如GPIO、NVIC等
主機(jī)(串口調(diào)試助手)發(fā)送數(shù)據(jù)到STM32的USART1, USART1將收到的數(shù)據(jù)直接再發(fā)送到主機(jī)。
void My_USART1_Init(void){
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate=115200;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
USART_InitStructure.USART_Parity=USART_Parity_No;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_Init(USART1,&USART_InitStructure);
USART_Cmd(USART1,ENABLE);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructure);
}
void USART1_IRQHandler(void){
u8 res;
if(USART_GetITStatus(USART1,USART_IT_RXNE)){
res=USART_ReceiveData(USART1);
USART_SendData(USART1,res);
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
}
}
int main(void){
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
My_USART1_Init();
while(1);
}
struct __FILE {
int handle;
};
FILE __stdout;
int fputc(int ch, FILE *f){
while((USART1->SR&0x40)==0); //等待發(fā)送完成
USART1->DR = (u8) ch;
return ch;
}
6、STM32F407支持多少UART、多少USART
2個(gè)UART。掛在APB1:UART4、UART5.
4個(gè)USART。掛在APB1:USART2、3,掛在APB2:USART1、USART6
第10講I2C
1、I2C簡(jiǎn)介
兩線式串行總線,連接微控制器及外圍設(shè)備。雙向同步半雙工。每個(gè)器件有唯一地址,工作在主模式或從模式,可以發(fā)送或接收。主控器能產(chǎn)生時(shí)鐘信號(hào),總線上開(kāi)漏模式上拉。
2、I2C協(xié)議內(nèi)容:空閑、開(kāi)始、停止、應(yīng)答、數(shù)據(jù)有效性、數(shù)據(jù)傳輸?shù)?/strong>
空閑:SDA和SCL都是高電平,則空閑。
開(kāi)始:SCL為高期間,SDA由高到低跳變
停止:SCL為高期間,SDA由低到高跳變
應(yīng)答:發(fā)送器每發(fā)送一個(gè)字節(jié),就在第9時(shí)鐘脈沖期間釋放數(shù)據(jù)線,由接收器反饋一個(gè)應(yīng)答信號(hào)。有效應(yīng)答信號(hào)為低電平,非應(yīng)答信號(hào)為高電平。對(duì)有效應(yīng)答ACK要求:接收器在第9個(gè)SCL信號(hào)前的低電平期間拉低SDA,確保SCL的高電平期間為穩(wěn)定的低電平。
數(shù)據(jù)有效性:SCL上升沿時(shí)采集數(shù)據(jù),且在SCL下降沿前SDA上的數(shù)據(jù)必須穩(wěn)定。
數(shù)據(jù)傳輸:I2C總線上傳輸?shù)拿總€(gè)字節(jié)均為8位,首先傳輸MSB,每次啟動(dòng)一次I2C總線,其后傳輸?shù)淖止?jié)數(shù)是沒(méi)有限制的。每傳輸一個(gè)字節(jié)后都必須由接收器回應(yīng)一個(gè)應(yīng)答(ACK或NACK)。SDA上,第一幀為尋址字節(jié),包括7位被控器的地址和1位讀寫(xiě)方向位,接著是被控器的應(yīng)答位。緊接著是主控器和被控器的數(shù)據(jù)傳輸和應(yīng)答,傳輸結(jié)束后,主控器要發(fā)停止信號(hào)。
3、用GPIO口軟件仿真I2C方法
void IIC_Init(void){//初始化
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
//GPIOB8、9初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
IIC_SCL=1;
IIC_SDA=1;
}
void IIC_Start(void){//開(kāi)始
SDA_OUT(); //sda線輸出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0; //START:SCL高,SDA從高到低跳變
delay_us(4);
IIC_SCL=0; //鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
}
void IIC_Stop(void){//IIC結(jié)束信號(hào)
SDA_OUT(); //sda線輸出
IIC_SCL=0;
IIC_SDA=0;
delay_us(4);
IIC_SCL=1; //STOP:SCL高,SDA從低到高跳變
IIC_SDA=1;
delay_us(4);
}
u8 IIC_Wait_Ack(void){//等待應(yīng)答
u8 ucErrTime=0;
SDA_IN(); //SDA線輸入
IIC_SDA=1; delay_us(1);
IIC_SCL=1; delay_us(1);
while(READ_SDA) {
ucErrTime++;
if(ucErrTime>250){
IIC_Stop();
return 1;
}
}
IIC_SCL=0;
return 0;
}
void IIC_Ack(void){//應(yīng)答
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;//ACK
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
void IIC_NAck(void){//非應(yīng)答
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;//NACK
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
void IIC_Send_Byte(u8 txd){//發(fā)送數(shù)據(jù)
u8 t;
SDA_OUT();
IIC_SCL=0; //拉低時(shí)鐘準(zhǔn)備發(fā)送
for(t=0;t<8;t++){
IIC_SDA=(txd&0x80)>>7; //先發(fā)送MSB(最高有效位)
txd<<=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0; //時(shí)鐘低電平才允許數(shù)據(jù)改變
delay_us(2);
}
}
u8 IIC_Read_Byte(unsigned char ack) {//接收數(shù)據(jù)
unsigned char i,receive=0;//接受字節(jié)
SDA_IN(); //SDA線輸入
for(i=0;i<8;i++ ){
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;//上升沿采集數(shù)據(jù)
receive<<=1;
if(READ_SDA) receive++;
delay_us(1);
}
if (!ack)
IIC_NAck(); //發(fā)送NACK
else
IIC_Ack(); //發(fā)送ACK
return receive;
}
第11講SPI
SPI2/SPI3掛載在APB1上,其余掛載在APB2上。
1、SPI簡(jiǎn)介
高速、全雙工、同步串行通信總線,只占4根線,任何時(shí)候只能有一個(gè)主機(jī)和從機(jī)通信。發(fā)送數(shù)據(jù)時(shí)必然接收到數(shù)據(jù)
2、SPI從設(shè)備的選擇方法
SPI_CR1的SSM位設(shè)置硬件或軟件管理NSS(從器件選擇),為1時(shí)軟件管理,NSS由SPI_CR1寄存器的SSI位驅(qū)動(dòng)。為0時(shí)是硬件管理,根據(jù)SPI_CR2的SSOE位控制模式。
3、SPI主要寄存器
SPI_CR1:控制寄存器1.
SPI_CR2:控制寄存器2,與中斷相關(guān)。
SPI_SR:位1TXE,發(fā)送緩沖區(qū)空。位0RXNE,接收緩沖區(qū)非空。位7BSY,忙標(biāo)志。
SPI_DR:數(shù)據(jù)寄存器。物理上分兩個(gè)緩沖區(qū):發(fā)送緩沖區(qū)和接收緩沖區(qū)。
SPI_I2SCFGR:I2S模式配置。
4、SPI常用庫(kù)函數(shù)
void SPI_Init(SPI_TypeDef* SPIx,SPI_InitTypeDef* SPI_InitStruct);
void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);//使能
void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);//設(shè)置中斷
void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState);
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);//傳送數(shù)據(jù)
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);//接收數(shù)據(jù)
void SPI_DataSizeConfig(SPI_TypeDef* SPIx,uint16_t SPI_DataSize);
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);//清除狀態(tài)標(biāo)志位
ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);//獲取中斷標(biāo)志位
void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
5、如何判斷SPI一個(gè)數(shù)據(jù)發(fā)送完成、如何判斷SPI接收到一個(gè)數(shù)據(jù)
數(shù)據(jù)先于時(shí)鐘,選擇第一邊沿采集。數(shù)據(jù)時(shí)鐘同時(shí),選擇第二邊沿。while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
//一個(gè)數(shù)據(jù)沒(méi)發(fā)完,等待發(fā)送完成while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
//沒(méi)有接受到數(shù)據(jù),等待接收到1幀數(shù)據(jù)SPI_I2S_SendData(SPI1,ch);
//庫(kù)函數(shù)方式發(fā)送數(shù)據(jù)SPI1->DR=ch;
//寄存器方式
第12講ADC
掛載在APB2上
1、STM32F4 ADC簡(jiǎn)介:特點(diǎn)、性能、分辨率、數(shù)據(jù)對(duì)齊、通道數(shù)量等
特點(diǎn):模擬看門(mén)狗特性允許應(yīng)用程序檢測(cè)輸入電壓是否超出用戶定義的高/低閥值。 在轉(zhuǎn)換結(jié)束、注入轉(zhuǎn)換結(jié)束以及發(fā)生模擬看門(mén)狗溢出事件時(shí)產(chǎn)生中斷??瑟?dú)立設(shè)置各通道采樣時(shí)間 外部觸發(fā)器選項(xiàng),可為規(guī)則轉(zhuǎn)換和注入轉(zhuǎn)換配置極性
性能:ADC電源要求:全速運(yùn)行2.4V ~ 3.6V,慢速運(yùn)行1.8V
分辨率:可以配置為12位、10位、8位或6位。
對(duì)齊:左對(duì)齊或右對(duì)齊的方式存儲(chǔ)在16位數(shù)據(jù)寄存器中。
通道數(shù)量:3個(gè)AD轉(zhuǎn)換器,每個(gè)AD轉(zhuǎn)換器有16個(gè)外部通道,共24個(gè)外部通道。3個(gè)內(nèi)部通道(ADC1)
2、規(guī)則通道、注入通道的概念
規(guī)則通道組:相當(dāng)于正常運(yùn)行的程序,最多16個(gè)通道。
注入通道組:相當(dāng)于中斷,最多4個(gè)通道。
3、工作模式:?jiǎn)未?、連續(xù)、掃描、間斷
單次:將ADC_CR2的CONT位置0,則處于單次轉(zhuǎn)換模式。該模式下ADC僅執(zhí)行一次轉(zhuǎn)換,然后ADC停止。此模式下,可通過(guò)以下方式啟動(dòng)轉(zhuǎn)換:將ADC_CR2的SWSTART位置1(規(guī)則通道),將JSWSTART位置1(注入通道)、外部觸發(fā)。所選通道轉(zhuǎn)換結(jié)束后結(jié)果保存在16位ADC_DR(ADC_JDR1)中EOC(JEOC)標(biāo)志置1.EOCIE(JEOCIE)位置1時(shí)將產(chǎn)生中斷
連續(xù):將ADC_CR2的CONT位置1,則處于連續(xù)轉(zhuǎn)換模式。該模式下ADC結(jié)束一個(gè)轉(zhuǎn)換后立即啟動(dòng)一個(gè)新的轉(zhuǎn)換。此模式下,可通過(guò)以下方式啟動(dòng)轉(zhuǎn)換:將ADC_CR2的SWSTART位置1、外部觸發(fā)。每次轉(zhuǎn)換結(jié)束后轉(zhuǎn)換結(jié)果存儲(chǔ)在16位 ADC_DR中.EOC標(biāo)志置1;EOCIE位置1時(shí)將產(chǎn)生中斷
掃描:掃描一組通道。將ADC_CR1中的SCAN位置1選擇掃描模式。ADC會(huì)掃描在ADC_SQRx寄存器(規(guī)則通道)或ADC_JSQR寄存器(注入通道)中選擇的所有通道。為組中的每個(gè)通道都執(zhí)行一次轉(zhuǎn)換。自動(dòng)注入模式下需要禁止外部事件觸發(fā),EXTEN/JEXTEN[1:0]=00
間斷:將ADC_CR1的DISCEN位置1使能此模式。該模式可用于轉(zhuǎn)換n(n≤8)個(gè)轉(zhuǎn)換的短序列,該短序列是在ADC_SQRx中選擇的轉(zhuǎn)換序列的一部分。出現(xiàn)外部觸發(fā)時(shí),將啟動(dòng)在ADC_SQRx寄存器中選擇的接下來(lái)n個(gè)轉(zhuǎn)換,直到序列中的所有轉(zhuǎn)換均完成為止。
4、轉(zhuǎn)換時(shí)間計(jì)算
可使用ADC_SMPR1和ADC_SMPR2的SMPx[2:0]位修改采用周期數(shù)。ADC會(huì)在數(shù)個(gè)ADCCLK周期內(nèi)對(duì)輸入電壓進(jìn)行采樣。
總轉(zhuǎn)換時(shí)間
T
c
o
n
v
=
采樣時(shí)間
+
周期數(shù)
(
分辨率
12
)
?
每個(gè)
A
D
C
C
L
K
的時(shí)長(zhǎng)
T_{conv}=采樣時(shí)間+周期數(shù)(分辨率12)*每個(gè)ADCCLK的時(shí)長(zhǎng)
Tconv?=采樣時(shí)間+周期數(shù)(分辨率12)?每個(gè)ADCCLK的時(shí)長(zhǎng)
采樣時(shí)間最少3周期,定義在ADC_SMPR1
5、如何啟動(dòng)ADC
ADC啟動(dòng)可由軟件控制,將SWSTART/JSWSTART的位置1開(kāi)始轉(zhuǎn)換。也可由外部事件觸發(fā)。void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
ADC_Cmd(ADC1, ENABLE);
//使能ADC1void ADC_SoftwareStartConv(ADC_TypeDef* ADCx)
ADC_SoftwareStartConv(ADC1);
//軟件啟動(dòng)ADC1規(guī)則組轉(zhuǎn)換ADC1->CR2|=1<<30
//寄存器方式ADC_SoftwareStartInjectedConv(ADC1);
//注入組ADC1->CR2|=1<<22
//寄存器方式
6、如何讀取轉(zhuǎn)換結(jié)果(注入組、規(guī)則組,庫(kù)函數(shù)、寄存器)uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
return ADC_GetConversionValue(ADC1);
//獲取ADC1轉(zhuǎn)換結(jié)果
u16 Get_Adc(u8 ch){
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles );
ADC_SoftwareStartConv(ADC1);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待ADC1規(guī)則組轉(zhuǎn)換結(jié)束
while((ADC1->SR&(1<<1))==0)//等待ADC1規(guī)則組轉(zhuǎn)換結(jié)束,寄存器
return ADC_GetConversionValue(ADC1);//規(guī)則組讀取
return ADC1->DR;//規(guī)則組讀取,寄存器
return ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1);//注入組讀取
return ADC1->JDR1;//注入組讀取,寄存器
}
7、常用寄存器ADC_SR
:狀態(tài)寄存器,STRT和JSTRT中斷無(wú)關(guān),其余位中斷有關(guān)。ADC_CR1
:控制寄存器。ADC_CR2
:控制寄存器。CONT
位=1位連續(xù),CONT
=0為單次ADC_SMPR1/2
:采樣時(shí)間寄存器。每個(gè)通道可以設(shè)置不同采樣時(shí)間。ADC_JOFRx
:注入通道數(shù)據(jù)偏移寄存器,轉(zhuǎn)換注入通道時(shí)從原始轉(zhuǎn)換數(shù)據(jù)減去偏移量ADC_HTR
:上閾值寄存器。ADC_LTR
:下閾值寄存器。ADC_SQR1/2/3
:定義通道順序。ADC_JSQR
:注入通道順序ADC_DR
:數(shù)據(jù)寄存器。AD轉(zhuǎn)換結(jié)果。規(guī)則組數(shù)據(jù)寄存器低16位有用,可設(shè)置左右對(duì)齊。ADC_JDR1/2/3/4
:注入通道轉(zhuǎn)換結(jié)果。ADC_CSR
:3個(gè)ADC公用的狀態(tài)寄存器,只讀。ADC_CCR
:公用控制寄存器,可以讀寫(xiě)。
8、常用庫(kù)函數(shù)
void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct);//通用控制寄存器ADC_CCR初始化
void ADC_Init(ADC_TypeDef* ADCx,ADC_InitTypeDef* ADC_InitStruct);//ADC_CR初始化
void ADC_DeInit(ADC_TypeDef* ADCx)//取消初始化
void ADC_Cmd(ADC_TypeDef* ADCx,FunctionalState NewState);
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT,FunctionalState NewState);//中斷配置
void ADC_SoftwareStartConv(ADC_TypeDef* ADCx);//開(kāi)始轉(zhuǎn)換
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);//規(guī)則組通道配置
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
9、ADC數(shù)據(jù)采集程序,單通道連續(xù)轉(zhuǎn)換
整體流程
RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
GPIO_Init();//1.開(kāi)啟PA口時(shí)鐘和ADC1時(shí)鐘,設(shè)置PA1(ADC1通道1)為模擬輸入
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);//2.復(fù)位ADC1
ADC_CommonInit();//3.初始化ADC_CCR寄存器,同時(shí)設(shè)置ADC1分頻因子
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
//4.初始化ADC1參數(shù),設(shè)置ADC1的工作模式以及規(guī)則序列的相關(guān)信息
ADC_RegularChannelConfig();//5.配置規(guī)則通道參數(shù)
ADC_Cmd(ADC1, ENABLE);//6.使能ADC1
ADC_SoftwareStartConv(ADC1);//7.軟件開(kāi)啟轉(zhuǎn)換
ADC_GetConversionValue(ADC1);//8.等待轉(zhuǎn)換完成讀取ADC
NVIC_Init();
ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
ADC_IRQHandler();//9.如采用中斷方式,還需
void Adc_Init(void){
GPIO_InitTypeDef GPIO_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div4 //不能超過(guò)36MHz
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE);
}
第13講DAC
掛載在APB1上
1、STM32F4 DAC簡(jiǎn)介:特點(diǎn)、數(shù)據(jù)格式、分辨率等
特點(diǎn):12位數(shù)字輸入,電壓輸出型的DAC
數(shù)據(jù)格式/分辨率:
8 位右對(duì)齊:必須將數(shù)據(jù)加載到 DAC_DHR8Rx [7:0] 位(存儲(chǔ)到DHRx[11:4] 位)。
12 位左對(duì)齊:必須將數(shù)據(jù)加載到 DAC_DHR12Lx [15:4] 位(存儲(chǔ)到DHRx[11:0] 位)。
12 位右對(duì)齊:必須將數(shù)據(jù)加載到 DAC_DHR12Rx [11:0] 位(存儲(chǔ)到DHRx[11:0] 位)。
2、輸出電壓計(jì)算方法
D
A
C
O
U
T
P
U
T
=
V
R
E
F
+
?
D
O
R
4095
DAC_{OUTPUT}=V_{REF+}*\frac{DOR}{4095}
DACOUTPUT?=VREF+??4095DOR?
V
R
E
F
+
V_{REF+}
VREF+?為參考電壓輸入,
D
O
R
DOR
DOR為數(shù)據(jù)輸出寄存器的值
3、主要寄存器DAC_CR
:控制寄存器DAC_SWTRIGR
:軟件觸發(fā)寄存器DAC_DHR yyyx
:數(shù)據(jù)輸入寄存器,如DAC_DHR12R1
,DAC_DHR12L1
,DAC_DHR8R1
DAC_DORx
:數(shù)據(jù)輸出寄存器,通道1的數(shù)據(jù)為DAC_DOR1
,通道2的數(shù)據(jù)為DAC_DOR2
DAC_SR
:狀態(tài)寄存器
4、常用庫(kù)函數(shù)void DAC_Init(uint32_t DAC_Channel,DAC_InitTypeDef* DAC_InitStruct);
//初始化void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState);
//使能void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data);
//寫(xiě)入DHR數(shù)據(jù)uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel);
//回讀輸出數(shù)據(jù)
5、如何啟動(dòng)DACvoid DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState);
//CR對(duì)應(yīng)位置1
定時(shí)器 TRGO 輸出或外部中斷線 9 上檢測(cè)到上升沿時(shí),DAC_DHRx中的數(shù)據(jù)即會(huì)加載到DAC_DORx 中。再經(jīng)過(guò)三個(gè)APB1 周期,DAC_DORx 將會(huì)得到更新。
如果選擇軟件觸發(fā),一旦 SWTRIG 位置 1, 轉(zhuǎn)換即會(huì)開(kāi)始.DAC_DHRx 加載到DAC_DORx 后,SWTRIG 即由硬件復(fù)位。
6、如何將一個(gè)數(shù)據(jù)送DAC轉(zhuǎn)換(庫(kù)函數(shù)、寄存器)DAC_SetChannel1Data(DAC_Align_12b_R, 500);
//將500送入,庫(kù)函數(shù)DAC->DHR12R1 = 500;
//將500送入,寄存器num=DAC->DOR1;
7、DAC產(chǎn)生相應(yīng)波形輸出的編程
void Dac1_Init(void){
GPIO_InitTypeDef GPIO_InitStructure; DAC_InitTypeDef DAC_InitType;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
DAC_InitType.DAC_Trigger=DAC_Trigger_None;
DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;
DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;
DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;
DAC_Init(DAC_Channel_1,&DAC_InitType);
DAC_Cmd(DAC_Channel_1, ENABLE);
DAC_SetChannel1Data(DAC_Align_12b_R, 0);
}
void Dac1_Set_Vol(u16 vol){//設(shè)置通道1輸出電壓
double temp=vol;
temp/=1000;
temp=temp*4096/3.3;//vol:0~3300,代表0~3.3V
DAC_SetChannel1Data(DAC_Align_12b_R,temp);//12位右對(duì)齊數(shù)據(jù)格式DAC值
}
int main(void){
u16 adcx;
float temp;
u8 t=0;
u16 dacval=0;
u8 key;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168);
uart_init(115200);
LED_Init();
Adc_Init();
KEY_Init();
Dac1_Init();
DAC_SetChannel1Data(DAC_Align_12b_R,dacval);
while(1){
t++;
key=KEY_Scan(0);
if(key==WKUP_PRES){
if(dacval<4000)
dacval+=200;
DAC_SetChannel1Data(DAC_Align_12b_R, dacval);
}else if(key==KEY1_PRES) {
if(dacval>200)
dacval-=200;
else dacval=0;
DAC_SetChannel1Data(DAC_Align_12b_R, dacval);
}
if(t==10||key==KEY1_PRES||key==WKUP_PRES) {
adcx=DAC_GetDataOutputValue(DAC_Channel_1);
printf(“DAC寄存器的值是:%d\n”,adcx);
temp=(float)adcx*(3.3/4096);
printf(“DAC的輸出電壓是:%f\n”,temp);
adcx=Get_Adc_Average(ADC_Channel_5,10);
temp=(float)adcx*(3.3/4096);
printf(“ADC采集到的電壓是:%f\n”,temp);
LED0=!LED0;
t=0;
}
delay_ms(10);
}
}
第14講 RTOS
1、理解嵌入式應(yīng)用軟件的設(shè)計(jì)的兩種方式
前后臺(tái)系統(tǒng)方式(裸機(jī)方式):沒(méi)有嵌入式操作系統(tǒng)支持,直接操作裸機(jī),在裸機(jī)上寫(xiě)程序,比如用51單片機(jī)進(jìn)行設(shè)計(jì),基本就沒(méi)有操作系統(tǒng)的概念。通常把程序分為兩部分:前臺(tái)系統(tǒng)和后臺(tái)系統(tǒng)。
RTOS方式:在嵌入式操作系統(tǒng)的支持下進(jìn)行應(yīng)用程序設(shè)計(jì),由嵌入式操作系統(tǒng)進(jìn)行內(nèi)存、任務(wù)、外圍設(shè)備等管理,減輕開(kāi)發(fā)人員負(fù)擔(dān)。
2、對(duì)RTOS有兩個(gè)基本要求:功能正確、時(shí)間正確,硬實(shí)時(shí)、軟實(shí)時(shí)
能使計(jì)算機(jī)系統(tǒng)及時(shí)響應(yīng)外部事件的請(qǐng)求,并能及時(shí)控制所有實(shí)時(shí)設(shè)備與實(shí)時(shí)任務(wù)協(xié)調(diào)運(yùn)行,且能在規(guī)定的時(shí)間內(nèi)完成對(duì)事件的處理,邏輯或功能正確,時(shí)間正確.
硬實(shí)時(shí)操作系統(tǒng):必須在極嚴(yán)格的時(shí)間內(nèi)完成任務(wù)
軟實(shí)時(shí)操作系統(tǒng):對(duì)完成任務(wù)的截止時(shí)間要求不是十分嚴(yán)格,對(duì)超時(shí)有一定的容忍度
3、RTOS內(nèi)核的兩種類型
不可剝奪型內(nèi)核(合作型多任務(wù)內(nèi)核):總是優(yōu)先級(jí)別高的任務(wù)最先獲得CPU使用權(quán),每個(gè)任務(wù)必須能主動(dòng)放棄CPU使用權(quán)
可剝奪型內(nèi)核:CPU總是運(yùn)行多個(gè)任務(wù)中優(yōu)先級(jí)別最高的任務(wù),高級(jí)別任務(wù)可以剝奪正在運(yùn)行任務(wù)的CPU使用權(quán)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-479483.html
4、任務(wù)的組成
由三部分組成:任務(wù)堆棧、任務(wù)控制塊和任務(wù)函數(shù)
任務(wù)堆棧:上下文(任務(wù))切換的時(shí)候用來(lái)保存任務(wù)的工作環(huán)境,即STM32的內(nèi)部寄存器值
任務(wù)控制塊:用來(lái)記錄任務(wù)的各個(gè)屬性
任務(wù)函數(shù):由用戶編寫(xiě)的任務(wù)處理代碼
5、μCOSIII的特點(diǎn)
μC/OS III是一個(gè)可裁剪、可剝奪型的多任務(wù)內(nèi)核,而且沒(méi)有任務(wù)數(shù)限制。μC/OS III提供了實(shí)時(shí)操作系統(tǒng)所需的所有功能,包括資源管理、同步、任務(wù)通信等。
μC/OS III是用C和匯編寫(xiě)的,其中絕大部分都是用C語(yǔ)言編寫(xiě)的,只有極少數(shù)的與處理器密切相關(guān)的部分代碼才是用匯編寫(xiě)的,結(jié)構(gòu)簡(jiǎn)潔,可讀性很強(qiáng)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-479483.html
到了這里,關(guān)于【嵌入式系統(tǒng)】 期末復(fù)習(xí)提綱的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!