2013-02-06 02:09 AM
2013-02-06 02:59 AM
You overwrite previous value of TIM1->CCER (twice).
It might perhaps be a good idea to write to one register only once per function. [EDIT] You also don't set mode for channel 2. [/EDIT] JW2013-02-06 03:02 AM
I do not want to use ST Peripheral Library. I prefer bare metal because it enable me to understand the Hardware.
Awesome, so you're several days into a task that will take several weeks. Does this also preclude you from fashioning a working example with the library, and reviewing the source code for it, a task that might consume an hour or less.I desperately need help A good time then to reflect on your strategy, should I double down, or approach the problem from a different direction? Are you running the part at 56 MHz, in which case ARR = 2800 - 1, if 72 MHz ARR = 3600 - 1 would be the value for 20KHz2013-02-06 09:01 AM
Hello,
Thanks for the reply. I have it working now. I use a different approach as suggested..please find below the working code.Thanks alot #include ''stm32f10x.h'' void Init_6CHPWM(); int main(void) { volatile uint32_t dly; RCC-> CFGR |= RCC_CFGR_ADCPRE_DIV4; //ADC divided by 4 /*Enable all GPIO Clock & Alternate Function Clock*/ RCC->APB2ENR = RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN; /*Enable ADC1 & ADC2 Clock*/ RCC->APB2ENR |= RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN; /*Enable TIMER1 & USART1 Clock*/ RCC->APB2ENR |= RCC_APB2ENR_TIM1EN | RCC_APB2ENR_USART1EN; /*Enable TIMER2, TIMER3 & I2C1 Clock*/ RCC->APB1ENR = RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN |RCC_APB1ENR_I2C1EN | RCC_APB1ENR_TIM4EN; RCC->AHBENR = RCC_AHBENR_DMA1EN ; //DMA1 clock enable GPIOB->CRL = 0x444444AA; //Configure PB0 & PB1 as Alternate Function Push Pull Output GPIOB->CRH = 0x44444222; //Configure PB8 & PB9 as Output (Push Pull) GPIOA->CRL = 0xA4444444; //PA7 Alternate Function Push Pull Output GPIOA->CRH = 0x44444AAA; //PA8 - PA10 Alternate Function Push Pull Output /*Partial remap TIM1: CH1/PA8,CH2/PA9,CH3/PA10,CH4/PA11,CH1N/PA7,CH2N/PB0,CH3N/PB1 * Remap USART1: TX/PB6, RXPB7 */ AFIO->MAPR |= 0x00000044; Init_6CHPWM(); //Initialize 20KHz PWM on CH 1-3 while(1) { for(dly = 0; dly < 500000; dly++); GPIOB->BSRR = (1 << 8); GPIOB->BSRR = (1 << 9); for(dly = 0; dly < 500000; dly++); GPIOB->BRR = (1 << 8); GPIOB->BRR = (1 << 9); } } void Init_6CHPWM() { TIM1->CCMR1 |= 0x00006868; //CH1 & CH2 Output Compare, Preload, PWM1 Enable TIM1->CCMR2 |= 0x00000068; //CH3 Output Compare, Preload, PWM1 Enable /*CH1, CH2, CH3 and their Corresponding Complement Output Enable*/ TIM1->CCER |= 0x00000555; TIM1->CR1 |= 0x000000A0; // Centre Align Mode 1 & Auto-reload Preload enable TIM1->PSC = 0; TIM1->ARR = (1400 - 1); // Auto reload value 1400 (Period = 50us) TIM1->CCR1 = 700; // Start PWM duty for channel 1 TIM1->CCR2 = 500; // Start PWM duty for channel 2 TIM1->CCR3 = 350; // Start PWM duty for channel 3 TIM1->BDTR |= 0x00008800; // Enable Main O/P & Enable OSSR TIM1->CR1 |= 0x00000001; //Counter Enable } ________________ Attachments : 6_CH_PWM.jpg : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HtTT&d=%2Fa%2F0X0000000aQT%2F3USRSsVWWP0ZuBk2ft.k1iOe9Q.TqEcdBc_h0EZ0JN4&asPdf=false2013-02-06 09:27 AM
I like the symbolic names for the bits/fields more.
I also use an amended version of the stm32f4xx.h file (a better idea would be perhaps to create another header file, but I am not going to revert it now), so I have e.g.// OCyM bits determine generation of OCyREF signal
#define TIM_CCMR_OCM__FROZEN 0 // output compare mode is FROZEN, OCyREF does not change #define TIM_CCMR_OCM__HIGH_ON_MATCH 1 // signal OCyREF goes high (active) upon compare match #define TIM_CCMR_OCM__LOW_ON_MATCH 2 // signal OCyREF goes low (inactive) upon compare match #define TIM_CCMR_OCM__TOGGLE_ON_MATCH 3 // signal OCyREF toggles upon compare match #define TIM_CCMR_OCM__FORCE_LOW 4 // OCyREF <- 0 (inactive) #define TIM_CCMR_OCM__FORCE_HIGH 5 // OCyREF <- 1 (active) #define TIM_CCMR_OCM__PWM1 6 // if upcounting, OCyREF = (TIMx_CNT < TIMx_CCRy) ? 1 : 0; if downcounting OCyREF = (TIMx_CNT > TIMx_CCRy) ? 0 : 1; #define TIM_CCMR_OCM__PWM2 7 // if upcounting, OCyREF = (TIMx_CNT < TIMx_CCRy) ? 0 : 1; if downcounting OCyREF = (TIMx_CNT > TIMx_CCRy) ? 1 : 0; and then I write things like// select OC2 as compare, mode is toggle, and enable the output
TIM3->CCMR1 |= 0 OR ( TIM_CCMR_CCS__OUTPUT * TIM_CCMR1_CC2S_0) /* CC3S[1:0] bits (Capture/Compare 3 Selection) */ OR ( TIM_CCMR_OCM__TOGGLE_ON_MATCH * TIM_CCMR1_OC2M_0) /* OC3M[2:0] bits (Output Compare 3 Mode) */ ; YMMV. JW