Upload
lamxung-baotudau
View
138
Download
14
Embed Size (px)
DESCRIPTION
Tai lieu lap trinh cua Th.s Ngo Thi Vinh
Citation preview
1
CHNG 3: LP TRNH KIT STM32
3.1. Lp trnh qua cc chn vo ra chung
Cc b vi x l STM32 l nhng h thng phc tp vi nhiu thit b ngoi
vi. Bt k thit b ngoi vi cng phi c cu hnh trc khi s dng. Mt s cu
hnh ny l dung chung chng hn cu hnh xung clock hay chn, phn cn li l
cu hnh thit b ngoi vi c th. Trong phn ny chng ta s xy dng chng
trnh nhy LED lm th d c th.
Cc bc khi to c bn cn thit s dng bt k thit b ngoi vi no ca
STM32 l:
1. Kch hot xung clock cho ngoi vi
2. Cu hnh chn theo yu cu ca cc thit b ngoi vi
3. Cu hnh phn cng ca ngoi vi
Vi x l STM32 cng nh cc thnh vin ca h Cortex-M3 u c mt b
nh thi h thng c s dng cung cp xung nhp thng xuyn "tick". Th
d sau s dng timer ny to tc nhy lin tc cho cc LED. Cu trc tng
th ca chng trnh ny c minh ha trong hnh di y. Chng trnh bt
u bng vic khao bo cc th vin phn mm c lin quan - trong trng hp
ny l khai bo timer h thng v cu hnh cc pin. Chng trnh chnh gm cc
bc khi to c m t trn v mt vng lp cha hm Toggles() bt mt n
LED sang v ch 250ms.
Hm tip theo thc hin chc nng to tr trong s dng timer h thng.
Cui cng, mt mt hm tr gip c cung cp x l vi phm cho php trong
th vin firmware (cn thit lnh if USE_FULL_ASSERT c nh ngha khi
bin dch cc module trong th vin firmware). Ni dung hm assert_failed khng
lm g nhng n l rt hu ch khi g li cc d n khi cc th vin phn mm s
thc hin kim tra tham s m rng. Trong trng hp vi phm vng qun l,
2
trnh debug GDB c th c s dng kim tra cc thng s ca hm ny
xc nh im tht bi.
#include
#include
#include
void Delay(uint32_t nTime);
int main(void) {
GPIO_InitTypeDef GPIO_InitStructure;
// Enable Peripheral Clocks
... (1) ...
// Configure Pins
... (2) ...
// Configure SysTick Timer
... (3) ... while (1) {
static int ledval = 0;
// toggle led
... (4) ...
Delay(250); // wait 250ms }
}
// Timer code
... (5) ...
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line) {
/* Infinite loop */
/* Use GDB to find out why we're here */ while (1);
} #endif
KIT STM32 VL discovery c mt LED c ghp ni ti chn PC9, chng
ta phi cu hnh xung Clock nh sau:
3
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // (1)
Trong th gii ca cc b x l nhng, in nng tiu th l rt quan trng;
do , b x l nhng tinh vi nht cung cp c ch tt ngun khi khng cn thit
cho mt ng dng c th. STM32 c mt mng li phn phi xung clock phc
tp m bo rng ch nhng thit b ngoi vi thc s cn thit c cung cp.
H thng ny, c gi l Reset v Clock Control (RCC) c h tr bi cc m-
un firmware stm32f10x_rcc. [ch]. Trong khi m-un ny c th c s dng
kim sot cc xung clock h thng v cc PLLs chnh, bt k yu cu cu hnh no
ca ngi lp trnh cng c x l bi phn m khi ng. y chng ta n
gin ch kch hot xung clock cho cc ngoi vi.
Cc thit b ngoi vi ca STM32 c t chc thnh ba nhm ring bit gi
l APB1, APB2, v AHB. Thit b ngoi vi APB1 bao gm cc thit b I2C,
USART t 2-5, v cc thit b SPI; Thit b APB2 bao gm cc cng GPIO, b
iu khin ADC v USART1; thit b AHB ch yu bao gm cc b iu khin
DMA v giao din b nh ngoi (v mt s thit b khc).
Xung clock cung cp cho cc thit b ngoi vi khc nhau c th c kim
sot vi mt trong ba hm khi to firmware nh sau:
RCC_APB1PeriphClockCmd(uint32_t RCC_APB1PERIPH, FunctionalState
NewState)
RCC_APB2PeriphClockCmd(uint32_t RCC_APB2PERIPH, FunctionalState
NewState)
RCC_AHBPeriphClockCmduint32_t RCC_AHBPERIPH, FunctionalState
NewState)
Mi hm c 2 tham s: mt tham s ch thit b ngoi vi mun s dng v mt
tham s ch hnh ng s thc hin vi mt trong 2 gi tr ENABLE hoc
DISABLE. Th d, khi to xung clock cho cng A v cng B ta c lnh sau:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
RCC_APB2Periph_GPIOB, ENABLE);
4
Th d trn l ph hp vi STM32 F1, i vi cc STM32 khc phi c file dng
stm32fxxxx_rcc.h xem cc nh ngha xung trn tng bus c th.
Bng 3.1. Bng phn phi cc xung clock trn kt STM32F1
Bng nh ngha phn b cc xung clock cho cc ngoi vi trn STM32 F1
(stm32f10x_rcc.h)
Ngoi ra, ngi lp trnh c th cu hnh thanh ghi RCC_APB2ENR cho php
hoc khng cho php cc xung clock n cc ngoi vi tng ng. Thanh ghi
RCC_APB2ENR gm cc bt cu hnh xung clock nh sau:
Hnh 3.1. Thanh ghi RCC_APB2ENR vi cc bt cu hnh xung clock
5
Th d, cu hnh xung ca cng GPIOA v GPIOB ta c th s dng lnh:
ABP2ENR |= 0x0C;
Sau khi cu hnh xung clock cho ngoi vi, chng ta cu hnh cc chn vo ra, trong
th d sau ta s cu hnh chn PC9:
/* (2) */
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
Sau khi c cu hnh xong, chn vo/ra c th c thit lp (set) hoc xo
(reset) nh lnh sau:
/* (4) */
GPIO_WriteBit(GPIOC, GPIO_Pin_9, (ledval) ? Bit_SET : Bit_RESET);
ledval = 1 - ledval;
Hu ht cc chn ca STM32 c th c cu hnh nh l chn u vo hoc u
ra v c th c mt trong hai chc nng l cng GPIO hay "chc nng thay th"
(i vi thit b ngoi vi khc). Nh mt quy c t tn chun, cc chn c gi
bng chc nng GPIO ca chng - v d PA0 (bit 0 ca cng A) hoc PB9 (bit 9
ca cng B).
Vi mi rng buc phn cng c th, mi pin c th c cu hnh mt trong
cc ch nh sau:
6
Bng 3.2. Cc ch ca mt chn (stm32f10x_gpio.h)
Mc nh khi ch reset tt c cc chn ch Input Floating
m bo khng c xung t phn cng no xy ra. Th vin firmware cung cp
cc hm khi to trong file stm32f10x_gpio.[ch] cho php cu hnh cc chn.
Khi cu hnh vi u ra nh trn, chng ta c ba la chn tc u ra l:
50 MHz, 10 MHz, v 2 MHz. Ni chung, v l do tiu th in nng v nhiu,
ngi ta thng s dng cc tc thp khi cu hnh chn vi mc ch vo ra.
cu hnh cc chn kt hp vi cc nt nhn trn KIT, ta s dng on code sau:
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
c gi tr hin hnh ca nt nhn ta s dng lnh:
GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)
16 bt ca mi cng vo ra c th c cu hnh vi thanh ghi CRL (cc
chn t 0-7) v CHR (chn t 8-15). h tr cc ch vo ra khc nhau ngi
ta s dng 4 bt cu hnh cho tng chn ca cng GPIO. c cc bt song song
trn cng s dng thanh ghi IDR v ghi song song s dng thanh ghi ODR. Cc
thanh ghi BSRR v BRR cho php set v reset cc bt ring r. Thanh ghi LCKR
cung cp mt c ch cho php kho thanh ghi bo v phn cng khi nhng li
khi phn mm cu hnh li thanh ghi.
Hng s SystemCoreClock l s chu k xung clock/giy c nh ngha
trong th vin ngoi vi:
/* (3) */
if (SysTick_Config(SystemCoreClock / 1000)) while (1);
7
y, c sau msec th b to timer li gi phng thc SysTick_Handler.
demo led nhp nhy, chng ta gim b m chia s bng cch khao bo __IO
m bo rng cc trnh bin dch khng thc hin cc ti u khng mong mun.
/* (5) */
static __IO uint32_t TimingDelay;
void Delay(uint32_t nTime){
TimingDelay = nTime;
while(TimingDelay != 0);
}
void SysTick_Handler(void){
if (TimingDelay != 0x00)
TimingDelay--; }
3.2. Lp trnh ngt ngoi
Phn ny s hng dn cch lp trnh ngt ngoi trn kt STM32F4. Mi
thit b STM32F4 c 23 ngun ngt ngoi. Chng c chia lm 2 loi. Loi 1 l
cc ngoi vi cc chn t chn P0 n chn P15 trn tng cng v loi 2 l ngt
cho cc loi khc nh RTC, Ethernet, USB, .
3.2.1. Ngt trn cc chn vo ra
Cc ng ngt: Chng ta c th cu hnh cc chn vo ra l cc chn ngt
v iu khin chng vi cc hnh CMSIS. Ngt loi 1 c 16 ng ngt t line0
n line15 tng ng vi cc chn t pin0 n pin15 trn mi cng. Tc l PA0
tng ng vi line0, PA12 tng ng vi line12,.
Tt c cc chn trn kt u l chn ngt, Px0 kt ni ti line0, px3 kt ni
ti line3 v c tip tc nh vy. S hiu chn cng vi s hiu line, nhng ti mt
thi im ch c 1 chn kt ni ti 1 line.
Mi chn c th bt cc tn hiu ngt khi c tn hiu sn tng hoc sn gim
hoc lc tng, lc gim.
3.2.2. iu khin ngt:
8
STM32F4 c 7 trnh iu khin ngt cho cc chn GPIO. Chng c m t trong
bng di dy:
S hiu ngt Tn trnh iu khin M t
EXTI0_IRQn EXTI0_IRQHandler iu khin ngt cho cc chn
kt ni ti line 0
EXTI1_IRQn EXTI1_IRQHandler iu khin ngt cho cc chn
kt ni ti line 1
EXTI2_IRQn EXTI2_IRQHandler iu khin ngt cho cc chn
kt ni ti line 2
EXTI3_IRQn EXTI3_IRQHandler iu khin ngt cho cc chn
kt ni ti line 3
EXTI4_IRQn EXTI4_IRQHandler iu khin ngt cho cc chn
kt ni ti line 4
EXTI9_5_IRQn EXTI9_5_IRQHandler iu khin ngt cho cc chn
kt ni ti cc line t 5 n 9
EXTI15_10_IRQn EXTI15_10_IRQHandler iu khin ngt cho cc chn
kt ni ti cc line t 10 n 15
Bng 3.3. Trnh iu khin ngt ngoi cho GPIO trn kt STM32F4
Sau khi thit lp ngt, ngi lp trnh c th thm n vo b iu khin ngt
NVIC.
3.3.3. Th d
Chng trnh sau s thit lp cc chn PD0 v PB12 l cc chn ngt.
#include "stm32f4xx.h"
#include "stm32f4xx_exti.h"
#include "stm32f4xx_syscfg.h"
#include "misc.h"
/* Cu hnh cc chn l chn ngt */
9
void Configure_PD0(void) {
/* Khai bo cc bin */
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
/* Cho php xung clock ti cng GPIOD */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
/* Cho php xung clock SYSCFG */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* Thit lp cc chn l u vo */
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOD, &GPIO_InitStruct);
/* Bo cho h thng bit chn PD0 s dng cho EXTI_Line0 */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource0);
/* PD0 c kt ni ti EXTI_Line0 */
EXTI_InitStruct.EXTI_Line = EXTI_Line0;
/* Cho php ngt */
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
/* Chn ch ngt */
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
/* Ngt xy ra khi c c sng tng hoc gim */
10
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
/* Thm vo cu trc ngt EXTI */
EXTI_Init(&EXTI_InitStruct);
/* Thm vector IRQ vo NVIC */
/* PD0 kt ni ti EXTI_Line0 tng ng vi vector EXTI0_IRQn */
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
/* Thit lp u tin */
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
/* Thit lp u tin trong nhm */
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
/* Cho php ngt*/
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
/* Thm vo NVIC */
NVIC_Init(&NVIC_InitStruct);
}
void Configure_PB12(void) {
/* Khai bo cc bin */
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
/* Cho php xung clock cng GPIOB */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* Cho php xung clock SYSCFG */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* Thit lp chn l u vo */
11
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Bo cho h thng bit chn PB12 l ngt EXTI_Line12 */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource12);
/* PB12 c kt ni ti EXTI_Line12 */
EXTI_InitStruct.EXTI_Line = EXTI_Line12;
/* Cho php ngt */
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
/* Chn ch l ngt */
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
/* Cho php xy ra ngt theo c sng tng vo sn gim */
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
/* Thm vo EXTI */
EXTI_Init(&EXTI_InitStruct);
/* Thm vector ngt vo NVIC */
/* PB12 c kt ni ti EXTI_Line12, tng ng vi vector EXTI15_10_IRQn
*/
NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
/* Thit lp u tin */
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
/* Thit lp u tin trong nhm */
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01;
12
/* Cho php ngt */
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
/* Thm vo NVIC */
NVIC_Init(&NVIC_InitStruct);
}
/* Vit chng trnh con phc v ngt */
/* iu khin ngt ti chn PD0*/
void EXTI0_IRQHandler(void) {
/* Kim tra trng thi ca c ngt c thit lp */
if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
/* Cc lnh khi xy ra ngt */
/* Xo c ngt */
EXTI_ClearITPendingBit(EXTI_Line0);
}}
/*iu khin ngt ti chn PB12 */
void EXTI15_10_IRQHandler(void) {
/*Kim tra xem c ngt c c thit lp khng */
if (EXTI_GetITStatus(EXTI_Line12) != RESET) {
/* Cc lnh cn c thc hin khi c ngt xy ra */
/* Xo c ngt */
EXTI_ClearITPendingBit(EXTI_Line12);
}}
int main(void) {
/* Khi to h thng */
SystemInit();
/* Cu hnh ngt PD0 */
Configure_PD0();
13
/* Cu hnh ngt PB12 */
Configure_PB12();
while (1) {
}}
3.3. Lp trnh Timer
3.3.1. C bn v Timer trong STM32
Timer trong STM32 c rt nhiu chc nng chng hn nh b m counter,
PWM, input capture, ngoi ra cn mt s chc nng t bit iu khin ng c
nh encoder, hall sensors.
Timer l b nh thi c th s dng to ra thi gian c bn da trn cc
thng s: clock, prescaler, autoreload, repetition counter.
Timer ca STM32 l timer 16 bits c th to ra cc s kin trong khong
thi gian t nano giy ti vi pht gi l UEV(update event).
3.3.2. Cc thnh phn c bn ca mt timer trong STM32
TIM_CLK: Xung Clock cung cp cho timer.
PSC (prescaler): L thanh ghi 16 bt lm b chia cho timer, c th chia t 1 ti
65535
ARR (auto-reload register): L gi tr m ca timer (16 bt hoc 32 bt).
RCR (repetition counter register): Gi tr m lp li 16 bt.
Gi tr UEV c tnh theo cng thc sau:
UEV = TIM_CLK/((PSC + 1)*(ARR + 1)*(RCR + 1))
V d: TIM_CLK = 72MHz, PSC = 1, ARR = 65535, RCR = 0.
UEV = 72000000/((1 + 1)*(65535 + 1)*(1)) = 549.3 Hz
Vi gi tr ARR (auto-reload) c cung cp th b nh thi (timer) thc
hin cc ch m khc nhau: m ln, m xung hoc kt hp c 2. Khi thc
hin m ln th gi tr b m bt u t 0 v m ti gi tr ARR-1 th bo trn.
Khi thc hin m xung th b m bt u t gi tr ARR m xung 1 th bo
trn.
3.3.3. Cc ch hot ng ca Timer
14
Timer c 4 ch c bn
- Input capture: Chn chp u vo
- Output compare: So khp trn chn ra
- PWM generation (Edge- and Center-aligned modes): Ch to xung
- One-pulse mode output: u ra ch to mt xung
3.3.4. nh ngha struct cu hnh cho timer c bn
typedef struct
{
uint16_t TIM_Prescaler; /*Gi tr tin nh c s dng chia xung TIM;
l mt s nm trong khong t 0x0000 n 0xFFFF */
uint16_t TIM_CounterMode; /*Ch nh ch m; c th l mt gi tr ca @ref
TIM_Counter_Mode */
uint32_t TIM_Period; /* Ch nh gi tr s c ti vo thanh ghi Auto-Reload
Register ti s kin update tip theo v phi l gi tr nm trong khong 0x0000 n
0xFFFF */
uint16_t TIM_ClockDivision; /*Ch nhg gi tr chia Clock; c th c s dng
bi @ref TIM_Clock_Division_CKD */
uint8_t TIM_RepetitionCounter; /*!< Ch nh gi tr lp li ca Counter value. Mi
ln RCR m li v t ti 0, mt s kin update s c sinh ra v khi ng b m t
RCR (N). Trong ch PWM (N+1) yu cu:
+) S chu k PWM trong ch edge-aligned
+) S chu k PWM trong ch center-aligned
Tham s ny phi l gi tr nm trong khong 0x00 n 0xFF.
@ch : Tham s ny ch hp l cho cc timer t TIM1 n TIM8. */
} TIM_TimeBaseInitTypeDef;
- TIM_Prescaler: Tham s TIM_Prescaler hiu n gin nh mt b chia tn s.
Th d STM32F4 Tn s cao nht m clock timer 4 t c l 84Mhz sau khi qua
b chia ny s ra tn s clock timer(Fc_timer). Nu chn Fc_timer = 1Mhz t
Fc_timer = 84000000/84. TIM_Prescaler c cng thc l:
((SystemCoreClock/2)/1000000)-1 = 83 ,
15
do h m bt u t 0 ch khng phi l 1 nn bt u m t 0 -> 83 s, tc l
84 gi tr.
TIM_Prescaler = ((SystemCoreClock/n)/Fc_timer)-1
Ch : Ty vo timer no m ch s chia n s khc nhau. V d trong STM32F4
gm c nhng timer v h s chia khc nhau nh hnh bn di :
Bng 3.4 Timer v cc h s chia ca STM32F4
- TIM_CounterMode: Thit lp mode cho timer l m ln hay m xung. Nu
chn mode m tng c ngha l mi xung nhp timer, b m counter s t tng
ln mt gi tr theo chiu dng cho n khi no bng gi tr period s m li t
u, ngi ta thng gi trng hp ny l trn b m.
- TIM_Period: Period c ngha l chu k ca timer (khng phi l chu k ca 1
xung clock timer). V d mt chu k gm 1000 xung clock m mi xung clock =
1us ta s c period l 1ms.
Ch : Khi cu hnh s dng timer ta cn quan tm n 3 yu t chnh l :
+) m vi xung clock timer l bao nhiu (Fc_timer xc nh qua
TIM_Prescaler).
+) m ln hay m xung (TIM_CounterMode).
+) m n bao nhiu (TIM_Period).
3.3.5. Th d
16
Th d 1: Cu hnh cho timer 3 trong STM32F1 to ngt vi 100ms
Phn tch: ( lu 1 giy = 1ms x 1000).
- Tn s cao nht m timer 3 trong STM32F1 t c l 72Mhz. Yu cu cn
timer 3 to interrupt mi 100ms.
- Gi s cn Counter ca timer m 100 ln c 100ms v sinh ngt th ta c:
Tn s Fc_timer3 = (100ms x 100 clock) x 10 = 10.000 clock/ 1 giy (10Khz).
Kt qu:
+) TIM_Prescaler = (72000000/10.000 1); //Fc_timer l 10khz
+) TIM_Period = 100 ln 1 = 99
- Gi s cn Counter timer m 1000 ln c 100ms v sinh ngt th tng
t: Tn s Fc_timer3 = (100ms x 1000 clock) x 10 = 100.000 clock/1 giy
(100Khz)
Kt qu:
+) TIM_Prescaler = (72000000/100.000 1); //Fc_timer l 100khz
+) TIM_Period = 1000 ln 1 = 999
Cu hnh cc thng s cho timer3 vi trng hp period = 99:
TIM_TimeBaseStructure.TIM_Period = 99; // delay 10ms
TIM_TimeBaseStructure.TIM_Prescaler = (72000000/10000 1); //10khz
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
Trong Th d ny, chn Fc_timer3 = 10000 (10khz) ngha l :
-> Tn s timer 10.000 xung/1giy tng ng 10 xung/1ms nn tn s cho 10ms
l 100xung/10ms
Th d 2: V d cu hnh cho timer 4 trong STM32F4 sinh ngt sau mi 1ms
Phn tch: Tn s cao nht m m timer 4 trong STM32F4 t c l 84Mhz -
Yu cu cn timer 4 to interrupt mi 1ms: Gi s cn counter ca timer m 100
ln c 1ms v sinh ngt th ta c: Tn s Fc_timer4 = (1ms x 100 clock) x
1000 = 100.000 clock/ 1 giy (100Khz).
17
Kt qu:
+) TIM_Prescaler = (84000000/100.000 1); //Fc_timer l 100khz
+) TIM_Period = 100 ln 1 = 99
- Gi s cn counter timer m 1000 ln c 1ms v sinh ngt th tng t:
Tn s Fc_timer4 = (1ms x 1000 clock) x 1000 = 1000.000 clock/1giy (1Mhz).
Kt qu:
+) TIM_Prescaler = (72000000/1000.000 1); //Fc_timer l 1Mhz
+) TIM_Period = 1000 ln 1 = 999 ;
Cu hnh cc thng s cho timer4 vi trng hp period = 999:
// f = 1Mhz
TIM_TimeBaseStructure.TIM_Prescaler = ((SystemCoreClock/2)/1000000)-1;
TIM_TimeBaseStructure.TIM_Period = 1000 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
Trng hp timer 4 trong STM32F4, period = 999; Yu cu m 1000 xung
c ngt 1ms th 1 xung s tng ng vi 1us; H s chia TIM_Prescaler =
1.000.000 trong khi xung h thng cp l 84.000.000 do mi xung ca clock
timer s bng 84 xung ca system clock.
3.4. Lp trnh truyn thng qua UART
3.4.1. Gii thiu chun truyn thng ni tip
Phng php c bn nht giao tip vi mt b x l nhng l ni tip
khng ng b. Truyn thng ni tip khng ng b, thng tin c truyn trn 2
ng dy i xng c kt ni vi nhau. y s cp n host v target.
18
Hnh 3.2. 2 chn truyn v nhn d liu c bn trn STM32
Khi d liu gi t Host sang Target, n gi mt chui bit m ha trn
ng dy truyn TX ca n, Target nhn d liu trn ng dy nhn RX ca n.
Tng t, Target gi d liu sang Host, n gi mt chui bit m ha trn ng
dy truyn TX ca n, Host nhn d liu trn ng dy nhn RX ca n. Ch
ny c gi l truyn thng khng ng b bi v host v target c thi gian
khng ng b vi nhau. Thay vo , chui bit c m ha bn pht v gii
m bn nhn.
Mt thit b thng c s dng m ha v gii m chui bit khng
ng b nh vy l UART, n chuyn i cc byte d liu bi phn mm vo mt
chui cc bit ring l v ngc li, chuyn i mt chui cc bit vo byte d liu
c truyn ti phn mm. Vi iu khin STM32 c 5 thit b c gi l
USART(universal synchronous/ asynchronous receiver/ transmitter) bi v n c
ch truyn thng khng ng nht vi nhau. Trong chng ny, chng ta s
truyn thng ni tip gia Target l STM32 USART v host l b chuyn i
USB/UART.
UARTs cng c th c s dng giao tip vi cc thit b ngoi vi
khc. V d nh Modem di ng GSM/GPRS hay Modem Blutooth c s dng
rng ri vi giao din b iu khin UART. Nh cc giao din khc, trong tng
lai giao thc truyn thng ni tip s tip cn c vi nhiu loi thit b khc.
19
Hnh 3.3. Giao thc truyn thng ni tip
Mt trong nhng cch gii m c bn c s dng cho truyn thng ni
tip khng ng b c minh ha nh hnh trn. Mi k t c truyn trong
mt khung, bt u l 1 bit thp sau l 8 bit d liu v cui cng l 1 bit cao(bit
dng). D liu c m ha thnh cc mc tn hiu cao v thp (1 v 0). Gia cc
khung, tnh trng nhn ri c bo hiu bng cch truyn mt tn hiu cao lin
tc. Mi khung c m bo bt u vi mt s chuyn tip high-low v cha
t nht mt qu trnh chuyn i t mc cao xung mc thp. La chn cu trc
khung c bn bao gm s cc bt d liu khc nhau, mt bt chn l sau bit d liu
cui cng pht hin li v iu kin dng.
Khng c tn hiu clock c m ha trc tip trong tn hiu (ngc li vi
giao thc bo hiu khc nh m ha Manchester), qu trnh chuyn i ch cung
cp thng tin theo thi gian trong dng d liu. bn pht v bn thu, mi bn
duy tr mt ng h chy c lp (l bi s ca) tn s chung v khng chnh xc,
c gi l tc Baud. Hai ng h cha c ng b v khng m bo
chnh xc cng mt tn s, nhng 2 tn s phi gn ging nhau c th khi
phc c d liu.
Hnh 3.4. Gii m tn hiu UART.
hiu lm th no bn nhn hiu c tn hiu m ha, gi s c 1 ng
h chy vi tc Baud(16x), bt u t trng thi nhn ri (idle) nh hnh trn.
20
Bn nhn nhn mu tn hiu RX cho n khi n pht hin mt qu trnh chuyn
i cao thp, sau n ch trong thi gian 1,5 bit (24 chu k ng h) ly mu
tn hiu RX ca n v c tnh bit 0 l d liu trung tm. Bn nhn nhn mu tn
hiu RX sau 16 chu k ng h, khi c 7 bit d liu v c bit dng. T thi
im , qu trnh c lp i lp li. D liu truyn thnh cng trn mt
khung yu cu, hn 10,5 chu k bit, s chnh lch xung clock bn thu v bn
pht v 0,5 bit l dnh cho giai on pht hin bit dng.
3.4.2. Giao thc truyn thng UART trn STM32
Hnh thc truyn thng n gin nht l da trn trng thi ca thit b
USART. Mi STM32 USART c 6 thanh ghi 4 thanh ghi c s dng cu
hnh phn cng thng qua vic khi to trong th vin. Hai thanh ghi cn li l
thnh ghi d liu v thanh ghi iu khin. Thanh ghi d liu chim 1 v tr b nh
duy nht, n thc s l 2 v tr ring bit, khi thanh ghi d liu c ghi vo th d
liu c truyn bi USART, khi thanh ghi d liu c, cc k t gn nht s
nhn c do USART gi tr li. Thanh ghi trng thi cha 1 s c xc nh
trng thi ca USART. Quan trng nht trong s l:
USART_FLAG_TXE -- Transmit data register empty (C bo m truyn d liu
rng)
USART_FLAG_RXNE -- Receive data register not empty (C m nhn d liu
rng)
Cc c khc cung cp thng tin nh kim tra li chn l, li khung v trn
bt, cn c kim tra trong vic thc thi.
truyn 1 k t phn mm ng dng phi i cho n khi thanh ghi d
liu rng, sau mi ghi d liu c vo thanh ghi. Trng thi ca thanh ghi d
liu c xc nh bi c USART_FLAG_TXE ca thanh ghi trng thi USART.
on code sau thc hin vic ghi d liu vo m d liu c bn trong USART1.
int putchar( int c){
while ( USART_GetFlagStatus (USART1 , USART_FLAG_TXE ) == RESET);
USART1 ->DR = (c & 0xff);
21
return 0;
}
Vi 1 thanh ghi d liu truyn n l, n s thc hin nhanh nh tc Baud v
phi i c trng thi gia cc k t.
on code sau thc hin vic c mt k t c bn:
int getchar( void ){
while ( USART_GetFlagStatus (USART1 , USART_FLAG_RXNE ) == RESET);
return USART1 ->DR & 0xff;
}
C trng thi USART_FLAG_RXNE c s dng khi mun nhn mt k t.
3.2.3. Khi to USART
Ging nh tt c cc ngoi vi ca STM32, USART phi c khi to
trc khi c s dng. Vic khi to bao gm cu hnh chn, bt xung clock v
khi to thit b ngoi vi. i vi STM32F10X th c 3 USART ln lt l
USART1, USART2 v USART3.
C 3 module m mi phn ca th vin c yu cu cho ng dng ca
USART(bao gm cc tp tin lin quan n i tng ca bn).
# include
# include
# include
# include
Bc u tin cho vic khi to l cho php tn hiu RCC (thit lp v khi
ng li xung clock) cho cc khi chc nng khc nhau cn thit cho vic s dng
USART bao gm cc cng GPIO (nh cng A cho USART1), cc thnh phn ca
USART v module thay th AF khc. Vi USART, cc bc khi to vi RCC
nh sau:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1
|RCC_APB2Periph_AFIO |
RCC_APB2Periph_GPIOA , ENABLE);
22
Vi USART2 l thit b ngoi vi APB1, v th khi to RCC s hi khc
mt cht. Thng bo cho c APB2 n cho php xung clock c hot ng
trong mi bc.
Sau khi bt xung clock, tip theo l cu hnh cho cc chn tng ng vi 3
USART, mc nh nh trong bng di y:
Hnh 3.4. Cc chn UART trn kt STM32F4
Trong ti liu hng dn, STM32 cung cp nhng thng tin cho vic cu
hnh cc chn GPIO tng ng vi cc thit b ngoi vi khc.
i vi cc USARTs, thng tin c th hin trong bng di y:
Hnh 3.5. Cc ch chn ca UART
Nh cp trc , cc USARTs trong STM32 c kh nng h tr mt
ch hot ng khc - ng b ni tip m i hi mt tn hiu ng h ring
bit (USARTx_CK) m chng ta s khng c s dng. Ngoi ra, cc USART
cn c kh nng h tr iu khin phn cng (tn hiu USARTx_RTS v
23
USARTx_CTS). truyn thng ni tip c bn ta phi cu hnh cho 2 chn
USART1_Tx v USART1_Rx. u ra c nh hng bi cc thnh phn
USART, khi n l u vo th c th c cu hnh ch floating or pulled up.
Cc chc nng v hng s cu hnh cho chn c nh ngha trong th vin
stm32f10x_gpio.h.
on code sau minh ha cho vic cu hnh chn cho USART1_Tx v
USART1_Rx.
GPIO_InitTypeDef GPIO_InitStruct ;
GPIO_StructInit (&GPIO_InitStruct );
// Initialize USART1_Tx
GPIO_InitStruct.GPIO_PIN = GPIO_Pin_9 ;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz ;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP ;
GPIO_Init (GPIOA,& GPIO_InitStruct );
// Initialize USART1_RX
GPIO_InitStruct.GPIO_PIN = GPIO_Pin_10 ;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING ;
GPIO_Init (GPIOA,& GPIO_InitStruct );
Bc khi to cui cng l khi to cho USART, chng ta s dng khi to mc
nh cho USART vi tc Baud l 9600, 8 bit d liu, 1 bit stop, khng c bit
kim tra chn l v khng c iu khin bi cc th tc ca th vin
USART_StructInit.
thay i cc khi to c mc nh, ta thay i cc thng s ca cc
trng tng ng trong USART_InitStructure.
USART_InitTypeDef USART_InitStructure ;
// Initialize USART
USART_StructInit (&USART_InitStructure );
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx ;
24
USART_Init (USART1 ,& USART_InitStructure );
USART_Cmd (USART1 , ENABLE);
Th d: Chng trnh truyn ch hello world t kt STM32 ln my tnh.
Cc on code trong cc phn trc cung cp tt c cc chc nng c bn
cn thit truyn thnh cng mt USART STM32. Di y s l 1 tin trnh to
ra mt ng dng n gin l gi ch hello world t STM32 v my tnh. y l
ng dng u tin i hi phi kt ni cc thit b phn cng vi nhau. V vy cn
c thit b chuyn i USB to COM.
Cc hm chc nng nh sau:
M cng USART:
int uart_open ( USART_TypeDef * USARTx , uint32_t baud , uint32_t
flags);
ng cng sau khi kt thc truyn thng:
int uart_close ( USART_TypeDef * USARTx);
Gi 1 k t qua cng
int uart_putc ( int c, USART_TypeDef * USARTx);
Nhn mt k t t cng:
int uart_getc ( USART_TypeDef * USARTx);
Chc nng ca hm uart_open l:
1. Thit lp xung clock cho gpio/usart
2. Cu hnh cho chn ca usart
3. Cu hnh v cho php usart1 hot ng
25
Hnh 3.6: S ni dy vi USART1
Trong file usart bao gm:
# include
# include
# include
# include
# include " uart.h "
Chc nng ca hm uart_getchar v uart_putchar dng c v ghi tng
k t. Hai hm ny c s dng ging nh trong Linux. Trong hm main.c bao
gm:
26
1. Thit lp thi gian tick
2. Thit lp cho usart
3. Vit dng ch Hello Word vi thi gian tr l 25ms.
Trong file main.c phi bao gm cc th vin: stm32f10x.h,
stm32f10x_usart.h v uart.h. Chng ta ch cn 3 dy kt ni nh minh ha
hnh trn. Tn hiu GND Board mch v B chuyn i uart c ni vi nhau.
C nhiu chn GND trn Board mch, tt c u c kt ni in bi PCB. Do
, ch cn 1 dy duy nht (thng l dy mu en) ni cc tn hiu t chung
vi nhau. Sau , chng ta cn ni cc tn hiu tx(rx) ca USART1 tng ng vi
chn rx (tx) ca b chuyn i USB/uart.
3.5. Lp trnh qua giao din I2C
3.5.1. Gii thiu truyn thng I2C
I2C (inter-integrated circuit) l chun truyn thng ni tip 2 dy gm 1
dy xung clock(SCL) v 1 dy d liu (SDA). Cc chip ch-t c ni chung vi
nhau trn hai ng dy ny v c ni vi in tr treo.
Hnh 3.7. S khi giao din SPI
3.5.2. Kt ni phn cng
S kt ni phn cng nh bn di:
27
Hnh 3.8. Th d s kt ni phn cng qua I2C
3.5.3. Lp trnh I2C c bn
Trong th d ny s dng 2 b I2C, I2C1 vai tr l chip master, I2C2 l chip
slave. Master truyn d liu theo kiu thng thng khng thit lp ngt v DMA,
ring slave thit lp ngt s kin.
Gii thch hm I2C_Configuration() t dng 35 ->102:
Dng 37 > 43: y l cc on m tin x l trong C, in hnh dng 37
#ifdef FAST_I2C_MODE c ngha l nu nh macro FAST_I2C_MODE c
nh ngha th s thc hin 2 dng 38-39, nu FAST_I2C_MODE cha c nh
ngha th s thc hin 2 dng 40-41. dng 8 nh ngha s dng
FAST_I2C_MODE.
Dng 51: s dng I2C th phi chn mode OD (open drain) cu hnh cho
GPIO.
Dng 52: Do kt ni phn cng khng s dng in tr treo ln mc cao nn
28
phi cu hnh in tr treo ni ln mc cao.
Dng 63: Lnh ny dng reset li cc thanh ghi ca khi I2C a v mc
nh.
Dng 64: Chn mode hot ng l I2C, ngoi ra cn mt s chun khc da
trn chun I2C nh SMBus.
Dng 65: Chn t l mc thp/mc cao ca xung clock. Macro
I2C_DUTYCYCLE ny c nh ngha pha bn trn dng 37.
Dng 66: a ch ca thit b I2C, chip master c th khng cn thit do
chip master l chip ch ng, chip mun c giao tip vi chip khc.
Dng 67: Bt xc nhn ACK.
Dng 68: Thit lp tc xung clock trn chn SCL, macro c nh
ngha dng 37.
Dng 69: Chn ch a ch 7 bit, mng I2C s c ti a l 128 thit b.
Phn thit lp cho slave tng t nh master, dng 81 thit lp a ch ca
thit b slave, iu ny l rt quan trng, trong giao tip I2C master giao tip
vi slave th master phi bit c a ch ca thit b slave , th d ny nh
ngha a ch ny l 0x68. Dng 89 thit lp ngt li v ngt s kin trn slave,
mi khi c mt hot ng g trn ng truyn th slave s phn tch cc s
kin ny hm ngt.
Kt thc hm I2C_Configuration():
Dng 12: To mng MasterTxBuffer[] cha d liu m master truyn i,
v khi to sn d liu bn trong mng ny l 1, 2, 3.
Dng 13: Mng cha d liu m master s nhn v.
Dng 14: Mng cha d liu slave pht i.
Dng 15: Mng cha d liu m slave nhn v. Mng ny s c hm ngt
cp nht d liu.
chng trnh chnh ti s dng hm I2C_ByteWrite() pht d liu ca
mng MasterTxBuffer[] n slave, v hm I2C_BufferRead() c d liu t
slave pht n master, d liu nhn v s c gn vo mng MasterRxBuffer[].
29
Hai hm ny c vit trong th vin MY_I2C.h.
Gii thch file stm32f4xx_it.c. Qu trnh slave x l ch yu nm trong file
ny:
dng 74: Mi khi c mt s kin truyn nhn d liu, a ch, ca slave
s xy ra mt ngt v s c tr n hm ny.
Gi s xt trng hp slave truyn d liu, hon tt qu trnh ny s sinh ra
rt nhiu ngt, cc bc m ngt ln lc thc hin:
Bc 1: Khi pht hin ra mt s kin trn ng truyn u tin n s nhy
vo ngt I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED li
dng vic ny ti gn Tx_Idx = 0 bin ny l mt bin m th t d liu gi i.
Bc 2: Nu master mun slave gi d liu th ln ngt tip theo s nhy vo
y, ngt ny s gi d liu trong mng SlaveTxBuffer[] n master. Ngt ny
s c thc hin nhiu ln, chng trnh thc hin php tng bin Tx_Idx mi
ln xy ra ngt. Qu trnh xy ra cho n khi master khng mun nhn d liu na
n s pht ra mt tn hiu kt thc.
Bc 3: Bc cui trong qu trnh truyn d liu ca slave, n s nhy n
ngt I2C_EVENT_SLAVE_STOP_DETECTED dng 113.
Qu trnh nhn d liu ca slave cng xy ra tng t nh 3 bc trn nhng
cc s kin c khc ph hp vi qu trnh nhn vi cc dng t 101 -> 106.
File main.c:
001 #include "stm32f4xx.h"
002 #include "MY_I2C.h"
003
004 /* MASTER SLAVE
005 PB8 --- I2C1_SCL PB10 --- I2C2_SCL
006 PB9 --- I2C1_SDA PB11 --- I2C2_SDA
007 */
008 #define FAST_I2C_MODE
009 #define Slave_Address 0x68
010 #define BufferSIZE 3
011
30
012 volatile uint8_t MasterTxBuffer[BufferSIZE] = {1 , 2 , 3};
013 volatile uint8_t MasterRxBuffer[BufferSIZE];
014 volatile uint8_t SlaveTxBuffer[BufferSIZE] = {4 , 5 , 6};
015 volatile uint8_t SlaveRxBuffer[BufferSIZE];
016
017 GPIO_InitTypeDef GPIO_InitStructure;
018 I2C_InitTypeDef I2C_InitStructure;
019 NVIC_InitTypeDef NVIC_InitStructure;
020
021 void I2C_Configuration(void);
022 void Delay(__IO uint32_t nCount);
023
024 int main(void)
025 {
026 I2C_Configuration();
027 while (1)
028 {
029 I2C_ByteWrite(I2C1, Slave_Address, (u8*)MasterTxBuffer,3);
030 I2C_BufferRead(I2C1, Slave_Address, (u8*)MasterRxBuffer,3);
031 while(1);
032 }
033 }
034
035 void I2C_Configuration(void)
036 {
037 #ifdef FAST_I2C_MODE
038 #define I2C_SPEED 400000
039 #define I2C_DUTYCYCLE I2C_DutyCycle_16_9
040 #else /* STANDARD_I2C_MODE*/
041 #define I2C_SPEED 100000
042 #define I2C_DUTYCYCLE I2C_DutyCycle_2
043 #endif /* FAST_I2C_MODE*/
044
045 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
31
046 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
047 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
048
049 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
050 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
051 GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
052 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // enable pull up resistors
053 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
054 GPIO_Init(GPIOB, &GPIO_InitStructure);
055
056 GPIO_PinAFConfig(GPIOB,GPIO_PinSource8,GPIO_AF_I2C1); // only connect to
057 GPIO_PinAFConfig(GPIOB,GPIO_PinSource9,GPIO_AF_I2C1); // only connect to
058 GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_I2C2); // only connect to
059 GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_I2C2); // only connect to
060
061/***************************Master ******************/
062 /* I2C De-initialize */
063 I2C_DeInit(I2C1);
064 I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
065 I2C_InitStructure.I2C_DutyCycle = I2C_DUTYCYCLE;
066 I2C_InitStructure.I2C_OwnAddress1 = 0x01;
067 I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
068 I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
069 I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
070 I2C_Init(I2C1, &I2C_InitStructure);
071 /* I2C ENABLE */
072 I2C_Cmd(I2C1, ENABLE);
073 /* Enable Interrupt */
074 //I2C_ITConfig(I2C1, (I2C_IT_ERR ) , ENABLE);
075 //I2C_ITConfig(I2C1, (I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF) , ENABLE);
076 /************************************* Slave ******************************/
077 /* I2C De-initialize */
078 I2C_DeInit(I2C2);
079 I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
32
080 I2C_InitStructure.I2C_DutyCycle = I2C_DUTYCYCLE;
081 I2C_InitStructure.I2C_OwnAddress1 = Slave_Address;
082 I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
083 I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
084 I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
085 I2C_Init(I2C2, &I2C_InitStructure);
086 /* I2C ENABLE */
087 I2C_Cmd(I2C2, ENABLE);
088 /* Enable Interrupt */
089 I2C_ITConfig(I2C2, (I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF) , ENABLE);
090
091 NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQn;
092 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
093 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
094 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
095 NVIC_Init(&NVIC_InitStructure);
096
097 NVIC_InitStructure.NVIC_IRQChannel = I2C2_ER_IRQn;
098 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
099 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
100 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
101 NVIC_Init(&NVIC_InitStructure);
102 }
103
104 void Delay(__IO uint32_t nCount)
105 {
106 while(nCount--)
107 {
108 }
109 }
110
111 #ifdef USE_FULL_ASSERT
112 void assert_failed(uint8_t* file, uint32_t line)
113 {
33
114 /* User can add his own implementation to report the file name and line number,
115 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
116
117 /* Infinite loop */
118 while (1)
119 {
120 }
121 }
122 #endif
File stm32f4xx_it.c:
001 #include "stm32f4xx_it.h"
002
003 void NMI_Handler(void)
004 {
005 }
006
007 void HardFault_Handler(void)
008 {
009 /* Go to infinite loop when Hard Fault exception occurs */
010 while (1)
011 {
012 }
013 }
014
015 void MemManage_Handler(void)
016 {
017 /* Go to infinite loop when Memory Manage exception occurs */
018 while (1)
019 {
020 }
021 }
022
023 void BusFault_Handler(void)
024 {
34
025 /* Go to infinite loop when Bus Fault exception occurs */
026 while (1)
027 {
028 }
029 }
030
031 void UsageFault_Handler(void)
032 {
033 /* Go to infinite loop when Usage Fault exception occurs */
034 while (1)
035 {
036 }
037 }
038
039 void SVC_Handler(void)
040 {
041 }
042
043 void DebugMon_Handler(void)
044 {
045 }
046
047 void PendSV_Handler(void)
048 {
049 }
050
051 void SysTick_Handler(void)
052 {
053 }
054
055 void I2C2_ER_IRQHandler(void)
056 {
057 /* Check on I2C2 AF flag and clear it */
058 if (I2C_GetITStatus(I2C2, I2C_IT_AF))
35
059 {
060 I2C_ClearITPendingBit(I2C2, I2C_IT_AF);
061 }
062 }
063
064 /**
065 * @brief This function handles I2Cx event interrupt request.
066 * @param None
067 * @retval None
068 */
069 volatile uint32_t Event = 0;
070 volatile uint8_t Tx_Idx;
071 volatile uint8_t Rx_Idx;
072 extern uint8_t SlaveTxBuffer[];
073 extern uint8_t SlaveRxBuffer[];
074 void I2C2_EV_IRQHandler(void)
075 {
076 /* Get Last I2C Event */
077 Event = I2C_GetLastEvent(I2C2);
078 switch (Event)
079 {
080 /*
****************************************************************************/
081 /* Slave Transmitter Events */
082 /* */
083 /*
****************************************************************************/
084
085 /* Check on EV1 */
086 case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
087 Tx_Idx = 0;
088 I2C_ITConfig(I2C2, I2C_IT_BUF , ENABLE);
089 break;
090 /* Check on EV3 */
36
091 case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:
092 case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
093 I2C_SendData(I2C2, SlaveTxBuffer[Tx_Idx++]);
094 break;
095
096 /*
****************************************************************************/
097 /* Slave Receiver Events */
098 /* */
099 /*
****************************************************************************/
100
101 /* check on EV1*/
102 case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
103 Rx_Idx = 0;
104 break;
105
106 /* Check on EV2*/
107 case I2C_EVENT_SLAVE_BYTE_RECEIVED:
108 case (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_SR1_BTF):
109 SlaveRxBuffer[Rx_Idx++] = I2C_ReceiveData(I2C2);
110 break;
111
112 /* Check on EV4 */
113 case I2C_EVENT_SLAVE_STOP_DETECTED:
114 I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF);
115 I2C_Cmd(I2C2, ENABLE);
116 break;
117
118 default:
119 break;
120 }
121 }
3.6. Lp trnh SPI
37
3.6.1. Gii thiu giao din SPI
SPI (Serial Peripheral Interface, SPI bus Giao din Ngoi vi Ni tip) l
mt chun ng b ni tip truyn d liu ch song cng ton phn full-
duplex (hai chiu, hai pha), do cng ty Motorola thit k nhm m bo s lin
hp gia cc vi iu khin v thit b ngoi vi mt cch n gin v gi r. SPI
cn c gi l giao din bn-dy (four-wire).
Hnh 3.9. Giao din SPI 4 dy
Trong giao din SPI c s dng bn tn hiu s:
MOSI hay SI Cng ra ca bn ch ng, cng vo ca bn b ng
(Master Out Slave In), dnh cho vic truyn d liu t thit b ch ng n
thit b b ng.
MISO hay SO Cng vo ca bn ch ng, cng ra ca bn b ng
(Master In Slave Out), dnh cho vic truyn d liu t thit b b ng n
thit b ch ng.
SCLK hay SCK tn hiu ng ni tip (Serial Clock), dnh cho vic
truyn tn hiu ng cho thit b b ng.
CS hay SS chn vi mch, chn bn b ng (Chip Select, Slave Select).
Trong nu l chip master s c quyn quyt nh xung nhp SCK (hay ch
ng ngun xung nhp SCK).
ch song cng ton phn th trong cng mt thi im c hai thit b u
c th pht v nhn d liu, y l mt u th rt ln ca chun truyn thng ny.
38
Hnh 3.10. Ch song cng ton phn
Ngoi ra chip master c th giao tip vi nhiu chip slave trong cng mng v
c nhiu phng php khc nhau.
Hnh 3.11. Mt chp master SPI c th giao tip vi nhiu chip slave SPI
phng php ny chip master cn nhiu ng SS, c th thay th bng
ng IO thng thng. Trong mt thi im ch nn giao tip vi mt chip slave
trnh trng hp cc chip slave y d liu v cng lc s gy li d liu trn
ng MISO.
Th d s dng phng php nh hnh bn di c gi l "Daisy chain":
39
Hnh 3.12. Phng php giao tip Daisy Chain trong chun SPI
3.6.2. Kt ni phn cng
Kt ni phn cng nh s bn di:
40
Hnh 3.13. Th d kt ni phn cng trn SPI
3.6.3. Lp trnh SPI c bn
Th d ny s dng 2 b SPI, mt cho master v mt cho slave. Phn master
th s dng ch thng thng, khng ngt, khng DMA. Ring slave s dng
ngt nhn, do thi im truyn d liu ca master l khng bit trc nn cn
dng ngt trnh mt d liu.
Gii thch hm SPI_Configuration(), trong hm ny thit lp SPI cho c
master v slave.
Dng 54 : chn ch truyn d liu song cng full-duplex, iu ny c th
khng cn thit do trong th d ny ch dng master truyn m khng nhn d
liu, nhng ngi lp trnh cng c th nguyn nh trn v khng quan tm n
ch nhn.
Dng 55: Chn mode master cho SPI1.
Dng 56: Chn kch thc ca khung truyn l 8bit.
Dng 57-58: hai dng lnh ny cn tham kho hnh bn di nm r d
liu c ly mu cnh v pha nh th no.
Hnh 3.14. Ly mu d liu cnh v pha
Dng 59: Chn s dng chn SS bng phn mm, trn thc t c th khng
41
cn quan tm do bn trn khai bo mt chn IO (PA4) lm chc nng SS.
Dng 60: B chia tn s ca SPI, sau khi qua b chia ny ta s suy ra c
xung nhp trn chn SCK. Do ta s dng SPI1 thuc khi APB2 nn tc ti a
m ngoi vi trn khi ny t c l 84MHz. y chn b chia 256 vy tn s
ti a m chn SCK t c l 84MHz/256 = 328.125KHz.
Dng 61 : bit truyn i u tin l bit MSB c ngha l bit c trng s cao nht
bit th 8.
phn khai bo cho slave cng tng t nh khai bo cho master, nhng
mode hot ng l mode slave v thit lp thm ngt khi qu trnh nhn d liu
hon tt nh dng 95.
Kt thc hm ny bn cho c hai khi SPI ny hot ng.
chng trnh chnh dng 25 s dng 1 macro SS_DIS c ti nh
ngha dng 9 tin li nu thay i cc chn IO ta ch vic thay i bn trn
m khng cn thay i ton b chng trnh ca bn ang vit.
Dng 26: S dng hm SPI_I2S_SendData() gi d liu t master ln
ng truyn SPI, i s SPI_data_send chnh l bin d liu cn truyn i.
Dng 27: Vng lp ny by chng trnh, khi kt thc qu trnh truyn th s
thot khi vng lp. Vic ny trnh trng hp tc vi iu khin qu nhanh,
d liu c cn cha truyn i ht th d liu mi c gi tip.
Mc ch s dng delay dng 29 l tr hon khon mc cao m master
to ra trn SS, nu khng tr hon th chng trnh quay li dng 25 lm slave
cha kp pht hin ra tn hiu mc cao.
Khi c s kin nhn d liu trn slave lp tc chng trnh s nhy n hm
ngt SPI2_IRQHandler() dng 59 trong file stm32f4xx_it.c.
Gii thch trn file stm32f4xx_it.c:
dng 4 khai bo thm t kha extern main.c v stm32f4xx_it.c s dng
chung bin SPI_data_get.
Dng 63: Khi c mt tn hiu ngt do qu trnh nhn hon tt ti s dng
hm SPI_I2S_ReceiveData() ly d liu trong thanh ghi ra v gn vo bin
42
SPI_data_get.
File main.c
001 #include "stm32f4xx.h"
002
003 /* MASTER SLAVE
004 PA4 --- CONTROL_SS PB12 --- SPI2_SS
005 PA5 --- SPI1_SCK PB13 --- SPI2_SCK
006 PA6 --- SPI1_MISO PB14 --- SPI2_MISO
007 PA7 --- SPI1_MOSI PB15 --- SPI2_MOSI
008 */
009 #define SS_DIS GPIO_ResetBits(GPIOA, GPIO_Pin_4)
010 #define SS_EN GPIO_SetBits(GPIOA, GPIO_Pin_4)
011
012 volatile uint8_t SPI_data_send,SPI_data_get;
013 GPIO_InitTypeDef GPIO_InitStructure;
014 SPI_InitTypeDef SPI_InitStructure;
015 NVIC_InitTypeDef NVIC_InitStructure;
016
017 void SPI_Configuration(void);
018 void Delay(__IO uint32_t nCount);
019
020 int main(void)
021 {
022 SPI_Configuration();
023 while (1)
024 {
025 SS_DIS;
026 SPI_I2S_SendData(SPI1, SPI_data_send);
027 while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
028 SS_EN;
029 Delay(1000);
030 }
031 }
032
033 void SPI_Configuration(void)
034 {
035 /* SPI_MASTER configuration ------------------------------------------------*/
036 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
037 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
038
039 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
040 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
041 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
042 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
043 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
044 GPIO_Init(GPIOA, &GPIO_InitStructure);
045 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
046 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
047 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
43
048 GPIO_Init(GPIOA, &GPIO_InitStructure);
049
050 GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_SPI1);
051 GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_SPI1);
052 GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_SPI1);
053
054 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
055 SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
056 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
057 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
058 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
059 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
060 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
061 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
062 SPI_InitStructure.SPI_CRCPolynomial = 7;
063 SPI_Init(SPI1, &SPI_InitStructure);
064
065 /* SPI_SLAVE configuration ------------------------------------------------*/
066 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
067 RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
068 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
GPIO_Pin_15;
069 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
070 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
071 GPIO_Init(GPIOB, &GPIO_InitStructure);
072
073 GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_SPI2);
074 GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2);
075 GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_SPI2);
076 GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2);
077
078 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
079 SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
080 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
081 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
082 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
083 SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
084 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
085 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
086 SPI_InitStructure.SPI_CRCPolynomial = 7;
087 SPI_Init(SPI2, &SPI_InitStructure);
088
089 NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
090 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
091 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
092 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
093 NVIC_Init(&NVIC_InitStructure);
094
095 SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
096
097 /* Enable SPI_SLAVE */
44
098 SPI_Cmd(SPI2, ENABLE);
099 /* Enable SPI_MASTER */
100 SPI_Cmd(SPI1, ENABLE);
101 }
102
103 void Delay(__IO uint32_t nCount)
104 {
105 while(nCount--)
106 {
107 }
108 }
109
110 #ifdef USE_FULL_ASSERT
111 void assert_failed(uint8_t* file, uint32_t line)
112 {
113 /* User can add his own implementation to report the file name and line number,
114 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
115
116 /* Infinite loop */
117 while (1)
118 {
119 }
120 }
121 #endif
File stm32f4xx_it.c
01 #include "stm32f4xx_it.h"
02 #include "stm32f4xx.h"
03
04 extern uint8_t SPI_data_get;
05
06 void NMI_Handler(void)
07 {
08 }
09
10 void HardFault_Handler(void)
11 {
12 /* Go to infinite loop when Hard Fault exception occurs */
13 while (1)
14 {
15 }
16 }
17
18 void MemManage_Handler(void)
19 {
20 /* Go to infinite loop when Memory Manage exception occurs */
21 while (1)
22 {
23 }
24 }
45
25
26 void BusFault_Handler(void)
27 {
28 /* Go to infinite loop when Bus Fault exception occurs */
29 while (1)
30 {
31 }
32 }
33
34 void UsageFault_Handler(void)
35 {
36 /* Go to infinite loop when Usage Fault exception occurs */
37 while (1)
38 {
39 }
40 }
41
42 void SVC_Handler(void)
43 {
44 }
45
46 void DebugMon_Handler(void)
47 {
48 }
49
50 void PendSV_Handler(void)
51 {
52 }
53
54 void SysTick_Handler(void)
55 {
56
57 }
58
59 void SPI2_IRQHandler(void)
60 {
61 if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) != RESET)
62 {
63 SPI_data_get = SPI_I2S_ReceiveData(SPI2);
64 //SPI_I2S_ClearFlag(SPI2, SPI_I2S_IT_RXNE);
65 }
66 }
46
TI LIU THAM KHO
[1] Ng Th Vinh, Tp bi ging Lp trinh nhung nng cao, B mn Cng ngh
K thut my tnh (2014)
[2]. Hitex.com, The insiders guide to STM32, ARM7 based microcontroller.
[3]. Geoffrey Brown (2014), Discovering the STM32 Microcontroller
[4]. www.st.com, Cortex-M3 programming manual.
[5]. www.st.com (2013), Fun, easy introduction kit for STM32 microcontrollers
http://www.st.com/http://www.st.com/3.2.1. Ngt trn cc chn vo ra3.2.2. iu khin ngt:3.3.3. Th d3.3.1. C bn v Timer trong STM323.3.2. Cc thnh phn c bn ca mt timer trong STM323.3.3. Cc ch hot ng ca Timer3.3.4. nh ngha struct cu hnh cho timer c bn3.3.5. Th d3.4.1. Gii thiu chun truyn thng ni tipHnh 3.3. Giao thc truyn thng ni tip3.4.2. Giao thc truyn thng UART trn STM323.2.3. Khi to USARTHnh 3.6: S ni dy vi USART13.5.1. Gii thiu truyn thng I2C3.5.2. Kt ni phn cng3.5.3. Lp trnh I2C c bn3.6.1. Gii thiu giao din SPI3.6.2. Kt ni phn cng3.6.3. Lp trnh SPI c bn