嵌入式 系統 training - HT32F175x275x

Preview:

DESCRIPTION

嵌入式 系統 training - HT32F175x275x. 袁世一 逢甲通訊系. Outline. Embedded system vs. … Clock Control GPIO – General purpose I/O Counter Interrupt AFIO – Alternate Function I/O. Embedded system vs. …. So, programming in Embedded system different from … care about special purposes - PowerPoint PPT Presentation

Citation preview

1

嵌入式系統 training- HT32F175x275x

袁世一逢甲通訊系

2

Outline

• Embedded system vs. …• Clock Control• GPIO – General purpose I/O• Counter• Interrupt • AFIO – Alternate Function I/O

3

Embedded system vs. …PC Embedded Single chip

Purpose General Purpose Special Special

SoC No Yes Yes

IO Functions Easy Complicated Easy

Program type Complicated Complicated Easy

IO programming Easy Complicated Easy

Memory External Internal/External Internal/External

Internal Memory size Generally 0 ~ Kbyte ~ 100 Byte

Block Func Less / Fast More / Medium Less / Slow

So, programming in Embedded system different from …• care about special purposes• care about memory • care about HW considerations• care about COST

4

上課預計時程

日期 上午 (0900-1200) 下午 (1300-1600) 備註7/1 Clock, GPIO 教學 程式練習 GPIO 設定與

Clock 設定有關,必須同時練習

7/2 Counter 教學、程式練習

中斷教學、程式練習

以不同 Counter 程式設計方式 ( 迴圈 , 中斷 )做為練習目標

7/3 AFIO+ 中斷教學程式練習

王磊老師上課,下午時間需要確認

AFIO 將以 ADC 為例作為練習目標

* 希望 7/1 進度可以提前,以增加 7/3 的程式說明時間

5

Clock control (7/1)

• 基礎 ARM 時脈概念• HT32F125x 時脈控制單元 (clock control

unit, CKCU)• 範例程式

6

General ARM clock concept

• 時脈是控制嵌入式系統動作同步的訊號• ARM 為 : 系統晶片 SoC (System on Chip)– 許多功能區塊整合在 IC 內部• 連在不同的 Bus ( 匯流排 ) 上,以提升 IC 效能• 不同 Bus 可以使用不同的時脈

– Bus 種類 : 高 / 低速 bus• AHB: High speed bus• APB: Low speed (Peripheral) bus

7

8

ARM 時脈種類1. HSI & LSI – High/Low speed Internal RC oscillator

– HSI :• 系統預設時鐘,內部 RC 振盪• 可以直接作為系統時鐘或作為 PLL 輸入 (PLL=HSI/2)• 精度較差

– LSI :• 內部 RC 振盪• 低功耗時脈源• 可以在停機和待機模式下保持系統運做• 提供看門狗和自動喚醒單元時脈

2. HSE & LSE – High/Low speed External crystal– HSE :外部振盪器

• 提供非常精確的主時鐘– LSE :低速外部晶體

• 一般專門用於 RTC

9

10

11

3. PLL – phase lock loop ( 倍頻 / 除頻 )• prescalers/

multiplexers( 倍頻 / 除頻設定 )

• System clock (CK_SYS) -> AHB/APB

4. gating ( 停止某些電路功能 )

12

Clk setup: 以 PLL 設定為例

13

CKCU Registers 設定舉例• Global Clock

Configuration Register (GCFGR) – 32 bits– specifies clock source for

PLL/USART/Watchdog Timer/CKOUT circuits

• 使用 C 即可• 如需深入了解,請見

SPEC 中 Registers 說明CKCU_APBPerip0ClockConfig(CKCU_APBEN0_AFIO,

ENABLE);

CKCU_APBPerip0ClockConfig(BUTTON_GPIO_PIN, ENABLE);

14

GPIO – General purpose I/O (7/1)

• ARM GPIO 架構

• ARM IO 控制

15

16

ARM GPIO architecture

• 32 個 GPIO Pin– PA0 ~ PA15 / PB0 ~ PB15– 其他功能腳位也可以分享 GPIO port 來增加功能

的彈性– 透過相關的組態暫存器的設定

17

GPIO 控制• 方向:輸入 OR 輸出• 輸入腳位控制– 弱拉升 / 弱拉降

• 輸出腳位控制– 推拉式控制 OR 開汲極– 推動電流強度– 類比 / 數位 (AFIO 控制 ) – 之後會說明

• 組態鎖定

18

RESET( 或初供電 ) 時 GPIO 之預設值

– 均為 input• 無拉升 / 拉降電阻 (no pull-up/pull-down)

– 例外 :• PA9( 拉降 ) 、 PA10 ( 拉升 ) 、 PA13 ( 拉升 ) 、 PA14

( 拉升 )• For boot/debug

19

GPIO Registers 設定舉例• Port A Data Direction

Control Register (PADIRCR) – 32 bits– control the direction of

the GPIO Port

• 同時脈設定,使用 C即可

• 如需深入了解,請見SPEC 中 Registers 說明

GPIO_DirectionConfig(KEY1_BUTTON_GPIO_PORT, KEY1_BUTTON_GPIO_PIN, GPIO_DIR_IN);

GPIO_DirectionConfig(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_DIR_OUT);

20

程式範例int main(void){ system_init(); while(1) { x = read_input_pin; write_output(x); }}

while(1) { TmpStatus = GPIO_ReadInBit(WAKEUP_BUTTON_GPIO_PORT, WAKEUP_BUTTON_GPIO_PIN); GPIO_WriteOutBits(LED1_GPIO_PORT, LED1_GPIO_PIN, TmpStatus); TmpStatus = GPIO_ReadInBit(KEY1_BUTTON_GPIO_PORT, KEY1_BUTTON_GPIO_PIN); GPIO_WriteOutBits(LED2_GPIO_PORT, LED2_GPIO_PIN, TmpStatus); TmpStatus = GPIO_ReadInBit(KEY2_BUTTON_GPIO_PORT, KEY2_BUTTON_GPIO_PIN); GPIO_WriteOutBits(LED3_GPIO_PORT, LED3_GPIO_PIN, TmpStatus); }}

21

程式範例• system_init:

– Enable APB clock1. enable APB clock for 3 pins2. connect 3 pins to GPIO

function (Port, Pin, Func)3. 3 pins’ GPIO as Input4. enable 3 pins5. same as 1-4 for 3 output

pins

• loop– x=read input– output x -> y

• Too many codes– see code example

int main(void){…

CKCU_APBPerip0ClockConfig(CKCU_APBEN0_AFIO, ENABLE);

CKCU_APBPerip0ClockConfig(DVB_GpioClock[WAKEUP_BUTTON_GPIO_ID], ENABLE);…

HT32F_DVB_GPxConfig(WAKEUP_BUTTON_GPIO_ID, WAKEUP_BUTTON_AFIO_PIN, WAKEUP_BUTTON_AFIO_MODE);…

GPIO_DirectionConfig(WAKEUP_BUTTON_GPIO_PORT, WAKEUP_BUTTON_GPIO_PIN, GPIO_DIR_IN);…

GPIO_InputConfig(WAKEUP_BUTTON_GPIO_PORT, WAKEUP_BUTTON_GPIO_PIN, ENABLE);…

//5: 3 output pins…

while(1) { … }}

22

Practice

• Target1. 使用 for, 控制 LED 閃爍

2. 讀取按鈕值 , 控制 LED 閃爍• 按一次亮 , 再一次暗

3. 讀取按鈕值 , 控制 LED 閃爍的開始 / 停止• 按一次開始閃爍 , 再一次停止閃爍

23

Counter ( 計數器 ) (7/2)

• HT32Fx has 4 counters:– GPTM0/1: General Purpose Timer 0 & 1– BFTM0/1: Basic Function Timer 0 & 1

24

Counter

• This training uses BFTM0

• Two method:1. loop method – this

training2. Interrupt method –

next training

• BFTM 需要設定:– Counter Reg: up counter– Compare Reg: max value– Status Reg:

Counter==Compare

• Use C-lib

25

Counter loop programming

1. clock Init, LED(GPIO) Init2. BFTM setting

1. max value– sysCLK: 1sec– sysCLK/2: 0.5sec

2. counter value (=0)3. BFTM as OneShot

3. loop(1)1. start BFTM (enable)2. wait for BFTM.status

change3. toggle LED

int main(void){CKCU_APBPerip1ClockConfig(…);HT32F_DVB_LEDInit(LED2);

BFTM_SetCompare(BFTM1, SystemCoreClock);BFTM_SetCounter(BFTM1, 0);BFTM_OneShotModeCmd(BFTM1, ENABLE);

while (1) { BFTM_EnaCmd(BFTM1, ENABLE);

while (BFTM_GetFlagStatus(BFTM1) != SET);

BFTM_ClearFlag(BFTM1);

HT32F_DVB_LEDToggle(LED2); }}

26

Counter programming

• Interrupt counter control: – Training latter

27

Interrupt (7/2)

• Interrupt concept• ARM NVIC• sample code

28

Interrupt concept

• 中斷是一個訊號,會促使電腦改變其正常的運作流程。

• 在接收到來自外部硬體信號之後, CPU 將進行相應的硬/軟體處理– 發出的信號稱為中斷請求

( interrupt request , IRQ )– IRQ 導致 CPU 執行資訊切換

( context switch )來保存執行狀態

– 中斷會將控制權轉換到中斷處理常式 (Interrupt Service Routine, ISR)

• 軟體中斷則為 CPU 指令集中的一個中斷指令

29

30

• 種類– 狀態觸發– 邊沿觸發

• 中斷向量表– 中斷向量表包含數個中

斷向量,每個向量包含中斷處理程序的起始地址

31

• 中斷處理過程– 外部硬體信號發出 IRQ– CPU結束執行上一個機械碼

– CPU 同意中斷– CPU儲存 CPU 執行狀態– CPU 取得中斷位址– CPU 執行 ISR– ISR 執行完成– CPU 取得中斷前 CPU 執行

狀態– CPU繼續執行原本程式

32

ARM NVIC

• NVIC – Nested Vectored Interrupt Controller

• Interrupt Number: 31 peripheral Int

• Interrupt Types:– USART, SPI, I2C– Timer (BFTM, GPTM)– ADC, Comparator,– GPIO input– WakeUP signal, RTC, Low

Vdd– Clock (HSE, HIS, LSE, LSI,

PLL)

• Priority: configurable, 16 levels

NVIC_EnableIRQ(BFTM0_IRQn);

33

Counter Interrupt programming

1. clock Init, LED(GPIO) Init

2. BFTM_INT unmask3. BFTM setting

1. max value– sysCLK: 1sec– sysCLK/2: 0.5sec

2. counter value (=0)3. BFTM Interrupt enable4. begin BFTM

4. loop(1) do_nothing();

int main(void){CKCU_APBPerip1ClockConfig(…);HT32F_DVB_LEDInit(LED1);NVIC_EnableIRQ(BFTM0_IRQn);

BFTM_SetCompare(BFTM0, SystemCoreClock/2); BFTM_SetCounter(BFTM0, 0);BFTM_IntConfig(BFTM0, ENABLE); BFTM_EnaCmd(BFTM0, ENABLE);

while (1) { }}

//in ht32f…_it.c:// Interrupt service routing (ISR):void BFTM0_IRQHandler(void){ HT32F_DVB_LEDToggle(LED1); BFTM_ClearFlag(BFTM0);}

34

AFIO – Alternate Function I/O (7/3)

• 擴大 GPIO 的靈活性• GPIO 外設功能• 每個 GPIO 腳• 配置為有四個不同的功能 ( 設置 GPxCFGR

暫存器 )• 根據 IP 資源的使用情況和應用需求,可以

使用週邊 I/O 映射機制來選擇合適的功能

35

36

AFIO 功能

37

AFIO 功能

38

Example: ADC

• Set AFIO to ADC • Set ADC to get Analog

data from potentionmeter ( 電位計 )

39

HT32F ADC 特性• 12-bit ADC• Sample rate: Up to 1 uS/S• 8 external channels• 2 int_ref_voltage:Vssa &

Vdda• sampling time for each

channel• Three conversion modes

– One shot– Continuous– Discontinuous

• 8 dedicated sequencers and data registers

• Triggered by– Software– external interrupt– GPTM (MTO and PWM CHnO)

• Interrupts for ...– Single conversion end– Subgroup conversion end– Cycle conversion end– Analog Watchdog– Data register overwrite

40

• Function descriptionsConfiguration– ADRST [0] = 1: ADC reset

• Clock setup:– CK_ADC = APB_PCLK

• ADC Trigger– ADCTCR (Trigger Control

Registers)• ADTM = ADCTCR[2]: GPTM

enable• ADEXTI = ADCTCR[1]: EXTI

enable• ADSW = ADCTCR[2]: SW enable

– ADCTSR (Trigger Source Registers)• GPTME = ADCTSR[26:24]: GPTM

Event selection (all at rising edge_– 0: GPTM MTO– 1-4: CH0-CH3

• GPTMS = ADCTSR[18:16] GPTM selection– 2/3 = GPTM0/GPTM1

• ADEXTIS = ADCTSR[11:8] : EXTI line selection– 0-F: EXTI line 0-15

• ADSC = ADCSTR[0]: – set: SW Event begin once– reset: automatic when this

ADC complet

41

• Data save register• ADCDRn (n=0-7)• flag ADVLDn goes to

1, automatically , if ADCDRn is valid

• flag ADVLDn goes to 0, automatically, if ADCDRn is read

• if ADCDRn not read and overwrited by another ADC round, ADIAWO of ADCIRAW = 1

• Status Flags• ADIRAWO =

ADCIRAW[24]: data register overwrite error

• ADIRAWS = ADCIRAW[2]: register: single sample finish

• ADIRAWG = ADCIRAW[1]: register: sub-group finish

• ADIRAWC = ADCIRAW[0]: register: cycle (group) finish

42

• Interrupt • ADIMASKO = ADCIMSK[24]:

ADC Data overwrite INT mask

• ADIMASKC = ADCIMSK[2]: cycle (group) finish INT mask

• ADIMASKG = ADCIMSK[1]: sub-group finish INT mask

• ADIMASKS = ADCIMSK[0]: single ADC finish INT mask

• Trigger begin:• SW trigger: ADSC of

ADCTSR (when start ADC, ADSC reset)

• 5 GPTM trigger: MTO (master), 4 GPTM-CHn (n=0-3)

• EXTInt trigger:– setup: ADEXIS register -

EXTInt (n=0,1)– ADEXTI=1

43

• Sample time:• ADSTn of

ADCSTRn[7:0] (n=0-7):– sampling time of channel

n– T_conv = Tsample + Tlat– (conversion time,

sampling time, latency)– Tasmple = ADSTn + 1.5

cycle– minimum Tlat = 12.5 cycle

• Example:– CK_ADC = 14MHz,

ADSTn = 0 – Tconv = 1.5 + 12.5 = 14

cycles (=1us)

44

• Turn off ADC: ADCEN reset• Interrupt setup• All flags are set by SW for

clearing, and automatically reset by HW

• ADCICLRO = ADCICLR[24]: ADC Data overwrite INT Clear

• ADCICLRC = ADCICLR[2]: cycle (group) finish INT clear

• ADCICLRG = ADCICLR[1]: sub-group finish INT mask clear

• ADCICLRS = ADCICLR[0]: single ADC finish INT mask clear

45

Sample Codeint main(void){USART_Configuration(); //for PC

Enable_ADC_IRQ();

ADC_Clock_Enable();

AFIO_PIN6_SetTo_ADC(); ADC_Configure(ContinuousMode, 1 channel, sample rate, SW_trigger);

ADC_enable();

begin_ADC(); while (1) { /* Output gPotentiometerLevel if needed. */ printf("\rPotentiometer level is %d %% ", (int)gPotentiometerLevel); }}

46

USART_Configuration

void USART_Configuration(void){ USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WORDLENGTH_8B; USART_InitStructure.USART_StopBits = USART_STOPBITS_1; USART_InitStructure.USART_Parity = USART_PARITY_NO; USART_InitStructure.USART_Mode = USART_MODE_NORMAL;

HT32F_DVB_COMInit(COM1, &USART_InitStructure); }

47

Enable_ADC_IRQ

NVIC_EnableIRQ(ADC_IRQn);

48

ADC_Clock_Enable

/* Enable peripheral clock of ADC */ CKCU_APBPerip1ClockConfig(CKCU_APBEN1_ADC, ENABLE); CKCU_APBPerip0ClockConfig(CKCU_APBEN0_AFIO, ENABLE);

/* ADCLK frequency is set to 72/64 MHz = 1.125MHz */ CKCU_SetADCPrescaler(CKCU_PCLK_DIV64);

49

AFIO_PIN6_SetTo_ADC

/* Config AFIO mode as ADC function */ AFIO_GPAConfig(AFIO_PIN_6 , AFIO_MODE_1);

50

ADC_Configure /* Continuous Mode, Length 1, SubLength 1 */

ADC_RegularGroupConfig(ADC, CONTINUOUS_MODE, 1, 1);

/* ADC Channel 6, Rank 0, Sampling clock is (1.5 + 0) ADCLK Conversion time = (sampling clock + 12.5) / ADCLK = 12.4 uS */

ADC_RegularChannelConfig(ADC, ADC_CH_6, 0, 0); /* Use Software Trigger as ADC trigger source */

ADC_RegularTrigConfig(ADC, ADC_TRIG_SOFTWARE);

51

ADC_enable()

/* Enable ADC single end of conversion interrupt, The ADC ISR will store the ADC result into global variable gPotentiometerLevel. */

ADC_IntConfig(ADC,ADC_INT_SINGLE_EOC, ENABLE);

//in: ht32f175x_275x_it.cvoid ADC_IRQHandler(void){ ADC_ClearIntPendingBit(ADC, ADC_FLAG_SINGLE_EOC); gPotentiometerLevel = (((ADC->DR[0]&0x0FFF)*100)/4095);}

52

begin_ADC

/* Software trigger to start continuous mode */ ADC_SoftwareStartConvCmd(ADC, ENABLE);

53

Sample Codeint main(void){USART_Configuration();

Enable_ADC_IRQ();

ADC_Clock_Enable();

AFIO_PIN6_SetTo_ADC(); ADC_Configure(ContinuousMode, 1 channel, sample rate, SW_trigger);

ADC_enable();

begin_ADC(); while (1) { /* Output gPotentiometerLevel if needed. */ printf("\rPotentiometer level is %d %% ", (int)gPotentiometerLevel); }}

54

Sample Codeint main(void){USART_Configuration();NVIC_EnableIRQ(ADC_IRQn);CKCU_APBPerip1ClockConfig(CKCU_APBEN1_ADC, ENABLE);CKCU_APBPerip0ClockConfig(CKCU_APBEN0_AFIO, ENABLE);

CKCU_SetADCPrescaler(CKCU_PCLK_DIV64);AFIO_GPAConfig(AFIO_PIN_6 , AFIO_MODE_1);ADC_RegularGroupConfig(ADC, CONTINUOUS_MODE, 1, 1); Conversion time = (sampling clock + 12.5) / ADCLK = 12.4 uS */ADC_RegularChannelConfig(ADC, ADC_CH_6, 0, 0); ADC_RegularTrigConfig(ADC, ADC_TRIG_SOFTWARE); ADC_IntConfig(ADC,ADC_INT_SINGLE_EOC, ENABLE);ADC_SoftwareStartConvCmd(ADC, ENABLE); while (1) { printf("\rPotentiometer level is %d %% ", (int)gPotentiometerLevel); }}

55

Practice

Target 1 (first practice)1. read sample code –

knowing each line’s meaning

2. connect the behavior in mind

3. compiling/executing code

Target 2 (second practice)1. change PC’s ADC value

to binary2. check the stability of

ADC3. change ADC channel to

2 if possible

Note: 下午是王壘老師上課,下午上課時間需要確認

Recommended