Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - deejun

#1
ขาย IC MC3PHACVPE   MOTOR CONTROL  SPEED CONTROL :D   Tel 0838349010 สอบถามได้ครับ
3 phase motor control  หรือที่เรื่อง Inverter
#2
ในครั้งนี้มาทำการเรียนรู้ STM32F103  กัน  ตัวอ้างอิงของผมเป็น STM32F103VBT6  ขนาดหน่วยความจำโปรแกรม  128K
ความถี่  72Mhz   ใครที่ใช้ เบอร์อื่นก็แก้ไขเล้กน้อยตามสเป็ค MCU แต่คำสั่งหลายๆอย่างคล้ายๆกันครับ

เริ่มแรกในบทนี้ก็เหมือนเดิม  ให้สร้าง Folderใหม่ขึ้นมา  ตั้งชื้อตามความต้องการของผู้ใช้ สมมุติในบทนี้ผมจะใช้ Clock
ผมสร้าง Floder ชื่อ Clock  และไปทำการก๊อปปี้  File ชื่อ system_stm32f10x.c กับ stm32f10x.h
เข้ามาไว้ใน Floder Clock ที่เร้าสร้างขึ้นมา  เวลาเราก๊อปปี้ ทั้งFloder ไปที่ไหน จะได้ไม่มีปัญหา หา File พวกนี้ไม่เจอ

system_stm32f10x.c  ก็อปมาได้จาก        C:\Keil\ARM\INC\ST\STM32F10x
stm32f10x.h               ก็อปมาได้จาก        C:\Keil\ARM\Startup\ST\STM32F10x

เมื่อมี 2 File นี้ก็เตรียมพร้อม สร้างโปรเจคได้เลย

เปิด Keil เลือกเบอร์ MCU ที่ท่านใช้   ในที่นี้เป็น  stm32f103vb  ครับ  ใครใช้นอกเหนือนี้ก็เปลี่ยนค่าเบอร์เอาครับ
เมื่อเลือกได้แล้ว  โปแกรมจะถามว่าให้แอดเอา startup_stm32f10x.s เข้ามาไว้ในFloder ด้วยมั๊ย  ตอบเลย Yes
ถ้าตอบ No ท่านจะต้องไปก็อปมาใหม่ใน C:\Keil\ARM\Startup\ST\STM32F10x มิเช่นนั้นจะใช้งานมิได้น่ะครับ

เมื่อทำการแอดเสร็จก็เป็นอันเตรียมตัวเขียนโปรแกรมต่อไป   ในช่วงที่จะเริ่มเขียนก็มีคำแนะนำอีกนึดนะครับว่า
STM3210x มันมีหลายซีเรีย จะแบ่งตามขนาดของหน่วยความจำ ซึ่งเราจะต้องรู้ด้วยว่า MCU ที่เราใช้เนี่ยอะ
มันเป็นซีเรียไหน  .......ก็ดูได้จาก Data sheet ของมันอะ  ดูตามต้นไม้  ปะแป้ง ก็ไม่เห็นเลข เอ้ยไม่เห็น รุ่น
น่ะครับ   มาถึงตรงนี้ใจเย็นๆ อย่าพึ่งถอนใจ  ว่ายุ่งยาก  ถ้าเริ่มสัปสนพัก 10 นาทีเดี๋ยวมาต่อกัน
แว๊ปผ่านไป 10 นาที ไวอย่างจรวจ น้ำ  เมื่อเริ่มไม่เข้าใจ หรือเข้าใจ ไม่เป็นไร  มาต่อกัน  ......................
ในรุ่นอ้างอิงผม  stm32f103vb ของผมเป็น MD มิเดียมคือค่าของหน่วยความจำขนาด กลางซึ่งในรุ่นF1 จะมีซีเรียดังนี้

STM32F10X_LD                  =               STM32 Low density devices
STM32F10X_LD_VL            =               STM32 Low density Value Line devices
STM32F10X_MD                 =               STM32 Medium density devices
STM32F10X_MD_VL           =               STM32 Medium density Value Line devices
STM32F10X_HD                 =               STM32 High density devices
STM32F10X_HD_VL           =               STM32 High density value line devices
STM32F10X_XL                  =               STM32 XL-density devices
STM32F10X_CL                  =               STM32 Connectivity line devices */

ดังนั้นมันมีความสำคัญม๊ากมากน่ะครับ เราจะต้องรู้ว่า MCUที่เราใช้เป็นรุ่นได 
stm32f103vbt6  นี้ตรงกับ    STM32F10X_MD  ครับ  เมื่อเรารู้แล้วก็จะให้กดคีย์  Alt+F7พร้อมกันครับ
กดเลยครับ ผมรู้ท่านยังไม่กด กดซะ เดี๋ยวเราจะไปต่อไม่ได้  อะไม่มีไรเกิดขึ้น......ก็เปิดหน้า Keil ก่อนกดครับ
เปิดหน้าเว๊ปนี้กดไม่มีอะไรเกิดขึ้นแน่ๆ  เมื่อเปิด Keil แล้วกด Alt+F7 จะเกิดบล็อกชื่อOption for targetขึ้นม
ให้เลือกหัวข้อชื่อ  C/C++ คลิ๊กเข้าไป จะเห็นมีบล็อกและช่องว่างๆและรายละเอียดขึ้นมา
ในช่องบนสุดแรกที่ชื่อ  Define  และทางขวามือเป็นช่องว่างๆสีขาวให้ใส่รุ่นของ MCU เข้าไปครับ
ในที่นี้เป็นพิมพ์ว     STM32F10X_MD ลงไปเป็นอันสร็จการเลือกรุ่น MCU ถ้าเป็นเบอร์อื่นให้ดูว่าเบอร์นั้นไปตกรุ่นไหน
ก็ใส่ชื่อรุ่นลงไปครับ

ส่วนค่าอื่นๆให้ศึกษาเอาจาก Web keil การใช้งาน หรือที่เคยอ้างอิงไว้หลายลิงค์ก่อนหน้านี้ใน STM32F4 ได้แนบไว้ถ้าไม่เข้าใจก็หา
ศึกษาเพิ่มการใช้ Keil  เพราะต่อจากนี้เราจะไม่พูดเรื่องการ Setup Keil แล้ว เราจะไปต่อที่ตัว MCU เลยครับ

เมื่อทำตามมาถึงตรงนี้เราก็พร้อมเดินเครื่องกันได้เลยครับ  ตรงนี้ขอจบไว้ก่อนที่การ  Setup Keil ก่อนเขียนโปรแกรม
 










#3
1      สร้าง Floder ชื่อ PWM ขึ้นมา
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
/***************************************************************/
การสร้าง PWM แบบง่ายๆครับลองศึกษาโค๊ดตัวอย่างดูครับ ได้อธิบายเป็นสเต็ปไว้แล้ว จะได้ผลยิ่งนักให้ดู
ที่ Register ที่ใช้งานประกอบคำบรรยายของ Reference Manual RM0090ครับ จะได้ผลชะงัดแล

เอาท์พุตดูที่ขา GPIOC6 , GPIOC7, GPIOC8 , GPIOC9
#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 On
            while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Wait Pll On
}


int main(void)
               {
clock();
/*---------STEP 1 Select TIMx_CH (See Data sheet Pin)--------------*/
/*--Example Select TIM3_CH1(GPIOC6),TIM3_CH2(GPIOC7),TIM3_CH3(GPIOC8),TIM3_CH4(GPIO9)--*/
/*---------STEP 2 Set GPIOx,TIMx and Open clock module--------------*/

        RCC->AHB1ENR |=   RCC_AHB1ENR_GPIOCEN; // Open Clock GPIOC
// Select Pin Output  (GPIOC.6,GPIOC.7,GPIOC.8,GPIOC.9)
GPIOC->MODER |=   GPIO_MODER_MODER6_1|GPIO_MODER_MODER7_1|
                  GPIO_MODER_MODER8_1|GPIO_MODER_MODER9_1;
// Speed Pin Output  (GPIOC.6,GPIOC.7,GPIOC.8,GPIOC.9)
GPIOC->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6_0|GPIO_OSPEEDER_OSPEEDR7_0|
                  GPIO_OSPEEDER_OSPEEDR8_0|GPIO_OSPEEDER_OSPEEDR9_0;
GPIOC->PUPDR |= 0x00055000;

/*---------STEP 3 Set Alternate function Pin GPIO--------------*/

// Byte Low Function select (GPIOC.6,GPIOC.7) is AF2 of Timer3 Control Bit
GPIOC->AFR[0] |= 0x22000000;
//  Byte High Function select (GPIOC.8,GPIOC.9)is AF2 of Timer3 Control Bit
GPIOC->AFR[1] |= 0x00000022;

/*---------STEP 4 Set TIMER--------------*/

RCC->APB1ENR |= (1<<1); // Open clock Timer3
TIM3->PSC = 100;        // Prescale Fs/100 (Set Frequency PWM)
TIM3->ARR = 1000;       // Counter/Resolution/(Set Frequency PWM)
                        //Resolution PWM *...ARR = 1000, PWM  = 1000  Step
                        //Resolution PWM *...ARR = 100,  PWM  = 100  Step
                        //Resolution PWM *...ARR = 50,   PWM  = 50  Step

TIM3->EGR |= 1;         // Up Counter

/*---------STEP 5 Set Wave form PWM at register CCMRx --------------*/

//  Timer 3 Gen PWM comparator

TIM3->CCMR1 |= 0x6060;  // Set PWM channel 1 and PWM Channel 2
TIM3->CCMR2 |= 0x6060;  // Set PWM channel 3 and PWM Channel 4

/*---------STEP 6 Set Duty PWM --------------*/

TIM3->CCR1 = 800;       // Set Duty PWM1 ( CCR1 <= ARR )
TIM3->CCR2 = 400;       // Set Duty PWM2 ( CCR2 <= ARR )
TIM3->CCR3 = 200;       // Set Duty PWM3 ( CCR3 <= ARR )
TIM3->CCR4 = 100;       // Set Duty PWM4 ( CCR1 <= ARR )

TIM3->CCER |= 0x1111;   // Enable PWM1,PWM2,PWM3,andPWM4

TIM3->CR1 |= 1;         // Enable TIM3
while(1)
                       {
                //code Program
                       }
}




/*************************************************************************************/
ตัวอย่างที่ 2 เป็นการขับ PWM 4 ช่องออกทาง   LED4 ดวง   PD15,PD14,PD13,PD12  แสดงความสว่างไล่ละดับแสง


#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; 
        while (!(RCC->CR & 0x00020000));
        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->CR       |=    RCC_CR_PLLON;   
          while(!(RCC->CR & 0x02000000));     
          FLASH->ACR     =    0x00000605;     
          RCC->CFGR     |=    0x00000002;     
          while ((RCC->CFGR & 0x0000000F) != 0x0000000A);
}
void Set_GPIO()
            {
RCC->AHB1ENR |=   RCC_AHB1ENR_GPIODEN; // Open Clock GPIOD

GPIOD->MODER |=   GPIO_MODER_MODER15_1|GPIO_MODER_MODER14_1|
GPIO_MODER_MODER13_1|GPIO_MODER_MODER12_1;

GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR15_0|GPIO_OSPEEDER_OSPEEDR14_0|
GPIO_OSPEEDER_OSPEEDR13_0|GPIO_OSPEEDER_OSPEEDR12_0;
GPIOD->PUPDR  |= 0x55000000;
GPIOD->AFR[0] |= 0;
         GPIOD->AFR[1] |= 0x22220000;

}
void delay(long signed int sn)
                          {
                           while(sn--);
}


int main(void)
               {
int Ln;
            clock();
Set_GPIO(); 
              RCC->APB1ENR |=  RCC_APB1ENR_TIM4EN ;
            TIM4->PSC = 200;        // Prescale Fs/100 (Set Frequency PWM)
            TIM4->ARR = 100;       // Counter/Resolution/(Set Frequency PWM)
            TIM4->EGR |= 1;         // Up Counter

TIM4->CCMR1 |= 0x6060;  // Set PWM channel 1 and PWM Channel 2
TIM4->CCMR2 |= 0x6060;  // Set PWM channel 3 and PWM Channel 4

TIM4->CCR1 = 0;       // Set Duty PWM1 ( CCR1 <= ARR )
TIM4->CCR2 = 0;       // Set Duty PWM2 ( CCR2 <= ARR )
TIM4->CCR3 = 0;       // Set Duty PWM3 ( CCR3 <= ARR )
TIM4->CCR4 = 0;       // Set Duty PWM4 ( CCR1 <= ARR )

            TIM4->CCER |= 0x1111;   // Enable PWM1,PWM2,PWM3,andPWM4
                TIM4->CR1 |= 1;         // Enable TIM4
while(1)
                       {
for(Ln=0;Ln<100;Ln++)
                                        {                 
                                       TIM4->CCR1 = Ln;       // Set Duty PWM1 ( CCR1 <= ARR )
TIM4->CCR2 = Ln;       // Set Duty PWM2 ( CCR2 <= ARR )
TIM4->CCR3 = Ln;       // Set Duty PWM3 ( CCR3 <= ARR )
TIM4->CCR4 = Ln;       // Set Duty PWM4 ( CCR1 <= ARR )
                                         delay(40000);
                }


for(Ln=100;Ln>0;Ln--)
          {
TIM4->CCR1 = Ln;       // Set Duty PWM1 ( CCR1 <= ARR )
TIM4->CCR2 = Ln;       // Set Duty PWM2 ( CCR2 <= ARR )
TIM4->CCR3 = Ln;       // Set Duty PWM3 ( CCR3 <= ARR )
TIM4->CCR4 = Ln;       // Set Duty PWM4 ( CCR1 <= ARR )
delay(120000);

                                  }

}
}


/************************************************************************/

ตัวอย่างที่ 3 ไฟวิ่งแบบ PWM


#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; 
        while (!(RCC->CR & 0x00020000));
        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->CR       |=    RCC_CR_PLLON;   
          while(!(RCC->CR & 0x02000000));     
          FLASH->ACR     =    0x00000605;     
          RCC->CFGR     |=    0x00000002;     
          while ((RCC->CFGR & 0x0000000F) != 0x0000000A);
}
void Set_GPIO()
            {
RCC->AHB1ENR |=   RCC_AHB1ENR_GPIODEN; // Open Clock GPIOD

GPIOD->MODER |=   GPIO_MODER_MODER15_1|GPIO_MODER_MODER14_1|
GPIO_MODER_MODER13_1|GPIO_MODER_MODER12_1;

GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR15_0|GPIO_OSPEEDER_OSPEEDR14_0|
GPIO_OSPEEDER_OSPEEDR13_0|GPIO_OSPEEDER_OSPEEDR12_0;
GPIOD->PUPDR  |= 0x55000000;
GPIOD->AFR[0] |= 0;
         GPIOD->AFR[1] |= 0x22220000;

}
void delay(long signed int sn)
                             {
                              while(sn--);
}
int main(void)
               {
clock();
Set_GPIO(); 
              RCC->APB1ENR |=  RCC_APB1ENR_TIM4EN ;
            TIM4->PSC = 200;        // Prescale Fs/100 (Set Frequency PWM)
            TIM4->ARR = 100;       // Counter/Resolution/(Set Frequency PWM)
            TIM4->EGR |= 1;         // Up Counter

TIM4->CCMR1 |= 0x6060;  // Set PWM channel 1 and PWM Channel 2
TIM4->CCMR2 |= 0x6060;  // Set PWM channel 3 and PWM Channel 4

TIM4->CCR1 = 0;       // Set Duty PWM1 ( CCR1 <= ARR )
TIM4->CCR2 = 0;       // Set Duty PWM2 ( CCR2 <= ARR )
TIM4->CCR3 = 0;       // Set Duty PWM3 ( CCR3 <= ARR )
TIM4->CCR4 = 0;       // Set Duty PWM4 ( CCR1 <= ARR )

            TIM4->CCER |= 0x1111;   // Enable PWM1,PWM2,PWM3,andPWM4
                TIM4->CR1 |= 1;         // Enable TIM4
            while(1)
{
for(TIM4->CCR1=0;TIM4->CCR1<100;TIM4->CCR1++) {delay(30000);}
for(TIM4->CCR2=0;TIM4->CCR2<100;TIM4->CCR2++) {delay(30000);}
for(TIM4->CCR3=0;TIM4->CCR3<100;TIM4->CCR3++) {delay(30000);}
for(TIM4->CCR4=0;TIM4->CCR4<100;TIM4->CCR4++) {delay(30000);}
for(TIM4->CCR1=100;TIM4->CCR1>0;TIM4->CCR1--) {delay(30000);}
for(TIM4->CCR2=100;TIM4->CCR2>0;TIM4->CCR2--) {delay(30000);}
for(TIM4->CCR3=100;TIM4->CCR3>0;TIM4->CCR3--) {delay(30000);}
for(TIM4->CCR4=100;TIM4->CCR4>0;TIM4->CCR4--) {delay(30000);}
}
}
#4
STM32F4 discovery  โดย keil เรื่อง การใช้ DAC  และ การใช้ โมดูล ที่ผ่านๆมาใช้งานร่วม เช่น Timer , ADC เป็นต้น

1      สร้าง Floder ชื่อ ADC10_14 ขึ้นมา
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
**************************************************
DAC  เริ่มที่หน้า  311/1422  ของ Reference-Manual stm32F4xx
รีจีสเตอร์ที่ควรศึกษา

DAC control register      DAC_CR
DAC control register      DAC_SWTRIGR
DAC control register      DAC_DHR12R1
DAC control register      DAC_DHR12L1
DAC control register      DAC_DHR8R1
DAC control register      DAC_DHR12R2
DAC control register      DAC_DHR12L2
DAC control register      DAC_DHR8R2
DAC control register      DAC_DHR12RD
DAC control register      DAC_DHR12LD
DAC control register      DAC_DHR8RD
DAC control register      DAC_DOR1
DAC control register      DAC_DOR2
DAC control register      DAC_SR

DAC register map          หน้า  329/1422
*********************************************************

เอาท์พุตของ DAC1 และ DAC2 จะอยู่ที่ขา PA.4   และ PA.5 
PA04, PA05 are analog outputs


ตัวอย่างใช้งาน ADC และ Timer ร่วม

เอาท์พุตจะออกตามการแปลงของ ADC1 โดยใช้ Vr 3 ขา  ที่ขากลางขา(2) Vr ต่อที่ PC.4 อินพุต ADC1
ขา(1) ต่อลง กราวด์ (0V)  และขา(3) Vr ต่อไฟ (VCC) 3.3V   แล้วทดสอบโดยการปรับ Vr ซ้าย-ขวา ดู
แล้ววัดแรงดันเอาท์พุทที่ PA.4 และ PA.5 เทียบกราวด์ ใช้ มิเตอร์ หรือสโคปวัดได้

Timer ใช้ทำไฟกระพริบ ที่ขา PD.5  ติดดับ
และมีไฟ LED เป็นสเกลบอกระยะช่วงของแรงดัน PD15,PD14,PD13,PD12


#include"stm32f4xx.h"
void clock()
              {
               RCC->CFGR      =   0;
               RCC->CR        =   0;
               RCC->CFGR     |=   (RCC_CFGR_HPRE_DIV1|RCC_CFGR_PPRE1_DIV4|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->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 On
               while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Wait Pll On
}
void Set_GPIO()
                     {
                      // Set Speed GPIOD is 100Mhz
                      GPIOD->OSPEEDR =   0xFFFF;
                      // Open clock to GPIOD
                      RCC->AHB1ENR    |=   RCC_AHB1ENR_GPIOAEN|RCC_AHB1ENR_GPIOCEN|RCC_AHB1ENR_GPIODEN;
                       // Set GPIO  D.15,D.14,D.13,D.12 D.5 is Output
                      GPIOD->MODER    =    0x55000400;
                      GPIOD->ODR      =    0;
                      GPIOC->PUPDR    =    0;
                      GPIOC->MODER    =    0x00000300;
                      GPIOD->ODR      =    0x20;
}

void adc_1(void)
                 {
                  //ADC configuration
                  RCC->APB2ENR   |=   RCC_APB2ENR_ADC1EN;
                  ADC->CCR        =   ADC_CCR_ADCPRE_1;
                  ADC1->CR2       = ADC_CR2_ADON|ADC_CR2_EXTSEL|ADC_CR2_EXTEN;
                  ADC1->SQR3      =   14;     //channel number 14 PC4 first conversion
}
void DAC_1(void)
                {
                 RCC->APB1ENR    |=  RCC_APB1ENR_DACEN;      // Open clock to Dac
                 DAC->CR         |=  DAC_CR_EN1|DAC_CR_EN2;  // used Dac1 and Dac2
                 GPIOA->MODER    |=  0x00000f00;   // PA04, PA05 are analog outputs
}
void Tim2(long signed PSC2,long signed ARR2)
           {
            RCC->APB1ENR |=  RCC_APB1ENR_TIM2EN ;
            TIM2->PSC = PSC2;
            TIM2->ARR = ARR2;
            TIM2->SR &= ~TIM_SR_UIF ;                             
            TIM2->DIER |= TIM_DIER_UIE ;
            NVIC_EnableIRQ(TIM2_IRQn);
}
void TIM2_IRQHandler(void)
                                 {
                                  TIM2->SR       =  0;
                                  GPIOD->ODR    ^=  0x20;
}

int main()
             {
              unsigned adc1;
              clock();
              Set_GPIO();
              adc_1();
              DAC_1();
              Tim2(5000,500);
              TIM2->CR1 = TIM_CR1_CEN;
              while(1)
                         {
                          ADC1->CR2      |=    ADC_CR2_SWSTART;
                          while((ADC1->SR & ADC_SR_EOC )==0);
                          ADC1->SR        =   0;
                          adc1            =  ADC1->DR;
                          DAC->DHR12R1    =   adc1;    //channel1  12bit shift to right
                          DAC->DHR12R2    =   adc1;    //channel2  12bit shift to right
                          if(adc1>800)
                          GPIOD->ODR       |=  0x1000;
                          else
                          GPIOD->ODR     &=  0xE0F0;
                          if(adc1>1600)
                          GPIOD->ODR     |=  0x2000;
                          else
                          GPIOD->ODR     &=  0xD0F0;
                           if(adc1>2400)
                           GPIOD->ODR     |=  0x4000;
                           else
                           GPIOD->ODR    &=  0xB0F0;
                           if(adc1>3200)
                           GPIOD->ODR     |=  0x8000;
                           else
                           GPIOD->ODR     &=  0x70F0;
                          }
}




Code ที่2 สร้างสัญญาณ Sine Wave   เอาท์พุทที่ขา PA.4และ PA.5

ให้ใช้สโคปวัดโดยขั้วบวกวัดที่ขา PA.4  และ กราวด์ สโคปวัดที่ PA.5
Code จะสร้างสัญญาณ ฮาฟเวฟ ที่ DAC1 และ DAC2  ต่างเฟส 180 องศา
และมีความละเอียดที่สเต็ปละ 1องศา ดังนั้น 360 องศา เท่ากับ 360 สเต็ป
จะมีเคาท์เตอร์เป็นตัวนับเพื่อไปดึงขู้มูลในตารางที่เราใส่ค่าองศาไว้แล้วโดยมี
Timer เป็นตัวกำหนดจังหวะในการไปดึงข้อมูลจากตาราง เราสามารถเปลี่ยนความถี่
ที่สร้างได้จากการเปลี่ยนค่าใน Timer จาก ค่า ARR  42,=>420,=>4200  เปลี่ยนค่า
แล้ววัดดู  ถ้าเราวัดที่เอาท์พุตเทียบกราวด์ทั้ง 2Channel เราจะเห็นรูป ฮาฟบริดท์
ต่าง 180 องศาที่ ทั้งสอง Channel เทียบ กราวด์

#include"stm32f4xx.h"




unsigned int An[] = {0,71,142,214,285,356,428,499,569,640,711,781,851,921,990,1059,1128,1197,1265,1333,1400,1467,
1534,1600,1665,1730,1795,1859,1922,1985,2047,2109,2170,2230,2289,2348,2407,2464,2521,2577,2632,2686,2740,2792,2844,
2895,2945,2994,3043,3090,3136,3182,3226,3270,3312,3354,3394,3434,3472,3510,3546,3581,3615,3648,3680,3711,3740,3769,
3796,3823,3848,3871,3894,3916,3936,3955,3973,3990,4005,4019,4032,4044,4055,4064,4072,4079,4085,4089,4092,4094,4095,
4094,4092,4089,4085,4079,4072,4064,4055,4044,4032,4019,4005,3990,3973,3955,3936,3916,3894,3871,3848,3823,3796,
3769,3740,3711,3680,3648,3615,3581,3546,3510,3472,3434,3394,3354,3312,3270,3226,3182,3136,3090,3043,2994,2945,2895,
2844,2792,2740,2686,2632,2577,2521,2464,2407,2348,2289,2230,2170,2109,2047,1985,1922,1859,1795,1730,1665,1600,1534,
1467,1400,1333,1265,1197,1128,1059,990,921,851,781,711,640,569,499,428,356,285,214,142,71,0};



unsigned int Cn = 0;


void clock()
{
RCC->CFGR      =   0;         
RCC->CR        =   0;
RCC->CFGR     |=   (RCC_CFGR_HPRE_DIV1|RCC_CFGR_PPRE1_DIV4|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->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 On
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Wait Pll On
}
void delay(long signed count)
           {
            while(count--);
           }
void Set_GPIO()
            {
// Set Speed GPIOD is 100Mhz
GPIOD->OSPEEDR =   0xFFFF;
   // Open clock to GPIOD
RCC->AHB1ENR    |=   RCC_AHB1ENR_GPIOAEN|RCC_AHB1ENR_GPIOCEN|RCC_AHB1ENR_GPIODEN;
// Set GPIO  D.15,D.14,D.13,D.12 D.5 is Output
GPIOD->MODER    =    0x55000400;
GPIOD->ODR      =    0;
GPIOC->PUPDR    =    0 ;
GPIOC->MODER    =    0x00000300;
             GPIOD->ODR      =    0x20;
             
  }

void DAC_1(void)
                {
RCC->APB1ENR    |=  RCC_APB1ENR_DACEN;
                 DAC->CR         |=  DAC_CR_EN1|DAC_CR_EN2;
   DAC->CR         |=  (DAC_CR_MAMP1_3|DAC_CR_MAMP1_2);
   DAC->CR         |=  (DAC_CR_MAMP2_3|DAC_CR_MAMP2_2);
                 GPIOA->MODER    |=  0x00000f00;   // PA04, PA05 are analog outputs
}
void Tim2(long signed PSC2,long signed ARR2)
           {
            RCC->APB1ENR |=  RCC_APB1ENR_TIM2EN ;
            TIM2->PSC = PSC2;
            TIM2->ARR = ARR2;
            TIM2->SR &= ~TIM_SR_UIF ;                             
            TIM2->DIER |= TIM_DIER_UIE ;
            NVIC_EnableIRQ(TIM2_IRQn);
}
void TIM2_IRQHandler(void)
{
TIM2->SR        =  0;
if(Cn<179)
         {
          DAC->DHR12R1    =  An[Cn];
                        DAC->DHR12R2    =  0;
Cn             +=  1;
}
               else
          {
DAC->DHR12R2    =  An[Cn-179];
                        DAC->DHR12R1    =  0;
Cn             +=  1;
                        if(Cn>355)
                        Cn              =  0;

                        }
              ;
}


int main()
             {
clock();
  Set_GPIO();
DAC_1();
Tim2(0,42);
              TIM2->CR1 = TIM_CR1_CEN;
              while(1)
{

}
}




Code ตัวอย่างที่3 สร้างสัญญาณ Sine Wave แบบกราวด์รอย  เอาท์พุทที่ขา PA.4และ PA.5ให้วัดสัญญาณเทียบกราวด์ 0V


#include"stm32f4xx.h"




unsigned int An[] = {0,71,142,214,285,356,428,499,569,640,711,781,851,921,990,1059,1128,1197,1265,1333,1400,1467,
1534,1600,1665,1730,1795,1859,1922,1985,2047,2109,2170,2230,2289,2348,2407,2464,2521,2577,2632,2686,2740,2792,2844,
2895,2945,2994,3043,3090,3136,3182,3226,3270,3312,3354,3394,3434,3472,3510,3546,3581,3615,3648,3680,3711,3740,3769,
3796,3823,3848,3871,3894,3916,3936,3955,3973,3990,4005,4019,4032,4044,4055,4064,4072,4079,4085,4089,4092,4094,4095,
4094,4092,4089,4085,4079,4072,4064,4055,4044,4032,4019,4005,3990,3973,3955,3936,3916,3894,3871,3848,3823,3796,
3769,3740,3711,3680,3648,3615,3581,3546,3510,3472,3434,3394,3354,3312,3270,3226,3182,3136,3090,3043,2994,2945,2895,
2844,2792,2740,2686,2632,2577,2521,2464,2407,2348,2289,2230,2170,2109,2047,1985,1922,1859,1795,1730,1665,1600,1534,
1467,1400,1333,1265,1197,1128,1059,990,921,851,781,711,640,569,499,428,356,285,214,142,71,0};



unsigned int Cn = 0;


void clock()
{
RCC->CFGR      =   0;         
RCC->CR        =   0;
RCC->CFGR     |=   (RCC_CFGR_HPRE_DIV1|RCC_CFGR_PPRE1_DIV4|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->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 On
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Wait Pll On
}
void delay(long signed count)
           {
            while(count--);
           }
void Set_GPIO()
            {
// Set Speed GPIOD is 100Mhz
GPIOD->OSPEEDR =   0xFFFF;
   // Open clock to GPIOD
RCC->AHB1ENR    |=   RCC_AHB1ENR_GPIOAEN|RCC_AHB1ENR_GPIOCEN|RCC_AHB1ENR_GPIODEN;
// Set GPIO  D.15,D.14,D.13,D.12 D.5 is Output
GPIOD->MODER    =    0x55000400;
GPIOD->ODR      =    0;
GPIOC->PUPDR    =    0 ;
GPIOC->MODER    =    0x00000300;
             GPIOD->ODR      =    0x20;
             
  }

void DAC_1(void)
                {
RCC->APB1ENR    |=  RCC_APB1ENR_DACEN;
                 DAC->CR         |=  DAC_CR_EN1|DAC_CR_EN2;
   DAC->CR         |=  (DAC_CR_MAMP1_3|DAC_CR_MAMP1_2);
   DAC->CR         |=  (DAC_CR_MAMP2_3|DAC_CR_MAMP2_2);
                 GPIOA->MODER    |=  0x00000f00;   // PA04, PA05 are analog outputs
}
void Tim2(long signed PSC2,long signed ARR2)
           {
            RCC->APB1ENR |=  RCC_APB1ENR_TIM2EN ;
            TIM2->PSC = PSC2;
            TIM2->ARR = ARR2;
            TIM2->SR &= ~TIM_SR_UIF ;                             
            TIM2->DIER |= TIM_DIER_UIE ;
            NVIC_EnableIRQ(TIM2_IRQn);
}
void TIM2_IRQHandler(void)
{
TIM2->SR        =  0;
if(Cn<179)
         {
          DAC->DHR12R1    =  2047+((An[Cn])/2);
                        DAC->DHR12R2    =  DAC->DHR12R1;
Cn             +=  1;
}
               else
          {
DAC->DHR12R1    =  2047-((An[Cn-179])/2);
                        DAC->DHR12R2    =  DAC->DHR12R1;
Cn             +=  1;
                        if(Cn>355)
                        Cn              =  0;

                        }
              ;
}


int main()
             {
clock();
  Set_GPIO();
DAC_1();
Tim2(0,42);
              TIM2->CR1 = TIM_CR1_CEN;
              while(1)
{

}
}



Code ตัวอย่างที่4 สร้างสัญญาณ Sine Wave แบบกราวด์รอย  เอาท์พุท PA.4 ต่างเฟสกัน180องศากับ PA.5[/b]
#include"stm32f4xx.h"




unsigned int An[] = {0,71,142,214,285,356,428,499,569,640,711,781,851,921,990,1059,1128,1197,1265,1333,1400,1467,
1534,1600,1665,1730,1795,1859,1922,1985,2047,2109,2170,2230,2289,2348,2407,2464,2521,2577,2632,2686,2740,2792,2844,
2895,2945,2994,3043,3090,3136,3182,3226,3270,3312,3354,3394,3434,3472,3510,3546,3581,3615,3648,3680,3711,3740,3769,
3796,3823,3848,3871,3894,3916,3936,3955,3973,3990,4005,4019,4032,4044,4055,4064,4072,4079,4085,4089,4092,4094,4095,
4094,4092,4089,4085,4079,4072,4064,4055,4044,4032,4019,4005,3990,3973,3955,3936,3916,3894,3871,3848,3823,3796,
3769,3740,3711,3680,3648,3615,3581,3546,3510,3472,3434,3394,3354,3312,3270,3226,3182,3136,3090,3043,2994,2945,2895,
2844,2792,2740,2686,2632,2577,2521,2464,2407,2348,2289,2230,2170,2109,2047,1985,1922,1859,1795,1730,1665,1600,1534,
1467,1400,1333,1265,1197,1128,1059,990,921,851,781,711,640,569,499,428,356,285,214,142,71,0};



unsigned int Cn = 0;


void clock()
{
RCC->CFGR      =   0;         
RCC->CR        =   0;
RCC->CFGR     |=   (RCC_CFGR_HPRE_DIV1|RCC_CFGR_PPRE1_DIV4|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->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 On
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Wait Pll On
}
void delay(long signed count)
           {
            while(count--);
           }
void Set_GPIO()
            {
// Set Speed GPIOD is 100Mhz
GPIOD->OSPEEDR =   0xFFFF;
   // Open clock to GPIOD
RCC->AHB1ENR    |=   RCC_AHB1ENR_GPIOAEN|RCC_AHB1ENR_GPIOCEN|RCC_AHB1ENR_GPIODEN;
// Set GPIO  D.15,D.14,D.13,D.12 D.5 is Output
GPIOD->MODER    =    0x55000400;
GPIOD->ODR      =    0;
GPIOC->PUPDR    =    0 ;
GPIOC->MODER    =    0x00000300;
             GPIOD->ODR      =    0x20;
             
  }

void DAC_1(void)
                {
RCC->APB1ENR    |=  RCC_APB1ENR_DACEN;
                 DAC->CR         |=  DAC_CR_EN1|DAC_CR_EN2;
   DAC->CR         |=  (DAC_CR_MAMP1_3|DAC_CR_MAMP1_2);
   DAC->CR         |=  (DAC_CR_MAMP2_3|DAC_CR_MAMP2_2);
                 GPIOA->MODER    |=  0x00000f00;   // PA04, PA05 are analog outputs
}
void Tim2(long signed PSC2,long signed ARR2)
           {
            RCC->APB1ENR |=  RCC_APB1ENR_TIM2EN ;
            TIM2->PSC = PSC2;
            TIM2->ARR = ARR2;
            TIM2->SR &= ~TIM_SR_UIF ;                             
            TIM2->DIER |= TIM_DIER_UIE ;
            NVIC_EnableIRQ(TIM2_IRQn);
}
void TIM2_IRQHandler(void)
{
TIM2->SR        =  0;
if(Cn<179)
         {
          DAC->DHR12R1    =  2047+((An[Cn])/2);
                        DAC->DHR12R2    =  2047-((An[Cn])/2);
Cn             +=  1;

}
               else
          {
DAC->DHR12R1    =  2047-((An[Cn-179])/2);
                        DAC->DHR12R2    =  2047+((An[Cn-179])/2);
Cn             +=  1;
                        if(Cn>355)
                        Cn              =  0;
                       

                        }
              ;
}


int main()
             {
clock();
  Set_GPIO();
DAC_1();
Tim2(0,42);
              TIM2->CR1 = TIM_CR1_CEN;
              while(1)
{

}
}
#5
STM32F4 discovery การใช้ Interrupt external  EXTI 0

1      สร้าง Floder ชื่อ ADC10_14 ขึ้นมา
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

Interrupt external สามารถปรับให้รับได้ถึง  15 External ทำงานด้วยกัน เรียงละดับไปตามความสำคํญ
ขาทุกขาที่เป็นGPIO สามารถกำหนดให้เป็นขารับรู้การเกิดเหตุการต่างๆ เพื่อนำไปควบคุมลูป หรือการทำงาน
ที่กำหนดได้  ตัวอย่าง GPIOA 0.....GPIO15 เราจะได้ External Event ดังนี้
GPIOA0 ===> คุบ  Ext 0
GPIOA1===>  คุบ  Ext 1
GPIOA2===>  คุบ  Ext 2
.                            .
.                            .
GPIOA14===>  คุบ  Ext 14
GPIOA15===>  คุบ  Ext 15

หรือ

GPIOB0 ===> คุบ  Ext 0
GPIOB1===>  คุบ  Ext 1
GPIOB2===>  คุบ  Ext 2
.                            .
.                            .
GPIOB14===>  คุบ  Ext 14
GPIOB15===>  คุบ  Ext 15

หรือ
.
.
.

GPIOn0 ===> คุบ  Ext 0
GPIOn1===>  คุบ  Ext 1
GPIOn2===>  คุบ  Ext 2
.                            .
.                            .
GPIOn14===>  คุบ  Ext 14
GPIOn15===>  คุบ  Ext 15

จะเห็นได้ว่า ที่ GPIO(x)  ต่างๆ ตำแหน่ง Bit0  จะคุม  Ext 0
จะเห็นได้ว่า ที่ GPIO(x)  ต่างๆ ตำแหน่ง Bit1  จะคุม  Ext 1
.                                .                                 .
.                                .                                 .
จะเห็นได้ว่า ที่ GPIO(x)  ต่างๆ ตำแหน่ง Bit15  จะคุม  Ext 15 
เราสามารถให้ Ext 0  เกิดที่ GPIO ไหนก็ได้โดยการใช้ รีจีสเตอร์ควบคุม
และสามารถใช้พร้อมกันได้ถึง  15 External Event และแต่ละ อันสามารถ
ใช้ต่าง GPIO ในการรับค่าได้

SYSCFG_EXTICR1 ใช้ในการเลือก GPIO ต่างให้เป็น Ext นั้นๆ 

SYSCFG_EXTICR1 คุม  Ext0 ถึง Ext3
SYSCFG_EXTICR2 คุม  Ext4 ถึง Ext7
SYSCFG_EXTICR3 คุม  Ext8 ถึง Ext11
SYSCFG_EXTICR4 คุม  Ext12 ถึง Ext15








************************************************************************
#define SYSCFG_EXTICR1_EXTI0_PA         ((uint16_t)0x0000) /*!<PA[0] pin */
#define SYSCFG_EXTICR1_EXTI0_PB         ((uint16_t)0x0001) /*!<PB[0] pin */
#define SYSCFG_EXTICR1_EXTI0_PC         ((uint16_t)0x0002) /*!<PC[0] pin */
#define SYSCFG_EXTICR1_EXTI0_PD         ((uint16_t)0x0003) /*!<PD[0] pin */
#define SYSCFG_EXTICR1_EXTI0_PE         ((uint16_t)0x0004) /*!<PE[0] pin */
#define SYSCFG_EXTICR1_EXTI0_PF         ((uint16_t)0x0005) /*!<PF[0] pin */
#define SYSCFG_EXTICR1_EXTI0_PG         ((uint16_t)0x0006) /*!<PG[0] pin */
#define SYSCFG_EXTICR1_EXTI0_PH         ((uint16_t)0x0007) /*!<PH[0] pin */
#define SYSCFG_EXTICR1_EXTI0_PI         ((uint16_t)0x0008) /*!<PI[0] pin */   
.                                                                   .
.                                                                   .
.                                                                   .   
#define SYSCFG_EXTICR4_EXTI15_PA        ((uint16_t)0x0000) /*!<PA[15] pin */
#define SYSCFG_EXTICR4_EXTI15_PB        ((uint16_t)0x1000) /*!<PB[15] pin */
#define SYSCFG_EXTICR4_EXTI15_PC        ((uint16_t)0x2000) /*!<PC[15] pin */
#define SYSCFG_EXTICR4_EXTI15_PD        ((uint16_t)0x3000) /*!<PD[15] pin */
#define SYSCFG_EXTICR4_EXTI15_PE        ((uint16_t)0x4000) /*!<PE[15] pin */
#define SYSCFG_EXTICR4_EXTI15_PF        ((uint16_t)0x5000) /*!<PF[15] pin */
#define SYSCFG_EXTICR4_EXTI15_PG        ((uint16_t)0x6000) /*!<PG[15] pin */
#define SYSCFG_EXTICR4_EXTI15_PH        ((uint16_t)0x7000) /*!<PH[15] pin */

EXTI_RTSR        รีจีสเตอร์คุมการตรวจสอบ ขอบขาขึ้นของเหตุการ
EXTI_FTSR        รีจีสเตอร์คุมการตรวจสอบ ขอบขาลงของเหตุการ

ดูข้อมูลได้จาก Reference manual stm32f4 st หน้า 259/1422 - 262/1422
และ หน้า 208/1422 - 210/1422
       


#include"stm32f4xx.h"

int in = 0; 
int b[]={0x8020,0x4020,0x2020,0x1020,0x20,0};


void clock(void)
       {
                       RCC->CFGR     =   0;
                       RCC->CR       =   0;
                       RCC->CFGR     |= 0x00009400;
                       RCC->CR       |=  RCC_CR_HSEON;    //  HSE Xtal On
                       while (!(RCC->CR & 0x00020000));   // wait Xtal osc stability
                       RCC->PLLCFGR  =   0x07405408;      // Set PLL   M=8, N=336, P=2 ve Q=7
                       RCC->CR |= RCC_CR_PLLON;            // PLL On
                       while(!(RCC->CR & 0x02000000))      // wait Pll on
                       FLASH->ACR = 0x00000605;        // Flash ROM is 5 Wait state
                       RCC->CFGR |= 0x00000002;        // System PLL On
                       while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Wait Pll On
}

void delay(long signed count)    //  ฟังก์ชันหน่วงเวลา
           {
            while(count--);
           }




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 |
                                                GPIO_OSPEEDER_OSPEEDR5_0);

           GPIOA->PUPDR    |=    0xFC;   
           GPIOA->MODER    |=    0xFC;   //  Input รับค่า
}

void EXTI0_IRQHandler(void)   // .....ลูปการเกิด interrupt External 0
             {
               EXTI->PR       =   EXTI_PR_PR0;       //เคลียร์ค่าอินเตอร์รัป
               GPIOD->ODR     =   b[in];           
               in             =   in+1;
               if(in>5)
               in  =  0;
               delay(1000);              // หน่วงเวลาสำหรับ หน้าสำผัสสวิตสวิงเวลา กด-ปล่อย
               }

int main(void)
                {
                 clock();
                 Set_GPIO();
                 RCC->APB2ENR  |=  RCC_APB2ENR_SYSCFGEN ;  // ป้อนคล็อกให้กับระบบ External interrupt
                 EXTI->FTSR         =  EXTI_FTSR_TR0;                    // ตั้งให้รับการตรวจสอบขอบขาลงในช่องที่เลือก ทำงาน
                 EXTI->IMR           =  EXTI_IMR_MR0;                     // กำหนดช่องที่เลือกให้ทำงาน 
                 NVIC_EnableIRQ(EXTI0_IRQn);                              //  สั่งให้ Interrupt ทำงาน
                 while(1)
                           {
                             ;
                           }
}
#6
STM32F4 discovery  การใช้ADC1 , ADC2 , ADC3 ทำงานพร้อมกัน

1      สร้าง Floder ชื่อ ADC123  ขึ้นมา
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

PC.0 Channel  10   ADC1
PC.1 Channel  11   ADC2
PC.2 Channel  12   ADC3

แรงดัน input  0-3.3V (VCC) 

เป็นตัวอย่างในการศึกษาการ Scan แต่ละช่อง พร้อมกัน นำไปดัดแปลงใช้งานได้

#include"stm32f4xx.h"
void clock(void)
{
                  RCC->CFGR     =   0;
                  RCC->CR       =   0;
                  RCC->CFGR     |= 0x00009400;
                  RCC->CR       |=  RCC_CR_HSEON;    //  HSE Xtal On
                  while (!(RCC->CR & 0x00020000));   // wait Xtal osc stability
                  RCC->PLLCFGR  =   0x07405408;      // Set PLL   M=8, N=336, P=2 ve Q=7
                  RCC->CR |= RCC_CR_PLLON;            // PLL On
                   while(!(RCC->CR & 0x02000000))      // wait Pll on
                  FLASH->ACR = 0x00000605;        // Flash ROM is 5 Wait state
                  RCC->CFGR |= 0x00000002;        // System PLL On
                  while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Wait Pll On
}
void GPIO(void)
                     {
                       // Set Speed GPIOD is 100Mhz
                       GPIOD->OSPEEDR =   0xFFFF;
                       // Open clock to GPIOD
                       RCC->AHB1ENR    |=   RCC_AHB1ENR_GPIOCEN|RCC_AHB1ENR_GPIODEN;
                       // Set GPIO  D.15,D.14,D.13,D.12,D5 is Output
                       GPIOD->MODER     =    0x55000400;
                       GPIOD->ODR       =    0x20;
                       GPIOC->MODER    |=    0x000003FF;  // Set PC.0,PC.1,PC.2,PC.3,PC.4 is Analog input
                       //ch10->ADC1,ch11->ADC2,ch12->ADC3,
                       GPIOC->PUPDR     =    0;
}
void adc1(void)
                     {
                      //ADC configuration
                      RCC->APB2ENR   |=          RCC_APB2ENR_ADC1EN|RCC_APB2ENR_ADC2EN; // Open clock ADC1,ADC2
                      RCC->APB2ENR   |= RCC_APB2ENR_ADC3EN;  // Open clock ADC3
                      ADC->CCR     =         ADC_CCR_ADCPRE_1;       // Prescale ADC

                      ADC1->CR2       = ADC_CR2_ADON|ADC_CR2_EXTSEL|ADC_CR2_EXTEN; // Set SWSTART Trig
                      ADC2->CR2       = ADC_CR2_ADON|ADC_CR2_EXTSEL|ADC_CR2_EXTEN; // Set SWSTART Trig
                      ADC3->CR2       = ADC_CR2_ADON|ADC_CR2_EXTSEL|ADC_CR2_EXTEN; // Set SWSTART Trig
                     
}

int main()
             {
              clock();
              GPIO();
              adc1();
              ADC1->SQR3      =   10;   // ADC1--> CH10  PC.0
              ADC2->SQR3      =   11;   // ADC2--> CH11  PC.1
              ADC3->SQR3      =   12;   // ADC2--> CH12  PC.2
              while(1)
{
                 
                  ADC1->CR2      |=    ADC_CR2_SWSTART;  // ADC1 Tgir
                  ADC2->CR2      |=    ADC_CR2_SWSTART;  // ADC2 Tgir
                  ADC3->CR2      |=    ADC_CR2_SWSTART;  // ADC3 Tgir
                  while((ADC1->SR & ADC_SR_EOC )==0); //wait ADC1
                  while((ADC2->SR & ADC_SR_EOC )==0); //wait ADC2
                  while((ADC3->SR & ADC_SR_EOC )==0); //wait ADC3
                  ADC1->SR        =   0;
                  ADC2->SR        =   0;
                  ADC3->SR        =   0;
                  if(ADC1->DR>2000)     //  ADC1
                  GPIOD->ODR  |=    0x8020;
                  else
                  GPIOD->ODR  &=    0x7F2F;
                  if(ADC2->DR>2000)    //   ADC2
                  GPIOD->ODR  |=    0x4020;
                  else
                  GPIOD->ODR  &=    0xBF2F;
                  if(ADC3->DR>2000)    //   ADC3
                  GPIOD->ODR  |=    0x2020;
                  else
                  GPIOD->ODR  &=    0xDF2F;
}
}


#7
STM32F4 discovery  การใช้ADC1 ช่อง 10-11-12-13-14

1      สร้าง Floder ชื่อ ADC10_14 ขึ้นมา
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

PC.0 Channel  10
PC.1 Channel  11
PC.2 Channel  12
PC.3 Channel  13
PC.4 Channel  14

แรงดัน input  0-3.3V (VCC) 

เป็นตัวอย่างในการศึกษาการ Scan แต่ละช่อง ที่ละค่า  นำไปดัดแปลงใช้งานได้


#include"stm32f4xx.h"
void clock(void)
       {
                       RCC->CFGR     =   0;
                       RCC->CR       =   0;
                       RCC->CFGR     |= 0x00009400;
                       RCC->CR       |=  RCC_CR_HSEON;    //  HSE Xtal On
                       while (!(RCC->CR & 0x00020000));   // wait Xtal osc stability
                       RCC->PLLCFGR  =   0x07405408;      // Set PLL   M=8, N=336, P=2 ve Q=7
                       RCC->CR |= RCC_CR_PLLON;            // PLL On
                       while(!(RCC->CR & 0x02000000))      // wait Pll on
                       FLASH->ACR = 0x00000605;        // Flash ROM is 5 Wait state
                       RCC->CFGR |= 0x00000002;        // System PLL On
                       while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Wait Pll On
}
void GPIO(void)
                      {
                       // Set Speed GPIOD is 100Mhz
                       GPIOD->OSPEEDR        =       0xFFFF;
                       // Open clock to GPIOD
                       RCC->AHB1ENR    |=   RCC_AHB1ENR_GPIOCEN|RCC_AHB1ENR_GPIODEN;
                       // Set GPIO  D.15,D.14,D.13,D.12,D5 is Output
                       GPIOD->MODER     =    0x55000400;
                       GPIOD->ODR         =    0x20;
                       GPIOC->MODER    |=    0x000003FF; 
                       //  Set PC.0,PC.1,PC.2,PC.3,PC.4 is Analog input
                       //  ch10,ch11,ch12,ch13,ch14
                       GPIOC->PUPDR     =    0;
}
void adc1(void)
                     {
                      //ADC configuration
                      RCC->APB2ENR    |=       RCC_APB2ENR_ADC1EN; // Open clock ADC1
                      ADC->CCR             =       ADC_CCR_ADCPRE_1;  //Prescale ADC

                      ADC1->CR2           =       ADC_CR2_ADON|ADC_CR2_EXTSEL|ADC_CR2_EXTEN; // Set SWSTART Trig       
                      ADC1->SQR3          =       14;     //channel number 14 PC4   first   conversion
         
}
int main()
             {
              clock();
              GPIO();
              adc1();
               while(1)
                         {
                          ADC1->SQR3      =   14;   // channel 14 input Analog
                          ADC1->CR2      |=    ADC_CR2_SWSTART;
                          while((ADC1->SR & ADC_SR_EOC )==0);
                          ADC1->SR        =   0;
                          if(ADC1->DR>2000)
                          GPIOD->ODR  |=    0x8020;
                          else
                          GPIOD->ODR  &=    0x7F2F;
                          ADC1->SQR3      =    13;   // channel 13 input Analog
                          ADC1->CR2       |=    ADC_CR2_SWSTART;
                          while((ADC1->SR & ADC_SR_EOC )==0);
                          ADC1->SR        =   0;
                          if(ADC1->DR>2000)
                          GPIOD->ODR  |=    0x4020;
                          else
                          GPIOD->ODR    &=     0xBF2F;
                          ADC1->SQR3      =     12;   // channel 12 input Analog
                          ADC1->CR2       |=      ADC_CR2_SWSTART;
                          while((ADC1->SR & ADC_SR_EOC )==0);
                          ADC1->SR        =   0;
                          if(ADC1->DR>2000)
                          GPIOD->ODR  |=    0x2020;
                          else
                          GPIOD->ODR  &=    0xDF2F;
                          ADC1->SQR3      =   11;   // channel 11 input Analog
                          ADC1->CR2       |=   ADC_CR2_SWSTART;
                          while((ADC1->SR & ADC_SR_EOC )==0);
                          ADC1->SR        =   0;
                          if(ADC1->DR>2000)
                          GPIOD->ODR  |=    0x1020;
                          else
                          GPIOD->ODR  &=    0xEF2F;
                          ADC1->SQR3      =   10;   // channel 10 input Analog
                          ADC1->CR2      |=    ADC_CR2_SWSTART;
                          while((ADC1->SR & ADC_SR_EOC )==0);
                          ADC1->SR        =   0;
                          if(ADC1->DR>2000)
                          GPIOD->ODR  &=    0xFFDF;
                          else
                          GPIOD->ODR  |=    0x20;
                         }
}

#8
STM32F4 discovery  การใช้ ADC

1      สร้าง Floder ชื่อ ADC ขึ้นมา
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

เลือก PC.4      เป็นรับสัญญาณอะนาล็อก ตรงกับช่อง 14
การแปลงของ ADC1 โดยใช้ Vr 3 ขา  ที่ขากลางขา(2) Vr ต่อที่ PC.4 อินพุต ADC1
ขา(1) ต่อลง กราวด์ (0V)  และขา(3) Vr ต่อไฟ (VCC) 3.3V   แล้วทดสอบโดยการปรับ Vr ซ้าย-ขวา ดู


#include"stm32f4xx.h"
void clock(void)
       {
                       RCC->CFGR     =   0;
                       RCC->CR       =   0;
                       RCC->CFGR     |= 0x00009400;
                       RCC->CR       |=  RCC_CR_HSEON;    //  HSE Xtal On
                       while (!(RCC->CR & 0x00020000));   // wait Xtal osc stability
                       RCC->PLLCFGR  =   0x07405408;      // Set PLL   M=8, N=336, P=2 ve Q=7
                       RCC->CR |= RCC_CR_PLLON;            // PLL On
                       while(!(RCC->CR & 0x02000000))      // wait Pll on
                       FLASH->ACR = 0x00000605;        // Flash ROM is 5 Wait state
                       RCC->CFGR |= 0x00000002;        // System PLL On
                       while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Wait Pll On
}
void GPIO(void)
                      {
                       // Set Speed GPIOD is 100Mhz
                       GPIOD->OSPEEDR        =       0xFFFF;
                       // Open clock to GPIOD
                       RCC->AHB1ENR    |=   RCC_AHB1ENR_GPIOCEN|RCC_AHB1ENR_GPIODEN;
                       // Set GPIO  D.15,D.14,D.13,D.12,D5 is Output
                       GPIOD->MODER     =    0x55000400;
                       GPIOD->ODR         =    0x20;
                       GPIOC->MODER    |=    0x00000300;    // เลือก PC.4 เป็นรับสัญญาณอะนาล็อก ตรงกับช่อง 14
                       GPIOC->PUPDR     =    0;
}
void adc1(void)
                     {
                      //ADC configuration
                      RCC->APB2ENR    |=      RCC_APB2ENR_ADC1EN;    // Open clock ADC1
                      ADC->CCR     =      ADC_CCR_ADCPRE_1;       // Prescale ADC

                      ADC1->CR2           =      ADC_CR2_ADON|ADC_CR2_EXTSEL|ADC_CR2_EXTEN; // Set SWSTART Trig;         
                      ADC1->SQR3          =       14;     //เลือกช่องรับสัญญาณอะนาล็อกช่อง 14 (เปลี่ยนแปลงช่องได้)
                     
}
int main()
             {
              clock();  // เซ็ทค็อก
              GPIO(); // เซ็ทขา อินพุตอะนาล็อก  เอาท์พุทดิจิตอล
              adc1(); //  เซ็ทการทำงานของ ADC1
               while(1)
                         {
                          ADC1->CR2        |=        ADC_CR2_SWSTART;  // กระตุ้นให้ ADC1 ทำงาน
                          while((ADC1->SR & ADC_SR_EOC )==0);          // รอ ADC1 ทำการแปลงสัญญาณให้เสร็จ
                          ADC1->SR           =         0;                     // เคลียร์ค่าการแจ้งสภาวะทำงาน ADC1เสร็จภารกิจ
                         if(ADC1->DR<800)
                         GPIOD->ODR      =   0x1020;
                         if((ADC1->DR<1600)&&(ADC1->DR>=800))
                         GPIOD->ODR      =   0x2020;
                         if((ADC1->DR<2400)&&(ADC1->DR>=1600))
                         GPIOD->ODR      =   0x4020;
                         if((ADC1->DR<3200)&&(ADC1->DR>=2400))
                         GPIOD->ODR      =   0x8020;
                         if(ADC1->DR>3200)
                         GPIOD->ODR      =   0;
                         }
}




การใช้งาน Interrupt ADC ร่วม เพื่อที่จะไม่ต้องคอยมาวนตรวจสอบ EOC ตลอดเวลา เราสามารถที่จะส่งงานให้
ADCทำงาน และก็ให้ไปทำงานอย่างอื่นก่อนได้ เมื่อ ADC ทำการแปลงเสร็จจะส่งสัญญาณการ Interruptเพื่อให้
MCU กระโดดไปทำงานในลูปของ การเกิด Interrupt ADC เองแบบอัตโนมัติ เมื่อเสร็จจะกระโดดกลับมาทำงาน
ในโปรแกรมหลักต่อไปหรือลูปเมนฟังก์ชันหลัก 


เลือก PC.4      เป็นรับสัญญาณอะนาล็อก ตรงกับช่อง 14
การแปลงของ ADC1 โดยใช้ Vr 3 ขา  ที่ขากลางขา(2) Vr ต่อที่ PC.4 อินพุต ADC1
ขา(1) ต่อลง กราวด์ (0V)  และขา(3) Vr ต่อไฟ (VCC) 3.3V   แล้วทดสอบโดยการปรับ Vr ซ้าย-ขวา ดู

ตัวอย่างการใช้งาน

#include"stm32f4xx.h"
void clock(void)
{
RCC->CFGR     =   0;         
RCC->CR       =   0;
  // RCC->CFGR     =  (RCC_CFGR_HPRE_DIV2|RCC_CFGR_PPRE1_DIV2|RCC_CFGR_PPRE2_DIV1|RCC_CFGR_SW_PLL|RCC_CFGR_SWS_PLL);
                  RCC->CFGR     |= 0x00009400;
RCC->CR       |=  RCC_CR_HSEON;    //  HSE Xtal On       
while (!(RCC->CR & 0x00020000));   // wait Xtal osc stability
RCC->PLLCFGR  =   0x07405408;      // Set PLL   M=8, N=336, P=2 ve Q=7
RCC->CR |= RCC_CR_PLLON;            // PLL On 
while(!(RCC->CR & 0x02000000))      // wait Pll on
  FLASH->ACR = 0x00000605;        // Flash ROM is 5 Wait state
RCC->CFGR |= 0x00000002;        // System PLL On
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Wait Pll On
}
void GPIO(void)
            {
// Set Speed GPIOD is 100Mhz
GPIOD->OSPEEDR =   0xFFFF;
   // Open clock to GPIOD
RCC->AHB1ENR    |=   RCC_AHB1ENR_GPIOCEN|RCC_AHB1ENR_GPIODEN;
// Set GPIO  D.15,D.14,D.13,D.12,D5 is Output
GPIOD->MODER     =    0x55000400;
GPIOD->ODR       =    0x20;


             GPIOC->MODER    |=    0x00000300;    // Set PC.4 is Analog input
GPIOC->PUPDR     =    0;
  }
void adc1(void)
           {
//ADC configuration
RCC->APB2ENR   |=   RCC_APB2ENR_ADC1EN; // Open clock ADC1
ADC1->CR1      |=   ADC_CR1_EOCIE; // Interrupt ADC
ADC1->CR2      |=   ADC_CR2_ADON|ADC_CR2_EXTSEL|ADC_CR2_EXTEN; // SWSTART Trig
NVIC_EnableIRQ(ADC_IRQn); // Interrupt Enable
   

}
void ADC_IRQHandler(void)
{
              ADC1->SR   =   0;  // Clear Interrupt ADC

if(ADC1->DR<800)
GPIOD->ODR      =   0x1020;
if((ADC1->DR<1600)&&(ADC1->DR>=800))
GPIOD->ODR      =   0x2020;
if((ADC1->DR<2400)&&(ADC1->DR>=1600))
GPIOD->ODR      =   0x4020;
if((ADC1->DR<3200)&&(ADC1->DR>=2400))
GPIOD->ODR      =   0x8020;
if(ADC1->DR>3200)
GPIOD->ODR      =   0;

ADC1->CR2      |=    ADC_CR2_SWSTART;  // Start ADC Convert
}

int main()
             {
clock();
  GPIO();
adc1();
              ADC1->SQR3      =    14;     //channel number 14 PC4
              ADC1->CR2      |=    ADC_CR2_SWSTART;  // Start ADC
              while(1)
{
//  Code Program
}
}


การใช้งาน Interrupt ADC ร่วม กับ DAC เก็บค่า 1000 ค่า พร้อมหาค่าเฉลี่ย 2 รูปแบบ
พร้อมทั้งแสดงค่าออกทาง DAC ทั้ง2ช่อง แสดงค่าออกมาเทียบกัน


เลือก PC.4      เป็นรับสัญญาณอะนาล็อก ตรงกับช่อง 14
การแปลงของ ADC1 โดยใช้ Vr 3 ขา  ที่ขากลางขา(2) Vr ต่อที่ PC.4 อินพุต ADC1
ขา(1) ต่อลง กราวด์ (0V)  และขา(3) Vr ต่อไฟ (VCC) 3.3V   แล้วทดสอบโดยการปรับ Vr ซ้าย-ขวา ดู


#include"stm32f4xx.h"
unsigned int Cn = 0; // Counter
unsigned int Av = 0; // Average Value
unsigned int Dn[999]; // Keep Data 0...999 Point
long signed int Total = 0;  // 32bit value

void clock(void)
{
RCC->CFGR     =   0;         
RCC->CR       =   0;
  // RCC->CFGR     =  (RCC_CFGR_HPRE_DIV2|RCC_CFGR_PPRE1_DIV2|RCC_CFGR_PPRE2_DIV1|RCC_CFGR_SW_PLL|RCC_CFGR_SWS_PLL);
                  RCC->CFGR     |= 0x00009400;
RCC->CR       |=  RCC_CR_HSEON;    //  HSE Xtal On       
while (!(RCC->CR & 0x00020000));   // wait Xtal osc stability
RCC->PLLCFGR  =   0x07405408;      // Set PLL   M=8, N=336, P=2 ve Q=7
RCC->CR |= RCC_CR_PLLON;            // PLL On 
while(!(RCC->CR & 0x02000000))      // wait Pll on
  FLASH->ACR = 0x00000605;        // Flash ROM is 5 Wait state
RCC->CFGR |= 0x00000002;        // System PLL On
while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Wait Pll On
}
void GPIO(void)
            {
// Set Speed GPIOD is 100Mhz
GPIOD->OSPEEDR =   0xFFFF;
   // Open clock to GPIOD
RCC->AHB1ENR    |=   RCC_AHB1ENR_GPIOCEN|RCC_AHB1ENR_GPIODEN;
// Set GPIO  D.15,D.14,D.13,D.12,D5 is Output
GPIOD->MODER     =    0x55000400;
GPIOD->ODR       =    0x20;


             GPIOC->MODER    |=    0x00000300;    // Set PC.4 is Analog input
GPIOC->PUPDR     =    0;
  }
void adc1(void)
           {
//ADC configuration
RCC->APB2ENR   |=   RCC_APB2ENR_ADC1EN; // Open clock ADC1
ADC1->CR1      |=   ADC_CR1_EOCIE; // Interrupt ADC
ADC1->CR2      |=   ADC_CR2_ADON|ADC_CR2_EXTSEL|ADC_CR2_EXTEN; // SWSTART Trig
NVIC_EnableIRQ(ADC_IRQn); // Interrupt Enable
   

}
void ADC_IRQHandler(void)
{
              ADC1->SR   =   0;                // Clear Interrupt ADC
Dn[Cn]     =   ADC1->DR;         // Storage Value Point
Av         =   (Av+ADC1->DR)/2;  // Average and Storage Value
Total      =    Total+Dn[Cn];    // Storage sum Value
              Cn        +=   1;                // Increment pointer 
              if(Cn>999)
       {
                      Cn      =   0;
Total  =   Total/1000;   // Average sum Value
                      DAC->DHR12R1    =   Av;   //  Show Dc Average DAC1
                      DAC->DHR12R2    =   Total;//  Show Dc Average sum Value DAC2
                     }

ADC1->CR2      |=    ADC_CR2_SWSTART;  // Start ADC Convert
}
void DAC_1(void)
                {
RCC->APB1ENR    |=  RCC_APB1ENR_DACEN;
                 DAC->CR         |=  DAC_CR_EN1|DAC_CR_EN2;
   DAC->CR         |=  (DAC_CR_MAMP1_3|DAC_CR_MAMP1_2);
   DAC->CR         |=  (DAC_CR_MAMP2_3|DAC_CR_MAMP2_2);
                 GPIOA->MODER    |=  0x00000f00;   // PA04, PA05 are analog outputs
}

int main()
             {
clock();
  GPIO();
adc1();
DAC_1();
              ADC1->SQR3      =    14;     //channel number 14 PC4
              ADC1->CR2      |=    ADC_CR2_SWSTART;  // Start ADC
              while(1)
{
//  Code Program
}
}
#9
STM32F4 discovery โดยkeil บทที่6 ใช้ T1,T2,T3,T4,T5 พร้อมกัน
1      สร้าง Floder ชื่อ Timer1_6 ขึ้นมาหรือชื่อที่ต้องการอะไรก็ได้ที่บ่งบอกการทำงาน
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

#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->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 Tim1(long signed PSC1,long signed ARR1)
           {
            RCC->APB2ENR |=  RCC_APB2ENR_TIM1EN
            TIM1->ARR = ARR1;    // ค่านับเก็บได้ 16bit ค่า
            TIM1->PSC = PSC1;    // ค่าปรีสเกล  ปรับได้ 16 bit ค่า
            TIM1->SR &= ~TIM_SR_UIF ;
            TIM1->DIER |= TIM_DIER_UIE ;
            NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
}

void Tim2(long signed PSC2,long signed ARR2)
           {
            RCC->APB1ENR |=  RCC_APB1ENR_TIM2EN ;
            TIM2->ARR = ARR2;    // ค่านับเก็บได้ 16/32bit ค่า
            TIM2->PSC = PSC2;    // ค่าปรีสเกล  ปรับได้ 16 bit ค่า
            TIM2->SR &= ~TIM_SR_UIF ;
            TIM2->DIER |= TIM_DIER_UIE ;
            NVIC_EnableIRQ(TIM2_IRQn);
}

void Tim3(long signed PSC3,long signed ARR3)
           {
            RCC->APB1ENR |=  RCC_APB1ENR_TIM3EN ;
            TIM3->ARR = ARR3;    // ค่านับเก็บได้ 16bit ค่า
            TIM3->PSC = PSC3;    // ค่าปรีสเกล  ปรับได้ 16 bit ค่า
            TIM3->SR &= ~TIM_SR_UIF ;
            TIM3->DIER |= TIM_DIER_UIE ;
            NVIC_EnableIRQ(TIM3_IRQn);
}
void Tim4(long signed PSC4,long signed ARR4)
           {
            RCC->APB1ENR |=  RCC_APB1ENR_TIM4EN ;
            TIM4->ARR = ARR4;    // ค่านับเก็บได้ 16bit ค่า
            TIM4->PSC = PSC4;    // ค่าปรีสเกล  ปรับได้ 16 bit ค่า
            TIM4->SR &= ~TIM_SR_UIF ;
            TIM4->DIER |= TIM_DIER_UIE ;
            NVIC_EnableIRQ(TIM4_IRQn);
}
void Tim5(long signed PSC5,long signed ARR5)
           {
            RCC->APB1ENR |=  RCC_APB1ENR_TIM5EN ;
            TIM5->ARR = ARR5;    // ค่านับเก็บได้ 16bit ค่า
            TIM5->PSC = PSC5;    // ค่าปรีสเกล  ปรับได้ 16 bit ค่า
            TIM5->SR &= ~TIM_SR_UIF ;
            TIM5->DIER |= TIM_DIER_UIE ;
            NVIC_EnableIRQ(TIM5_IRQn);
}
void Set_GPIO()
                      {
         // Set Speed GPIOD is 100Mhz
         GPIOD->OSPEEDR =   0xFFFF;
          // Open clock to GPIOD
          RCC->AHB1ENR    |=   0x08;
          // Set GPIO  D.15,D.14,D.13,D.12,D.5 is Output     
          GPIOD->MODER    =    0x55000400;
          GPIOD->ODR      =    0x20;   // ให้ LED ดับหมด        หมายเหตุ LED D.5 แอททีฟ โล
}

//....................Loop Timer1........................................
void TIM1_UP_TIM10_IRQHandler(void)
          {
                                                            TIM1->SR &= 0;
                                                            GPIOD->ODR    ^=0x20;
}

//....................Loop Timer2........................................
void TIM2_IRQHandler(void)
                         {
                                           TIM2->SR &= 0;
                                           GPIOD->ODR    ^=0x8000;
}
//....................Loop Timer3........................................
void TIM3_IRQHandler(void)
                         {
                                           TIM3->SR &= 0;
                                           GPIOD->ODR    ^=0x4000;
}
//....................Loop Timer4........................................
void TIM4_IRQHandler(void)
                         {
                                           TIM4->SR &= 0;
                                           GPIOD->ODR    ^=0x2000;
}
//....................Loop Timer5........................................
void TIM5_IRQHandler(void)
                         {
                                           TIM1->SR &= 0;
                                           GPIOD->ODR    ^=0x1000;
}

int main(void)
                   {
                    clock();
                    Set_GPIO();
                    Tim1(5000,2000);    // Bus Clock 84Mhz  (5000 ค่าปรีสเกลหรือตัวหาร ,  2000 ค่าตัวนับ)
                    Tim2(5000,2000);    // Bus Clock 42Mhz  (5000 ค่าปรีสเกลหรือตัวหาร ,  2000 ค่าตัวนับ)
                    Tim3(5000,4000);    // Bus Clock 42Mhz  (5000 ค่าปรีสเกลหรือตัวหาร ,  4000 ค่าตัวนับ)
                    Tim4(5000,8000);    // Bus Clock 42Mhz  (5000 ค่าปรีสเกลหรือตัวหาร ,  8000 ค่าตัวนับ)
                    Tim5(5000,16000);  // Bus Clock 42Mhz  (5000 ค่าปรีสเกลหรือตัวหาร ,  16000 ค่าตัวนับ)


                    TIM1->CR1 = TIM_CR1_CEN;  //  Timer1  ทำงาน
                    TIM2->CR1 = TIM_CR1_CEN;  //  Timer2  ทำงาน
                    TIM3->CR1 = TIM_CR1_CEN;  //  Timer3  ทำงาน
                    TIM4->CR1 = TIM_CR1_CEN;  //  Timer4  ทำงาน
                    TIM5->CR1 = TIM_CR1_CEN;  //  Timer5  ทำงาน



                    while(1)
                              {
                              ;
                              }
}


#10
STM32F4 discovery โดยkeil บทที่5 Timer 1

1      สร้าง Floder ชื่อ Time1 ขึ้นมา หรือชื่ออะไรก็ได้ที่บ่งบอกการทำงาน
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


#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 Tim1(long signed PSC1,long signed ARR1)
           {
            RCC->APB2ENR |=  RCC_APB2ENR_TIM1EN ;
            TIM1->ARR = ARR1;    // ค่านับเก็บได้ 16bit ค่า
            TIM1->PSC = PSC1;    // ค่าปรีสเกล  ปรับได้ 16 bit ค่า
            TIM1->SR &= ~TIM_SR_UIF ;
            TIM1->DIER |= TIM_DIER_UIE ;
            NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
}
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);
                     
}

void TIM1_UP_TIM10_IRQHandler(void)  // ลูปการเกิดเหตุการอินเตอร์รัป
{
                  TIM1->SR &        =   0;  //เคลียร์ค่ารีจีสเตอร์ อินเตอร์รัป
                  GPIOD->ODR    ^=     0xF000;           // Code ทำงาน กลับสภาวะ LED
}

int main(void)
                   {
                    clock();
                    Set_GPIO();
                    Tim1(5000,3000); // ตั้งค่า ปรีสเกลหาร และ  ค่านับ  ปรับเปลี่ยนค่า หลักพัน ดูการกระพริบ LED
                    TIM1->CR1 = TIM_CR1_CEN;  // เปิดการอินเตอร์รัป Timer1
                    while(1)
                              {
                              ;
                              }
}



#11
มาขอแนะนำผู้เริ่มต้นใหม่ 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/

GPIOx->MODER   
  GPIOx->OTYPER                  0-PushPull, 1-OpenDrain
  GPIOx->OSPEEDR              Output SPEED Register    : 00-2, 01-25, 10-50, 11-100 [MHz]
  GPIOx->PUPDR                   PullUp PullDown Register : 00-none, 01-Pup, 10-Pdn, 11-reserved
  GPIOx->IDR                        Input Data Register
  GPIOx->ODR                      Output Data Register
  GPIOx->BSRRL                    Bit Set Reset Register Hi: bit  sets  PortPin
  GPIOx->BSRRH                   Bit Set Reset Register Lo: bit resets PortPin
  GPIOx->LCKR                     LoCK Register
  GPIOx->AFR[0]                   Alternative Function Register Lo - select 1of16
  GPIOx->AFR[1]                   Alternative Function Register Hi - select 1of16



ถ้าท่านใช้ขาที่เลือกเป็น 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;
                              }
}
#12
1       สร้าง Floder ชื่อ GPIO  ขึ้นมา
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/


ขั้นตอนแรกการควบคุม GPIO ครับ
ขา IC แต่ละขา มีหน้าที่ทำงานต่างๆ และต่างกัน ในขาเดียวกันอาจมีสามหรือสี่ฟังก์ชันในขาเดียวกัน หรือ ไม่มีหน้าที่เลย (NC)
แล้ว NC มีไว้ทำอะไร  ประโยชน์ที่เห็นมี 2 อย่าง    (1)  ไว้ช่วยยึดตัว IC   (2)  ความสวยงามของตัวถัง ถ้าไม่มีไม่เท่

กลับมาต่อครับ   มารู้จัก รีจีสเตอร์ที่ควบคุม GPIOกัน


Register ที่ควรศึกษา


  GPIOx->MODER   
  GPIOx->OTYPER                  0-PushPull, 1-OpenDrain
  GPIOx->OSPEEDR              Output SPEED Register    : 00-2, 01-25, 10-50, 11-100 [MHz]
  GPIOx->PUPDR                   PullUp PullDown Register : 00-none, 01-Pup, 10-Pdn, 11-reserved
  GPIOx->IDR                        Input Data Register
  GPIOx->ODR                      Output Data Register
  GPIOx->BSRRL                    Bit Set Reset Register Hi: bit  sets  PortPin
  GPIOx->BSRRH                   Bit Set Reset Register Lo: bit resets PortPin
  GPIOx->LCKR                     LoCK Register
  GPIOx->AFR[0]                   Alternative Function Register Lo - select 1of16
  GPIOx->AFR[1]                   Alternative Function Register Hi - select 1of16



ถ้าท่านใช้ขาที่เลือกเป็น Digital Output จะต้องดูที่รีจีสเตอร์ 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) คือค่าทางลอจิของบิตนั้นๆ
Output  ต้อง Set x = 1, Set y  = 0     อ้างอิงจาก Reference Manual RM0090 หน้า186/1422 ST
เช่นต้องการให้  Bit 0, Bit 1 ของ GPIOA เป็น เอาท์พุต ได้  GPIOA->MODER   =    0x00000005;
ต้องการให้  Bit 0, Bit 15 ของ GPIOB เป็น เอาท์พุต ได้     GPIOB->MODER   =    0x10000001;

ถัดมา รีจีสเตอร์ปรับความเร็วที่GPIO 
เราสามารถปรับความเร็วของขาแต่ละขาได้จากรีจีสเตอร์ OSPEEDR  ครับ 32bit คล้าย MODER
GPIO(Bit0)  =  OSPEEDR Bit0(x) กับ OSPEEDR Bit1(y) ควบคุม
GPIO(Bit1)  =  OSPEEDR Bit2(x) กับ OSPEEDR Bit3(y) ควบคุม
GPIO(Bit2)  =  OSPEEDR Bit4(x) กับ OSPEEDR Bit5(y) ควบคุม
.                      .
.                      .
GPIO(Bit14)  =  OSPEEDR Bit28(x)  กับ OSPEEDR Bit29(y) ควบคุม
GPIO(Bit15)  =  OSPEEDR Bit30(x)  กับ OSPEEDR Bit31(y) ควบคุม
(x),(y) คือค่าทางลอจิของบิตนั้นๆ
(x =  0,  y  = 0)  ขานั้นจะมีความเร็วสูงสุดแค่  2 Mhz อ้างอิงจาก Reference Manual RM0090 หน้า199/1422 ST
(x =  0,  y  = 1)  ขานั้นจะมีความเร็วสูงสุดแค่  25 Mhz
(x =  1,  y  = 0)  ขานั้นจะมีความเร็วสูงสุดแค่  50 Mhz
(x =  1,  y  = 1)  ขานั้นจะมีความเร็วสูงสุดแค่  100 Mhz
ตัวอย่าง
ต้องการขา GPIOB Bit0 เป็น 25Mhz Bit15 เป็น 100Mhz ได้ GPIOB->SPEEDR  = 0xC0000001;

ถัดมารีจีสเตอร์ 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)  No Pull-up, No Pull-down อ้างอิงจาก Reference Manual RM0090 หน้า200/1422 ST
(x =  0,  y  = 1)  Pull-up
(x =  1,  y  = 0)  Pull-down
(x =  1,  y  = 1)  (ไม่ใช้งาน ไม่เกิดอะไรขึ้น)

อีกตัวที่สำคัญคือ รีจีสเตอร์ OTYPER
OTYPER จะมีแค่  15 bit ตามจำนวนขาของ GPIO ดังนั้นคำสั่งจะมีแค่ ลอจิก 0 กับ 1
GPIO(Bit0)  =  OTYPER Bit0(x)
GPIO(Bit1)  =  OTYPER Bit1(x)
.                       .
GPIO(Bit15)  =  OTYPER Bit15(x)
ถ้า x = 0  bitนั้น  =  Output Push-Pull
ถ้า x = 1  bitนั้น  =  Output Open drain
..............................................................................
GPIOx   ชื่อของ Port ต่างๆ เช่น GPIOA,GPIOB......
GPIOx-> เป็นรูปแบบการใช้งาน
GPIOA->ODR  เมื่อ ODR คือการกระทำตัวรีจีสเตอร์ทั้ง 32bit หมายเหตุ รีจีสเตอร์มี 32bit แต่ว่าขาที่ต่อ
ไม่จำเป็นต้องมี 32 ขา ในค่ายของ ST cortex M จะมีขาให้ใช้มากสุด  15 ขา หรือ 15bit

ตัวอย่าง GPIOA->ODR   = 0x1000F281; แต่รีจีสเตอร์ GPIOA แสดงออกที่ขาได้แค่ 0xF281


ใน #include "stm32f4xx.h"  จะมีการบบรจุตัวอ้างอิงใช้สือความหมายแทนค่าระดับ bit และ แทนรีจีสเตอร์ได้
เราสามารถนำค่าเหล่านั้นมาใช้เพื่อสื่อความหมายในการเขียนโปรแกรมได้

/******************  Bits definition for GPIO_MODER register  *****************/
#define GPIO_MODER_MODER0                    ((uint32_t)0x00000003)       //   เซ็ทเป็น อะนาล็ก บิท 0
#define GPIO_MODER_MODER0_0                  ((uint32_t)0x00000001)     //   เซ็ทเป็น  เอาท์พุท  บิท 0
#define GPIO_MODER_MODER0_1                  ((uint32_t)0x00000002)    //    เซ็ทเป็นขาฟังก์ชันร่วม บิท 0

#define GPIO_MODER_MODER1                    ((uint32_t)0x0000000C)       //   เซ็ทเป็น อะนาล็ก บิท 1
#define GPIO_MODER_MODER1_0                  ((uint32_t)0x00000004)     //   เซ็ทเป็น  เอาท์พุท  บิท 1
#define GPIO_MODER_MODER1_1                  ((uint32_t)0x00000008)     //    เซ็ทเป็นขาฟังก์ชันร่วม บิท 1

#define GPIO_MODER_MODER2                    ((uint32_t)0x00000030)
#define GPIO_MODER_MODER2_0                  ((uint32_t)0x00000010)
#define GPIO_MODER_MODER2_1                  ((uint32_t)0x00000020)

#define GPIO_MODER_MODER3                    ((uint32_t)0x000000C0)
#define GPIO_MODER_MODER3_0                  ((uint32_t)0x00000040)
#define GPIO_MODER_MODER3_1                  ((uint32_t)0x00000080)

#define GPIO_MODER_MODER4                    ((uint32_t)0x00000300)
#define GPIO_MODER_MODER4_0                  ((uint32_t)0x00000100)
#define GPIO_MODER_MODER4_1                  ((uint32_t)0x00000200)

#define GPIO_MODER_MODER5                    ((uint32_t)0x00000C00)
#define GPIO_MODER_MODER5_0                  ((uint32_t)0x00000400)
#define GPIO_MODER_MODER5_1                  ((uint32_t)0x00000800)

#define GPIO_MODER_MODER6                    ((uint32_t)0x00003000)
#define GPIO_MODER_MODER6_0                  ((uint32_t)0x00001000)
#define GPIO_MODER_MODER6_1                  ((uint32_t)0x00002000)

#define GPIO_MODER_MODER7                    ((uint32_t)0x0000C000)
#define GPIO_MODER_MODER7_0                  ((uint32_t)0x00004000)
#define GPIO_MODER_MODER7_1                  ((uint32_t)0x00008000)

#define GPIO_MODER_MODER8                    ((uint32_t)0x00030000)
#define GPIO_MODER_MODER8_0                  ((uint32_t)0x00010000)
#define GPIO_MODER_MODER8_1                  ((uint32_t)0x00020000)

#define GPIO_MODER_MODER9                    ((uint32_t)0x000C0000)
#define GPIO_MODER_MODER9_0                  ((uint32_t)0x00040000)
#define GPIO_MODER_MODER9_1                  ((uint32_t)0x00080000)

#define GPIO_MODER_MODER10                   ((uint32_t)0x00300000)
#define GPIO_MODER_MODER10_0                 ((uint32_t)0x00100000)
#define GPIO_MODER_MODER10_1                 ((uint32_t)0x00200000)

#define GPIO_MODER_MODER11                   ((uint32_t)0x00C00000)
#define GPIO_MODER_MODER11_0                 ((uint32_t)0x00400000)
#define GPIO_MODER_MODER11_1                 ((uint32_t)0x00800000)

#define GPIO_MODER_MODER12                   ((uint32_t)0x03000000)
#define GPIO_MODER_MODER12_0                 ((uint32_t)0x01000000)
#define GPIO_MODER_MODER12_1                 ((uint32_t)0x02000000)

#define GPIO_MODER_MODER13                   ((uint32_t)0x0C000000)
#define GPIO_MODER_MODER13_0                 ((uint32_t)0x04000000)
#define GPIO_MODER_MODER13_1                 ((uint32_t)0x08000000)

#define GPIO_MODER_MODER14                   ((uint32_t)0x30000000)
#define GPIO_MODER_MODER14_0                 ((uint32_t)0x10000000)
#define GPIO_MODER_MODER14_1                 ((uint32_t)0x20000000)

#define GPIO_MODER_MODER15                   ((uint32_t)0xC0000000)     //   เซ็ทเป็น อะนาล็ก บิท 15
#define GPIO_MODER_MODER15_0                 ((uint32_t)0x40000000)   //   เซ็ทเป็น  เอาท์พุท  บิท 1
#define GPIO_MODER_MODER15_1                 ((uint32_t)0x80000000)  //    เซ็ทเป็นขาฟังก์ชันร่วม บิท 15


เช่นต้องการให้  Bit 0, Bit 1 ของ GPIOA เป็น เอาท์พุต ได้  GPIOA->MODER   =  GPIO_MODER_MODER0_0|GPIO_MODER_MODER1_0 ;
ต้องการให้  Bit 0, Bit 15 ของ GPIOB เป็น เอาท์พุต ได้     GPIOB->MODER   =  GPIO_MODER_MODER0_0|GPIO_MODER_MODER15_0 ;


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


 



#include"stm32f4xx.h"

void delay(long signed count)    //  ฟังก์ชันหน่วงเวลา
           {
            while(count--);
           }

void clock()   // ฟังก์ชัน ฐานเวลา
   {
                 RCC->CFGR      =   RCC_CFGR_HPRE_DIV1|RCC_CFGR_PPRE1_DIV4|RCC_CFGR_PPRE2_DIV2 ;
                 RCC->CR        =   0;
                 RCC->CR       |=   RCC_CR_HSEON;  // ให้ HSE Xtal เป็น ฐานเวลาหลัก     
                 while (!(RCC->CR & 0x00020000));//   รอเวลาให้  Xtal osc ทำงาน
                 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);
                 // เซ็ทค่าความถี่ และตัวคูณต่าง  ดูข้อมูลใน  Ref-manual stm32f407xx
                 // หัวข้อการเซ็ทอัป system clock
                 RCC->CR       |=    RCC_CR_PLLON;      // สั่งให้ตัวคูณ PLL ทำงาน
                 while (!(RCC->CR & 0x02000000));      // รอจนกว่า PLL พร้อมทำงาน
                 FLASH->ACR     =    0x00000605;        // จัดเวลา Flash ROM is 5 Wait state
                 RCC->CFGR     |=    0x00000002;        //  เลือกสัญญาณหลัก System PLL On
                 while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // รอระบบ Wait system Pll พร้อมทำงาน
                }

int main(void)   //  ฟังก์ชันโปรแกรมหลัก
                    {
                      clock();
                      GPIOD->OSPEEDR =   0xFFFF;   // Set Speed GPIOD is 100Mhz
      RCC->AHB1ENR    |=   0x08;     // Open clock to GPIOD
      GPIOD->MODER    =    (GPIO_OSPEEDER_OSPEEDR15_0 |GPIO_OSPEEDER_OSPEEDR14_0 |
                                                         GPIO_OSPEEDER_OSPEEDR13_0 |GPIO_OSPEEDER_OSPEEDR12_0);
                      // Set GPIO  D.15,D.14,D.13,D.12 is Output

                      while(1)  // ลูปวนค่าไม่รู้จบ
                                {
                                 GPIOD->ODR  ^=  0xF000;   // กลับค่าจากค่าเดิมก่อนหน้านี้
                                 delay(50000000);
}




                    }   
#13
มาขอแนะนำผู้เริ่มต้นใหม่ STM32F4 discovery โดยkeil บทที่2 system clock

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

http://waijung.aimagin.com/default8mhz.png    ดูที่ภาพและบล็อกเพื่อความเข้าใจที่ดีขึ้นครับ
http://waijung.aimagin.com/stm32f4xx_clocktree_zoom60.png
http://waijung.aimagin.com/stm32f40x_block_diagram.png
http://waijung.aimagin.com/stm32f41x_block_diagram.png

http://waijung.aimagin.com/amg_f4connect2_diagram.png

ใครที่ใช้   Math lab โปรแกรมแบบ GUI น่าจะชื่นชอบแบบนี้ครับ  ดีมากแนะนำ
เข้าไปดูเลยครับตามลิงค์

http://waijung.aimagin.com/adc_demo.png
http://waijung.aimagin.com/stm32f4_regulardac_demo_model.png
http://waijung.aimagin.com/digital_input_demo.png
http://waijung.aimagin.com/advance_pwm_demo.png


http://waijung.aimagin.com/waijunginstall01.png
http://waijung.aimagin.com/waijunginstall02.png
http://waijung.aimagin.com/waijunginstall03.png
http://waijung.aimagin.com/waijunginstall04.png
http://waijung.aimagin.com/waijunginstall05.png
http://waijung.aimagin.com/openstlinkutility.png
http://waijung.aimagin.com/stlink-connecttotarget.png
http://waijung.aimagin.com/stlinkfirmwareupdate.png


http://waijung.aimagin.com/  เป็นเว็ป  แนะนำที่ดีครับ  รายละเอียดดีมากลองเปิดอ่านดูแต่ละบทๆ






บางครั้งเราก็ใช้ #include "stm32f4xx.h" เอาตัวอ้างอิงมาใช้งานเพื่อสื่อความหมายให้กับโปรแกรม
เพราะถ้าเอาแต่ใช้ ลอจิก อย่างเดียวอาจทำให้ไม่รู้ว่าทำอะไรกับบิตตรงไหน มันคือบิตอะไรเราใช้รูปแบบจาก
ตัวincludeมาช่วยก็ดีครับ

/******************************************************************************/
/*                                                                            */
/*                         Reset and Clock Control                            */
/*                                                                            */
/******************************************************************************/
/********************  Bit definition for RCC_CR register  ********************/
#define  RCC_CR_HSION                        ((uint32_t)0x00000001)
#define  RCC_CR_HSIRDY                       ((uint32_t)0x00000002)

#define  RCC_CR_HSEON                        ((uint32_t)0x00010000)
#define  RCC_CR_HSERDY                       ((uint32_t)0x00020000)
#define  RCC_CR_HSEBYP                       ((uint32_t)0x00040000)
#define  RCC_CR_CSSON                        ((uint32_t)0x00080000)
#define  RCC_CR_PLLON                        ((uint32_t)0x01000000)
#define  RCC_CR_PLLRDY                       ((uint32_t)0x02000000)
#define  RCC_CR_PLLI2SON                     ((uint32_t)0x04000000)
#define  RCC_CR_PLLI2SRDY                    ((uint32_t)0x08000000)


*********************************************************************************

รีจีสเตอร์ที่สำคัญในโหมดนี้คือ
************************************ 
RCC_CR

RCC_PLLCFGR

RCC_CFGR

RCC_CIR

***************************************

#include"stm32f4xx.h"
void clock()
   {
    RCC->CFGR      =   RCC_CFGR_HPRE_DIV1|RCC_CFGR_PPRE1_DIV4|RCC_CFGR_PPRE2_DIV2 ;
                 RCC->CR        =   0;
                 RCC->CR       |=   RCC_CR_HSEON;  // ให้ HSE Xtal เป็น ฐานเวลาหลัก     
    while (!(RCC->CR & 0x00020000));//   รอเวลาให้  Xtal osc ทำงาน
                 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);
                 // เซ็ทค่าความถี่ และตัวคูณต่าง  ดูข้อมูลใน  Ref-manual stm32f407xx
                 // หัวข้อการเซ็ทอัป system clock
                 RCC->CR       |=    RCC_CR_PLLON;      // สั่งให้ตัวคูณ PLL ทำงาน
                 while (!(RCC->CR & 0x02000000));      // รอจนกว่า PLL พร้อมทำงาน
                 FLASH->ACR     =    0x00000605;        // จัดเวลา Flash ROM is 5 Wait state
                 RCC->CFGR     |=    0x00000002;        //  เลือกสัญญาณหลัก System PLL On
                 while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // รอระบบ Wait system Pll พร้อมทำงาน
                }
int main(void)
                    {
                      clock();  //เรียกใช้งานจัดระบบ
                 //  Code โปรแกรม ที่จะทำการเขียน
}
#14
แนะนำผู้เริ่มต้นใหม่ STM32F4 discovery ด้วย keil ครับ  สำหรับมือใหม่ 32 bit
แต่ว่าท่านต้องมีพื้นฐาน หรือเคยใช้ หรือจะต้องศึกษา การใช้ keil ให้เป็นก่อน ครับ
ถ้าไม่เคยใช้ ให้หาอ่านได้ตามเว็ปต่างๆ หรือของทาง keil เอง ก็มีเอกสารการใช้
IDE และ Complier     ซึ่งตรงนี้จะแนะนำในตัวของ Code program เป็นหลัก

หาอ่านได้ตรงนี้เว็ปอ้างอิง
http://tentuts.meritox.com/2012/05/how-to-use-keil-uvision-4-ide-project.html
http://www.keil.com/support/man/docs/uv4/
http://www.datasheetarchive.com/Keil%20uVision%204%20user%20manual-datasheet.html
http://www.cs.uregina.ca/Links/class-info/301/ARM/lecture.html
http://vshamu.wordpress.com/2011/03/25/micrcontroller-programming-using-c-with-keil-ide/


อันดับแรกเมื่อต้องการสร้างโปรเจคใหม่  ให้ท่านสร้าง Folder ที่จะเก็บขึ้นมาเพื่อทำการ
เก็บตัวโปรเจคใหม่ไว้   ใน Folder จะมีการเก็บ File เบื้องต้น 2 ตัว ที่จะต้องไปก๊อปปี้
มาจาก keil เพื่อให้ง่ายและตัดปัญหาการหา file ไม่เจอในการ Compiler ของ Keil
เมื่อมีการก็อปปี้ Folder ไปที่อื่น 
File ทั้ง2 นี้มีดังนี้

1      system_stm32f4.c  ไปก็อปปี้ได้จาก   C:\Keil\ARM\Startup\ST\STM32F4xx    เข้าตาม Floder
2      stm32f4xx.h           ไปก็อปปี้ได้จาก   C:\Keil\ARM\INC\ST\STM32F4xx          เข้าตาม Floder

เตรียม File ไว้ใน Floder ให้พร้อม เมื่อครบแล้วเตรียมการสร้างโปรเจคใหม่ได้เลยครับ

รูปแบบนี้ใช้ได้กับ  MCU ทั้งหมดที่ keil รู้จัก    

system_stm32f4.c  เป็นcode เกี่ยวกับการจัดการ Clock และฐานเวลาเบื้องต้น  ที่ทาง Keil ให้มา
stm32f4xx.h     เป็นพารามิเตอร์ต่างๆ ที่อ้างอิง Register ของ MCU  แอดไว้ดูและดึงมาใช้งานจะสะดวก
#15
ประกาศใช้ GPIOA  STM32F4 เป็นอินพุทหมด ตกใจพอรัน แล้วมันจะมองไม่เห็น Chip อีก 
ใครเคยเจอปัญหานี่หรือยัง  ที่ประกาศใช้ GPIOA  STM32F4 แล้วโปรแกรมลงไป
พอจะเปลี่ยนโปรแกรมใหม่ลง  ปรากฎว่าบอดมองไม่เห็นชิป stm32f4 อีก  ใครเคยไม่เป็นไรครับ
หรือยังไม่เคย  ลองดูครับ
#include"stm32f4xx.h"

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    =    0;
GPIOA->MODER    =    0;
  }

int main(void)
             {

  Set_GPIO(); 
    while(1)
{
  if(GPIOA->IDR & GPIO_IDR_IDR_0)
GPIOD->ODR   =  0xF000;
if(!(GPIOA->IDR & GPIO_IDR_IDR_0))
GPIOD->ODR   =  0;
}
             }


ลองดูครับ  ว่ามีใครเกิดปัญญหาแบบนี้มั่ง
ถ้าเกิดแล้วจะทำอย่างไร

ตอนแรกก้ตกใจ ดูไปดูมา เอาวว  ไปทับขาโปรแกรม SWD เข้าแล้วทีนี้จะโปรแกรมยังไงละ
ไม่ต้องตกใจไปครับ  ใครที่ไปประกาศขาทับซ้อนกับขาโปรแกรม สามารถกู้กลับมาได้ครับ
แค่เปิดโปรแกรม ST link Utility ครับ เลือกที่เมนู Target  แล้วเลือกที่ settingครับ
จากนั้นเลือกเมนู SWD และกด OK  มันจะติดต่อกับ MCUให้ครับ จากนั้นก็ไปลบโปรแกรมเก่า
ที่คอนฟิตขาเป็นอินพุท โดยเลือกลบ เมนู Target อีกครั้ง เลือก Erase Chip เท่านี้ มันก็จะกลับมาทำงาน
ได้เหมือนเดิม เป็นการลบโปรแกรมเก่าทิ้งไปครับ
;D ;D
#16
ลองใช้งาน Timer 1-2-3-4   พร้อมกัน   ใน keil 4.60 แล้วทำงานได้
แต่พอใช้ keil 4.7a ปรากฎว่า ไม่ทำงานซะอย่างนั้น  แต่ไม่มีปัญหาด้านการ compiler
ผ่านไม่ติดปัญหา              ใช้ stm32f407ทดลอง
มีท่านไดเจอปัญหาประเภคต่างเวอรชั่น แล้ว บางโมดูลไม่ทำงานบ้างครับ   
#17
ARM Processors / XMC4500 Relax / Relax Lite
April 15, 2013, 07:53:08 PM
XMC4500 Relax / Relax Lite
เป็นอีกหนึ่งค่ายที่น่าสนใจทางฝั่งยุโรป ค่าย Infineon Technologies ที่มีความน่าเชื่อถือสูง Cortex M4
http://www.infineon.com/cms/en/product/microcontrollers/32-bit-industrial-microcontrollers-based-on-arm-registered-cortex-tm-m/32-bit-xmc4000-industrial-microcontrollers-arm-registered-cortex-tm-m4/channel.html?channel=db3a30433580b3710135a03abaf9385e

ในราคาที่จับจองเล่นได้ไม่โหดนัก มาพร้อมกับ jtag j-link ในตัว
งานด้านMotor control , Switching , Driver , ไม่เป็นรองใคร
มีตัวอย่าง การควบคุมผ่านเว๊ป เซฟเวอร์ น่าสนใจ สามารถหาศึกษาได้ในเว็ปเดโม
มีสองรุ่น รุ่นที่ติดต่อเว๊ปได้  และติดต่อไม่ได้ ราคาต่างกัน  10Euro /30Euro
แล้วแต่เป้าหมายการใช้งาน 
http://www.infineon.com/cms/en/product/microcontrollers/32-bit-industrial-microcontrollers-based-on-arm-registered-cortex-tm-m/32-bit-xmc4000-industrial-microcontrollers-arm-registered-cortex-tm-m4/xmc-development-tools,-software-and-kits/xmc4500-relax/relax-lite-kit/channel.html?channel=db3a30433a747525013a97f6e265721e