System timer


register + ALU +Control unit => CPU
CPU 참고 -> ARMxx.pdf

CPU + 성능을 위한 장치(cache,MPU,FPU,systick..)=>ARM processor(Cortex M4)
Programming manual, TRM.pdf 참고

ARM processor + perpherial,I/O(GPIO,UART,TIMER,SPI,..)=>MCU(SoC) stm32f429××
UM,Reference.pdf 참고

stm32f429xx + 입출력장치. LED,key,gps+MEM => Nucleo 실습 보드

SysTick에 대한 설명은 programming manual.pdf를 참고해야한다.

 

ARM core 주변 장치 중 하나이다.
AHB와 연결된 클럭을 이용하며, ARM processor 에 내장된 24비트 다운카운터로, 주로 주기적인 인터럽트를 발생시켜 타이머 기반 작업을 처리하는 데 사용한다. 

1. 레지스터 제어로 500ms마다 polling으로 '.'출력하기

2. 500ms마다 익셉션 인터럽트로 출력하기

 

SysTick timer 레지스터

1. SysTick control and status register(STK_CTRL)

  • COUNTFLAG : 타이머가 0까지 카운트되면 1을 반환
  • CLKSOURCE : 클럭 소스 선택 비트
  • 0 → AHB/8 1 → AHB
  • TICKINT : SysTick 익셉션 요청 발생 여부
  • 0 → 익셉션 요청 X 1 → 0까지 카운트 되었을 때 예외 요청 발생
  • ENABLE : 카운터 동작 제어 비트
  • 0 → 카운터 비활성화 1 → 카운터 활성화 활성화 시, LOAD 레지스터의 값을 로드하고 카운트가 0이 되면 COUNTFLAG=1 설정 및 선택에 따라 예외 요청 발생

 

2. SysTick reload value register(STK_LOAD)


카운팅 값(reload 값)을 설정한다.

  • 카운터가 활성화될 때와 카운터가 0에 도달했을 때 STK_VAL 에 로드될 시작값을 지정해줌
  • 주기가 N 프로세서 클럭 사이클인 주기적 인터럽트를 만들려면 → RELOAD = N - 1
  • N 프로세서 클럭 사이클 뒤에 한 번만 인터럽트를 발생시키려면 RELOAD = N

3. SysTick current value register(STK_VAL)


SysTick 카운터의 현재 값을 담고 있음

이 레지스터에 어떤 값을 쓰더라도 필드는 0으로 클리어되고, 동시에 STK_CTRL의 COUNTFLAG 비트도 0으로 리셋된다.

 

Polling (500ms마다 . 찍기)

void uart3_init(void){
//1.clock 활성화
    RCC->AHB1ENR |= 1<<3;//GPIOD
    RCC->APB1ENR |= 1<<18;//USART3

//2.PD8,9핀 Alternative Function으로 설정
    GPIOD->MODER &= ~((0x3<< (2*8))| (0x3<<(2*9)));
    GPIOD->MODER |=((0x2<<(2*8)) | (0x2<<(2*9)));

//3.MUX AFR uart tx,rx핀으로 설정.
    GPIOD->AFR[1]&= ~(0xf<<4 | 0xf<<0);//MUX PD8,9(AFRH 8~15)
    GPIOD->AFR[1] |= (0x7<<4 | 0x7<<0);//uart3(AF7)

//4.uart 레지스터 설정
    //oversampling by 16(15bit),UE,wordlength8bit+stop1bit(12bit),parityX(10bit),TE,RE
    USART3->CR1 =(0<<15 |1<<13 | 0<<12 |0<<10 | 1<<3 | 1<<2);
    //USART3->CR2 &=~(0x3<<12);//1 stopbit, reset value 0이라서 필수X
    USART3->BRR=(22 << 4) | 13;//115200bps,42MHZ =356

}

void uart3_send(char c){
    while(!(USART3->SR>>7 &0x1));
    USART3->DR=c;
}
void uart3_printf(const char* str){
    while(*str){
        uart3_send(*str++);
    }
}

int main(void)
{
  HAL_Init();
  uart3_init();
  SystemClock_Config();

int msec=500, hclk=168000000;
SysTick->CTRL=(0<<2 | 0<<1 |0<<0);//reset
SysTick->LOAD=(int)((hclk/(8.0*1000)*msec)+0.5); //msec 1000은 0xFFFFFF 초과해 오버플로우

SysTick->CTRL|=1<<0; //count start

  while (1)
  {
      if((SysTick->CTRL >>16) &0x1){//카운트 0될때마다 Flag 1
          uart3_printf(".");
      }
  }
}

 

Exception으로 500ms마다 출력하기

//exception 두 번할 때 polling 한번 출력:@@. @@. @@. @@. @@. 
//(polling :"."출력,exception :"@"출력(systick타이머500ms)))
void uart3_init(void){
    //1.clock 활성화
    RCC->AHB1ENR |= 1<<3;//GPIOD
    RCC->APB1ENR |= 1<<18;//USART3

//2.PD8,9핀 Alternative Function으로 설정
    GPIOD->MODER &= ~((0x3<< (2*8))| (0x3<<(2*9)));
    GPIOD->MODER |=((0x2<<(2*8)) | (0x2<<(2*9)));

//3.MUX AFR uart tx,rx핀으로 설정.
    GPIOD->AFR[1]&= ~(0xf<<4 | 0xf<<0);//MUX PD8,9(AFRH 8~15)
    GPIOD->AFR[1] |= (0x7<<4 | 0x7<<0);//uart3(AF7)

//4.uart 레지스터 설정
    //oversampling by 16(15bit),UE,wordlength(12bit),parityX(10bit),TE,RE
    USART3->CR1 =(0<<15 |1<<13 | 0<<12 |0<<10 | 1<<3 | 1<<2);
    USART3->CR2 &=~(0x3<<12);//1 stopbit, reset value 0이라서 필수는 X
    USART3->BRR=(22 << 4) | 13;//115200bps,42MHZ =356
}

void uart3_send(char c){
    while(!(USART3->SR>>7 &0x1));
    USART3->DR=c;
}
void uart3_printf(const char* str){
    while(*str){
        uart3_send(*str++);
    }
}

extern volatile uint32_t sys_tick;

int main(void)
{
  HAL_Init();
  uart3_init();
  int poll_tick=0;

  SystemClock_Config();

int msec=500, hclk=168000000;
SysTick->CTRL=(0<<2 | 1<<1 |0<<0);//Exception 발생
SysTick->LOAD=(int)((hclk/(8.0*1000)*msec)+0.5);
SysTick->CTRL|=1<<0;//counter start

  while (1)
  {
      if(((sys_tick-poll_tick)>=2)&&((SysTick->CTRL >>16)&0x1)){//check count flag
          uart3_printf(".");
          poll_tick=sys_tick;

      }

  }

}

<stm32f4xx_it.c 파일>에 핸들러함수가 생성되어서 여기에 두고 사용했는데, 핸들러 함수를 main.c로 이동함. stm32f4xx_it.c에 두고 extern선언해 사용해도 된다

_____________________________________________________
//stm32f4xx_it.c

volatile uint32_t sys_tick=0;

void SysTick_Handler(void)
{

    uart3_printf("@");
    ++(sys_tick);

  HAL_IncTick();

}

+ Recent posts