[STM8] PWM does not stop.
Hi friends,
Again I have come with a problem. Please see my code. PWM works as usual. But it is made to stop by resetting PC3 bit, PWM does not stop rather, it behaves randomly. Sometimes the PWM channels are driven high, driven low or PWM pulse is there. Many modifications has turned futile. Hence I seek your support.
Regards
ankhola
Main,c
/* MAIN.C file
*
* Copyright (c) 2002-2005 STMicroelectronics
*/
#include "stm8s.h"
#include "ccp.h"
void inv_on(void);
void inv_off(void);
void sw_state(void);
unsigned int pwm_duty1 = 40;
unsigned int pwm_duty2 = 50;
unsigned int i=0;
unsigned int duty;
unsigned char toggle=0;
unsigned char off_state;
unsigned char on_state;
unsigned const int table []= {0, 16, 32, 48, 64, 80, 96,
112, 127, 143, 159, 174, 190, 205, 220, 235, 250, 264, 279,
293, 307, 321, 335, 349, 362, 375, 388, 400, 413, 425, 437,
448, 460, 471, 481, 492, 502, 511, 521, 530, 539, 547, 555,
563, 570, 577, 584, 590, 596, 602, 607, 612, 616, 620, 623,
627, 630, 632, 634, 636, 637, 638, 638, 638, 638, 637, 636,
634, 632, 630, 627, 623, 620, 616, 612, 607, 602, 596, 590,
584, 577, 570, 563, 555, 547, 539, 530, 521, 511, 502, 492,
481, 471, 460, 448, 437, 425, 413, 400, 388, 375, 362, 349,
335, 321, 307, 293, 279, 264, 250, 235, 220, 205, 190, 174,
159, 143, 127, 112, 96, 80, 64, 48, 32, 16};
@far @interrupt void TIM2_UPD_OVF_IRQHandler(void) {
// 1. Clear the Interrupt Pending Bit
if (TIM2->SR1 & TIM2_SR1_UIF)
{
if (toggle == 0) {
TIM1_SetCompare2 (0);
i++;
if(i == 125) {
i = 0;
toggle = ~ toggle;
}
TIM1_SetCompare1(table[i]);
}
else {
TIM1_SetCompare1 (0);
i++;
if(i == 125) {
i = 0;
toggle = ~ toggle;
}
TIM1_SetCompare2(table[i]);
}
TIM2->SR1 &= ~TIM2_SR1_UIF;
}
}
void sw_state(void) {
if (GPIO_ReadInputPin, (GPIOC, GPIO_PIN_3))
on_state = 1;
else
on_state = 0;
}
void inv_on() {
TIM1_ComplementaryPWM_Init();
TIM2_OC_Init();
//GPIO_Init(GPIOD,GPIO_PIN_7, GPIO_MODE_OUT_PP_HIGH_FAST);
enableInterrupts();
do {
sw_state();
} while (on_state == 1);
}
void inv_off () {
//TIM1 -> CCER1 &= 0xFA;
TIM1->CCER1 &= ~TIM1_CCER1_CC1E;
TIM1->CCER1 &= ~TIM1_CCER1_CC1NE;
TIM2 -> IER = TIM2_IER_UIE;
GPIOB -> DDR |= 0x03;
GPIOB -> ODR &= 0xFC;
GPIOC -> DDR |= 0x06;
GPIOC -> ODR &= 0xF9;
GPIOB -> CR1 |= 0x03;
GPIOC -> CR1 |= 0x06;
TIM1_CtrlPWMOutputs(DISABLE);
do {
sw_state();
} while (on_state == 0);
}
void main(void)
{
Clock_Config();
gpio_init();
do {
sw_state();
if (on_state == 1)
inv_on();
else
inv_off();
} while (1);
//while(1) {
// Main loop can be used for other tasks or dynamically changing PWM values
// }
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
while (1)
{
}
}
#endif
ccp.h
#include "stm8s.h"
void gpio_init(void) {
GPIO_Init(GPIOC, GPIO_PIN_3, GPIO_MODE_IN_PU_IT);
}
void Clock_Config(void) {
CLK->ICKR |= CLK_ICKR_HSIEN; // Enable HSI
while (!(CLK->ICKR & CLK_ICKR_HSIRDY)); // Wait for stabilization
CLK->CKDIVR = 0x00; // HSI 16MHz / 1 = 16MHz
CLK->SWR = 0xE1; // Use HSI as master clock
}
void TIM2_OC_Init(void)
{
CLK->PCKENR1 = 0xFF;
TIM2->PSCR = 0x00;
TIM2 -> ARRH = 1280 >> 8;
TIM2 -> ARRL = 1280 & 0xFF;
//TIM2->CCMR1 = 0x00;
//TIM2 -> EGR |= (1 << TIM2_EGR_UG);
TIM2 -> IER = 0x01;
TIM2->CR1 |= TIM2_CR1_CEN;
}
void TIM1_ComplementaryPWM_Init(void)
{
// 1. Enable TIM1 Clock
CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, ENABLE);
// 2. Configure GPIOs for TIM1 Channels (PC6-CH1, PC7-CH1N, PC3-CH2, PC4-CH2N)
// Note: Depends on specific STM8 variant, check datasheet for pinout
GPIO_Init(GPIOC, GPIO_PIN_1, GPIO_MODE_OUT_PP_LOW_FAST);
GPIO_Init(GPIOC, GPIO_PIN_2, GPIO_MODE_OUT_PP_LOW_FAST);
GPIO_Init(GPIOB, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST);
GPIO_Init(GPIOB, GPIO_PIN_1, GPIO_MODE_OUT_PP_LOW_FAST);
// 3. Time Base Configuration: PWM Frequency = 16MHz / (15+1) / (999+1) = 1kHz
TIM1_TimeBaseInit(1, TIM1_COUNTERMODE_UP, 639, 0);
// 4. Channel 1 Configuration (PWM1 Mode)
TIM1_OC1Init(TIM1_OCMODE_PWM1,
TIM1_OUTPUTSTATE_ENABLE,
TIM1_OUTPUTNSTATE_ENABLE, // Enable complementary
500, // Duty Cycle (CCR1)
TIM1_OCPOLARITY_HIGH,
TIM1_OCNPOLARITY_HIGH,
TIM1_OCIDLESTATE_RESET,
TIM1_OCNIDLESTATE_RESET);
// 5. Channel 2 Configuration (PWM1 Mode)
TIM1_OC2Init(TIM1_OCMODE_PWM1,
TIM1_OUTPUTSTATE_ENABLE,
TIM1_OUTPUTNSTATE_ENABLE, // Enable complementary
250, // Duty Cycle (CCR2)
TIM1_OCPOLARITY_HIGH,
TIM1_OCNPOLARITY_HIGH,
TIM1_OCIDLESTATE_RESET,
TIM1_OCNIDLESTATE_RESET);
// 6. Dead Time Configuration (e.g., 10 ticks)
TIM1->DTR = 0x30;
// 7. Enable Main Output
TIM1_CtrlPWMOutputs(ENABLE);
// 8. Enable Timer
TIM1_Cmd(ENABLE);
}
