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();
}
'Cortex-M' 카테고리의 다른 글
| TIM9 구조와 활용, 익셉션(인터럽트)활용, PWM 파형 출력 (로직 애널라이저) (0) | 2025.05.25 |
|---|---|
| TIM6 타이머 -polling, 익셉션 핸들러(인터럽트) 이용 | STMF429ZI (0) | 2025.05.25 |
| IWDG Independent watch dog | 레지스터 제어로 코드 구현(STM32F429ZI) (0) | 2025.05.23 |
| button Key 인터럽트로 LED 토글하기(레지스터제어) | STM32cubeIDE(32F429ZI) (0) | 2025.05.23 |
| UART 시리얼 통신, 로직 애널라이저 파형 출력, 레지스터 제어 구현하기 | STM32F429ZI (2) | 2025.05.23 |