แนะนำผู้เริ่มต้นใหม่ STM32F4 discovery โดยkeil บทที่4 Input/Output

บทความคัดลอกจากเวบอิเลคทูเดย์ เพื่อเก็บเข้าคลังข้อมูล http://www.electoday.com/index.php/topic,10213.0.html Tongue out

มาขอแนะนำผู้เริ่มต้นใหม่ STM32F4 discovery โดยkeil บทที่4 Input/Output

1 สร้าง Floder ชื่อInput_Output ขึ้นมาหรือชื่ออะไรก็ได้ที่บ่งบอกการทำงาน
2 ทำการเพื่ม File  system_stm32f4xx.c และ stm32f4xx.hไว้ใน Floder
3 ทำการสร้างโปรเจคใหม่ เลือก เบอร์ IC stm32f407VG และให้ ADD File startup_stm32f4.s
เข้ามาด้วย  เพื่อที่จะได้ไม่ต้องไปก๊อปมาจาก Lib st ให้ยุ่งยากอีก  ความสำคัญคือมันจะช่วยจัดการค่า
เบื้องต้นให้กับ IC ให้พร้อมรับการโปรแกรมและการทำงาน ถ้าไม่มี  MCU จะ compiler ไม่ผ่าน
4 เขียนClode และ save โปรเจคเป็นนามสกุล .C

เว๊ปไซด์อ้างอิงและให้อ่านศึกษาต่อยอด
http://blog.mark-stevens.co.uk/?p=854
http://jeremyherbert.net/get/stm32f4_getting_started
http://www.farrellf.com/projects/hardware/2012-06-28_STM32F4_Basics:_GPIOs/

ถ้าท่านใช้ขาที่เลือกเป็น Digital Input จะต้องดูที่รีจีสเตอร์ MODER

GPIO จะมีขาให้ใช้มากสุด 15 ขา หรือ 15 bit     เช่น GPIOA 0;........GPIOA14 , GPIOA15 .
ขา GPIO แต่ละบิด จะใช้  2 บิตของรีจีสเตอร์ MODER ควบคุม ดังนี้
GPIO(Bit0)  =  MODER Bit0(x) กับ MODER Bit1(y) ควบคุม
GPIO(Bit1)  =  MODER Bit2(x) กับ MODER Bit3(y) ควบคุม
GPIO(Bit2)  =  MODER Bit4(x) กับ MODER Bit5(y) ควบคุม
.                      .
.                      .
GPIO(Bit14)  =  MODER Bit28(x) กับ MODER Bit29(y) ควบคุม
GPIO(Bit15)  =  MODER Bit30(x) กับ MODER Bit31(y) ควบคุม

(x),(y) คือค่าทางลอจิของบิตนั้นๆ
Input  ต้อง Set x = 0, Set y  = 0 อ้างอิงจาก Reference Manual RM0090 หน้า186/1422 ST
เช่นต้องการให้  Bit 0, Bit 1 ของ GPIOA เป็น Input ได้  GPIOA->MODER   =     0xFFFFFFF0;

ต้องการให้  Bit 0, Bit 15 ของ GPIOB เป็น Input ได้     GPIOB->MODER   =    0x3FFFFFFC;

ถัดมารีจีสเตอร์ PUPDR  ใช้ในการทำ พูอัป พูดาว ของตัวต้านทานที่ขานั้นๆ หลักการคล้ายกับ MODER,OSPEEDR
GPIO(Bit0)  =  PUPDR Bit0(x) กับ PUPDR Bit1(y) ควบคุม
GPIO(Bit1)  =  PUPDR Bit2(x) กับ PUPDR Bit3(y) ควบคุม
GPIO(Bit2)  =  PUPDR Bit4(x) กับ PUPDR Bit5(y) ควบคุม
.                      .
.                      .
GPIO(Bit14)  =  PUPDR Bit28(x)  กับ PUPDR Bit29(y) ควบคุม
GPIO(Bit15)  =  PUPDR Bit30(x)  กับ PUPDR Bit31(y) ควบคุม
(x =  0,  y  = 0)  ขาปล่อยลอยๆ    อ้างอิงจาก Reference Manual RM0090 หน้า200/1422 ST
(x =  0,  y  = 1)  Pull-up
(x =  1,  y  = 0)  Pull-down
(x =  1,  y  = 1)  (ไม่ใช้งาน   แต่มีผลทำให้ขาปล่อยลอยๆ )

และรีจีสเตอร์ที่ใช้ในการสั่งเก็บค่า Input คือ IDR
เช่น    GPIOA->ODR   =   GPIOB->IDR;  //อ่านค่าจากPort B และส่งค่าไปไว้ที่ PortA
หรื่อต้องการตรวจสอบ Bit ต่างๆ เช่น Bit0 GPIOC ได้ว่า      if(GPIOC->IDR&0x01)   // ตรวจสอบบิต0
GPIOD = 0x01;  // ถ้า บิต0 เป็น  1
else
GPIOD = 0;       //  ถ่าบิต0ไม่ใช่  1

ใน #Include "stm32f4xx.h"  จะมีตัวอ้างอิงค่าเราสามารถนำมาใช้ได้เลยเพื่อสื่อความหมายที่เข้าใจง่าย

/******************  Bits definition for GPIO_IDR register  *******************/
#define GPIO_IDR_IDR_0                       ((uint32_t)0x00000001)       // แทน บิต0
#define GPIO_IDR_IDR_1                       ((uint32_t)0x00000002)       // แทน บิต1
#define GPIO_IDR_IDR_2                       ((uint32_t)0x00000004)       // แทน บิต2
#define GPIO_IDR_IDR_3                       ((uint32_t)0x00000008)
#define GPIO_IDR_IDR_4                       ((uint32_t)0x00000010)
#define GPIO_IDR_IDR_5                       ((uint32_t)0x00000020)
#define GPIO_IDR_IDR_6                       ((uint32_t)0x00000040)
#define GPIO_IDR_IDR_7                       ((uint32_t)0x00000080)
#define GPIO_IDR_IDR_8                       ((uint32_t)0x00000100)
#define GPIO_IDR_IDR_9                       ((uint32_t)0x00000200)
#define GPIO_IDR_IDR_10                      ((uint32_t)0x00000400)
#define GPIO_IDR_IDR_11                      ((uint32_t)0x00000800)
#define GPIO_IDR_IDR_12                      ((uint32_t)0x00001000)
#define GPIO_IDR_IDR_13                      ((uint32_t)0x00002000)
#define GPIO_IDR_IDR_14                      ((uint32_t)0x00004000)    //  แทน บิต14
#define GPIO_IDR_IDR_15                      ((uint32_t)0x00008000)    //  แทน บิต15

เราสามารถใช้คำว่า  GPIO_IDR_IDR_0 แทน บิต 0 ได้เลย
หรื่อต้องการตรวจสอบ Bit ต่างๆ เช่น Bit0 GPIOC ได้ว่า      if(GPIOC->IDR&GPIO_IDR_IDR_0)   // ตรวจสอบ บิต0
GPIOD = 0x01;  // ถ้า บิต0 เป็น  1
else
GPIOD = 0;       //  ถ่าบิต0ไม่ใช่  1

สุดท้ายอย่าลืมปล่อยสัญญาณ clock ให้ Port ที่ใช้งานด้วยครับเดี๋ยวจะไม่ทำงานกัน หลับปุ๋ย

 

#include"stm32f4xx.h"
void clock()
               {
                RCC->CFGR       =    0;
                RCC->CR           =    0;
                RCC->CFGR      |=   (RCC_CFGR_PPRE1_0|RCC_CFGR_PPRE1_DIV2|RCC_CFGR_PPRE2_DIV2);
                RCC->CR          |=   RCC_CR_HSEON;  // select HSE Xtal is main clock
                while (!(RCC->CR & 0x00020000));// wait time to Xtal osc stability
                RCC->PLLCFGR   =   (RCC_PLLCFGR_PLLQ_2|RCC_PLLCFGR_PLLQ_1|RCC_PLLCFGR_PLLQ_0
                                                |RCC_PLLCFGR_PLLSRC_HSE);
                RCC->PLLCFGR  |=   (RCC_PLLCFGR_PLLN_8 |RCC_PLLCFGR_PLLN_6 |RCC_PLLCFGR_PLLN_4
                                                |RCC_PLLCFGR_PLLM_3);
                RCC->CR           |=    RCC_CR_PLLON;    // PLL On
                while(!(RCC->CR & 0x02000000));      // Pll Stable
                FLASH->ACR      =    0x00000605;      // Flash ROM is 5 Wait state
                RCC->CFGR       |=    0x00000002;      // System PLL
                while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Wait Pll
}
void Set_GPIO()
                       {
                         // Set Speed GPIOD is 100Mhz
                         GPIOD->OSPEEDR     =    0xFFFF;
                         // Open clock to GPIOD
                         RCC->AHB1ENR        |=   (RCC_AHB1ENR_GPIOAEN|RCC_AHB1ENR_GPIODEN);
                         // Set GPIO  D.15,D.14,D.13,D.12 is Output
                         GPIOD->MODER        =    (GPIO_OSPEEDER_OSPEEDR15_0 |GPIO_OSPEEDER_OSPEEDR14_0 |
                                                                GPIO_OSPEEDER_OSPEEDR13_0 |GPIO_OSPEEDER_OSPEEDR12_0);
                        // Set GPIOA is input
                        GPIOA->PUPDR          |=   0xFC; Pa.0 is input
                        GPIOA->MODER         |=   0xFC;
}

int main(void)
                   {
                    clock();
                    Set_GPIO();
                    while(1)
                              {
                               if(GPIOA->IDR & GPIO_IDR_IDR_0)   //  ถ้า PA.0 เป็น 1  :LED ติดหมดสี่ดวง
                               GPIOD->ODR   =  0xF000;
                               if(!(GPIOA->IDR & GPIO_IDR_IDR_0)) //  ถ้า PA.0 เป็น 0  :LED ดับหมดสี่ดวง
                               GPIOD->ODR   =  0;
                              }
}