STM8和STM32開發總結

1 通用描述
1.1 STM8
STM8型號單片機分爲STM8A、STM8L、STM8S三個系列。
STM8A:汽車級應用
STM8L:超低功耗MCU
STM8S:標準系列

1.2 STM32
- F1系列用的最多,最大工作頻率72MHz
- STM32固件庫(函數)使用手冊
STM32F107:DWC2 FS OTG
STM32MP157C-DK2:MPU

1.3 ST開發板種類
ST官方出的有NUCLEO板、Discovery板以及評估板,配置從低到高,價格也是從低到高。
NUCLEO:一般只將MCU引腳引出,還有一個串口(通過STLINK USB虛擬),價格也就幾十到100RMB左右。
Discovery板:一般比NUCLEO板多USB(MCU帶USB),音頻解碼,耳機插孔。價格也就100多點。
評估板:功能是最全的,一般外設都有引出,功能最全,價格最高,幾百到1000+RMB。

2 開發環境搭建
2.1 STM32CubeMX_V4.27.0
www.st.com/stm32cubemx

2.2 IAR8.30.1
IAR embedded Workbench 8.30
https://m.baidu.com/ala/c/m.3322.cc/mip/40168.html

3 Reference Manual
3.1 STM32中文參考手冊
In search engine, typo-in <STM32中文參考手冊>, then find "百度文庫", open it.

3.2 文檔下載
如何在STM官網下載STM32英文數據手冊datasheet
第一步 百度“ST官網”,點擊進入第一個鏈接
第二步 點擊目錄Products-Microcontrollers(微控制器),進入芯片選擇的頁面

第三步,找到你對應的芯片型號,進到芯片的詳細頁面。這裏我以STM32F103ZE爲例。

第四步,芯片詳細頁面往下翻,找到Reference Manuals點擊跳轉到下載頁面。

第五步,點擊PDF下載,完成。

4 ADC
4.1 TRGO(trigger output)原理
當TIM1(需要配置成PWM模式)每次計數溢出時就會產生所期待的TRGO事件。
對於TIM1, TRGO的事件源有多個選項可以選擇, 默認狀態只有RESET事件才產生TRGO,對於ADC應該配置爲UPDATE 事件, 所以即使使能ADC外部觸發和選擇外部觸發事件TRGO,還要記得對TIM1的TRGO事件進行配置,否則不會觸發ADC捕獲功能。

4.2 示例代碼
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);

5 NVIC
5.1 中斷服務程序
STM32的中斷服務程序的名字不能自定義,必須使用官方已經定義好的名字,名字可參考如下的文件。

@ Drivers\CMSIS\Device\ST\STM32L0xx\Source\Templates\iar\startup_stm32l061xx.s
當然服務程序的具體內容還是自己寫,放在stm32f10x_it.c裏。

5.2 BASEPRI
FreeRTOS中進入臨界區時沒有關閉所有中斷,而是使用優先級屏蔽寄存器BASEPRI(= configMAX_SYSCALL_INTERRUPT_PRIORITY)關閉了部分中斷;這個寄存器最多有9位(由表達優先級的位數決定)。它定義了被屏蔽優先級的閾值。當它被設成某個值後,所有優先級號大於等於此值的中斷都被關(優先級號越大,優先級越低)。但若被設成0,則不關閉任何中斷,0也是缺省值。

FreeRTOS任務代碼中臨界段的進入和退出主要是通過操作寄存器BASEPRI實現的。進入臨界區BASEPRI關閉了所有大於等於宏定義configMAX_SYSCALL_INTERRUPT_PRIORITY所定義的中斷優先級,這樣臨界段代碼就不會被中斷干擾到,而且實現任務切換功能的 PendSV 中斷和SysTick滴答定時器中斷是最低優先級中斷,所以此任務在執行臨界段代碼期間是不會被其它高優先級任務打斷的。退出臨界段時重新操作BASEPRI寄存器,即打開被關閉的中斷(這裏我們不考慮不受FreeRTOS 管理的更高優先級中斷)。

Cortex-M內核的“中斷優先級寄存器”是以最高位(MSB)對齊的。STM32使用了優先級寄存器中的4位,則這4個位位於中斷優先級寄存器的bit 4、bit5、bit6、bit7位。剩餘的bit0 ~ bit3可以設置成任何值。所以FreeRTOS中的中斷優先級計算是有移位操作的。

 CMSIS以及不同的微控制器供應商提供了可以設置某個中斷優先級的庫函數。一些庫函數的參數使用最低位對齊,另一些庫函數的參數可能使用最高位對齊,所以,使用時應該查閱庫函數的應用手冊進行正確設置。

可以在FreeRTOSConfig.h中設置宏configMAX_SYSCALL_INTERRUPT_PRIORITY和
configKERNEL_INTERRUPT_PRIORITY的值。(關於這兩個宏可以參考參數設置一章,網址:http://openmcu.net/post/kernel-config.html)。這兩個宏需要根據Cortex-M內核自身的情況進行設置,要以最高有效位對齊。比如某MCU使用中斷優先級寄存器中的4位,設置configKERNEL_INTERRUPT_PRIORITY的值爲5,則代碼爲:
#define configKERNEL_INTERRUPT_PRIORITY (5<<(8-4))

對於每一個官方FreeRTOS演示例程,這也是在FreeRTOSConfig.h中要設置宏configKERNEL_INTERRUPT_PRIORITY爲最低優先級時,爲什麼要將它設置爲255(1111 1111B)的原因。使用這種方式指定這個值的原因是,FreeRTOS內核是直接在Cortex-M內核硬件上運行的(沒有使用第三方接口庫函數),要比大多數庫函數先運行。現在也有開發第一個Cortex-M庫函數計劃。

5.3 IPR
typedef struct
{
    vu32 ISER[2];
    u32 RESERVED0[30];
    vu32 ICER[2];
    u32 RSERVED1[30];
    vu32 ISPR[2];
    u32 RSERVED2[30];
    vu32 ICPR[2];
    u32 RSERVED3[30];
    vu32 IABR[2];
    u32 RSERVED4[30];
    vu32 IPR[15];
} NVIC_TypeDef;

NVIC IPR[15]:Interrupt Priority Registers,中斷優先級控制寄存器組。STM32的中斷分組與這個寄存器密切相關。因爲STM32的中斷多達60多個,所以STM32採用中斷分組的辦法來確定中斷的優先級。IPR寄存器由15個32bit的寄存器組成,每個可屏蔽中斷佔8bit,這樣總共可以表示15x4=60個可屏蔽中斷。IPR[0]的[31:24],[23:16],[15:8],[7:0]分別對應中斷3到0,總共對應60個外部中斷。而每個可屏蔽中斷佔用的8bit並沒有全部使用,只用了高4位。這4位又分爲搶佔優先級和子優先級。這兩個優先級要根據SCB->AIRCR(System Control Block,Application Interrupt and Reset Register)中斷分組的設置來決定。

簡單介紹STM32的中斷分組:STM32將中斷分爲0~4共5個組,該組是由SCB->AIRCR寄存器的bit10:8來定義的。如Table 5-1所示。
Table 5-1 AIRCR中斷分組設置表

AIRCR[10:8]

bit[7:4]分配情況

分配結果

0

111

0:4

0位搶佔優先級,4位響應優先級

1

110

1:3

1位搶佔優先級,3位響應優先級

2

101 

2:2

2位搶佔優先級,2位響應優先級

3

100 

3:1  

3位搶佔優先級,1位響應優先級

4

011

4:0

4位搶佔優先級,0位響應優先級

通過這個表,可以清楚的看到組0~4對應的配置關係,例如組設置爲0x03,此時所有的60箇中斷,每個中斷的中斷優先級寄存器的高四位中最高3位是搶佔優先級,低1位是響應優先級。每個中斷都可以設置搶佔優先級爲0~7,響應優先級爲1或0。搶佔優先級的級別高於響應優先級,數值越小所代表的優先級越高。

具體優先級的確定和嵌套規則:
(1)只能高搶先優先級的中斷可以打斷低搶佔優先級的中斷服務,構成中斷嵌套;
(2)當2個(N個)相同搶佔優先級的中斷出現,他們之間不能構成中斷嵌套,但STM32首先響應子優先級高的中斷;
(3)當2個(N個)個搶佔優先級和子優先級相同的中斷出現,STM32首先響應中斷通道所對應的中斷向量地址低的中斷,就是誰先發生誰先被執行。

5.4 SHPRx-System Handler Priority Registers
Cortex M4系統中斷的中斷號從-15~-1(優先級由SHPRx控制),外設中斷的中斷號從0~63(優先級由IPR控制)。

SHPR1至SHPR3,3個32位寄存器,每8位設置一箇中斷優先級,共12個可配置的系統中斷,8爲裏面用了高位configPRIO_BITS,其它位寫無效,讀爲0。還有3箇中斷的優先級系統默認爲-3、-2、-1。
Figure 5-1 Cortex-M中斷分佈


Figure 5-2 SHPRx寄存器的位分配

5.5 示例代碼
/* interrupt priority register */
static int command_dump_ipr(cli_node_t *cmd, int argc, char **argv)
{
    const volatile uint8_t * const pcInterruptPriorityRegisters =
        (const volatile uint8_t * const)0xE000E3F0;
    uint8_t i;

    console_puts_lite(""CR_LF);
    console_puts_lite("configPRIO_BITS                      = %d"CR_LF,
            configPRIO_BITS);
    console_puts_lite("configKERNEL_INTERRUPT_PRIORITY      = 0x%02x"CR_LF,
            configKERNEL_INTERRUPT_PRIORITY);
    console_puts_lite("configMAX_SYSCALL_INTERRUPT_PRIORITY = 0x%02x"CR_LF,
            configMAX_SYSCALL_INTERRUPT_PRIORITY);
    console_puts_lite(""CR_LF);

    /* (4-7, 8-11, 12-15) */
    console_puts_lite("System Handler Priority Registers"CR_LF);
    for (i = 0; i < 12; i++){
        console_puts_lite("PRI_%d - 0x%02x"CR_LF, (4 + i), SCB->SHP[i]);
    }
    console_puts_lite(""CR_LF);

    console_puts_lite("User Interrupt Priority Registers"CR_LF);
    for (i = 16; i < (16 + IRQ_NUMBER_MAX); i++) {
        console_puts_lite("IRQ%d - 0x%02x"CR_LF,
                (i - 16), pcInterruptPriorityRegisters[i]);
    }
    return 0;
}
DECLARE_CONSOLE_COMMAND(dump_ipr, command_dump_ipr, NULL);

6 Timer
6.1 捕獲模式
STM32輸入捕獲模式,主要用於測量輸入信號的週期,進而計算波形的頻率。正常情況下。輸入捕獲模式只能測量週期,因爲stm32在輸入捕獲模式設置爲檢測上升沿或者下降沿。當檢測到邊沿後,保存定時器的當前值到TIMx->CCR1(Capture/Compare Registers)寄存器。在中斷中讀取此寄存器就可以得到兩個上升沿或者下降沿之間的脈衝數,然後在根據定時器的時鐘去計算波形的週期。
如果要測量佔空比就要在中斷中重新設置邊沿即可。
定時器計數器最大值爲0xffff。

6.2 TIM_Prescaler、TIM_Period和TIM_ClockDivision的區別
TIM_Prescaler(PSC):用來指定TIM時鐘的分頻值,也就是說它是進一步來分頻TIM clock的,簡單來說也就是定時器每一次計數的時間間隔是多少。
TIM_Period(ARR):它控制的是定時週期。比如說將TIM_Period(TIM1_ARR)設置成999,則計數器向上計數到1000(999+1)後產生更新事件,計數值歸零。
TIM_ClockDivision:時鐘分割,通常值爲0。

假設時鐘頻率爲48MHZ,如果指定預分頻器即TIM_Prescaler的值爲48000(-1),那麼經48000分頻之後的工作頻率就是1000,也就是所謂的1KHz;如果再指定計數值即TIM_Period爲1000(-1)的話,恰好就是1秒了。

比如官方例程中的,要用TIM3來實現輸出36KHz(大約)。
1) 首先規定了TIM3要運行在24000000Hz下,由此可以得出TIM_Prescaler的大小
PrescalerValue = (uint16_t) (SystemCoreClock/ 24000000) - 1;
所以 TIM_Prescaler爲2。

2) 然後由The TIM3 is running at 36 KHz:
TIM3 Frequency = TIM3 counter clock / (ARR+ 1) = 24 MHz / 666 = 36 KHz
得到TIM_Period 爲666-1。

3) 如果要修改佔空比需要修改參數 TIM_Pulse
TIM3 Channel1 duty cycle = (TIM3_CCR1/TIM3_ARR)* 100 = 50%
TIM3 Channel2 duty cycle = (TIM3_CCR2/TIM3_ARR)* 100 = 37.5%
TIM3 Channel3 duty cycle = (TIM3_CCR3/TIM3_ARR)* 100 = 25%
TIM3 Channel4 duty cycle = (TIM3_CCR4/TIM3_ARR)* 100 = 12.5%

6.3 單通道捕獲模式
STM32並不支持雙邊沿捕獲,因此我們要手工實現雙邊沿,也就是在中斷中我們可以選擇檢測本次中斷是上升沿中斷還是下降沿中斷,如果是上升沿中斷,就修改爲下降沿中斷,反之就修改爲上升沿中斷。

6.4 雙通道捕獲模式
@ stm32f10x_it.c
該函數是TIM捕獲波形的中斷函數,同一個(TIM5)中斷入口,有兩個通道,也是計算頻率和佔空比重要的函數。

Figure 6-1 捕獲上升沿

Figure 6-2 捕獲下降沿

7 USART
7.1 USART空閒中斷
1)檢測到接收數據後,在數據總線上的一個字節時間內,沒有接收到數據觸發空閒中斷。RXNE置位一次,空閒總線就檢測一次。
2)空閒中斷是接受數據後出現一個byte的高電平(空閒)狀態,就會觸發空閒中斷。並不是空閒就會一直中斷,準確的說應該是上升沿(停止位)後一個byte,如果一直是低電平是不會觸發空閒中斷的(會觸發break中斷)。

7.2 Hardware flow control
本地的RTS連接到對端的CTS,本地的CTS連接到對端的RTS,即交叉連接,其中RTS是輸出,CTS是輸入,並且RTS和CTS都是低電平有效。
參考STM32英文手冊RM0008 Rev 20 page815,有詳細的波形圖描述。

7.3 USART synchronous mode
等效於SPI接口。參考STM32英文手冊RM0008 Rev 20 page805,有詳細的原理圖描述。
MISO:mi s əu
MOSI:m əu si

8 USB
純軟件實現USB1.1從協議
USBasp - USB programmer for Atmel AVR controllers
https://www.fischl.de/usbasp/

HS握手時,Chirp KJ的頻率大概是10KHz。

9 General Abbreviations
AIRC:Application Interrupt and Reset Register
ARR: Automatic Reload Register
BKP: BackUp
BSP:Board Support Package
CCER: Capture/Compare Enable Register,用來判斷當前是下降沿捕獲中斷還是上升沿捕獲中斷,同時也能隨時改變上升沿捕獲還是下降沿捕獲
CCR: Capture/Compare Register,表示當前中斷髮生時的CNT寄存器的值,也就是用來判斷時間的;PWM輸出時作爲佔空比寄存器,函數是TIM_SetCompare1(...)
CNT: Counter Register,用來計數的,每個定時器時鐘週期自動+1,在需要的時間將其清零,便於計時
CmBacktrace:Cortex Microcontroller Backtrace,是一款針對ARM Cortex-M系列MCU的錯誤代碼自動追蹤、定位、錯誤原因自動分析的開源庫
CubeMX:Microcontroller GUI
eCC-USB:eCos Centric USB
GHS:Green Hills Software,提供GHS hypervisor(類似於QNX hypervisor)、儀表專用RTOS、MCU開發IDE
IAR:後兩個字母取之於創始人名字Anders Rundgren的首字母,瑞典語Ingenjörsfirman Anders Rundgren,意爲Anders Rundgren工程公司
IAR icf:ILINK Configuration File
MDATA:More DATA,USB ep雙緩衝(ep_kind配置使能)切換機制對應到DATA0和DATA1
MSP:MCU Specific Package
NVIC:Nested Vectors Interrupts Controller
NVIC IPR:Interrupt Priority Registers
OC:Output Compare(輸出比較),用於輸出PWM信號;寄存器CNT與CCR比較,大於輸出1,小於輸出0
PMA:Packet Buffer Memory Area
PSC:PreSCaler register,預分頻寄存器
RCC:Reset and Clock Control
RCR:Repetition Counter Register,重複次數寄存器
SHPRx:System Handler Priority Registers
SR: Status Register,用來判斷是不是輸入捕獲中斷
ST AMG:Analog and MEMS Group,模擬和MEMS部門(現在改成了Analog, MEMS and Sensors Group)
STM32H7:High-perf Cortex-M7
STM32WB:WB表示集成了Wireless Bluetooth模塊
STM32WL:WL表示集成了Wireless LoRa模塊
PendSV:Pendable 服務是一箇中斷請求,如果沒有其他中斷需要響應時,系統將強制執行上下文切換
SVCall:SuperVisor Call由SVC指令觸發,FreeRTOS用它來啓動任務調度
USB BH reset:Bigger Hammer or Brad Hosler,表示warm reset;you may be confused why the USB 3.0 spec calls the same type of reset "warm reset" in some places and "BH reset" in other places. "BH" reset is supposed to stand for "Big Hammer" reset, but it also stands for "Brad Hosler". Brad died shortly after the USB 3.0 bus specification was started, and they decided to name the reset after him. The suggestion was made shortly before the spec was finalized, so the wording is a bit inconsistent.
USB KVM:KVM是鍵盤(Keyboard)、顯示器(Video)、鼠標(Mouse)的縮寫;KVM端口是25-pin,包含VGA接口和USB接口
uSOF:micro Start of Frame,125us

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