STM32 BARE-METAL CODING DIMMER WITH PWM
Before write the code, you should a glance stm32 user manual, core pin connection schematics, alternate function numbers timers and timers…
STM32 BARE-METAL CODING DIMMER WITH PWM
Before write the code, you should a glance stm32 user manual, core pin connection schematics, alternate function numbers timers and timers channel which you want to use.
I prefer m0+ and g031k8t6 nucleo board for this example.
First step determining timer and timers channel to use PWM( PULSE WIDTH MODULATION )

GPIO PORT B AND PIN0 is chosen, so there are two option that TIMER3 OR TIM1. I chose timer3 channel3. İt means we should configure GPIO PORTB PIN 0.
CONFIGURE MODER(MODE REGISTER), RCC( RESET AND CLOCK CONTROL) AND AFR(ALTERNATE FUNCTION REGISTER) . LETS CODİNG
RCC->IOPENR |= (1U << 1); // RCC REGISTER BIT1 ENABLE RCC->APBENR1 |= RCC_APBENR1_TIM3EN ; //SET TO BIT1 TO TIM ENABLE

RCC INPUT OUTPUT PORT CLOCK ENABLE “5–0 BITS”

ALTERNATE FUNCTION CLOCK ENABLE REGISTER
Clock configuration is done, then continue to configure GPIO registers
GPIOB->MODER &= ~(3U << 20 ); // RESET PIN0 GPIOB->MODER |= (2U << 20) ;// this register every pin represent two bits 20 what is it ? 2 coeffiecnt comes from that the every pin represents two bits to configure input-output or alternate func. 2U what is it ? ; “2" it comes form alternate function definition from user manual U is represent unsigned

MODE register (MODER)
then alternate function register must set depends on alternate function.

*GPIOB->AFR[0] |= (1U << 40 ); //port Bpin 0 alternate func 1 every pin represent 4 bits in this register to configure tım3_ch3 is AF1 it shown stm32 documents, schematics. If pins between 8 and 15 would used you must configure AFR[1] register.**
1U comes from alternate function 1, if it was another alternate function for example it was alternate function 3, the value must 3U .

ALTERNATE FUNCTION REGISTER PINS CONFIGURATION
TIM3->PSC = 15 ; //PRESCALER REGISTER, IT DEVIDE TIMER CLOCK TIM3->ARR = 2000 ; // AUTORELOAD REGISTER, TIMER UP-DOWN COUNT TO VALUE FROM ZERO TIM3->CNT = 0 ; // CNT is keep the current ınstant value
PSC ARR and CCR registers are related to frequency and period of PWM.ARR value should equal tımer bus clock / PSC +1, CCRx value determine out duty, it means depend on mode1–2 the pin high the timer count up-down to the ARR value. for mode 1 if the CNT register smaller CCRx register the pin is HİGH , when hit the CNT value CCRx value the pin is setted LOW, that is the PWM thing :).. We may set the voltage via CRRx value.
// reset duty cycle on channel 3 TIM3->CCR3 = 0 ; // CCRx, X is 3 here because the channel3 using this example. if ccr3 equals 2000 pin voltage eqauls 3volt, if the ccr3 value equals 1500 pin out 1.5 Volts so we may set the votlage this values.
TIM3->CCMR2 |= 0x68U; // USE ccmr2 cause TIM3 is used. tım1–2 bit3 enable for preload , ARR value and bits6–4 enable to compare mod enable 0x68 equals 0110_1000 they set the modes

this register two mode input capture mode and output compare mode.
// enable capture/compare ch3 enable reg TIM3->CCER |= ( 0x100U );


// enable update interrupt TIM3->DIER |= (1 << 0) ; NVIC_SetPriority(TIM3_IRQn, 1) ; // enable TIM3 IRQ from NVIC NVIC_EnableIRQ(TIM3_IRQn) ; // Enable Timer 3 module (CEN, bit0) TIM3->CR1 |= 1U ; void TIM3_IRQHandler(void) { // clear interrupt status if (TIM3->DIER & 0x01) { if (TIM3->SR & 0x01) { TIM3->SR &= ~(1U << 0); //interrupt clear } } TIM3->CCR3 = X; if (!state) X+=1; else X-=1; if (X > 1900){ state = 1; TIM3->CNT = 0; } if( X < 30) { state=0; TIM3->CNT = 0; } }
this is my repo, you would like to try, you may download and run.
gtu, #mehmetkose
메타데이터
- post_id
- c26901a2f601
- slug
- stm32-bare-metal-codi̇ng-di̇mmer-wi̇th-pwm-c26901a2f601
- url
- https://medium.com/@neosapienss/stm32-bare-metal-codi%CC%87ng-di%CC%87mmer-wi%CC%87th-pwm-c26901a2f601
- canonical_url
- https://medium.com/@neosapienss/stm32-bare-metal-codi%CC%87ng-di%CC%87mmer-wi%CC%87th-pwm-c26901a2f601
- author_url
- https://medium.com/@neosapienss
- status
- ok
- fetched_at
- 2026-07-27 00:46:47