Programming microcontrollers using STVD and Cosmic C compiler

Publisher:TranquilDreamsLatest update time:2023-02-09 Source: elecfansKeywords:STVD Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

  Pulse width modulation (PWM) is an analog modulation technique in which the duration or width of a pulse varies over time. It is a commonly used technique for generating a continuous pulse signal with a defined frequency and duty cycle. Simply put, PWM changes the width of the pulse while keeping the frequency constant.


  Using PWM signals, you can easily control the speed of a servo motor or the brightness of an LED. Since general purpose microcontrollers can only provide logic 1 (high) or logic 0 (low) on their output pins, they cannot provide varying analog voltages unless it has a built-in digital-to-analog converter (DAC) or an external connection . In this case, the microcontroller can be programmed to output pulse width modulation (PWM) with different duty cycles, which can then be converted to different analog voltages.


  So, in this tutorial, we will interface the LED with a universal STM8S microcontroller which is controlled using PWM signals generated by the microcontroller, we will program the microcontroller using STVD and Cosmic C compiler. Before that, let's understand some basics of PWM signals.


  Understand the basics of PWM signals

  As you may have heard, PWM stands for Pulse Width Modulation. It is an analog modulation technique used in a large number of different applications and projects. An image of the PWM signal is shown below.

pYYBAGLqMy6AHCpXAAAlnuE7YZ0999.png

  The image you see above is a generic square wave with the same ON time and OFF time. Now, assume that the total period of the square wave is 1 second, which means that the square wave's on time and the square wave's off time are also 500 milliseconds. So if we connect an LED and power it with this square wave, the LED will be on for half a cycle and off for half a cycle. It looks like the LED is glowing at half brightness.

poYBAGLqMyqADzNdAAAwYIXeBo8056.png

  In the picture above, you can see that we have reduced the duty cycle, if we consider the same 1S period, our On-TIme is 250ms and our OFF time is 750ms. Now, if we connect the same LED, we will observe that the LED becomes dimmer as the duty cycle decreases.

  STM8S PWM generator circuit: hardware setup and requirements

poYBAGLqMyaAKdsoAASFvcAnjno997.png

  Since we use PWM to control the LED, we need an LED connected to the STM8S board. Since the STM8S development board has LEDs, I will use it for demonstration. We also need the STM8S development board and ST-LINK programmer. In addition to this we will need a 5V power supply to power the board as the board has an onboard micro USB cable which we will use to power the board.


  LED dimmer circuit diagram based on STM8S microcontroller

  To program the circuit, we connected the ST-Link V2 programmer to the 3.3V, SWIM and GROUND pins of the STM8S development board. The most interesting thing about the STM8 microcontroller is that it only requires one SWIM pin to program the microcontroller.

poYBAGLqMyKAPF7zAACxf6XoCvE915.png

  As you can see in the schematic above, the test LED is connected to the development board and is connected to port 1.4 on the far left side of the board

  PWM pins on ST Micro STM8S microcontroller

  STM8S has 20 pins, 8 of which can be configured as PWM. The image below shows the PWM pins marked in red boxes. These pins are also GPIO pins that can be used for other functions.

pYYBAGLqMx6AUo2EAAPoV7FxGeo124.png

  As we can see in the above image, the labeled pins can generate PWM signals. So we will use one of the ones on the board to generate the PWM signal. However, enabling PWM disables other features, so we need to be careful about which pin we configure as PWM. Since we are building this circuit for online demonstration, we will use PIN D4 to generate the PWM signal.


  Programming an STM8s microcontroller to generate PWM signals

  Create a workspace and new project as we discussed in our Getting Started with STM8S Microcontrollers tutorial. You can add all header and source files, or just the gpio, TImer2, config and stm8s files. Open the main.c file and start writing the program.

poYBAGLqMxqAbR1vAAG64NW0vds762.png

  Make sure you have included the header file as shown above. Open the main.c file and start the code. The complete main.c code can be found at the bottom of this page, where you can also download the project file. The code is explained below, if you are confused about the coding part you can also refer to the SPL User Manual or the video linked at the bottom of this page.  


Before we start the coding process, you need to include stm8s_gpio.c, stm8s_TIm2.c and in the source and header folders you need to include stm8s_gpio.h, stm8s_TIm2. H. You can get these header files from the STM8S103F3P6 SPL GitHub Repository. Once completed, we start our code by including all required libraries and defining all necessary variables. For this lab code, we just need to save the PWM value in a variable, which is why we include a variable called pwm_duty.

 

#Include "STM8S.h"
signed int pwm_duty = 0;

 

Once we have declared all libraries and variables, we need to build our defer function as cosmic c compiler does not provide any predefined defer function. We will use the assembly instruction NOP which takes only one clock cycle. And since the core of the microcontroller runs at 2MHz, we can easily speculate on the latency. For this reason, we combine the delay with two for loops. This is the simplest and most accurate way to defer the cosmic C compiler.

 

void delay_ms (int ms) //Function definition
{
            for (int i=0; i<=ms; i++)
                        for (int j=0; j<120; j++) // Nop = Dark/4
                                    _asm("nop"); //Perform no operation //Assembly code
}

 

Next, we'll look at our main loop. For this section we need to look at the SPL user manual. We start the main function by deinitializing the GPIO pins and Timer2. If the GPIO or Timer has been used previously by other applications, they should be initialized before using them. This is not mandatory, but it is a good practice.

 

GPIO_DeInit(GPIOD);
TIM2_DeInit();

 

Next, we have to declare the pin as output, set up Timer2 with the help of TIM2_OC1Init() function and use a prescaler in the timer to achieve a PWM frequency of 4KHz. We do this with the help of the TIM2_TimeBaseInit() function. Once completed, we enable the timer with the help of TIM2_Cmd(ENABLE) function. For this project we decided to use PIN D4 on the board, which is a PWM capable PIN.

 

GPIO_DeInit(GPIOD);
TIM2_DeInit();          
GPIO_Init(GPIOD,GPIO_PIN_4,GPIO_MODE_OUT_PP_HIGH_FAST);           
TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000,
                   TIM2_OCPOLARITY_HIGH);           
TIM2_TimeBaseInit(TIM2_PRESCALER_1, 500);
TIM2_Cmd(enable);

 

Next, we have our infinite loop. In the infinite loop, we set up the for loop and enabled capture and compare statements, which will allow us to set up the PWM channel.

 

  while(true){                   
    对于(pwm_duty = 0;pwm_duty < 1000;pwm_duty += 2){
      TIM2_SetCompare1(pwm_duty);
      delaymilliseconds(10);
                        }                      
    对于(pwm_duty = 1000;pwm_duty > 0;pwm_duty -= 2){
      TIM2_SetCompare1(pwm_duty);
      delaymilliseconds(10);
    }
  }

 

The above code is responsible for generating the PWM signal, because in the first for loop the PWM signal will change from high level to low level, and because of the next for loop, the PWM signal will change from low level to high level and continue cycle.

  Use STM8S to generate PWM signals

  Compile the code and upload it to your STM8S development board. If you encounter any compilation errors, make sure you have added all header and source files as mentioned before. After uploading the code, you should see the brightness of the LED connected on pin D4 change.

poYBAGLqMxOACG_aAAhd_uyBQz0104.png

#Includes "STM8S.h"

signed int pwm_duty = 0;

void delay_ms (int ms) //Function definition

{

for (int i=0; i<=ms; i++)

for (int j=0; j<120 ; j++) // Nop = Fosc/4

_asm("nop"); // Perform no operation // Assembly code

}

void main (void)

{

GPIO_DeInit(GPIOD);

TIM2_DeInit();

GPIO_Init(GPIOD,GPIO_PIN_4,GPIO_MODE_OUT_PP_HIGH_FAST) ;

TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 1000,

TIM2_OCPOLARITY_HIGH);

TIM2_TimeBaseInit(TIM2_PRESCALER_1, 500);

TIM2_Cmd(enabled);

while(true) {

for(pwm_duty = 0; pwm_duty < 1000 ; pwm_duty += 2){ // Loop

TIM2_SetCompare1( pwm_duty); //Set Timer2's capture comparison

delay milliseconds (10); //Delay 10ms

}

For (pwm_duty = 1000; pwm_duty > 0; pwm_duty -= 2) {

TIM2_SetCompare1(pwm_duty);

Delay milliseconds (10);

}

}

}


Keywords:STVD Reference address:Programming microcontrollers using STVD and Cosmic C compiler

Previous article:Directly debug and run the program without resetting the MCU, making bugs fearful
Next article:[Ultra-low power consumption series three] Selection of BAM mode and Stop mode

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号