Forums

STMicroelectronics 8 bit MCUs

Started by DebD 3 weeks ago9 replieslatest reply 2 weeks ago69 views

Hello! I'm learning to code an STMicroelectronics 8 bit micro-controller. I want to control a BLDC motor with this MCU for electric vehicle application. I'm using the STM8S DISCOVERY Board, based on the STM8S105C6T6 (48 pin) MCU. This MCU has 4 timers, with TIMER 1 being the advanced timer (complementary PWM channels, dead time capability etc. in output compare mode). However I'm facing difficulty in generating PWM signals from the TIMER 1, which has 4 channels. Channel 2 and Channel 2N produce complementary PWM outputs as expected. However every time I connect Channel 1 and Channel 1N pins respectively to the scope (or Channel 3 and Channel 3N pins), Channel 1 (or 3) produce nearly no output while their counterparts produce perfect PWM pulse train. Channel 4 also produces a correct output PWM, but it doesn't have a complementary pin. Given below is the code (released by STMicroelectronics itself) and the oscilloscope waveforms I'm getting with Channels 1 and 2. 

Can someone tell me where I am going wrong?ch1_ch1n(1)_44431.jpg

ch2_ch2n_25079.jpg

N.B.: Please don't suggest me to contact STMicroelectronics for tech. support. I've done that more than once already. The reply they send to me each time is: "Can you please provide your business name and business website?". This is actually a college level project

#include "stm8s.h"
/**  
    * @addtogroup TIM1_7PWM_Output  
    * @{  
*/
/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
#define CCR1_Val  ((uint16_t)2047)
#define CCR2_Val  ((uint16_t)1535)
#define CCR3_Val  ((uint16_t)1023)
#define CCR4_Val  ((uint16_t)511)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/ 
/* Private function prototypes -----------------------------------------------*/
static void TIM1_Config(void);
/* Private functions ---------------------------------------------------------*/
/* Public functions ----------------------------------------------------------*/

/**  
* @brief  Main program.  
* @param  None  
* @retval None  
*/
void main(void)
{  
    /* TIM1 configuration -----------------------------------------*/  
    TIM1_Config();  
    while (1) 
 {} 
}

/**  
* @brief  Configure TIM1 to generate 7 PWM signals with 4 different duty cycles  
* @param  None  
* @retval None  
*/
static void TIM1_Config(void)
{   
    TIM1_DeInit();  
    /* Time Base configuration */  
    /*  
    TIM1_Period = 4095  
    TIM1_Prescaler = 0  
    TIM1_CounterMode = TIM1_COUNTERMODE_UP  
    TIM1_RepetitionCounter = 0  
    */  

    TIM1_TimeBaseInit(0, TIM1_COUNTERMODE_UP, 4095, 0); 
 
    /* Channel 1, 2,3 and 4 Configuration in PWM mode */  

    /*  
    TIM1_OCMode = TIM1_OCMODE_PWM2  
    TIM1_OutputState = TIM1_OUTPUTSTATE_ENABLE  
    TIM1_OutputNState = TIM1_OUTPUTNSTATE_ENABLE  
    TIM1_Pulse = CCR1_Val  
    TIM1_OCPolarity = TIM1_OCPOLARITY_LOW  
    TIM1_OCNPolarity = TIM1_OCNPOLARITY_HIGH  
    TIM1_OCIdleState = TIM1_OCIDLESTATE_SET  
    TIM1_OCNIdleState = TIM1_OCIDLESTATE_RESET 
 
    */  
    TIM1_OC1Init(TIM1_OCMODE_PWM2, TIM1_OUTPUTSTATE_ENABLE, TIM1_OUTPUTNSTATE_ENABLE,                                   
                    CCR1_Val, TIM1_OCPOLARITY_LOW, TIM1_OCNPOLARITY_HIGH, TIM1_OCIDLESTATE_SET,               
                    TIM1_OCNIDLESTATE_RESET);  

     /*TIM1_Pulse = CCR2_Val*/  
    TIM1_OC2Init(TIM1_OCMODE_PWM2, TIM1_OUTPUTSTATE_ENABLE, TIM1_OUTPUTNSTATE_ENABLE, 
                CCR2_Val,TIM1_OCPOLARITY_LOW, TIM1_OCNPOLARITY_HIGH, TIM1_OCIDLESTATE_SET,                
                TIM1_OCNIDLESTATE_RESET);  

    /*TIM1_Pulse = CCR3_Val*/  
    TIM1_OC3Init(TIM1_OCMODE_PWM2, TIM1_OUTPUTSTATE_ENABLE, TIM1_OUTPUTNSTATE_ENABLE,               
                CCR3_Val, TIM1_OCPOLARITY_LOW, TIM1_OCNPOLARITY_HIGH, TIM1_OCIDLESTATE_SET,               
                TIM1_OCNIDLESTATE_RESET);  

    /*TIM1_Pulse = CCR4_Val*/  
    TIM1_OC4Init(TIM1_OCMODE_PWM2, TIM1_OUTPUTSTATE_ENABLE, CCR4_Val, TIM1_OCPOLARITY_LOW,                               
                 TIM1_OCIDLESTATE_SET);  

    /* TIM1 counter enable */  
    TIM1_Cmd(ENABLE);  

    /* TIM1 Main Output Enable */  
    TIM1_CtrlPWMOutputs(ENABLE);
}

#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) */  

    /* Infinite loop */  
    while (1)  
    {      
    }
#endif

/**  
    * @}  
*/

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
[ - ]
Reply by stephanebAugust 30, 2019

Hi Deb, could you please edit your post and try to make the code snippet readable?  It is currently showing on a single line. Thanks.

[ - ]
Reply by DebDAugust 30, 2019

Post deleted by author

[ - ]
Reply by stephanebAugust 30, 2019

You should be able to edit your original post at the top and replace the 'one line' code with this full snippet.  

[ - ]
Reply by DebDAugust 31, 2019

I was using my cellphone to edit it last night. Sorry for the delay! Is the code readable now?

[ - ]
Reply by MarkDSylvaAugust 30, 2019

Hi Deb,


I don't have an answer to your question, but have you tried posting in the community forums instead of creating a support question?  That way, ST won't ask for your company name etc.


Here is a link to the area for the STM8  

 https://community.st.com/s/topic/0TO0X000000BSqdWAG/stm8-mcus


Mark


[ - ]
Reply by mr_banditAugust 30, 2019
Channel 4 also produces a correct output PWM, but it doesn't have a complementary pin.

You can get a fast inverter and make the complementary signal. The faster the better. The other trick is getting two buffers - one inverting and one not, with the same propagation delay.

It seems like you need a pullup on the one that you are having issues with.

Also, are you using an eval board? If so, look at the schematics and see if the "bad" channel is also connected to something. Also, pretty common that digital pins have an internal pullup that can be switch into the circuit.

Are you using the vendor-supplied library? Look at the code and compare how it controls the various channels.

BTW - thanks for supplying scope screenshots. I assume you are using a school lab oscope. If you want one of your own, you can get a great one for under $400. I have both that one and a 12yo Tek oscope that was $1200 new. The Rigol does 95% of the tek oscope and some extra tricks. I cannot tell you about the hack on the interwebs that converts it from 50MHz to 100MHz...

https://www.tequipment.net/Rigol/DS1054Z/Digital-Oscilloscopes/?v=0

Keep us informed of your journey!

[ - ]
Reply by DebDAugust 31, 2019

Yes I'm using an Eval board. I'm attaching the image of the board schematics. I'm having issues with TIM1 CH1 and TIM1 CH3 pins, which are Port C pins 1 and 3 of the MCU respectively (PC1 and PC3)

I've used the vendor supplied library and also tried it with codes I found on another blog. The same error persists! I have a doubt here though. Given below is the code snippet for GPIO initialization, taken from the blogger's codes (He's using a different eval board and MCU altogether btw). This configures TIM1 CH1 and CH1N pins as output pins (Ofcourse I've changed the code to configure corresponding pins on my board). 

Screenshot (2).png

In STM8S MCUs, a pin in output mode can have any of the following configurations, as given in their gpio.h file. I've configured all channels as GPIO_MODE_OUT_PP_HIGH_FAST. CH2 and CH2N work fine as seen in the scope waveforms, but CH1 and CH3 pins don't respond! I'm not sure if I have to use any other declaration as given in the list below for these two pins!

  /* gpio.h */

  GPIO_MODE_OUT_OD_LOW_FAST  = (uint8_t)0xA0,  /*!< Output open-drain, low level, 10MHz */
  GPIO_MODE_OUT_PP_LOW_FAST  = (uint8_t)0xE0,  /*!< Output push-pull, low level, 10MHz */
  GPIO_MODE_OUT_OD_LOW_SLOW  = (uint8_t)0x80,  /*!< Output open-drain, low level, 2MHz */
  GPIO_MODE_OUT_PP_LOW_SLOW  = (uint8_t)0xC0,  /*!< Output push-pull, low level, 2MHz */
  GPIO_MODE_OUT_OD_HIZ_FAST  = (uint8_t)0xB0,  /*!< Output open-drain, high-impedance level,10MHz */
  GPIO_MODE_OUT_PP_HIGH_FAST = (uint8_t)0xF0,  /*!< Output push-pull, high level, 10MHz */
  GPIO_MODE_OUT_OD_HIZ_SLOW  = (uint8_t)0x90,  /*!< Output open-drain, high-impedance level, 2MHz */
  GPIO_MODE_OUT_PP_HIGH_SLOW = (uint8_t)0xD0   /*!< Output push-pull, high level, 2MHz */
void GPIO_setup(void)
{        
 GPIO_DeInit(GPIOB);
 GPIO_Init(GPIOB, GPIO_PIN_0, GPIO_MODE_OUT_PP_HIGH_FAST); /* CH1N Pin setup. This one produces correct output */
 
 GPIO_DeInit(GPIOC);
 GPIO_Init(GPIOC, GPIO_PIN_1, GPIO_MODE_OUT_PP_HIGH_FAST); /* CH1 Pin setup. This one doesn't give any output */
}
[ - ]
Reply by DebDAugust 31, 2019

Sorry about the image quality of the schematic. I'm attaching the pdf of the board's user guide. Please scroll to page 15, to view the schematic

en.CD00250600DISCOVERYBOARDDATASHEET.pdf

Screenshot (2).png

[ - ]
Reply by mr_banditSeptember 3, 2019

The first thing I see is you are configuring pins B0, not C0.

Suggestion: write a little program that jut configures each pin you want to use as outputs, then a loop to toggle them. Look at them with a scope. This will give you a first cut at making sure they are properly setup as GPIO pins.

But - be aware that when they are assigned to a device, they are not GPIO pins. They are device pins.