Chào các Bác. Em đang làm pwm cho con STM32 thì gặp lỗi như sau:
- Em cần băm một chùm xung và sau đó lại nghỉ, tần số PWM là 20KHz. Chu kỳ cứ lặp lại liên tục. giá trị PWM được lấy từ môt mảng cố định. Các giá trị trong mảng là khác nhau và cố định. Em dùng AVR và PIC thì khi băm PWM và nhìn trên oscillocope thì thấy giữa các chùm xung là đều nhau và giống nhau, không bị co giãn, thấy nó theo đúng quy luật của mảng. Khi dùng STM32 thì nó bị co giãn và PWM không ổn định, có lúc nó còn mất một hai xung pwm. Các bác xem video này sẽ thấy rõ: Dạng xung co giãn - YouTube
- Em có gửi kèm theo code, các bác xem giúp em xem lỗi ở chỗ nào. Em đã dùng nhiều mạch để test thử nhưng xung ra đều giống nhau. Loay hoay 3 tuần rồi mà chưa tìm được nguyên nhân. Cũng nhờ các cao thủ rồi mà chưa được. Mong các bác giúp em với.
Cảm ơn các bác nhiều.
- Em cần băm một chùm xung và sau đó lại nghỉ, tần số PWM là 20KHz. Chu kỳ cứ lặp lại liên tục. giá trị PWM được lấy từ môt mảng cố định. Các giá trị trong mảng là khác nhau và cố định. Em dùng AVR và PIC thì khi băm PWM và nhìn trên oscillocope thì thấy giữa các chùm xung là đều nhau và giống nhau, không bị co giãn, thấy nó theo đúng quy luật của mảng. Khi dùng STM32 thì nó bị co giãn và PWM không ổn định, có lúc nó còn mất một hai xung pwm. Các bác xem video này sẽ thấy rõ: Dạng xung co giãn - YouTube
- Em có gửi kèm theo code, các bác xem giúp em xem lỗi ở chỗ nào. Em đã dùng nhiều mạch để test thử nhưng xung ra đều giống nhau. Loay hoay 3 tuần rồi mà chưa tìm được nguyên nhân. Cũng nhờ các cao thủ rồi mà chưa được. Mong các bác giúp em với.
Cảm ơn các bác nhiều.
Code:
#include "stm32f10x.h" void RCC_Configuration(void); void GPIO_Configuration(void); void delay_init(void); void Delay(__IO uint32_t nTime); void TimingDelay_Decrement(void); void pwm_init(void); int main(void); static __IO uint32_t TimingDelay; const uint16_t volt_tb[64] = { 28, 28, 57, 57, 85, 85, 112, 112, 139, 139, 164, 164, 187, 187, 209, 209, 229, 229, 247, 247, 263, 263, 276, 276, 287, 287, 295, 295, 300, 300, 303, 303, 303, 303, 300, 300, 295, 295, 287, 287, 276, 276, 263, 263, 247, 247, 229, 229, 209, 209, 187, 187, 164, 164, 139, 139, 112, 112, 85, 85, 57, 43, 28, 14}; void RCC_Configuration(void) { /* PCLK1 = HCLK/4 */ RCC_PCLK1Config(RCC_HCLK_Div1); //clock cho PCLK = 36MHz /* TIM4 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); /* GPIOA and GPIOB clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE); } void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable | GPIO_Remap_TIM4, ENABLE); /*GPIOB Out put PWM */ /* TIM4: CH1,CH2,CH3 PWM */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } /* * Setup SysTick Timer for 1 msec interrupts * SystemCoreClock is defined in system_stm32f10x.c - thoi gian "delay_"(Hz) duoc tinh = SystemCoreClock/delay_; vi du: delay_ = 1ms = 1000Hz => SystemCoreClock/1000; */ void delay_init(void) { if (SysTick_Config(SystemCoreClock / 20000)) //delay 50us { /* Capture error */ while (1) { } } } /** * @brief This function handles SysTick Handler. * @param None * @retval None */ void SysTick_Handler(void) { TimingDelay_Decrement(); } /** * @brief Inserts a delay time. * @param nTime: specifies the delay time length, in milliseconds. * @retval None */ void Delay(__IO uint32_t nTime) { TimingDelay = nTime; while(TimingDelay != 0); } /** * @brief Decrements the TimingDelay variable. * @param None * @retval None */ void TimingDelay_Decrement(void) { if (TimingDelay != 0x00) { TimingDelay--; } } void pwm_init(void) { uint16_t PrescalerValue = 0; //phep chia he so timer TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* Compute the prescaler value */ PrescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1; //tan so timer TIM4 clock = 24MHz //PrescalerValue = 0; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 600;//600;//600; 20KHz TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; //chia tan so cho timer TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM_CounterMode_CenterAligned1;//TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//TIM_OCPolarity_High; //tin hieu PWM nguoc TIM_OC1Init(TIM4, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); /* PWM2 Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; //TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC2Init(TIM4, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); /* PWM3 Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; //TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//TIM_OCPolarity_High; TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM4, ENABLE); /* TIM3 enable counter */ TIM_Cmd(TIM4, ENABLE); } int main(void) { uint32_t _index=0; uint8_t blink=0; RCC_Configuration(); GPIO_Configuration(); pwm_init(); delay_init(); while(1) { _index++; if(_index==64)//chum xung co 64 gia tri trong mang volt_tb[] { _index = 0; blink=~blink; } if(blink) //nua ban ky dau co chum xung { TIM4->CCR1= volt_tb[_index]; } else //nua ban ky tiep theo khong co xung { TIM4->CCR1=0; } Delay(2); } } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ while (1) {} } #endif /** * @} */ /** * @} */
Comment