반응형
어느샌가 1us 마다 정확하게 delay 시키는 함수 및 방법이 궁금해서 아래와 같이 자료를 정리한다.
결과적으로 STM32F103에서 제공하는 timer interrupt event 처리로 1ms 마다 거의 정확하게 delay 함수를 사용할 수 있지만, 1us 마다 delay 함수 사용하는 것은 사용자 MCU 및 컴파일러 환경에 따라 달라지는 것을 확인할 수가 있다. 그럼에도 불구하고 거의 1us에 가깝게 GPIO toggling할 수 있는 방법을 찾고자 한다면 괜찮지 않을까?
구글링에서 검색되는 delay_us 함수 중에 가장 많이 검색되는 function structure는 아래와 같다.
void Delay_us(__IO u32 nCount)
{
for (; nCount != 0;nCount--);
}
void Delay_us(__IO uint32_t nCount)
{
if(nCount>1){
uint32_t count=nCount*8-6;
while(count--); //asm volatile("nop");
}
else{
uint32_t count=2;
while(count--); // asm volatile("nop");
}
}
실험을 해보니, 굳이 번거롭게 및 제법 있어보이게(?) 어셈블러 코드 같은거 갖다 쓰는데, 나와 같이 평범한 사람들은 그냥 아래와 같은 간단한 코드를 사용하면 된다.
#define NOP_1 asm volatile("NOP")
#define NOP_2 NOP_1; NOP_1
#define NOP_4 NOP_2; NOP_2
#define NOP_10 NOP_4; NOP_4; NOP_2
#define NOP_20 NOP_10; NOP_10
#define NOP_40 NOP_20; NOP_20
void delay_1us(bool state){ // High & LOW
if (state)
{
NOP_20;
}
else{
NOP_40;
}
}
void GPIO_Toggle(){
GPIO_ResetBits(GPIOC, GPIO_Pin_0);
delay_1us(LOW);
GPIO_SetBits(GPIOC, GPIO_Pin_0);
delay_1us(HIGH);
}
이클립스 개발 환경에서 default option으로 컴파일을 하고, delay_us(1)마다 GPIO toggling을 하면 아래와 같은 파형이 관찰된다. 아울러 High / Low level timing도 서로 다른 것도 확인할 수가 있다.
그래서 정확하게 delay_us(1) 마다 GPIO toggling을 하는 방법은 아래와 같이, 컴파일 옵션 중에 Optimization Level을 "Optimize size (-Os)"를 선택하고 컴파일을 하면 다음과 같은 파형(High 및 LOW)을 얻을 수가 있다.
반응형
'Engineer > 소프트웨어 정보' 카테고리의 다른 글
CRC example code [TE HTU21D datasheet] (0) | 2021.02.15 |
---|---|
[STM32] hardware SPI example code (0) | 2020.09.09 |
[STM32] Interrupt 사용하기 (0) | 2020.06.24 |
임의 길이의 숫자 데이터를 signed extend number로 표현 (0) | 2020.05.19 |
[STM32F103 Series] HSI clock 사용 (내부 8Mhz to 64Mhz) (0) | 2020.02.18 |