## STMicroelectronics 8 bit MCUs

Started by 6 months ago9 replieslatest reply 6 months ago92 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?

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"
/**
* @{
*/
/* 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****/

[ - ]

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.

[ - ]

Post deleted by author

[ - ]

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

[ - ]

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

[ - ]

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

Mark

[ - ]
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...

Keep us informed of your journey!

[ - ]

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 */
}

[ - ]