Hello there!
I'm quite new to the STM32 mcu, so I'm trying to implement basic things to understand how it works. To do so, I tried to multiplex a 4 rows by 11 columns LED array, using two timers, one to drive the 4 rows with the PWM output and another timer to switch the LEDs in the columns.
My code kinda works, but it works not as I expected: for example, it turns on in the same row two LEDs, one of them is switched on as it should be, the other led should be lit in another row and not in this row. Same behavior in the other rows. It seems like the PWM switching is too slow in comparison to the switching of the columns, and because of this there is this this "ghosting" effect, but i set the timers with the same prescaler and the same period count in both timers, so i don't know (prescaler set to 32000 and period count set to 1 @ timer clock 32MHz)
This is my code:
void displayNumber(struct time input)
{
volatile uint16_t intTimerOld=0;
uint8_t cnt=0;
htim2.Instance->CCR1 = 100;// set the duty cycle to 100
htim2.Instance->CCR2 = 100;
htim2.Instance->CCR3 = 100;
htim2.Instance->CCR4 = 100;
HAL_TIM_Base_Start_IT(&htim3);
while(intTimer < 6500)
{
if(intTimerOld != intTimer)
{
switch(cnt)
{
case 0:
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);//stop all the PWM
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_2);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_4);
resetPin();
associateNumber(0);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);//start the first PWM
cnt++;
break;
case 1:
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_2);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_4);
resetPin();
associateNumber(0);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
cnt++;
break;
case 2:
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_2);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_4);
resetPin();
associateNumber(0);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);
cnt++;
break;
case 3:
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_2);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_4);
resetPin();
associateNumber(0);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4);
cnt++;
break;
case 4:
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_2);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_4);
resetPin();
associateNumber(10);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
cnt=0;
break;
}
intTimerOld = intTimer;
}
}
resetPin();
htim2.Instance->CCR1 = 0;
htim2.Instance->CCR2 = 0;
htim2.Instance->CCR3 = 0;
htim2.Instance->CCR4 = 0;
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_2);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_4);
HAL_TIM_Base_Stop_IT(&htim3);
intTimerOld=0;
intTimer=0;
}
The function resetPin() is a custom function that I made, which reset to low all the pin of the columns, using for example "HAL_GPIO_WritePin(GPIOC, MUX_9_Pin, GPIO_PIN_RESET)"
The function associatePin() is also a custom function that I made, which select the right column by its argument and it switch it to high, using for example "HAL_GPIO_WritePin(GPIOA, MUX_1_Pin, GPIO_PIN_SET)"
Do you have any suggestions to achieve a proper multiplexing? What am I doing wrong? Can you help me?