extern "C" {
#define RCC_BASE 0x40021000
#define GPIOA_BASE 0x50000000
#define TIM1_BASE 0x40012C00
#define RCC_IOPENR (*(volatile unsigned int *)(RCC_BASE + 0x34))
#define RCC_APBNR2 (*(volatile unsigned int *)(RCC_BASE + 0x40)) // for the timer pin
#define GPIOA_MODER (*(volatile unsigned int *)(GPIOA_BASE + 0x00)) // pinmode for general purpose pins
#define GPIOA_AFRH (*(volatile unsigned int *)(GPIOA_BASE + 0x24)) // pinmode for advanced pins
#define TIM1_CR1 (*(volatile unsigned int *)(TIM1_BASE + 0x00)) // enables the counter when switched on
#define TIM1_CCMR1 (*(volatile unsigned int *)(TIM1_BASE + 0x18)) // enables output + pwm mode
// also enables shadow mode
#define TIM1_CCER (*(volatile unsigned int *)(TIM1_BASE + 0x20)) // flips the gateway switch between the
// pwm modulation and the physical external pins
#define TIM1_PSC (*(volatile unsigned int *)(TIM1_BASE + 0x28)) // determines the frequency
#define TIM1_ARR (*(volatile unsigned int *)(TIM1_BASE + 0x2C)) // determines the counter's ceiling
#define TIM1_CCR1 (*(volatile unsigned int *)(TIM1_BASE + 0x34)) // stores the duty cycle
#define TIM1_BDTR1 (*(volatile unsigned int *)(TIM1_BASE + 0x44)) // master safety switch
void ms_delay(int count) {
while (count--) {
for (volatile int i = 0; i < 1500; i++) {
__asm("nop");
}
}
}
int main(void) {
RCC_IOPENR = (1 << 0); // flips the peripheral clock enable on
RCC_APBNR2 = (1 << 11); // do the same for the advanced clock
GPIOA_MODER &= ~(3 << (8 * 2)); // clear the pin mode pin
GPIOA_MODER |= (2 << (8 * 2));
// AFRH refers to four bits
GPIOA_AFRH &= ~(0xF << ((8 - 8) * 4)); // clear the bits
GPIOA_AFRH |= (2 << ((8 - 8) * 4)); // hooks the timer pin PA8 to the output of timer
TIM1_PSC = 12 - 1;
TIM1_ARR = 100 - 1;
TIM1_CCMR1 &= ~(7 << 4); // clear the first four bits to set the mode
TIM1_CCMR1 |= (6 << 4) | (1 << 3);
// output mode, pwm generation
TIM1_CCER |= (1 << 0); // flips the gateway switch between the pwm modulation and physical external pins
TIM1_BDTR1 |= (1 << 0);
TIM1_CR1 |= (1 << 0); // enable timer
while (1) {
for (int duty = 0; duty <= 99; duty++) {
TIM1_CCR1 = duty;
ms_delay(500);
}
}
}
}Loading
st-nucleo-c031c6
st-nucleo-c031c6