I am trying to send PWM signals using STM32F100RBTx but it is not working. I double checked all the addresses but it is still the same. I wasn't sure if I was flashing at the beginning but I configured the PB7 pin to be GPIO output and connected to a LED and the LED is working so I can flash it and my GPIO conifgurations must be working. Here is the code, I don't know what to try:
TUFAN_VLDCMS_Global.h:
#include <stdint.h>
#define RCC 0x40021000
#define RCC_AHBENR 0x40021014
#define RCC_APB2ENR 0x40021018
#define RCC_APB1ENR 0x4002101C
#define AFIO 0x40010000
#define AFIO_MAPR 0x40010004
#define GPIOB 0x40010C00
#define GPIOB_ODR 0x40010C0C
#define TIM4 0x40000800
#define TIM4_CR1 0x40000800
#define TIM4_CR2 0x40000804
#define TIM4_SMCR 0x40000808
#define TIM4_DIER 0x4000080C
#define TIM4_SR 0x40000810
#define TIM4_EGR 0x40000814
#define TIM4_CCMR1 0x40000818
#define TIM4_CCMR2 0x4000081C
#define TIM4_CCER 0x40000820
#define TIM4_CNT 0x40000824
#define TIM4_PSC 0x40000828
#define TIM4_ARR 0x4000082C
#define TIM4_CCR1 0x40000834
#define TIM4_CCR2 0x40000838
#define TIM4_CCR3 0x4000083C
#define TIM4_CCR4 0x40000840
#define TIM4_DCR 0x40000848
#define TIM4_DMAR 0x4000084C
main.c:
#include <stdio.h>
#include <stdint.h>
#include "TUFAN_VLDCMS_Global.h"
int main(){
volatile uint32_t * tim4Cr1 = (volatile uint32_t *) TIM4_CR1;
volatile uint32_t * tim4Psc = (volatile uint32_t *) TIM4_PSC;
volatile uint32_t * tim4Arr = (volatile uint32_t *) TIM4_ARR;
volatile uint32_t * tim4Ccr1 = (volatile uint32_t *) TIM4_CCR1;
volatile uint32_t * tim4Ccmr1 = (volatile uint32_t *) TIM4_CCMR1;
volatile uint32_t * tim4Ccer = (volatile uint32_t *) TIM4_CCER;
volatile uint32_t * tim4Egr = (volatile uint32_t *) TIM4_EGR;
volatile uint32_t * rccApb1enr = (volatile uint32_t *) RCC_APB1ENR;
volatile uint32_t * rccApb2enr = (volatile uint32_t *) RCC_APB2ENR;
volatile uint32_t * gpiobCrL = (volatile uint32_t *) GPIOB;
volatile uint32_t * gpiobOdr = (volatile uint32_t *) GPIOB_ODR;
volatile uint32_t * afioMapr = (volatile uint32_t *) AFIO_MAPR;
*rccApb1enr |= (1<<2); //enable TIM4 from APB1
*rccApb2enr |= (1<<0); //enable AFIO from APB2
*rccApb2enr |= (1<<3); //enable IOPB from APB2
*afioMapr &= ~(1<<12); //set alternate function remap to 0
*gpiobCrL |= (3<<24); //PB6 Output Mode 50Mhz
*gpiobCrL |= (2<<26); //PB6 Alternate function Push-Pull
*gpiobCrL |= (3<<28); //Configuring PB7 to for test to see if i can flash it
*gpiobCrL &= ~(3<<30);
*tim4Cr1 |= 0x0000; //reseting it just in case
*tim4Psc = 7; //calculated it thinking default clock speed is 8MHz
*tim4Arr = 62; //I want to have PWM signal around 16kHz
*tim4Ccr1 = 31; //and %50 duty cycle
*tim4Ccmr1 |= 0x68; //configuring channel 1
*tim4Ccer |= (1<<0); //enabling channel 1
*tim4Cr1 |= (1<<0); //enable the timer
*tim4Egr |= (1<<0);
while (1){
*tim4Ccr1 = 31;
*gpiobOdr |= (1<<7);
}
}
The problem with:
*gpiobCrL |= (3<<24); //PB6 Output Mode 50Mhz
*gpiobCrL |= (2<<26); //PB6 Alternate function Push-Pull
*gpiobCrL |= (3<<28);
*gpiobCrL &= ~(3<<30);
is that the reset state of GPIOx_CRL
is 0x44444444
and not zero:
(0x44444444 | (3<<24) | (2<<26) | (3<<28)) & ~(3<<30) == 0x3F444444
The part (2<<26)
does not clear bit 26 which is 1 in the reset state, so you end up with CNF6 == 3
. To set CNF6 == 2
you need:
*gpiobCrL &= ~(3<<26); // Clear CNF6 bits
*gpiobCrL |= (2<<26); // PB6 Alternate function Push-Pull
((0x44444444 & ~(3<<26)) | (3<<24) | (2<<26) | (3<<28)) & ~(3<<30) == 0x3B444444
^^^^^^^^^^