---
# System prepended metadata

title: STM32
tags: [Car Project]

---

---
title: STM32
tags: Car Project
---
[toc]

:::success
This is a personal project developed for learning and experimentation.
Suggestions and feedback are always welcome. Thank you. 
Created on April 1, 2026 by Chia-Lun
:::

# **STM32**
## Pin define
| Pin | 原定義 | 我的定義 |        PIN |原定義 | 我的定義 |
| -------- | -------- | -------- | -------- | -------- | -------- |
| 1    | VBAT |      | 33 | PB12_CS | PB12_GPIO_OUT    |
| 2    |      |      | 34| PB13_SCL | PB13_GPIO_OUT     |
| 3    | PC14_OSC_IN1  |  PC14_OSC_IN1    | 35| PB14_SDO     |  PB14_EXTI14    |
| 4    | PC15_OSC_OUT1 |  PC15_OSC_OUT1    | 36| PB15_SDI     |  PB15_EXTI15    |
| 5    | OSC_IN2 |  OSC_IN2    | 37| PC6_RS     | PC6_USART6_TX     |
| 6    | OSC_OUT2 |  OSC_OUT2    | 38| PC7_BLK     | PC7_USART6_RX     |
| 7    | RESET |  RESET    | 39|      | PC8_PWMA |
| 8    |      |      | 40|      | PC9_PWMB |
| 9    |      |      | 41| PA8_LED     |      |
| 10    |      |  PC2_EXTI2   | 42| PA9_TXD1     |   USART1_TX   |
| 11    |      | PC3_EXTI3   | 43| PA10_RXD1     | USART1_RX      |
| 12    | GND |      | 44| PA11_USB_D-     | PA11_USB_D-      |
| 13    | 3.3V |      | 45| PA12_USB_D+     | PA12_USB_D+      |
| 14    | WK_UP |  PA0_TIM2_CH1    | 46| PA13_SWDIO     |   PA13_SWDIO    |
| 15    |      | PA1_TIM2_CH2     | 47|      |      |
| 16    |      | PA2_TIM5_CH3     | 48|      |      |
| 17    |      | PA3_TIM5_CH4     | 49| PA14_SWCLK     |  PA14_SWCLK    |
| 18    | GND |      | 50| PA15_FLASH_CS     | PA15_FLASH_CS     |
| 19    | 3.3V |      | 51|      |      |
| 20    |      |ADC1_IN4      | 52|      |      |
| 21    |      | PA5_STBY     | 53|      |      |
| 22    |      | PA6_TIM3_CH1     | 54|      |      |
| 23    |      | PA7_TIM3_CH2     | 55| PB3_SPI3_SCK | PB3_SPI1_SCK     |
| 24    |      | PC4_AIN1     | 56| PB4_SPI3_MISO    | PB4_SPI1_MISO     |
| 25    |      | PC5_AIN2     | 57| PB5_SPI3_MOSI     | PB5_SPI1_MOSI     |
| 26    |      | PB0_BIN1     | 58|      |  PB6_EXTI6    |
| 27    |      | PB1_BIN2     | 59|      | TIM4_CH2     |
| 28    | BOOT1 |      | 60| BOOT0     |      |
| 29    |      | I2C2_SCL     | 61|      | I2C1_SCL     |
| 30    |      | I2C2_SDA     | 62|      | I2C1_SDA    |
| 31    | GND |      | 63|      |      |
| 32    | 3.3V |      | 64|      |      |

![image](https://hackmd.io/_uploads/BkOp0HR5Wg.png)
- APB2的速度會比APB1快可以到168MHz，注意哪些Timer連到APB2

- STM32F405的clock limitation
![image](https://hackmd.io/_uploads/BydncC95-l.png)
## STM32CubeMX for STM32F405RGT6(用來做初始的pin define和code gen)
### New Project
![image](https://hackmd.io/_uploads/rJ8Bovqc-g.png)
### USART1、USART6
- USART6(讀sensor用)
    - Mode：Asynchronous (發送方和接收方不需要共用同一個時脈訊號)
    - CTS / RTS：Disabled (我的資料量不大)
    - Baud rate：115200 (每秒鐘傳輸的位元數較多，資料傳輸速度快，之後可以試試921600)
    - DMA：Enabled (開RX就好，隨時準備接收資料，並設定DMA (直接記憶體存取) 循環模式 (Circular Mode) 是一種讓數據傳輸不間斷的自動化機制。初始化後，DMA 會自動重新載入記憶體位址和傳輸數量，在一幀資料發送或接收完畢後立即自動開始下一幀，無需 CPU 介入，適用於 ADC 數據採集、音訊串流或 UART 連續發送等情境。)
    - NVIC：Enabled (Nested Vectored Interrupt Controller，嵌套向量中斷控制器) 是 ARM Cortex-M 系列處理器核心的硬體模組，負責管理 MCU 中所有中斷與異常。
- USART1(Debug PA9、PA10)
    - Mode：Asynchronous
    - Baud rate：115200
### Timer(Tim8、Tim6)
>[!Note] 
> TIM1/TIM8：APB2
> TIM2/TIM3/TIM4：來源於APB1
- Tim8
    - Clock source：Internal clock 
    - PWM Generation CH3和CH4(因為要控制兩個輪子) (並確認GPIO Mode = Alternate Function (AF))
    - Parameter Setting：Prescaler=83、Period=99
    - Pinout view
        - right click
            - Enter User label：PWMA、PWMB
>[!Note] 這設定是假設PWM頻率要10KHz
>因為 PWM頻率 = Timer clock / (Prescaler + 1) / (Period + 1)
如果APB prescaler不等於1則Timer clock=APB clock x 2(APB clock可以從Clock configuration看到)
>Prescaler是用來把 clock 變慢
>Period愈大控制愈精細，它代表的是解析度

>[!Note] 控制馬達轉速時
>Duty = Percentage * (ARR+1)
>ARR為(Period)Auto reload register

>[!Note] PWM的速度(DUTY)改CCR（Capture Compare Register決定何時輸出 High/Low）
>Duty = CCR / Period

- Tim6(PID控制、感測更新，用來發interrupt)
    - 假設要設成1kHz
      而APB1 Timer Clock = 84 MHz
      那prescaler可以是8400-1，Period可以是10-1
      最後84/8400*10=1000Hz
    - prescaler：8399
    - Period：9
    - Auto-reload period：Enabled
    - NVIC：Enable Interrupt
>[!Note] Timer配置
>Tim1、Tim8：高級(PWM、馬達)
>Tim2~5：Encoder、PWM
>Tim6、Tim7：時間中斷(基本定時器，最乾淨，專門用來定時觸發)
### Timer(Tim2、Tim3)
| Mode	| CNT增加規則 | 實際脈衝數/圈|
| -------- | -------- | -------- | 
|TI1	|只看 A 相	|PPR|
|TI2	|只看 B 相	|PPR|
|TI12	|AB 相	|4 × PPR|

- Combined channels：Encode mode
    - Parameter Settings：
        - Prescaler：0
        - Counter Period：65535
        - IC Polarity：Rising
        (正緣觸發)
        - Encoder Mode：Tl1 and Tl2 
        (因為霍爾編碼器有兩個輸出CLK和DT)
        CLK：A 相（Phase A）
        DT：B 相（Phase B）
        是兩個差90度的方波
        速度看脈波數量，轉動方向看AB先後順序

>[!Note]Pulses Per Revolution / Counts per Revolution
>由馬達規格得知Pulses Per Revolution為13，也就是轉一圈會產生13個脈波(每發生low到high再到low完整脈波算一個)。
>因此Counts per Revolution = 13x4，因為使用了AB相，成90度去偵測，且每次由low到high或high到low都算一個count(也就是4倍頻)

>[!Note]RPM(Revolution Per Minute)每分鐘轉速
>霍爾增量編碼公式為 $RPM=Diff / CPR /Sample Time*60$
>Diff為固定間隔時間內讀到的脈衝數
>Sample Time為取樣的間隔時間
>1. 所以diff/CPR是單位時間內轉了幾圈
>2. 除以Sample Time得到每秒轉了幾圈
>3. 乘上60得到每分轉了幾圈
>
>最後再除以齒輪的減數比(我的馬達為1:30)，可以得到輸出軸的轉速

>[!Note]Low-Pass Filter Formula 可以抑制減少雜訊
$RPM_{filtered}$ = $RPM_{prev}$ × (1−α)+$RPM_{new}$ x α
RPM_prev：前一次濾波後的結果
RPM_new：這次計算的瞬時值
α：濾波係數（0~1） → 越小平滑效果越強、延遲越大

### Timer(Tim4)
- Tim4
    - PWM Generation CH2(並確認GPIO Mode = Alternate Function (AF))
        - Parameter Setting：Prescaler=83、Period=199
        - Pulse：15(啟動時預設90度，進程式中再修改)
        >[!Note] 標準PWM Frequency要50Hz
        >Prescale = 84MHz / (83+1) = 1MHz (計數頻率)= 1us/tick (timer 計數周期(tick time))
        >Period = 1MHz / 50 = 20000 = (19999+1)
        
        >[!Note] 週期 = 1/頻率 = 1/50Hz = 0.02 = 20ms(PWM週期)

![image](https://hackmd.io/_uploads/B1JZT0j9Ze.png)
>[!Note] Pulse計算(計算我應送出這PWM周期的高電位長度也就是高電位持續的"計數值"或"Tick 數") (CCR)
> $Pulse = \dfrac{High Time}{Period Time} * (Period+1) = High Time / 20 * 20000 = 1000 * High Time$
> $HighTime = 0.5 ms + \dfrac{角度}{180}$ * (0.5ms to 2.5ms)
>- (High time控制的是要轉動多少角度，也就是Pulse time高電位持續的實際時間)
>- (PeriodTime是PWM period所以是20ms)
>- (Period+1為20000，這是之前填入CubeMX的值(19999))
>- 假設我要轉180度那HighTime會是2.5，最終Pulse會是2500
>- High Time公式前面的0.5 ms是舵機最小角度(0度)對應的高電位時間，是舵機規格
>- High Time公式後面的(0.5ms~2.5ms)是高電位的時間範圍(最小角度到最大角度)
>簡化後的公式 :
> $Pulse = 500 + \dfrac{ANGLE}{180}*1000$
> 或(以90度為中心)
> $Pulse = 1500 + \dfrac{ANGLE}{90}*1000$

### Timer(Tim5)
- Tim5
    - Channel 3：Input Capture direct mode
    - Channel 4：Input Capture direct mode
    - Parameter Settings：
        - Prescaler：83
        - Counter Period：39999
        - Input Capture Channel 3
            - Polarity Selection：Both Edges
        - Input Capture Channel 4
            - Polarity Selection：Both Edges
    - NVIC Settings：
        - checked TIM5 global interrupt 
>[!Note] 超音波速度343m/s，SRF05量測最大距離4.5m
>$t = \dfrac{(2d)}{v}=\dfrac{2*4.5}{343}=0.0262s=26ms$
>留點buff所以粗估40ms
>$ARR=0.04*10^6=40000=39999+1$


>[!Note] Timer計算
>公式 $T = \dfrac{(ARR+1)}{f_{timer}}$
>
>$f_{timer}$會先被分頻器降頻，所以
>$f_{timer}=\dfrac{84MHz}{83+1}=1MHz$
>然後 $T=\dfrac{(ARR+1)}{f_{timer}}=\dfrac{39999+1}{1MHz}$ = 0.04s ≈ 40ms
>或者當Timer = 1MHz時，每tick count需1us，那40000 count就約40ms

### GPIO
#### 左後輪
- Pinout view
    - PC4、PC5
        - GPIO Output (push and pull)
- System Core
    - GPIO
        - GPIO Mode：Output Push-Pull
        - Pull-up/down：no Pull 
        - Output speed：Medium
        - User label：AIN1、AIN2(讓code可以透過label識別哪個Pin)
#### 右後輪
- Pinout view
    - PB0、PB1
        - GPIO Output (push and pull)
- System Core
    - GPIO
        - GPIO Mode：Output Push-Pull
        - Pull-up/down：no Pull 
        - Output speed：Medium
        - User label：BIN1、BIN2
#### TB6612FNG的STBY
- PA5
    - GPIO_Output
        - GPIO output level：High(把它預設high即開機啟動)
        - GPIO Mode：Output Push-Pull
        - Pull-up/down：no Pull
        - Output speed：Low
        - User label：STBY
### GPIO
- PB12
    - GPIO_Output
        - GPIO output level：Low
        - GPIO Mode：Output Push-Pull
        - User label：Front_Ultrasonic
- PB13
    - GPIO_Output
        - GPIO output level：Low
        - GPIO Mode：Output Push-Pull
        - User label：Rear_Ultrasonic
>[!Note] Echo pin接到stm32要經過降壓，可選擇用1k和2K電阻分壓或
### Clock Configuration
- System Core
    - RCC
        - High Speed Clock (HSE)：Crystal/Ceramic Resonator(使用外部晶振)

>[!Note] Master Clock Output 1(MCO)：Microcontroller Clock Output
>MCO1 可以把 SYSCLK、HSE、HSI、 PLL輸出到某個腳位（PA8）
用途：
>1. 外部設備同步時鐘
>2. 調試用

- Clock Configuration Tab
    - HSE 的Input frequency：8 (我的外部晶振是8MHz) 
    - PLL source Mux：HSE（使用外部晶振）
    沒晶振再選HSI(內部時鐘)
    - PLL /M：/8， *N：*336 ， /P：/2
    - System Clock Mux：PLLCLK
    - AHB Prescale：1
    - HCLK：168 = SYSCLK
    - APB1 Prescale：4
    - APB2 Prescale：2
![image](https://hackmd.io/_uploads/SJ_t8yiqWx.png)
PLL主要目的是對時鐘信號源進行分頻以及倍頻
PLLM計算出來為VCO_IN：通常會先將VCO_IN湊成1
PLLN計算出來為VCO_OUT

![image](https://hackmd.io/_uploads/SJ7M_A99-l.png)

![image](https://hackmd.io/_uploads/S16IHhj5Wx.png)

>[!Note] AHB(Advanced High-performance Bus)有兩個高速總線
>APB1：Timer、I2C1、USART1
>APB2：Timer、ADC
>如果APB1 prescaler不等於1則Timer Clock = APB1 × 2
>所以即使 APB1 = 42 MHz，Timer實際是 84 MHz

>[!Note] Prescaler：分頻器
> 將 SYSCLK 分成較慢的 APB1/2 Clock

>[!Caution]為了USB正常
>Gen完Code後要改code將PLL main的/Q 改成7
### I2C (I2C1)
- I2C Speed Mode：Fast Mode
- I2C Clock Speed：400000
- DMA
    - Add I2C1RX
        - Mode : Normal 
        - Direction : Peripheral-to-Memory
        - Increment Address：checked Memory , unchecked Peripheral
- NVIC settings：enable DMA1 Stream global interrupt 
                I2C1 event interrupt：checked
                I2C1 error interrupt：checked
  >[!Note] I2C Clock = APB Clock / timing 計算出來

|Bank	|用途|
| -------- | -------- |
|BANK 0|	基本資料（Accel / Gyro / WHO_AM_I）|
|BANK 1|	Sensor 設定|
|BANK 2|	Gyro / Accel 詳細設定|
|BANK 3|	I2C Master（內部用）|

  >[!Note] ICM20948線路圖記得將5V改成3.3V
### EXTI6 (External Interrupt 6)
- Pinout view
    - PB6
        - EXTI6
- Pinout & Configuration
   
    - System Core
        - GPIO
            - PB6 Configuration
                - GPIO Mode：External Interrupt with Rising edge triger (正緣觸發)   
        - NVIC 
            - EXTI line[9:5]：Checked 
             >[!Note] EXTI 5~9公用同一個IRQ
             >PB6 → EXTI6 → EXTI9_5_IRQHandler →
HAL_GPIO_EXTI_IRQHandler(stm32f4xx_it.c) → HAL_GPIO_EXTI_Callback
>[!Note] ICM20948的INT需接4.7K歐姆上拉電阻

### I2C (I2C2)
- I2C Speed Mode：Fast Mode
- I2C Clock Speed：400000
### ADC (電壓檢測)
- Analog
    - ADC1
        - IN4(PA4)
            - Parameter Settings
                - Resolution：12 bits (4096)
                - Rank
                    - Sampling Time：15 Cycles
>[!Note] 採樣時間（Sampling Time）
>ADC 內部電容會接到輸入電壓，等電容充電穩定。
在 CubeMX 設定的 Sampling Time 就是這段時間。
這段時間越長 → 電壓穩定度越好、精度越高，但轉換速度越慢。

![image](https://hackmd.io/_uploads/ry888e9i-l.png)

>[!Note] 分壓公式
>$V_{out}$ = $V_{in}*\dfrac{R_2}{R_1+R_2}$
>$V_{out}$為要轉換後給ADC的目標電壓(3.3V)
>$V_{in}$為輸入電壓12V
>
>$\dfrac{V_{out}}{V_{in}}$ = $\dfrac{R_2}{R_1+R_2}$ = $\dfrac{3.3v}{12v}$ 
>=> 0.275 = $\dfrac{R_2}{R_1+R_2}$ => $0.275*R_1+0.275*R_2$=$R2$ 
>=> $0.275*\dfrac{R_1}{R_2}=0.725$ 
>=> $\dfrac{R_1}{R_2} = 2.64$ 
>=> $R_1 = R_2*2.64$
>先將$R_2$固定，通常選10K那$R_1$即為26.4K ≈ 27K
>總電阻10K~100K最佳
>總結公式$R_1=R_2*(\dfrac{V_{in}}{V_{out}}-1)$

>[!Note] ADC計算
>$V_{in}$ = $V_{Ref}*\dfrac{ADC_{value}}{2^n-1}$
>$2^n-1$ 通常為12bits，所以為4095，是將參考電壓切成4095份的意思，即是ADC解析度
>$V_{Ref} = 3.3v$ 
>所以3.3V / 4096 ≈ 0.000805V，每份約為0.000805V
>乘上$ADC_{value}$就可以得到我現在約為幾V
>最後要在乘上經過分壓後的倍率(我的為11)就可以還原原始電壓
>分壓倍率由(R1 + R2) / R2可得
### EXTI2、3、14、15 (External Interrupt)
- Pinout view
    - PC2
        - EXTI2
    - PC3
        - EXTI3
    - PB14
        - EXTI14
    - PB15
        - EXTI15
- Pinout & Configuration
    - System Core
        - GPIO
            - PB6 Configuration
                - GPIO Mode：External Interrupt with Falling edge triger
                - GPIO Pull Up/Down：Pull-up 
        - NVIC 
            - EXTI line[2]：Checked
            - EXTI line[3]：Checked 
            - EXTI line[15:10]：Checked
### Debug 設定
- System Core
    - SYS
        - Debug：Serial Wire
### SPI (W25Q16 FLASH使用)
- 先確定Debug有如上設定好，關閉JTAG避免SWD占用所有的pin
- Connectivity
    - SPI1
        - Mode：Full Duplex Master
        - Prescaler：2
  >[!Note] Prescaler選擇
  >沒有IO2/IO3並聯，所以只能用標準模式，frequency最高為80MHz
![image](https://hackmd.io/_uploads/B1iNOOR5Wl.png)
SPI1連到APB2，所以PCLK為84MHz
根據公式
![image](https://hackmd.io/_uploads/HJ7vYu0c-e.png)
所以Prescaler可以選1或2但，1會逼近Frequency上限可能會有危險，所以選2即可，最終Baud Rate為42MBits/s
![image](https://hackmd.io/_uploads/BJb6tdC5bl.png)

- Pingout view (CS(chip select)要自己透過GPIO設定)
    - PA15
        - GPIO output
        - Label：FLASH_CS

![image](https://hackmd.io/_uploads/r19UTohnbl.png)

### Enable CRC( hardware calculate Checksum )
- Computing
    - CRC：checked Actived 
### NVIC priority setting (Nested Vectored Interrupt Controller)
  >[!Note] 巢狀中斷向量控制器
  >負責管理中斷，中斷可互相打斷(高優先搶低優先)，每個中斷有固定的位址(Vectored)，CPU可直接Jump至對應的ISR
- System Core
    - NVIC
        - Time Base
            - preemption priority：0
        - DMA1 Stream0 global interrupt
            - preemption priority：1
        - EXTI[9:5] Interrupts
            - preemption priority：5
        - USART2 Global Interrupts
            - preemption priority：2
        - I2c event and error interrupts
            - preemption priority：2
        - EXTI[2] Interrupts
            - preemption priority：2 
        - EXTI[3] Interrupts
            - preemption priority：2
        - EXTI[10:10] Interrupts
            - preemption priority：2
### Generate Code設定
- Project Manager
    - Project toolchain/IDE：MDK-ARM
- Code Generate
    - Checked Generate peripheral initialization as a pair of .c/.h
    - Checked Keep User Code when re-generating(沒打勾改的 code 會全部被洗掉)
### 其它注意事項
- 寫code只能放在USER CODE區塊內
```
/* USER CODE BEGIN */
.
.
.
/* USER CODE END */
```
- 新增一個Src 資料夾，之後把User Code放裡面
    - 透過Add New item to group產生.c檔，依類別分好在從main function呼叫自定義function，之後只修改function內的code(可以避免Code放錯位置)
- 初始化流程
```
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USARTx_Init();
MX_TIMx_Init();
```
## Install STM32 ST-LINK utility(除錯、燒錄)
使用的燒錄器為STLINK-V3MINIE
- 使用Pin 1、7、8、9連到開發板做SWD(Serial Wire Debug)
![image](https://hackmd.io/_uploads/HJzUrE65Wg.png)

## Install Keil MDK(Keil MDK Version 5)(Coding開發)
### install package透過pack installer
- STMicroelectronics
    - STM32F4 series
        - STM32F305RG
            - 右側install STM32F4XX_DFP(安裝完左側晶片圖示會變綠)
- Project
    - Options for Target
        - Target
            - ARM compile：Use default compile version 6         
            - Checked Use MicroLIB (加入UART printf)
        - Debug(printf for SWO(要拉SWO線出來到STLink))
            - Settings
                - Trace
                    - Checked Enable Trace 
                    - Core Clock：168 MHz
- View (加入 Instrumentation Trace Macrocell (ITM) printf for SWO(要拉SWO線出來到STLink))
    - Serial Windows
        - Checked Debug (Printf) Viewer
Run Debug mode but don't flash
- 避免debug Mode CPU FREEZE
    在main中加入__HAL_DBGMCU_UNFREEZE_TIMx()，代號x需根據timer 編號修改
- 將code load 到 RAM而不執行燒錄動作
    - Options for Target
        - Target
            - IROM1
                - Start: 0x8000000 to 0x20000000 (SRAM 的起點)
                - Size: half the size of SRAM
                0x100000 to 0x010000
            - IRAM1
                - Start: 0x20000000 to 0x20010000
                - Size: 剩餘的大小
                0x1C000 to 0xC000
            - Initialization File: RAM.ini
        - Utilities
            - Unchecked Update Target before Debugging
- RAM.ini file
```
FUNC void Setup (void) {
  SP = _RDWORD(0x20000000);          // 設定堆疊指標 (Stack Pointer)
  PC = _RDWORD(0x2000004);           // 設定程式計數器 (Reset Vector)
  _WDWORD(0xE000ED08, 0x20000000);   // 設定 VTOR 暫存器
}

load %L incremental;                 // 載入當前專案的 axf 檔案
Setup();                             // 執行上面的設定
```
## Install STM32CubeIDE(更換開發工具)
### CubeMX Procedure
- Project Manager
    - Project toolchain/IDE：STM32CubeIDE

### CubeIDE Procedure
- Import Project
    1. Import > General > Existing Projects into Workspace
    2. Select root directory

- 右鍵Properties > Resource > Text file encoding > other > UTF-8
- 右鍵Properties > C/C++ Build > Settings > Tool Settings > MCU GCC Compiler -> Include paths > Add ../UserSrc
- 排除非code的目錄避免build code錯誤 > 流程圖資料夾 >右鍵 > Resource Configurations -> Exclude from Build... 
- 檢查UserSrc目錄是否被加入排除build code目錄，確定Exclude from Build... 裡的debug和release都不能被勾選
- MDK-ARM是keil MDK在使用的所以也排除它(如果有看到)
- 設定 SWD
    1. 小甲蟲」 圖示旁的箭頭，選擇 Debug Configurations...
    2. 找到 STM32 Cortex-M C/C++ Application 
    3. New Configuration
    4. Debug Page
        - Interface：請在下拉選單中選取 SWD（不要選 JTAG）
        - Frequency：建議維持 Auto
- 開啟float format
    - 右鍵Properties > C/C++ Build > Settings > MCU settings > checked Use float with printf....
    
## Git
1. Create git repo
```
cd [project folder]
git init
```
2. Create git gitignore
```
#create .gitignore file
touch .gitignore 
```
3. Add below in .gitignore 
```
# Build files
Debug/
Release/
*.o
*.d
*.elf
*.bin
*.map

# STM32CubeIDE
.settings/

# Logs
*.log

# OS
.DS_Store
Thumbs.db
```
3. Add my file into staging area
```
git add .
git status #確認檔案是否正確
```
4. Add my file into local db
```
git commit -m "Initial commit"
```
5. Login github and Create a new repository
6. Add repository
```
git remote add origin https://github.com/ChengChialun/Car_Project.git
```
7. Create main branch and push on repository
```
git branch -M master
git push -u origin master
```
                
