Explanation
Both the peripheral and CPU clocks are running at 2MHz.
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);
CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);
....
….
CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, ENABLE);
TIM4 is a basic timer and so it is better to use it for such tasks. We initialize it by setting its prescaler
to 32 and loading its counter with 128. These values will make TIM4 overflow and interrupt every 2ms
– enough time to project info in one seven segment. There are 4 seven segment displays and so within
8ms all four are updated and your eyes see it as if all projecting info at the same time – a trick of vision.
Lastly, we need to enable what kind of interrupt we are expecting from the timer and finally enable
the global interrupt.
void TIM4_setup(void)
{
TIM4_DeInit();
TIM4_TimeBaseInit(TIM4_PRESCALER_32, 128);
TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
TIM4_Cmd(ENABLE);
enableInterrupts();
}
Remember the first interrupt example? We have to let the compiler know which interrupt we are
using. If you look at the datasheet, you’ll see that TIM4 update/overflow is located in IRQ23. We need
this and so we should make the following change in the stm8_interrupt_vector.c file:
{0x82, (interrupt_handler_t)TIM4_UPD_IRQHandler}, /* irq23 */
Remember to add the interrupt header and source files as we are going to use interrupt here. Inside
the ISR, we do the scanning of each seven segment. Every time an overflow interrupt occurs, a seven
segment is changed. At the end of the ISR a counter is incremented to select the next display when
new overflow event occurs. Inside the Switch-Case, we turn on the seven segment and decide the
value that seven segment should show. Finally, the timer overflow/update flag is cleared.
switch(seg)
{
case 1:
{
n = (value / 1000);
GPIO_Write(GPIOD, num[n]);
GPIO_Write(GPIOC, 0xE0);
break;
}
case 2:
{
n = ((value / 100) % 10);
GPIO_Write(GPIOD, num[n]);
GPIO_Write(GPIOC, 0xD0);
break;
}
case 3:
{