Cortex-M3 Application


 
* Update history

- 2013.8.13 : Ãʱâ Release




 
4. Examples
   4.1 GPIO Output without SDK
   4.2 GPIO Output with SDK
   4.3 GPIO Output with BitBand
   4.4 GPIO Input - Polling
   4.5 GPIO Input - Interrupt
   4.6 General Purpose Timer
   4.7 Systick - Delay
   4.8 Systick - Interrupt
   4.9 USART - Polling
   4.10 USART - Interrupt
   4.11 USART - Name Card
   4.12 Interrupt Priority1
   4.13 Interrupt Priority2
   4.14 Power Management - Sleep
   4.15 Power Management - Stop
   4.16 Power Management - StandBy
   4.17 Mode Privilege




 



4. Examples
4.1 GPIO Output without SDK

STM32F ½Ã¸®Áî¿¡´Â CPU Datasheet¸¦ º¸Áö ¾Ê´õ¶óµµ ÇÔ¼ö À̸§¸¸ º¸°í¼­µµ µû¶ó ÇÒ¼ö ÀÖÀ» Á¤µµÀÇ ST»ç¿¡¼­ Á¦°øÇÏ´Â ¾ÆÁÖ ÈǸ¢ÇÑ Library °¡ ÀÖ½À´Ï´Ù. ÇÏÁö¸¸ ¿ì¸®´Â óÀ½¿¡´Â STM32F CPUÀÇ ·¹Áö½ºÅ͵éÀ» ´õ Àß ÀÌÇØÇϱâ À§Çؼ­ SDK ¶óÀ̺귯¸®¸¦ »ç¿ëÇÏÁö ¾Ê°í Á÷Á¢ SFR ·¹Áö½ºÅ͵带 ¼³Á¤ÇÏ´Â ¹æ¹ýÀ¸·Î Çغ¸µµ·Ï ÇÏ°Ú½À´Ï´Ù.

ù¹ø° ¿¹Á¦·Î Dragon °³¹ßº¸µåÀÇ Bottom º¸µå¿¡ ÀÖ´Â LEDµé Áß¿¡¼­ LED2, LED4´Â On, LED3 ´Â Off ½ÃÅ°´Â ¿¹Á¦¸¦ Çغ¸µµ·Ï ÇÏ°Ú½À´Ï´Ù.

(1) Dragon °³¹ßº¸µåÀÇ LED ȸ·Î

Cortex-M3

ȸ·Î¸¦ º¸¸é LED¸¦ Äѱâ À§Çؼ­´Â GPIOÆ÷Æ®¸¦ High·Î Çϸé LED°¡ ÄÑÁöµµ·Ï µÇ¾î ÀÖ½À´Ï´Ù.

(2) Peripheral Bus

Cortex-M3

GPIOE ´Â APB2 ¹ö½º¿¡ ¿¬°áÀÌ µÇ¾î ÀÖÀ¸¹Ç·Î APB2 ¹ö½ºÀÇ GPIOE Æ÷Æ®ÀÇ ClockÀ» Enable ½ÃÄÑÁÖ¾î¾ß ÇÕ´Ï´Ù.

(3) STM32 Peripheral Boundary Address : 0x4002 1000 ( STM32F103 Reference Guide Page 50 )

Cortex-M3

(4) RCC_APB2ENR Boundary Address : 0x4002 1000 + 0x18 ( STM32F103 Reference Guide Page 119 )

Cortex-M3

(5) RCC_APB2ENR Boundary Address : 0x4002 1018 ( STM32F103 Reference Guide Page 142 )

Cortex-M3

- GPIOE Port Enable : (*(volatile unsigned *)0x4002 1018) |= 0x01 << 6;

(6) GPIOE Port Boundary address : 0x4001 1800 ( STM32F103 Reference Guide Page 51 )

Cortex-M3

(7) GPIO and AFIO register maps ( STM32F103 Reference Guide Page 188 )

Cortex-M3
(8) GPIOE_CRL Register Boundary address : 0x4001 1800


Cortex-M3

Cortex-M3

- GPIOE Port2, 3, 4 ¸¦ Output push-pull ·Î ¼³Á¤

(9) GPIOE_BSRR(Set/Reset) Register Boundary address : 0x4001 1810

Cortex-M3

BSRR ·¹Áö½ºÅÍ´Â GPIO Set or Reset Àü¿ë ·¹Áö½ºÅÍ ÀÔ´Ï´Ù. 0 ~ 15ºñÆ®´Â Set Àü¿ëÀÌ°í 16 ~ 31ºñÆ®´Â Reset ·¹Áö½ºÅÍ ÀÔ´Ï´Ù.
LED2(GPIOE2), LED4(GPIOE4) Æ÷Æ®¸¦ Set ÇϱâÀ§Çؼ­´Â BSRR·¹Áö½ºÅÍÀÇ 2, 4 ¹ø ºñÆ®¸¦ 1·Î ¸¸µé¸é µË´Ï´Ù. "0"À» Write ÇßÀ»¶§ "No action" À̶ó°í µÇ¾î ÀÖ´Â ºÎºÐÀº ÀϹÝÀûÀ¸·Î ·¹Áö½ºÅÍÀÇ Æ¯Á¤ ºñÆ®¸¦ Set or Clear Çϱâ À§Çؼ­´Â LDR, Bit Á¶ÀÛ, STR ÀÇ 3´Ü°è°¡ ÇÊ¿äÇѵ¥, ÀÌ·¯ÇÑ Feature °¡ Áö¿øÀÌ µÇ¸é Bit Á¶ÀÛ ´ÙÀ½¿¡ ¹Ù·Î STR ¸í·É¾î¿¡ ÀÇÇؼ­ ·¹Áö½ºÅÍ ºñÆ® Á¶ÀÛÀÌ °¡´É ÇÏ°Ô µË´Ï´Ù.

(10) GPIOE_BRR(Reset) Register Boundary address : 0x4001 1814

Cortex-M3

GPIO Reset Àü¿ë ·¹Áö½ºÅ͸¦ ÀÌ¿ëÇؼ­ GPIOE3 À» Reset ÇÕ´Ï´Ù.

(*(volatile unsigned *) 0x40011814) = (0x1 << 3); // PE3 Off


* ¿¹Á¦ Àüü ÄÚµå

void led_test_wo_sdk(void)
{
// APB2 Clock enable
// Reference Page 47, 50, 119, 142
// APB2 peripheral GPIOE clock enable register (RCC_APB2ENR)
(*(volatile unsigned *)0x40021018) |= 0x01 << 6;


// General Purpose output push-pull
// Reference Page 51, 188, 166
// GPIOE_CRL
(*(volatile unsigned *)0x40011800) &= ~(0xf << 8);
(*(volatile unsigned *)0x40011800) &= ~(0xf << 12);
(*(volatile unsigned *)0x40011800) &= ~(0xf << 16);

// PE2, 3, 4 Ouput mode configuration
// Reference Page 51, 188, 166
// GPIOE_CRL
(*(volatile unsigned *)0x40011800) |= (0x3 << 8); // PE2 Ouput Mode 50MHz
(*(volatile unsigned *)0x40011800) |= (0x3 << 12); // PE3 Ouput Mode 50MHz
(*(volatile unsigned *)0x40011800) |= (0x3 << 16); // PE4 Ouput Mode 50MHz


// Reference Page 168
// GPIOE_BSRR
(*(volatile unsigned *)0x40011810) = (0x1 << 2); // PE2 On
// GPIOE_BSRR
(*(volatile unsigned *)0x40011810) = (0x1 << 4); // PE4 On
// GPIOE_BRR
(*(volatile unsigned *)0x40011814) = (0x1 << 3); // PE3 Off

}



4.2 GPIO Output with SDK
(1) ù¹ø° ¿¹Á¦¿Í µ¿ÀÏÇÑ µ¿ÀÛÀ» Çϴµ¥ À̹ø¿¡´Â ST»ç¿¡¼­ Á¦°øÇÑ SDK ¶óÀ̺귯¸®¸¦ ÀÌ¿ëÇؼ­ Çغ¸µµ·Ï ÇÏ°Ú½À´Ï´Ù.
(2) ÇÁ·ÎÁ§Æ®¿Í stm32f10x_conf.h ÆÄÀÏ ¼öÁ¤

Cortex-M3

GPIO ¶óÀ̺귯¸®¸¦ »ç¿ëÇϱâ À§Çؼ­´Â ÇÁ·ÎÁ§Æ®¿¡ stm32f10x_gpio.c ÆÄÀÏÀ» Ãß°¡ ÇÏ°í stm32f10x_conf.h ¿¡¼­ stm32f10x_gpio.h ¸¦ include ÇØ¾ß ÇÕ´Ï´Ù.

* ¿¹Á¦ Àüü ÄÚµå


void led_test_wt_sdk(void)
{

// Define GPIO Init structure
GPIO_InitTypeDef GPIO_InitStructure;

// APB2 Clock enable
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);


/* Configure the GPIOE ports for output*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);

GPIO_SetBits(GPIOE, GPIO_Pin_2); // LED2 On
GPIO_ResetBits(GPIOE, GPIO_Pin_3); // LED3 Off
GPIO_SetBits(GPIOE, GPIO_Pin_4); // LED4 On

}



º°µµÀÇ ¼³¸íÀ» ÇÏÁö ¾Ê¾Æµµ ÇÔ¼öÀÇ À̸§¸¸ ºÁµµ ½±°Ô Äڵ带 ÀÌÇØÇÒ¼ö ÀÖ½À´Ï´Ù.

4.3 GPIO Output with BitBand

(1) ¿¹Á¦ 2¹ø°ú µ¿ÀÏÇÑ ÀÛ¾÷À» Çϴµ¥, À̹ø¿¡´Â Bitband¸¦ ÀÌ¿ëÇؼ­ Çغ¸µµ·Ï ÇÏ°Ú½À´Ï´Ù.

Cortex-M3

Peripheral ¿µ¿ªÀÇ Bitband ¿µ¿ªÀ» ÀÌ¿ëÇؾßÇϱ⠶§¹®¿¡ Bitband base ¿µ¿ªÀº 0x40000000 ÀÌ µÇ°í Bitword base ´Â 0x42000000 ÀÌ µË´Ï´Ù.
Bitband ¿µ¿ªÀ» °è»ê½ÄÀ» ´Ù½ÃÇѹø »ó±â Çϸ鼭 ¼Ò½ºÄڵ带 ºÐ¼®ÇØ º¸½Ã±â ¹Ù¶ø´Ï´Ù. GPIOEÀÇ ODR ·¹Áö½ºÅ͸¦ ÀÌ¿ëÇؼ­ ±¸Çö ÇÏ¿´½À´Ï´Ù.

bit_word_offset = (byte_offset x 32) + (bit_number × 4)

bit_word_addr = bit_band_base + bit_word_offset


// GPIOE_ODR : 0x4001180C

// 2,3,4 Bit : PE2, PE3, PE4


* ¿¹Á¦ Àüü ÄÚµå


#define PERI_BASE 0x40000000
#define PERI_BB_BASE 0x42000000


void led_test_wt_bitband(void)
{

// Define GPIO Init structure
GPIO_InitTypeDef GPIO_InitStructure;


// APB2 Clock enable
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);


/* Configure the GPIOE ports */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);

(*(volatile unsigned *)(PERI_BB_BASE + (0x4001180C-PERI_BASE)*32 + 2*4)) = 0x1; // PE2 On
(*(volatile unsigned *)(PERI_BB_BASE + (0x4001180C-PERI_BASE)*32 + 3*4)) = 0x0; // PE3 On
(*(volatile unsigned *)(PERI_BB_BASE + (0x4001180C-PERI_BASE)*32 + 4*4)) = 0x1; // PE4 On

}





4.4 GPIO Input - Polling
Dragon °³¹ßº¸µå¿¡ ÀÖ´Â ¹öÆ° ÀÔ·ÂÀ» Polling ¹æ½ÄÀ¸·Î ó¸®ÇØ º¸µµ·Ï ÇÏ°Ú½À´Ï´Ù.

(1) BTN2°¡ ´­¸®¸é LED2¸¦ ON ½ÃÅ°°í, BTN2°¡ ´­¸®Áö ¾ÊÀº »óŸé LED2¸¦ Off ÇÕ´Ï´Ù.  µ¿ÀÏÇÑ ¹æ¹ýÀ¸·Î BTN3, BTN4 ¿¡µµ Àû¿ë ÇÕ´Ï´Ù. ±×¸®°í BTN1À» ´©¸£¸é Å×½ºÆ®¸¦ Á¾·á ÇÕ´Ï´Ù.


Cortex-M3

BTN ȸ·Î¸¦ º¸¸é ¹öÆ°ÀÌ ´­¸®Áö ¾Ê¾ÒÀ»¶§´Â VCC¿¡ ¿¬°áÀÌ µÇ¾î High »óÅÂÀÌ°í ¹öÆ°ÀÌ ´­¸®¸é GND¿¡ ¿¬°áÀÌ µÇ¸é¼­ Low »óÅ°¡ µË´Ï´Ù.

Cortex-M3

(2) GPIOC ±×·ìÀ» »ç¿ëÇϱâ À§Çؼ­´Â APB2 ¹ö½ºÀÇ GPIOC ±×·ìÀÇ ClockÀ» Enable ÇØ¾ß ÇÕ´Ï´Ù.
(3) GPIOC1, 2, 3 À» Input floating À¸·Î ¼³Á¤ ÇÕ´Ï´Ù.

* ¿¹Á¦ Àüü ÄÚµå


void key_input_test_polling_wt_sdk(void)
{

// Define GPIO Init structure
GPIO_InitTypeDef GPIO_InitStructure;


// APB2 Clock enable for LED
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);

// APB2 Clock enable for KEY
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);


/* Configure the GPIOE ports for output*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);

/* Configure the GPIOC ports for input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOC, &GPIO_InitStructure);

while(1)
{

    // BTN1
    if( (!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_0 )) )
    {
        break;
    }

    // BTN2
    if( (!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_1 )) )
    {
        GPIO_SetBits(GPIOE, GPIO_Pin_2); // LED2 On
    }
    else
    {
        GPIO_ResetBits(GPIOE, GPIO_Pin_2); // LED2 Off
    }

    // BTN3
    if( (!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_2 )) )
    {
        GPIO_SetBits(GPIOE, GPIO_Pin_3); // LED3 On
    }
    else
    {
        GPIO_ResetBits(GPIOE, GPIO_Pin_3); // LED3 Off
    }

    // BTN4
    if( (!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_3 )) )
    {
        GPIO_SetBits(GPIOE, GPIO_Pin_4); // LED4 On
    }
    else
    {
        GPIO_ResetBits(GPIOE, GPIO_Pin_4); // LED4 Off
    }
}

}


4.5 GPIO Input - Interrupt
À̹ø¿¡´Â BTN ÀÔ·ÂÀ» Æú¸µ ¹æ½ÄÀÌ ¾Æ´Ñ ÀÎÅÍ·´Æ® ¹æ½ÄÀ¸·Î ±¸ÇöÇØ º¸µµ·Ï ÇÏ°Ú½À´Ï´Ù.

(1) BTN2¸¦ Çѹø ´©¸£¸é LED2¸¦ On ½ÃÅ°°í,  ´Ù½Ã BTN2¸¦ ´©¸£¸é LED2¸¦ Off ÇÕ´Ï´Ù.
(2) BTN ÀÔ·ÂÀ» Falling Edge ¿¡¼­ °ËÃâµÇµµ·Ï ¼³Á¤ ÇÕ´Ï´Ù. Falling Edge ¿¡¼­ °ËÃâÇÑ´Ù´Â °ÍÀº KEY Down¿¡¼­ ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇϵµ·Ï ÇÑ´Ù´Â °ÍÀÌÁÒ.
     KEY UpÀ» °ËÃâÇϱâ À§Çؼ­´Â Rising Edge ¿¡¼­ °ËÃâµÇµµ·Ï ¼³Á¤ÇÏ¸é µË´Ï´Ù.

(3) PC1 Æ÷Æ®ÀÇ ÀÎÅÍ·´Æ® ÀÔ·ÂÀ» ¹ÞÀ¸·Á¸é ¿ÜºÎ ÀÎÅÍ·´Æ® 1¹ø¿¡ ¿¬°áÇØ¾ß ÇÕ´Ï´Ù. ´ç¿¬È÷ PC2´Â ¿ÜºÎ ÀÎÅÍ·´Æ® 2¹ø¿¡ ¿¬°áÇØ¾ß ÇÏ°ÚÁÒ.

Cortex-M3

Cortex-M3

(4) ÀÎÅÍ·´Æ® ·¹Áö½ºÅÍ ¼³Á¤

Cortex-M3

(5) SDK ¶óÀ̺귯¸® Ãß°¡

Cortex-M3

(6) ÀÎÅÍ·´Æ® ¿ì¼±¼øÀ§

Cortex-M3

STM32¿¡¼­ ÀÎÅÍ·´Æ® ¿ì¼±¼øÀ§ ºñÆ®´Â 8ºñÆ®Áß¿¡¼­ »óÀ§ 4ºñÆ®¸¸ »ç¿ëÀ» ÇÕ´Ï´Ù. 4ºñÆ® Áß¿¡¼­ À̹ø ¿¹Á¦¿¡¼­´Â Priority group 2¸¦ »ç¿ëÇؼ­ Group¿ì¼±¼øÀ§ 2ºñÆ® Sub ¿ì¼±¼øÀ§ 2ºñÆ®¸¦ »ç¿ëÇϵµ·Ï ¼³Á¤ ÇÕ´Ï´Ù.

(7) ÀÎÅÍ·´Æ® ¼­ºñ½º È帧µµ

Cortex-M3
¿ÜºÎ ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇؼ­ ÀÎÅÍ·´Æ® Çڵ鷯 ÇÔ¼ö·Î ºÐ±âÇϱ⠱îÁöÀÇ °úÁ¤À» µµ½ÄÈ­ Çغ¸¾Ò½À´Ï´Ù.

(8) ¿¹Á¦ ÄÚµå ÀÛ¼º ¼ø¼­

¡à APB2 Clock enable for LED
¡à APB2 Clock enable for KEY

¡à Configure the GPIOE ports for output

¡à Configure the GPIOC ports for input

¡à Configure EXTI  to generate an interrupt on falling edge

¡à EXTIPR : pending ¿©ºÎ¹× pending clear(1:pending clear)

¡à ICPR : pending clear Cortex-M3


* ¿¹Á¦ Àüü ÄÚµå


void key_input_test_interrupt(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    // Define GPIO Init structure
    GPIO_InitTypeDef GPIO_InitStructure;


     // APB2 Clock enable for LED
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);

    // APB2 Clock enable for KEY
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

    
    // for Interrupt
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    /* Configure the GPIOE ports for output*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOE, &GPIO_InitStructure);

    /* Configure the GPIOC ports for input */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOC, &GPIO_InitStructure);


    /* Connect EXTI */
    // External Interrupt configuration register1 (AFIO_EXTICR1)
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource1);

    /* Configure EXTI1 to generate an interrupt on falling edge */
    EXTI_InitStructure.EXTI_Line = EXTI_Line1;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);


    // 2 bit for pre-emption priority, 2 bits for subpriority
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);


    /* Clear EXTI Line Pending Bit */
    // STM32F10x Pending Register : 0x40010400 + 0x14
    EXTI_ClearITPendingBit(EXTI_Line1);

    /* Enable the Key EXTI line Interrupt */
    // Cortex-M3 Interrupt Clear-Pending Register : 0xE000E280-0xE000E29C
    NVIC_ClearPendingIRQ(EXTI1_IRQn);
}

void EXTI1_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line1) != RESET)
    {
        EXTI_ClearITPendingBit(EXTI_Line1);
        
         // Blink
        GPIOE->ODR ^= (0x1 << 2);
    }
}


4.6 General Purpose Timer
ÀÓº£µðµå ½Ã½ºÅÛ¿¡¼­ Timer´Â °¡Àå Áß¿äÇÏ°í ÇʼöÀûÀÎ ¿ä¼Ò·Î OS¿¡¼­ Task ½ºÄÉÁÙ¸µÀ» À§Çؼ­ »ç¿ëµÇ±âµµ ÇÏ°í, ÀüÀÚ¾×ÀÚ, Â÷·®¿ë ºí·¢¹Ú½º µîÀÇ ÀÀ¿ë ¾îÇø®ÄÉÀ̼ǿ¡¼­µµ ƯÁ¤ ½Ã°£ ÀÌÈÄ¿¡ ÀÎÅÍ·´Æ®¸¦ ¹ß»ý½ÃÄÑ Á¤ÇØÁø ÀÏÀ» ¼öÇàÇÏ´Â °æ¿ìµî ÀÀ¿ëºÐ¾ß´Â ¹«¼öÈ÷ ¸¹½À´Ï´Ù.

- Âü°í -

CPUÀÇ Å¬·° ¼Óµµ°¡ 1Hz ¶ó´Â °ÍÀº ¹«¾ùÀ» ÀǹÌÇÏ´Â °ÍÀϱî¿ä ?

ÀÌ°ÍÀº 1ÃÊ¿¡ 1¹øÀÇ Tick ÀÌ ¹ß»ýÇÑ´Ù´Â °ÍÀÓ. STM32°¡  72MHz ·Î µ¿ÀÛ ÇÑ´Ù¸é 1ÃÊ¿¡ 7õ2¹é¸¸¹øÀÇ TickÀÌ ¹ß»ýÇÏ´Â °Í

À̹ø ¿¹Á¦¿¡¼­´Â STM32 CPU¿¡ ³»ÀåµÈ Timer2¸¦ ÀÌ¿ëÇؼ­ 1ÃÊ¿¡ Çѹø¾¿ Timer ÀÎÅÍ·´Æ®¸¦ ¹ß»ý½ÃÄÑ LDE2, LED3 ¸¦ Toggle(On/Off ¸¦ ¹Ýº¹Çϴ°Í) ÇÏ´Â ½ÇÇèÀ» Çغ¸µµ·Ï ÇÏ°Ú½À´Ï´Ù.


- Âü°í -

1sec = 1,000ms = 1,000,000us = 1,000,000,000ns

1Hz  = 1KHz      = 1MHz          = 1GHz


(1) STM32F CPUÀÇ Å¸ÀÌ¸Ó Á¾·ù

Cortex-M3

(2) Timer Clock

Cortex-M3

Timer2´Â APB1 ¹ö½º¿¡ ¿¬°áµÇ¾î ÀÖ½À´Ï´Ù. APB1 ¹ö½ºÀÇ ÃÖ´ë µ¿ÀÛ ¼Óµµ´Â 36MHz ÀÌÁö¸¸ À§ÀÌ ±×¸²À» Àß º¸¸é APB1 ÀÇ Prescaler°¡ 1ÀÌ ¾Æ´Ï¸é PB1 Clock x2 ¸¦ ÇÏ°í ÀÖ½À´Ï´Ù. ±×·¯¹Ç·Î Timer2°¡ APB1¿¡ ¿¬°áµÇ¾î ÀÖÁö¸¸ Timer2¿¡ °ø±ÞµÇ´Â Clock Àº 72MHz °¡ µË´Ï´Ù. ÁÖÀÇÇؼ­ º¸Áö ¾ÊÀ¸¸é Timer2¿¡ °ø±ÞµÇ´Â ClockÀÌ 36MHz ¶ó°í Âø°¢ ÇÒ¼ö ÀÖ½À´Ï´Ù.

(3) ÇÁ·ÎÁ§Æ®¿Í stm32f10x_conf.h ÆÄÀÏ ¼öÁ¤

Cortex-M3

(4) ¿¹Á¦ ÄÚµå ÀÛ¼º ¼ø¼­

¡à APB1 Clock enable for TIM2

¡à GPIO Init for LED

¡à Configure the TIM2 interrupt

¡à Time base configuration

¡à TIM2 Enable

¡à TIM2 interrupt enable


* ¿¹Á¦ Àüü ÄÚµå

void gpio_init_led(void)
{
    // Define GPIO Init structure
    GPIO_InitTypeDef GPIO_InitStructure;


     // APB2 Clock enable
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);


     /* Configure the GPIOE ports for output*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOE, &GPIO_InitStructure);
}

void gpio_init_key(void)
{
    // Define GPIO Init structure
    GPIO_InitTypeDef GPIO_InitStructure;


    // APB2 Clock enable for KEY
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

    // for Interrupt
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);


    /* Configure the GPIOC ports for input */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}


void TIM2_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET )
    {
        // Also cleared the wrong interrupt flag in the ISR
        TIM_ClearFlag(TIM2, TIM_FLAG_Update);

        TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // Clear the interrupt flag

        // Blink
        GPIOE->ODR ^= (0x1 << 2);
        GPIOE->ODR ^= (0x1 << 3);
    }
}

void timer2_test(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

    /* TIM2 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    gpio_init_led();

    
    /* Enable the TIM2 global Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);


     // TIM2CLK = 72 MHz( APB1Àº ¿ø·¡ 36MHz Àε¥ ºÐÁÖ¸¦ Çؼ­ »ç¿ëÇϹǷΠ36*2 = 72MHz °¡ µÈ´Ù. )
    // ½Ã°£ÀÇ ±âº»´ÜÀ§ :S(ÃÊ)-->nS.uS.mS.S.
    // 72000000/60000=1200 Áï 1ÃÊ¿¡ 1200¹ø Ŭ·°ÀÌ ¹ß»ýÇϹǷÎ
    // ARR ·¹Áö½ºÅ͸¦ 1199+1 ¹ø¿¡ Çѹø ÀÎÅÍ·´Æ®°¡
    // ¹ß»ýÇϵµ·Ï ¼³Á¤Çϸé 1ÃÊ¿¡ Çѹø ÀÎÅÍ·´Æ®°¡ ¹ß»ýµÈ´Ù.

    /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Period = 1200-1; // ARR(Auto reload register)
    TIM_TimeBaseStructure.TIM_Prescaler = 60000-1;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    TIM_ARRPreloadConfig(TIM2, ENABLE);
    TIM_Cmd(TIM2, ENABLE);


     /* TIM IT enable */
    TIM_ITConfig(TIM2, TIM_IT_Update , ENABLE);
}


ÀÚÁÖ »ç¿ëÇÏ´Â LED, KEY Æ÷Æ®¸¦ ÃʱâÈ­ ÇÏ´Â ÇÔ¼ö gpio_init_led, gpio_init_key ¸¦ ¸¸µé¾î¼­ È£Ãâ ÇÏ¿´½À´Ï´Ù.


4.7 Systick - Delay
SysTick Timer¸¦ ÀÌ¿ëÇؼ­ 1us Delay ÇÔ¼ö¸¦ ±¸ÇöÇÏÀÚ.  delay_ms ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿©  LDE2, LED3 À» 1ÃÊ °£°ÝÀ¸·Î Toggle(On/Off) ÇØ º¾½Ã´Ù.


(1) System Control Space

Cortex-M3

System timer ÀÎ SysTick Àº System Control Space ¿µ¿ª¿¡ À§Ä¡ÇÏ°í ÀÖ½À´Ï´Ù.

(2) SysTick Control and Status Register

Cortex-M3

Cortex-M3

À̹ø¿¡´Â SysTick ÀÎÅÍ·´Æ®´Â »ç¿ëÇÏÁö ¾ÊÀ» °ÍÀÌ¿À CLKSOURCE´Â core clock(72MHz) À» ±×´ë·Î »ç¿ëÇÒ °ÍÀÔ´Ï´Ù.

(3) Systick Reload Register

Cortex-M3

Systick Current Value Register¸¦ º¸¸é Systick Timer ´Â 24ºñÆ® ŸÀÌ¸Ó ¶ó´Â°ÍÀ» ¾Ë¼ö ÀÖ½À´Ï´Ù.

* ¿¹Á¦ Àüü ÄÚµå

// 1us delay ÇÔ¼ö
void delay_us (const uint32_t usec)
{
    RCC_ClocksTypeDef RCC_Clocks;


     /* Configure HCLK clock as SysTick clock source */
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);

    RCC_GetClocksFreq(&RCC_Clocks);

    // Set SysTick Reload(1us) register and Enable
    // usec * (RCC_Clocks.HCLK_Frequency / 1000000) < 0xFFFFFFUL -- because of 24bit timer
    // RCC_Clocks.HCLK_Frequency = 72000000
    // Systick Reload Value Register = 72
    // 72 / 72000000 = 1us
    SysTick_Config(usec * (RCC_Clocks.HCLK_Frequency / 1000000));
    

    // SysTick Interrupt Disable
    SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk ;


    // Until Tick count is 0
    while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
}

// 1ms delay ÇÔ¼ö

void delay_ms (const uint32_t msec)
{
    delay_us(1000 * msec);
}

void systick_test_delay(void)
{
    gpio_init_led();
    gpio_init_key();

    while(1)
    {
        // BTN1
        if( (!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_0 )) )
        {
            break;
        }

        delay_ms(100);
        delay_ms(100);
        delay_ms(100);
        delay_ms(100);
        delay_ms(100);
        delay_ms(100);
        delay_ms(100);
        delay_ms(100);
        delay_ms(100);
        delay_ms(100);

        // Blink
        GPIOE->ODR ^= (0x1 << 2);
        GPIOE->ODR ^= (0x1 << 3);
    }
}


72MHz Ŭ·°À» °¡Áö´Â 24Bit SysTick ŸÀ̸ӷδ 1ÃÊ Delay¸¦ ¸¸µé¾î ³¾¼ö ¾ø±â ¶§¹®¿¡ 100msec delay ÇÔ¼ö¸¦ 10¹ø È£ÃâÇÏ¿© ±¸ÇöÇÏ¿´½À´Ï´Ù.

4.8 Systick - Interrupt
SysTick Timer¸¦ ÀÌ¿ëÇؼ­ 100msec °£°ÝÀ¸·Î SysTick_Handler ÀÎÅÍ·´Æ®¸¦ ¹ß»ý ½ÃÅ°°í LDE2, LED3 À» Toggle(On/Off) ÇØ º¾½Ã´Ù.


* ¿¹Á¦ Àüü ÄÚµå

void SysTick_Handler(void)
{
    // Blink
    GPIOE->ODR ^= (0x1 << 2);
    GPIOE->ODR ^= (0x1 << 3);
}

void systick_test_interrupt(void)
{
    RCC_ClocksTypeDef RCC_Clocks;

   
    gpio_init_led();

    /* Configure HCLK clock as SysTick clock source */
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);

    RCC_GetClocksFreq(&RCC_Clocks);

    /* Setup SysTick Timer for 100 msec interrupts */
    if (SysTick_Config(RCC_Clocks.HCLK_Frequency / 10))
    {
        /* Capture error */
        while (1);
    }
}



SysTick_Config ÇÔ¼ö¾È¿¡¼­ ±âº»À¸·Î SysTick ÀÎÅÍ·´Æ®¸¦ Enable ÇÏ°í Àֱ⠶§¹®¿¡ ´Ù¸¥ ¼³Á¤À» ÇÏÁö ¾Ê¾Æµµ SysTick_Handler ÀÎÅÍ·´Æ® Çڵ鷯·Î ÁøÀÔ ÇÕ´Ï´Ù.
ÀÌÀü SysTick Delay ¿¹Á¦ ¿¡¼­´Â ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇÏÁö ¾Êµµ·Ï Çϱâ À§Çؼ­

SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk ;

À§¿Í °°Àº Äڵ尡 »ðÀÔÀÌ µÇ¾î ÀÖ¾ú½À´Ï´Ù.

4.9 USART - Polling
UART1¸¦ PC¿Í 115200bps Baudrate·Î Åë½Å(RX, TX)À» ÇÏ´Â Echo server·Î ¸¸µé¾î º¾½Ã´Ù.

RX, TX Åë½ÅÀ» Æú¸µ ¹æ½ÄÀ¸·Î ó¸® ÇÕ´Ï´Ù. Å͹̳ο¡¼­ ‘x’ °¡ ÀԷµǸé Æú¸µÀ» Á¾·á ÇÕ´Ï´Ù.


(1) Dragon °³¹ßº¸µåÀÇ UART ȸ·Î

Cortex-M3

Dragon °³¹ßº¸µå¿¡´Â COMÆ÷Æ®°¡ ¾ø´Â ³ëÆ®ºÏ, µ¥½ºÅ©Å¾¿¡¼­ Æí¸®ÇÏ°Ô »ç¿ëÇÏ°Ô Çϱâ À§Çؼ­ USB to Serial Æ÷Æ®°¡ ³»ÀåµÇ¾î ÀÖ½À´Ï´Ù.
ȸ·Îµµ¸¦ º¸¸é PA10ÀÌ RX, PA9°¡ TX Æ÷Æ® ÀÔ´Ï´Ù. À̹ø ¿¹Á¦ Å×½ºÆ®¸¦ À§Çؼ­ ´Ü¼øÈ÷ USB ¹Ì´ÏÄÉÀ̺íÀ» ÀÌ¿ëÇؼ­ Dragon Bottom º¸µå¿¡ ÀÖ´Â UART0¹ø°ú PCB ÀÇ USB Æ÷Æ®¿¡ ¿¬°áÀ» ÇÏ¸é µË´Ï´Ù. À̶§ ¾ÆÁ÷ USB to Serial USB µå¶óÀ̹ö¸¦ ¼³Ä¡ÇÏÁö ¾Ê¾Ò´Ù¸é ÀÌÀü °­Á¿¡¼­ ¼³¸íÇÑ "PL2303 USB to Serial µå¶óÀ̹ö ¼³Ä¡" ºÎºÐÀ» ÂüÁ¶ ÇϽñ⠹ٶø´Ï´Ù.

(2) Peripheral Bus

Cortex-M3

APB2 ¹ö½º¿¡ ¿¬°áµÇ¾î ÀÖ´Â USART1°ú GPA9, 10 ¹ø Æ÷Æ®µµ »ç¿ëµÇ°í Àֱ⠶§¹®¿¡ 2°³ÀÇ Peripheral Clock À» ¸ðµÎ EnableÇØ ÁÖ¾î¾ß ÇÕ´Ï´Ù.

(3) UART1 »ç¿ëÀ» À§ÇÑ GPIO Æ÷Æ® ÃʱâÈ­

Cortex-M3
(4) ÇÁ·ÎÁ§Æ®¿Í stm32f10x_conf.h ÆÄÀÏ ¼öÁ¤

Cortex-M3

(5) USART Status register

Cortex-M3

* ¿¹Á¦ Àüü ÄÚµå


void usart1_test_polling(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    char receive_data;

    // APB2 Clock enable for USART(GPIOA9, A10)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    /* USART1 clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);


    /* Configure the GPIO ports( USART1 Transmit and Receive Lines) */
    /* Configure the USART1_Tx as Alternate function Push-Pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Configure the USART1_Rx as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

   
    /* Configure the USART1 */
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);


    /* Enable the USART1 */
    USART_Cmd(USART1, ENABLE);

    while(1)
    {
        // Rx not empty °¡ µÉ¶§±îÁö Polling
        while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET );
        // Rx not empty°¡ µÇ¸é USART Data register ¿¡¼­ data¸¦ Àоî¿È
        receive_data = USART_ReceiveData(USART1) & 0xFF;

        // Tx data Àü¼Û
        USART_SendData(USART1, receive_data);
        // Tx empty°¡ »óÅ°¡ µÉ¶§±îÁö Polling
        // Tx Àü¼Û½Ã ÀÌ Äڵ带 »ý·«ÇÏ¸é ºü¸¥ Data Àü¼Û½Ã Áß°£¿¡ Tx Data °¡ À¯½ÇµÉ¼ö ÀÖÀ½
        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET );

        if( receive_data == 'x' )
            break;
    }
}




4.10 USART - Interrupt
UART1¸¦ PC¿Í 115200bps Baudrate·Î Åë½Å(RX, TX)À» ÇÏ´Â Echo server·Î ¸¸µé¾î º¾½Ã´Ù.  TX ´Â Æú¸µ ¹æ½ÄÀ¸·Î ó¸® ÇÏ°í RX´Â Interrupt ¹æ½ÄÀ¸·Î  ó¸® ÇÕ´Ï´Ù.


(1) USART1 Control Register

Cortex-M3

* ¿¹Á¦ Àüü ÄÚµå


void USART1_IRQHandler(void)
{
    char receive_data;

    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        receive_data = USART_ReceiveData(USART1) & 0xFF;

        USART_SendData(USART1, receive_data);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET );

        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    }
}

void usart1_test_interrupt(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;


    // APB2 Clock enable for USART(GPIOA9, A10)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    /* USART1 clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

    /* Enable the USART1 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);


    /* Configure the GPIO ports( USART1 Transmit and Receive Lines) */
    /* Configure the USART1_Tx as Alternate function Push-Pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Configure the USART1_Rx as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);


    /* Configure the USART1 */
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);

    // Rx Not empty interrupt enable
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

   
    /* Enable the USART1 */
    USART_Cmd(USART1, ENABLE);
}




4.11 USART - Name Card
PCÀÇ Å͹̳ο¡ ´ÙÀ½°ú °°ÀÌ ¸íÇÔÀ» Ãâ·ÂÇØ º¸¼¼¿ä.

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

  * Name : Kyung Yeon Kim                               *

  * Company : JK Electronics                             *

  * No : 010-XXXX-XXXX                                  *

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

 

Âü°í1) Å͹̳ÎÀÇ Çà °³Çà ¹®ÀÚ´Â “\r\n”

Âü°í2) Å͹̳Π¹®ÀÚ¿­ Ãâ·ÂÀ» Çϴµ¥ ¹®ÀÚ¿­ Ãâ·Â ÇÔ¼ö¸¦ ¸¸µé ¾î »ç¿ëÇϼ¼¿ä.

         void usart1_send_string(char *data);

Âü°í3) usart1 Ãʱâ(Æú¸µ¹æ½Ä)È­ ÇÔ¼ö¸¦ ÀÛ¼ºÇϼ¼¿ä.

         void usart1_init(void);


* ¿¹Á¦ Àüü ÄÚµå


void usart1_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;


     // APB2 Clock enable for USART(GPIOA9, A10)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    /* USART1 clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);


     /* Configure the GPIO ports( USART1 Transmit and Receive Lines) */
    /* Configure the USART1_Tx as Alternate function Push-Pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Configure the USART1_Rx as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);


     /* Configure the USART1 */
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);


     /* Enable the USART1 */
    USART_Cmd(USART1, ENABLE);
}

void usart1_send_string(char* data)
{
    while(*data != '\0')
    {
        USART_SendData(USART1, *(unsigned char *)data);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET );
        data++;
    }
}

void usart1_test_namecard(void)
{
    usart1_init();

    usart1_send_string("\r\n");
    usart1_send_string("****************************************\r\n");
    usart1_send_string("* Name : Kyung Yeon Kim *\r\n");
    usart1_send_string("* Company : JK Electronics *\r\n");
    usart1_send_string("* No : 010-XXXX-XXXX *\r\n");
    usart1_send_string("****************************************\r\n");
    usart1_send_string("\r\n");
}


4.12 Interrupt Priority1
BTN3¸¦ ´©¸£¸é LED3 ¸¦ ¹«ÇÑ ¹Ýº¹À» Çϸ鼭 On À» ½ÃÅ°°í BTN4¸¦ ´©¸£¸é LED4 ¸¦ ¹«ÇÑ ¹Ýº¹À» Çϸ鼭 On À» ½ÃŲ´Ù.

(1) Group, Sub Priority bit ¸¦ °¢°¢ 2Bit¾¿ ¼³Á¤

(2) BTN3ÀÇ Group Priority¸¦ 2, Sub Priority¸¦ 0·Î ¼³Á¤

(3) BTN4ÀÇ Group Priority¸¦ 1, Sub Priority¸¦ 0·Î ¼³Á¤ ÈÄ Å×½ºÆ®


* ¿¹Á¦ Àüü ÄÚµå


void EXTI2_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line2) != RESET)
    {
        EXTI_ClearITPendingBit(EXTI_Line2);


         while(1)
        {
            GPIO_SetBits(GPIOE, GPIO_Pin_3); // LED3 On
        }
    }
}

 

void EXTI3_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line3) != RESET)
    {
        EXTI_ClearITPendingBit(EXTI_Line3);


         while(1)
        {
            GPIO_SetBits(GPIOE, GPIO_Pin_4); // LED4 On
        }
    }
}

void interrupt_priority1_test(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    gpio_init_led();
    gpio_init_key();

    /* Connect EXTI */
    // External Interrupt configuration register1 (AFIO_EXTICR1)
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource3);

    /* Configure EXTI2 to generate an interrupt on falling edge */
    EXTI_InitStructure.EXTI_Line = EXTI_Line2;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    /* Configure EXTI3 to generate an interrupt on falling edge */
    EXTI_InitStructure.EXTI_Line = EXTI_Line3;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    // 2 bit for pre-emption priority, 2 bits for subpriority
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);


    /* Clear EXTI Line Pending Bit */
    // STM32F10x Pending Register : 0x40010400 + 0x14
    EXTI_ClearITPendingBit(EXTI_Line2);
    EXTI_ClearITPendingBit(EXTI_Line3);

    /* Enable the Key EXTI line Interrupt */
    // Cortex-M3 Interrupt Clear-Pending Register : 0xE000E280-0xE000E29C
    NVIC_ClearPendingIRQ(EXTI2_IRQn);
    NVIC_ClearPendingIRQ(EXTI3_IRQn);
}



¿¹Á¦ÀÇ ½ÇÇà°á°ú¸¦ ¾Ë¼ö ÀÖ°ÔÁÒ. BTN3ÀÇ Group Priority¸¦ 2·Î BTN4º¸´Ù ³ô±â ¶§¹®¿¡ BTN3À» ¸ÕÀú ´©¸£¸é BTN4ÀÇ ÀÎÅÍ·´Æ®°¡ ½ÇÇàµÇÁö ¸øÇÕ´Ï´Ù. ¹Ý´ë·Î BTN4ÀÇ ÀÎÅÍ·´Æ® ½ÇÇàÁß¿¡ BTN3À» ´©¸£¸é Áï½Ã BTN3ÀÇ ÀÎÅÍ·´Æ® ¼­ºñ½º ·çƾÀÌ ½ÇÇà µË´Ï´Ù.

4.13 Interrupt Priority2
BTN3¸¦ ´©¸£¸é LED3 ¸¦ ¹«ÇÑ ¹Ýº¹À» Çϸ鼭 On À» ½ÃÅ°°í  BTN4¸¦ ´©¸£¸é LED4 ¸¦ ¹«ÇÑ ¹Ýº¹À» Çϸ鼭 On À» ½ÃŲ´Ù.

(1) Group, Sub Priority bit ¸¦ °¢°¢ 2Bit¾¿ ¼³Á¤

(2) BTN3ÀÇ Group Priority¸¦ 2, Sub Priority¸¦ 0·Î ¼³Á¤

(3) BTN4ÀÇ Group Priority¸¦ 2, Sub Priority¸¦ 1·Î ¼³Á¤ ÈÄ Å×½ºÆ®


* ¿¹Á¦ Àüü ÄÚµå


void EXTI2_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line2) != RESET)
    {
        EXTI_ClearITPendingBit(EXTI_Line2);


         while(1)
        {
            GPIO_SetBits(GPIOE, GPIO_Pin_3); // LED3 On
        }
    }
}

 

void EXTI3_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line3) != RESET)
    {
        EXTI_ClearITPendingBit(EXTI_Line3);


         while(1)
        {
            GPIO_SetBits(GPIOE, GPIO_Pin_4); // LED4 On
        }
    }
}

void interrupt_priority1_test(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    gpio_init_led();
    gpio_init_key();

    /* Connect EXTI */
    // External Interrupt configuration register1 (AFIO_EXTICR1)
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource3);

    /* Configure EXTI2 to generate an interrupt on falling edge */
    EXTI_InitStructure.EXTI_Line = EXTI_Line2;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    /* Configure EXTI3 to generate an interrupt on falling edge */
    EXTI_InitStructure.EXTI_Line = EXTI_Line3;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    // 2 bit for pre-emption priority, 2 bits for subpriority
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);


    /* Clear EXTI Line Pending Bit */
    // STM32F10x Pending Register : 0x40010400 + 0x14
    EXTI_ClearITPendingBit(EXTI_Line2);
    EXTI_ClearITPendingBit(EXTI_Line3);

    /* Enable the Key EXTI line Interrupt */
    // Cortex-M3 Interrupt Clear-Pending Register : 0xE000E280-0xE000E29C
    NVIC_ClearPendingIRQ(EXTI2_IRQn);
    NVIC_ClearPendingIRQ(EXTI3_IRQn);
}



À̹ø ¿¹Á¦¿¡¼­´Â BTN3°ú 4ÀÇ Group¿ì¼±¼øÀ§°¡ °°±â ¶§¹®¿¡ ¼­·Î ÀÎÅÍ·´Æ® ¼öÇàÁß¿¡´Â ¼±Á¡À» ÇÏÁö ¸øÇÕ´Ï´Ù.

4.14 Power Management - Sleep
Cortex-M3 ¿¡¼­ Power Management ±â´ÉÀº NVIC¿¡ Æ÷ÇԵǾî ÀÖ½À´Ï´Ù.

Cortex-M3

(1) Sleep ¸ðµå Å×½ºÆ®

Å͹̳Πâ¿¡ ¾Æ·¡¿Í °°ÀÌ Ç¥½Ã µÇµµ·Ï ÇÕ´Ï´Ù.

    Entered Sleep mode.

    __WFI();  // Sleep mode ·Î ÁøÀÔ

    Exit Sleep mode.


(2) BTN2 ¸¦ ÀÎÅÍ·´Æ® ¸ðµå·Î ÀÔ·Â ¹Þ¾Æ¼­ Sleep ¸ðµå¸¦ ºüÁ® ³ª¿Àµµ·Ï ÇÕ´Ï´Ù. Ãß°¡·Î BTN2¸¦ ´©¸£¸é LED2¸¦ On ½ÃÅ°°í BTN2¸¦ ¶¼¸é LED2¸¦ Off ÇÕ´Ï´Ù.
(3) STM32F Low Power Mode


Cortex-M3

STM32 ¿¡¼­ Sleep ¸ðµå·Î ÁøÀÔÇϱâ À§Çؼ­´Â WFI(Wait for Interrupt) or WFE(Wait for Event) ¾î¼Àºí¸®¾î¿¡ ÀÇÇؼ­ ÁøÀÔÇÒ ¼ö ÀÖ½À´Ï´Ù. À̹ø ¿¹Á¦¿¡¼­´Â WFI ¸¦ ÀÌ¿ëÇؼ­ Sleep ¸ðµå·Î ÁøÀÔ Çϵµ·Ï ÇÏ°Ú½À´Ï´Ù. WFI¿¡ ÀÇÇؼ­ ÁøÀÔÇÑ Sleep ¸ðµå¿¡¼­ ±ú¾î³ª±â À§Çؼ­´Â ¾î¶°ÇÑ ÀÎÅÍ·´Æ® ¹ß»ý¿¡ ÀÇÇؼ­¶óµµ ±ú¾î ³¯¼ö ÀÖ½À´Ï´Ù.

* ¿¹Á¦ Àüü ÄÚµå


void power_management_sleep_test(void)
{

    key_input_test_interrupt();

    usart1_send_string("\r\nEnter Sleep mode.\r\n");

    __WFI();

    usart1_send_string("\r\nExit Sleep mode.\r\n");

}


Sleep ¸ðµåÀÇ ÀåÁ¡Àº Cortex-M3 CoreÀÇ Clock¸¸ ¸ØÃß¾î ÀÖ´Â »óÅ¿©¼­ ÀÎÅÍ·´Æ®¿¡ ÀÇÇؼ­ Áï½Ã ±ú¾î³¯¼ö°¡ À־ Sleep ¸ðµå¿¡ ÁøÀÔÇØ ÀÖ´ÂÁö Á¶Â÷ ¾Ë¼ö°¡ ¾ø´Ù´Â °ÍÀÌ°í ´ÜÁ¡Àº Stop, StandBy ¸ðµå¿¡ ºñÇؼ­ ¼Ò¸ðÀü·ù°¡ ¸¹´Ù´Â °ÍÀÔ´Ï´Ù.

Cortex-M3

Sleep ¸ðµåº° Wakeup ¹æ½Ä°ú Clock Management ¹æ¹ýÀÔ´Ï´Ù.

4.15 Power Management - Stop
Stop, StnadBy ¸ðµå´Â ¸ðµÎ Cortex-M3 Deep sleep ¸ðµå¿¡ ÇØ´ç ÇÕ´Ï´Ù.

(1) Stop ¸ðµå ½ÇÇè
¡à Timer2 ÀÎÅÍ·´Æ®¸¦ 1ÃÊ °£°ÝÀ¸·Î ¹ß»ý ½ÃÄÑ LED2, LED3 ¸¦ Toggle

¡à PWR_EnterSTOPMode() ÇÔ¼ö¸¦ È£ÃâÇÏ¿© Stop ¸ðµå·Î ÁøÀÔ ÇÕ´Ï´Ù.

¡à BTN2 ¸¦ ÀÎÅÍ·´Æ® ¸ðµå·Î ÀÔ·Â ¹Þ¾Æ¼­ Stop ¸ðµå¸¦ ºüÁ® ³ª¿Àµµ·Ï ÇÕ´Ï´Ù. Ãß°¡·Î BTN2¸¦ ´©¸£¸é LED2¸¦ On ½ÃÅ°°í BTN2¸¦ ¶¼¸é LED2¸¦ Off ÇÕ´Ï´Ù.

¡à STOP ¸ðµå¸¦ ºüÁ®³ª¿Â ÀÌÈÄ¿¡ LED2, LED3ÀÌ 1ÃÊ °£°ÝÀ¸·Î Toggle

¡à PWR_EnterSTOPMode¸¦ È£ÃâÇϸé ÁøÀÔ

   ¡à SRAM, Register »óÅ´ À¯Áö

   ¡à 1.8V Domain¿¡ ÀÖ´Â ¸ðµç Ŭ·°ÀÌ Stop

   ¡à PLL, HIS RC, HSE crystal oscillator ¸ðµÎ disable

   ¡à Voltage regulator´Â normal or low power mode

¡à Wakeup

   ¡à EXTI line ÁßÀÇ Çϳª¸¦ ¹Þ¾Æ¾ß ÇÔ

   ¡à 16°³ÀÇ EXTI line or PVD ouput, RTC alarm, USB wakeup

 


(2) Peripheral Bus - PWR

Cortex-M3

STM32F ÀÇ Power ºí·°Àº APB1 ¹ö½º¿¡ ¿¬°áµÇ¾î ÀÖ½À´Ï´Ù.

(3) ÇÁ·ÎÁ§Æ®¿Í stm32f10x_conf.h ÆÄÀÏ ¼öÁ¤

Cortex-M3

(4) STM32 PWR ºí·°µµ

Cortex-M3

(5) Cortex-M3 System Control Register

Cortex-M3

Stop ¸ðµå·Î ÁøÀÔ ½ÃÅ°±â À§Çؼ­´Â 2¹ø ºñÆ®ÀÇ SLEEPDEEP À» Set ÇØ¾ß ÇÕ´Ï´Ù.



Cortex-M3

(6) STM32 Power Control Register

Cortex-M3

PDDS¸¦ 0À¸·Î, LPDS¸¦ 0À¸·Î ÇÒ¼öµµ ÀÖ°í, 1·Î ÇÒ¼öµµ ÀÖÀ¸³ª À̹ø ¿¹Á¦¿¡¼­´Â 1·Î ¼³Á¤ÇÏ¿© Vdd Domain¿¡ ÀÖ´Â Voltage Regulator¸¦ low-power ¸ðµå·Î ¼³Á¤ ÇÕ´Ï´Ù.

* ¿¹Á¦ Àüü ÄÚµå


// STOP ¸ðµå¿¡ ÁøÀÔÇϸé HSE Clock µîÀÌ Disale µÇ±â ¶§¹®¿¡ Wakeup½Ã¿¡ ´Ù½Ã ¼³Á¤À» ÇØÁÖ¾î¾ß ÇÕ´Ï´Ù.
void system_clock_config_stop(void)
{
    RCC_HSEConfig(RCC_HSE_ON); // Enable HSE

    if( RCC_WaitForHSEStartUp() == SUCCESS)
    {
        RCC_PLLCmd(ENABLE); // Enable PLL

        // Wait until PLL is ready
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {}

        // Select PLL as system clock source
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

        // wait until PLL is used as system clock source
        while(RCC_GetSYSCLKSource() != 0x08) {}
    }
}

void power_management_stop_test(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

    timer2_test();
    key_input_test_interrupt();

    usart1_send_string("\r\nEnter Stop mode.\r\n");

    // STOP ¸ðµå·Î ÁøÀÔÇÏ°í ¿ÜºÎ ÀÎÅÍ·´Æ®¿¡ ÀÇÇؼ­ ±ú¾î³²
    PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);

    system_clock_config_stop();

    usart1_send_string("\r\nExit Stop mode.\r\n");
}




4.16 Power Management - StandBy
(1) PWR_WakeUpPinCmd(ENABLE) ¸¦ È£Ãâ, PA0¸¦ Wakeup ÇÉÀ¸·Î ¼³Á¤

(2) BTN2 ¸¦ ÀÎÅÍ·´Æ® ¸ðµå·Î ÀÔ·Â ¹Þ¾Æ¼­ Stop ¸ðµå¸¦ ºüÁ®³ª¿Àµµ·Ï ¼³Á¤

(3) PWR_EnterSTANDBYMode()¸¦ È£Ãâ, StandBy ¸ðµå·Î ÁøÀÔ

StandBy ¸ðµå·Î ÁøÀÔÇÏ´Â ¹æ¹ýÀº STOP¸ðµå·Î ÁøÀÔÇÏ´Â ¹æ¹ý¿¡¼­ STM32ÀÇ PWR_CR ·¹Áö½ºÅÍÀÇ PDDS ¸¦ 1·Î ¼³Á¤Çϴ°ÍÀ» Á¦¿ÜÇÏ¸é µ¿ÀÏ ÇÕ´Ï´Ù. ´ÜÁö StandBy ¸ðµå¿¡¼­´Â Wakeup ÇÏ´Â ¹æ¹ý¿¡¼­ Â÷±â°¡ ÀÖÀ¸¸é StandBy ¸ðµå¿¡¼­ WakeupÀ» ÇÑ´Ù´Â °ÍÀº CPU°¡ óÀ½ºÎÅÍ ´Ù½Ã ºÎÆÃÇÏ´Â ÀýÂ÷¿Í µ¿ÀÏ ÇÕ´Ï´Ù. ÇÏÁö¸¸ StandBy ¸ðµå¿¡¼­ WakeupÀÌ µÇ´Â °æ¿ì¿¡´Â PWR_CSR ·¹Áö½ºÅÍÀÇ Standby Flag°¡ H/W ÀûÀ¸·Î SetÀÌ µÇ¾î ÀÖ½À´Ï´Ù.

(4) Power Control Register


Cortex-M3

(5) System Control Register

Cortex-M3


Cortex-M3

(6) Enable Wakeup PIN

Cortex-M3

StandBy ¸ðµå¿¡¼­ ±ú¾î³ª±â À§Çؼ­ Wakeup ÇÉÀ» Enable ÇÕ´Ï´Ù. ¹Ýµå½Ã PA0 ÇÉÀÌ ÀÌ¿ë µË´Ï´Ù.


(7) Power control/status register

Cortex-M3

* ¿¹Á¦ Àüü ÄÚµå


void power_management_standby_test(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

    // Enable Wakeup Pin(should be PA0)
    PWR_WakeUpPinCmd(ENABLE);

    usart1_send_string("\r\nWakeup pin enabled.\r\n");

     usart1_send_string("Enter Standby mode.\r\n");

    // Standby Mode
    PWR_EnterSTANDBYMode();

    // ÀÌ ÄÚµå´Â ½ÇÇàµÉ¼ö ¾øÀ½
    usart1_send_string("\r\nExit Standby mode.\r\n");
}




4.17 Mode Privilege
(1) Reset ÀÌÈÄÀÇ Mode(Privilege or Unprivilege)¿Í ¾î¶² StackÀ»  (Main Stack, Process Stack) »ç¿ëÇÏ´ÂÁö¸¦ PCÀÇ Å͹̳ο¡ Ç¥½Ã¸¦ ÇÕ´Ï´Ù.

(2) Mode¸¦ Unprivilege ¸ðµå·Î Àüȯ ÇÕ´Ï´Ù.

(3) ¸ðµç Àüȯ ÀÌÈÄ¿¡ Mode(Privilege or Unprivilege)¿Í ¾î¶² StackÀ» (Main Stack, Process Stack) »ç¿ëÇÏ´ÂÁö¸¦ PCÀÇ Å͹̳ο¡ Ç¥½Ã¸¦ ÇÕ´Ï´Ù.

(4) SVC ¸í·É¾î “__ASM("svc #1")” ¸¦ »ç¿ëÇؼ­ SVC_Handler ExceptionÀ» ¹ß»ý½ÃÅ°°í SVC_Handler Çڵ鷯 ÁøÀÔ ¿©ºÎ¸¦ Å͹̳ο¡ Ç¥½Ã ÇÕ´Ï´Ù.
(5) SVC Çڵ鷯³»¿¡¼­ Mode¸¦ Privilege ¸ðµå·Î Àüȯ ÇÕ´Ï´Ù.

(6) ¸ðµç Àüȯ ÀÌÈÄ¿¡ Mode(Privilege or Unprivilege)¿Í ¾î¶² StackÀ» (Main Stack, Process Stack) »ç¿ëÇÏ´ÂÁö¸¦ PCÀÇ Å͹̳ο¡ Ç¥½Ã¸¦ ÇÕ´Ï´Ù.


Cortex-M3

* ¿¹Á¦ Àüü ÄÚµå


void SVC_Handler(void)
{
    usart1_send_string("\r\nSVC_Handler\r\n");
    usart1_send_string("Mode change to privilege\r\n");
    __set_CONTROL(0x0);

}

void mode_privilege_test(void)
{
    usart1_send_string("\r\n\r\n---- mode privilege test start ----\r\n\r\n");

    // Mode
    if( (__get_CONTROL() & 0x1) == 0x1 )
        usart1_send_string("Mode = Unprivilege\r\n");
    else if( (__get_CONTROL() & 0x1) == 0x0 )
        usart1_send_string("Mode = Privilege Mode\r\n");

    // Stack
    if( (__get_CONTROL() & 0x2) == 0x0 )
        usart1_send_string("Stack = MSP Stack\r\n");
    else if( (__get_CONTROL() & 0x2) == 0x1 )
        usart1_send_string("Stack = PSP Stack\r\n");

    // mode change to unprivilege
    usart1_send_string("Mode change to unprivilege\r\n");
    __set_CONTROL(0x1);

    // Mode
    if( (__get_CONTROL() & 0x1) == 0x1 )
        usart1_send_string("Mode = Unprivilege\r\n");
    else if( (__get_CONTROL() & 0x1) == 0x0 )
        usart1_send_string("Mode = Privilege Mode\r\n");

    // Stack
    if( (__get_CONTROL() & 0x2) == 0x0 )
        usart1_send_string("Stack = MSP Stack\r\n");
    else if( (__get_CONTROL() & 0x2) == 0x1 )
        usart1_send_string("Stack = PSP Stack\r\n");

    __ASM("svc #1");


    // Mode
    if( (__get_CONTROL() & 0x1) == 0x1 )
        usart1_send_string("Mode = Unprivilege\r\n");
    else if( (__get_CONTROL() & 0x1) == 0x0 )
        usart1_send_string("Mode = Privilege Mode\r\n");

    // Stack
    if( (__get_CONTROL() & 0x2) == 0x0 )
        usart1_send_string("Stack = MSP Stack\r\n");
    else if( (__get_CONTROL() & 0x2) == 0x1 )
        usart1_send_string("Stack = PSP Stack\r\n");

    usart1_send_string("---- mode privilege test end ----\r\n\r\n");
}




¿©±â±îÁö ÀüÅëÀûÀÎ ARM ÇÁ·Î¼¼¼­ÀÎ ARM9ÀÇ ±¸Á¶¸¦ ½ÃÀÛÀ¸·Î ARM9 ApplicationÀ» °ÅÃÄ Cortex-M3 Architecture, Cortex-M3 ApplicationÀÇ ¸ðµç °úÁ¤ÀÌ ¸¶¹«¸® µÇ¾ú½À´Ï´Ù. ¸Ó¸®¼Ó¿¡ ÀÖ´Â ³»¿ëÀ» ±Û·Î ¿Å±ä´Ù´Â°ÍÀÌ ½±Áö´Â ¾Ê¾Ò´ø°Í °°½À´Ï´Ù. Cortex-M3 Application part¿¡¼­ ±âº»ÀûÀÎ ¿¹Á¦¸¸ ´Ù·é°ÍÀÌ ¾Æ½¬¿òÀÌ ³²³×¿ä. ±âȸ°¡ µÈ´Ù¸é STM32 Dragon °³¹ßº¸µå¿¡ ÀÖ´Â ¸ðµç µð¹ÙÀ̽ºµéÀ» Á¦¾îÇØ º¸´Â ¿¬À縦 ´Ù½Ã ½ÃÀÛÇØ º¼±î ÇÕ´Ï´Ù. ±×¸®°í °³¹ßȯ°æµµ GCC¿Í ÀÌŬ¸³½º ȯ°æÀ¸·Î ¹Ù²Ù¾î Á»´õ »çÀÌÁî°¡ Å©°í Àü¹®ÀûÀÎ S/W°³¹ß ¹æ¹ý¿¡ ´ëÇؼ­ °øºÎÇØ º¸µµ·Ï ÇÏ°Ú½À´Ï´Ù. ƯÈ÷ SD¸Þ¸ð¸®¿Í LCD¸¦ ÀÌ¿ëÇؼ­ ¿¹»Û GUI¸¦ ±¸¼ºÇÏ´Â ºÎºÐ¿¡ ´ëÇؼ­ ÁýÁßÀûÀ¸·Î Áغñ¸¦ Çغ¸µµ·Ï ÇÏ°Ú½À´Ï´Ù. ¼ö°íÇϼ̽À´Ï´Ù.