You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
the project: I want to dim an RGB-LED with PWM (MCU: STM8S103). The amount of dimming should be received as a datastream over DMX which is implemented via serial.
the problem: When I send data on a specific channel, the data is received, but there's a shift in the channel... So if I send data on channel 0 (DMXchannel 1), the channel which receives the data is drifting from 0 to 511, or even no data is received. So the system seem to be very unstable. Does someone know what could be the problem? here is my sktech:
/*
18.4.24, DMX sketch
DMX receiving-sketch
based on the uart loopback example: https://registry.platformio.org/platforms/platformio/ststm8/examples/spl-uart-loopback
PWM implementation based on: https://embedded-lab.com/blog/starting-stm8-microcontrollers/20/
*/
/* Includes ------------------------------------------------------------------*/
#include <Arduino.h>
/* Defines -----------------------------------------------------------------*/
#define DMX_CHANNEL_COUNT 512 //all 512 DMX channel
#define DMX_CHANNEL_LED 1 //DMX Data on channel 1
volatile bool dmxMessageStarted = false; //true if databytes are received
volatile bool dataFree = false; //true if nothing is written in array by interrupt
volatile uint8_t dmxData[DMX_CHANNEL_COUNT]; //array to store DMX data in
volatile uint16_t dmxIndex = 0;
/* Private function prototypes -----------------------------------------------*/
static void CLK_Config(void);
static void UART_Config(void);
void GPIO_setup(void);
void TIM2_setup(void);
void main(void)
{
pinMode(LED_BUILTIN, OUTPUT);
CLK_Config(); //configure prescaler
GPIO_setup();
TIM2_setup();
UART_Config(); //configure UART
while(TRUE)
{
if(dataFree){ //if data array is not used by interrupt
TIM2_SetCompare1(dmxData[DMX_CHANNEL_LED-1]);
TIM2_SetCompare2(dmxData[DMX_CHANNEL_LED]);
TIM2_SetCompare3(dmxData[DMX_CHANNEL_LED+1]);
// TIM2_SetCompare3(128); //Test-data on pin PA3
}
};
}
static void CLK_Config(void)
{
/* Initialization of the clock */
/* Clock divider to HSI/1 */
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
// reset clock
CLK_DeInit();
// Deactivate external and internal oscillator, activate internal oscillator
CLK_HSECmd(DISABLE);
CLK_LSICmd(DISABLE);
CLK_HSICmd(ENABLE);
// Wawait until oscillator is stable
while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);
// Clock Switching
CLK_ClockSwitchCmd(ENABLE);
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);
// config for clock switching
CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI,
DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);
// Deactivate clock for peripherals that are not required
CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, ENABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, ENABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);
}
void GPIO_setup(void)
{
GPIO_DeInit(GPIOA);
GPIO_Init(GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_HIGH_FAST);
GPIO_DeInit(GPIOD);
GPIO_Init(GPIOD, ((GPIO_Pin_TypeDef)GPIO_PIN_3 | GPIO_PIN_4),
GPIO_MODE_OUT_PP_HIGH_FAST);
}
// initialize timer 2 for PWM
void TIM2_setup(void)
{
TIM2_DeInit(); // reset timer 2
TIM2_TimeBaseInit(TIM2_PRESCALER_32, 255); // Timer 2 als Zeitbasis mit Vorteiler 32 und Periodenwert 1000 initialisieren
TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 255, // set timer 2 channel 1 as pwm, activate output, pulse and polarity
TIM2_OCPOLARITY_HIGH);
TIM2_OC2Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 255,// set timer 2 channel 2 as pwm, activate output, pulse and polarity
TIM2_OCPOLARITY_LOW);
TIM2_OC3Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 255, // set timer 2 channel 3 as pwm, activate output, pulse and polarity
TIM2_OCPOLARITY_HIGH);
TIM2_Cmd(ENABLE); // activate timer 2
}
void UART_Config(void)
{
UART1_DeInit();
// Configure UART1 for DMX mode
UART1_Init(250000,
UART1_WORDLENGTH_8D,
UART1_STOPBITS_2, // 2 Stop-Bits für DMX
UART1_PARITY_NO,
UART1_SYNCMODE_CLOCK_DISABLE,
UART1_MODE_RX_ENABLE);
// Enable DMX receiver interrupt
UART1_ITConfig(UART1_IT_RXNE_OR, ENABLE);
// Enable global interrupts
enableInterrupts();
}
INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
{
if (UART1_GetITStatus(UART1_IT_RXNE) != RESET)
{
uint8_t receivedData = UART1_ReceiveData8(); // receive data
if (dmxMessageStarted)
{
dataFree = false;
dmxData[dmxIndex] = receivedData; // write data in array
dmxIndex++;
if (dmxIndex >= DMX_CHANNEL_COUNT)
{
dmxIndex = 0;
dmxMessageStarted = false;
}
}
else
{
// break signal
if (receivedData == 0)
{
// digitalWrite(LED_BUILTIN, HIGH);
dataFree = true;
dmxMessageStarted = true; // begin of a new DMX message
dmxIndex = 0; // reset index
}
}
}
}
The text was updated successfully, but these errors were encountered:
kokospalme
changed the title
no PWM when using UART with interrupts
unstable datastream (UART with interrupts)/ DMX implementation
Apr 19, 2024
the project: I want to dim an RGB-LED with PWM (MCU: STM8S103). The amount of dimming should be received as a datastream over DMX which is implemented via serial.
the problem: When I send data on a specific channel, the data is received, but there's a shift in the channel... So if I send data on channel 0 (DMXchannel 1), the channel which receives the data is drifting from 0 to 511, or even no data is received. So the system seem to be very unstable. Does someone know what could be the problem? here is my sktech:
The text was updated successfully, but these errors were encountered: