---
# System prepended metadata

title: 微處理器基礎
tags: [基礎知識, 新生訓練]

---

[TOC]


# 簡介
- [處理器(Processor)](https://zh.wikipedia.org/wiki/%E5%A4%84%E7%90%86%E5%99%A8_(%E8%AE%A1%E7%AE%97))是電子計算機或數位設備中的一個核心元件，負責執行程序指令、進行數據處理和控制其他硬體組件。
- [CPU、MPU、MCU差別](https://blog.csdn.net/weixin_46187354/article/details/129196828)
    - 簡言之，CPU只能算，MPU本身能算又有I/O，MCU更完整，是MPU再結合一些外設(peripheral devices)
    - ![image](https://hackmd.io/_uploads/S1MBnbls0.png =80%x)
- 微控制器能做到指令處理、計算、外設控制、通訊等功能
    - **指令處理** : 從記憶體中提取並解讀指令
    - **計算** : 藉由算術邏輯單元(ALU)實現基本數學或邏輯運算
    - **外設控制** : 藉由控制輸出入接腳的高低電位，實現對外部設備的控制
    - **通訊** : 有些微控制器內涵通訊協定相關電路，再經由接腳與外部連接，可實現不同通訊功能
- 以最常見的Arduino UNO開發板來說，板上的ATmega328P晶片就是一個微控制器
- 
# 應用
- 以控制系統來說，我們能使用程式讓微處理器接收feedback的訊號，再與input(可能為外部輸入或程式指定)計算控制誤差，經由程式編寫好的控制計算規則，輸出訊號到受控體plant。如下圖框起來部分即由微處理器實現
- ![image](https://hackmd.io/_uploads/rJGaMFfhR.png)

# 結構組成
- 微處理器的主要組成都差不多，細節架構可能不同，下圖是Arduino UNO 晶片的架構圖，我們從圖中有的組成做介紹
- ![image](https://hackmd.io/_uploads/S1MoBgmQJg.png)


-  **中央處理單元(CPU)**
    -  算術邏輯單元(ALU)執行所有運算，從暫存器接收數據並將結果返回到暫存器或記憶體中
    -  控制單元(CU)負責指令解碼、控制微處理器內部各模塊的操作、時序操作、程式的分支與跳轉

- **記憶體**
    - 譬如圖中的EEPROM、FLASH、SRAM，用來儲存程式碼或運行時的變數資料等

-  **匯流排(Bus)系統**
    - 用於數據(data)、位址(address)、控制信號(control signal)的傳輸
    - 由於每條線只能是HIGH或LOW，因此需要使用好幾條線組成的排線來同時傳輸位元資料，匯流排可同時傳輸的資料數(位元數)就稱為寬度（width），通常說<font color="red">32位CPU</font> 代表該處理器的主要數據處理單元和內部架構基於32位元設計，計算和傳輸數據單元都基於32位，例如STM32的傳輸位元寬度也是32位元
    
-  **時鐘系統**
    -  作為一種數位集成電路(相關數位電路概念見新訓FPGA)，其多以同步電路組成，時鐘系統必不可少
    -  時鐘脈衝決定了微處理器中各個操作步驟的速度和同步性。微處理器的工作速度通常由其時鐘頻率來衡量，頻率越高，微處理器運行越快。

-  **輸入/輸出（I/O）接口**
    -  I/O接口負責微處理器與外部設備之間的通訊或控制、讀取。

- **其他外設**
    - 譬如USART、ADC等模組

-  **暫存器（Registers）**
    -  用於暫存數據和指令，速度遠高於主記憶體（RAM），一般暫存器容量為8位、16位、32位或64位
    -  <font color="red">尤其是狀態(status)類型的暫存器負責紀錄並決定微處理器各種功能模式，使用者即通過改寫這些暫存器去控制微處理器</font>，如旗標暫存器的「狀態旗標」和控制程序的「控制旗標」。STM32的每個暫存器大小即為32位元，了解使用的微處理器相當於要去了解暫存器的使用


# 程式運行

- 微處理器的主函式通常有一個無限的迴圈，例如
```
void main() {
    while (1) {
        // 監控感測器數據
        // 處理外部事件
        // 控制輸出設備
    }
}
```
- 由於微處理器在嵌入式系統中經常用於持續監控外部設備或控制系統狀態，因此通常需要它不斷運行，同時也簡化程式設計。
- 在進入這個運行的主迴圈之前，通常會有一連串設定暫存器或其他動作，這部分主要用於設定外設功能或初始化，因此只會執行一次。當然也可以視需求加入其他動作



# 常見功能
完整的微控制器晶片通常包含以下外設功能

## 定時與計時功能
- <font color="red">Timer，定時器</font>
    - 用於計時和計數操作，藉由時鐘的觸發，定時器可以在固定時間點使暫存器值增減以達到計數功能，計時再藉由時鐘頻率回推即可
    - 由於定時器可以計時，因此可以在固定頻率下做某件事情，譬如 : 每3秒切換LED亮暗
    - 定時器計時到指定時間也可以觸發中斷
    - 在數位信號處理中，取樣時間(sampling time)極為重要，這與控制系統的好與壞息息相關，因此在使用微處理器做控制時，會希望主控制程式能在固定時間點運行，因此常需要計時功能以確保操作頻率
- 其他依賴 Timer 的功能
    - <font color="red">Capture(捕獲) </font>
        - 捕獲功能指的是捕獲接腳的電平變化，HIGH變LOW或相反
        - 搭配 Timer 可以紀錄兩次變化的時間。想像有一個PWM波形進入捕獲接腳，搭配 Timer 可以準確算出PWM的週期與duty cycle
    - <font color="red">Compare (比較) 與 PWM（脈衝寬度調變)</font>
        - PWM 是數位訊號模擬類比訊號的方式，[上網查](https://www.digikey.tw/zh/blog/pulse-width-modulation)
        - ![image](https://hackmd.io/_uploads/H1xgs5tQmJx.png =50%x)
        - 比較功能搭配 Timer ，當計時到指定的比較值時，觸發比較事件，譬如翻轉電平，就可以產生指定PWM波形

## 中斷
- **輪詢(Polling)** 透過在主循環中反覆執行檢查操作，**中斷(Interrupt)** 則是一種讓外部設備或內部事件打斷微處理器正常執行的機制。以微處理機接收sensor訊號為例，輪詢方式會在主迴圈中等到程式跑到接收信號的那段程式碼才會執行，中斷方式則是當中斷發生就執行接收信號的程式。
- 中斷使用時機、流程等概念可見[這篇](https://hackmd.io/@shiroteam/B1RK_71jO)
- 中斷程式ISR (Interrupt Service Routine)內放中斷要做的事情，<font color="red">注意ISR是輕薄短小的程式，太龐大的計算或時間延遲等操作都不應該放在ISR</font>
- **外部中斷**由外部硬體給入微處理機腳位而產生，**內部中斷**則由程式內部產生
- 對於在執行某個中斷函式時又發生其他事件的中斷時，需要考慮到不同的中斷事件的**中斷優先級**以決定是否要從中斷函式又跳出到另一個中斷函式，中斷優先級有時不注意可能會導致程式執行與預期不符

## 通訊外設
- 通訊基礎概念可以見 野火的<STM32 HAL 庫開發實戰指南> 19章
- 不同通訊協定的原理也在<STM32 HAL 庫開發實戰指南>20、23、24、40、41章講解的很清楚
- 常見的通訊協定有UART、USART、SPI、I2C、CAN等
- 截自<STM32 HAL 庫開發實戰指南>:
    > 使用微處理器控制遵守通訊协议的控制引腳High/Low，就是标准的通讯。由于直接控制GPIO引脚电平产生通讯时序时，需要由CPU控制每个时刻的引脚状态，所以称之为“软件模拟协议”方式。
    > 相对地，还有“硬件协议”方式，STM32的I2C片上外设专门负责实现I2C通讯协议，只要配
置好该外设，它就会自动根据协议要求产生通讯信号，收发数据并缓存起来，CPU只要检测该外设的状态和访问数据寄存器，就能完成数据收发。这种由硬件外设处理I2C协议的方式减轻了CPU的工作，且使软件设计更加简单。
- 上面這段就是在說用硬體實現和軟體實現的區別，就像使用FPGA實作複雜功能電路還是用微控制器實現同樣功能的演算法的區別


## 數據處理與轉換
- <font color="red">ADC(Analog-to-digital converter)</font>，見[成大WIKI](https://wiki.csie.ncku.edu.tw/embedded/ADC#introduction-to-adc)
    - 類比訊號轉換成數位訊號後才能在微處理器內做數位訊號處理，記得微處理器是一種數位電路。例如 : 類比電壓3V轉換成以 8-bit 紀錄的數值為154 (0x9A)
    - 要達成 ADC 轉換需要以下定義
        - **解析度(Resolution)** : 轉換後數位值的位元數
        - **參考電壓(Vref)** : 要轉換的電壓不能比參考電壓高，參考電壓轉換後對應最大數位值
        - **取樣率(Sampling rate)** : 固定周期會抓一次類比訊號進來做轉換，取樣率影響到訊號重建等問題。取樣率高代表經常取，得到的數位波型更貼近類比波型
        - **轉換公式**，基本上就是線性mapping，把"負參考電壓 ~ 正參考電壓" mapping 到"0 ~ 最大數位值" : 
        <p class="text-center">
            數位值 = [類比電壓 / (正參考電壓-負參考電壓)] * (2^解析度)
        </p>
- <font color="red"> DAC(Digital-to-analog converte) </font>
    - 數位轉類比

## 輸入/輸出控制
- 即 <font color="red">GPIO (General-purpose input/output)</font>，通用輸入/輸出
- 微處理器的GPIO做為與外界溝通的橋梁，可用作接收訊號與發出控制訊號
- GPIO的模式可以看[這篇](https://www.youtube.com/watch?v=dgIyNq3TB_M)
- 微處理器的GPIO腳位有輸出電流限制，並不適合直接驅動高功率元件，譬如馬達
- 上、下拉電阻的功能
    - 對於input來說主要就是避免接腳處於未知狀態
    - [上拉與下拉](https://blog.csdn.net/xatsoft/article/details/87092400)
    - [上拉電阻](https://youtu.be/6boDPKeUZdU)







