46
1 CHƯƠNG 3: LẬP TRÌNH KIT STM32 3.1. Lp trình qua các chân vào ra chung Các bvi xlý STM32 là nhng hthng phc tp vi nhiu thiết bngoi vi. Bt kthiết bngoại vi cũng phải được cấu hình trước khi sdng. Mt scu hình này là dung chung chng hn cu hình xung clock hay chân, phn còn li là cu hình thiết bngoi vi cth. Trong phn này chúng ta sxây dựng chương trình nháy LED làm thí dcth. Các bước khi tạo cơ bản cn thiết để sdng bt kthiết bngoi vi nào ca STM32 là: 1. Kích hot xung clock cho ngoi vi 2. Cu hình chân theo yêu cu ca các thiết bngoi vi 3. Cu hình phn cng ca ngoi vi Vi xlý STM32 cũng như các thành viên của hCortex-M3 đều có mt bđịnh thi hthống được sdụng để cung cp xung nhp thường xuyên "tick". Thí dsau sdụng timer này để to tốc độ nháy liên tc cho các LED. Cu trúc tng thcủa chương trình này được minh họa trong hình dưới đây. Chương trình bắt đầu bng việc khao báo các thư viện phn mm có liên quan - trong trường hp này là khai báo timer hthng và cấu hình các pin. Chương trình chính gồm các bước khi tạo được mô ttrên và mt vòng lp cha hàm Toggles() bt một đèn LED sang và ch250ms. Hàm tiếp theo thc hin chức năng tạo trtrong đó sử dng timer hthng. Cui cùng, mt mt hàm trgiúp được cung cấp để xlý vi phm cho phép trong thư viện firmware (cn thiết lệnh if USE_FULL_ASSERT được định nghĩa khi biên dịch các module trong thư viện firmware). Ni dung hàm assert_failed không làm gì nhưng nó là rất hu ích khi gli các dán khi các thư viện phn mm sthc hin kim tra tham smrộng. Trong trường hp vi phm vùng qun lý,

Lap Trinh Tren Kit Stm32

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