This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EK-TM4C123GXL + 7 seg display for digital clock with funcions (time, schedule adjustment and chronometer

Other Parts Discussed in Thread: EK-TM4C123GXL

Hi, i need make a digital clock with functions mentioned in the subject with EK-TM4C123GXL, i have 7 segment display with 4 digits, and I'm having difficulty implementing the code using interrupts.

The functions should be able to run in the background, for example, have already activated chronometer and Watch function is on, the timer is still running in the background.

see the code below, this does not work, very unnecessary thing and written wrongly.I thought to implement with the switch case, that when he arrived in value compare with the pre-defined cases.


#include <stdint.h> #include <stdbool.h> #include "inc/tm4c123gh6pm.h" //Definitions for the interrupt and register assignments on the Tiva C Series device on the LaunchPad board #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "driverlib/sysctl.h" #include "driverlib/interrupt.h" // Defines and macros for NVIC Controller (Interrupt) API of driverLib. This includes API functions such as IntEnable and IntPrioritySet. #include "driverlib/gpio.h" #include "driverlib/timer.h" // Defines and macros for Timer API of driverLib. This includes API functions such as TimerConfigure and TimerLoadSet. uint32_t ui32Period; //essa variavel é para a contagem do tempo uint32_t ui32unidademin; int main(void) { //-------------------Clock Setup-------------------// SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); //40mhz SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); //função habilita o periferico TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); //configura o timer, configura o timer para utilizar o todo o periodo ui32Period = (SysCtlClockGet())*60; //60 segundos TimerLoadSet(TIMER0_BASE, TIMER_A, ui32Period -1); //???????This function con?gures the timer load value; if the timer is running then the value is immediately loaded into the timer. IntEnable(INT_TIMER0A); //The speci?ed interrupt is enabled in the interrupt controller. The ui32Interrupt parameter must be one of the valid INT_* values listed in Peripheral Driver Library User’s Guide and de?ned in the inc/hw_ints.h header ?le. Other enables for the interrupt (such as at the peripheral level) are unaffected by this function. TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); //This function enables the indicated timer interrupt sources. Only the sources that are enabled can be re?ected to the processor interrupt; disabled sources have no effect on the processor.The ui32IntFlags parameter must be the logical OR of any combination of the following: TIMER_TIMB_TIMEOUT - Timer B timeout interrupt IntMasterEnable(); //This function allows the processor to respond to interrupts. This function does not affect the set of interrupts enabled in the interrupt controller; it just gates the single interrupt from the controller to the processor TimerEnable(TIMER0_BASE, TIMER_A); //This function enables operation of the timer module. The timer must be con?gured before it is enabled. //MODELO //SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); //GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, 0b00000100); //GPIOPadConfigSet(GPIO_PORTD_BASE,0b00000100,GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); //limitador de corrente //GPIOPinWrite(GPIO_PORTD_BASE, 0b00000100, 0x04); //0x04 sinal alto só para o d2 //0xFF = todas as portas SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, 0b00000100); GPIOPadConfigSet(GPIO_PORTD_BASE,0b11010100,GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); //limitador de corrente //GPIOPinWrite(GPIO_PORTD_BASE, 0b00000100, 0x04); //0x04 sinal alto só para o d2 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,0b00000010); GPIOPadConfigSet(GPIO_PORTB_BASE,0xFF,GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); GPIOPinWrite(GPIO_PORTB_BASE, 0x02, 0b00000000); //0xFF = todas as portas while(1) {;} } void unidade_min(void) //adicionar prototipos { switch(ui32Period){ case 0: //caso o periodo tenha atingido 60 segundos GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b01111110, 0b00000000); ui32unidademin = 0; case 60: //caso o periodo tenha atingido 60 segundos GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b00110000, 0b00000000); ui32unidademin = 1; case 120: GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b01101101, 0b00000000); ui32unidademin = 2; case 180: GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b00111001, 0b00000000); ui32unidademin = 3; case 240: GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b00110011, 0b00000000); ui32unidademin = 4; case 300: GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b01011011, 0b00000000); ui32unidademin = 5; case 360: GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b01011111, 0b00000000); ui32unidademin = 6; case 420: GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b01110000, 0b00000000); ui32unidademin = 7; case 480: GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b01111111, 0b00000000); ui32unidademin = 8; case 540: GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b01111011, 0b00000000); ui32unidademin = 9; } } void dezena_min(uint32_t unidademin) //adicionar prototipos { switch(ui32unidademin){ case 0: //caso o periodo tenha atingido 60 segundos GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b01111110, 0b00000000); case 60: //caso o periodo tenha atingido 60 segundos GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b00110000, 0b00000000); case 120: GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b01101101, 0b00000000); case 180: GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b00111001, 0b00000000); case 240: GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b00110011, 0b00000000); case 300: GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b01011011, 0b00000000); case 420: GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80); GPIOPinWrite(GPIO_PORTB_BASE, 0b01110000, 0b00000000); case 480: GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80);// sinal alto somente para D4 GPIOPinWrite(GPIO_PORTB_BASE, 0b01111111, 0b00000000); case 540: GPIOPinWrite(GPIO_PORTD_BASE, 0b10000000, 0x80);// sinal alto somente para D4 GPIOPinWrite(GPIO_PORTB_BASE, 0b01111011, 0b00000000); } }

  • Your system clock runs at 40 MHz. At what period do you expect the timer interrupt to occur by this formula "ui32Period = (SysCtlClockGet())*60; //60 segundos" ? I would suggest toggle an IO pin in the timer ISR to see how often the interrupt is happening.

    Thanks and regards,

    Zhaohong
  • john abrie said:
     I have 7 segment display - 4 digits, having difficulty implementing the code using interrupts.     The functions should be able to run in the background, for example, have already activated chronometer and Watch function is on, the timer is still running in the background.     Code "does not work", very unnecessary thing and written wrongly.  

    May I suggest that you're attempting too much - far too soon - and as a result it becomes very difficult to test/troubleshoot?    (i.e. "where do you begin?")

    There is a superior method - used even by code/systems far more complex.     Called KISS - it succeeds by breaking your complex, inter-related project into far smaller (and more manageable) parts/components.   In this manner you isolate your objectives - focus on one small portion at a time - and most always this leads to faster/easier success.

    Where to begin - 4 digit display seems reasonable.    Unknown/unstated is whether this display is "bare" or includes an ASCII to 7 Segment converter/driver.    (CMOS 4511 past served such role)     Either way - you test to determine first that you can actuate individual segments (for a bare display) or individual numeric patterns (for a converted/driven display.)     Do not use interrupts at this early stage - again that's "too much - and too soon!"     Goal is to minimize complexity - not add to it.     This "violates" your spec of, "Everything runs in the background" - yet does not your landing here signal the bankruptcy of that, "complex, all at once" approach?

    Dawns now (D'uh) that if yours is a "dumb display" you'll have the potential joy/nightmare of employing 28 MCU GPIO (outputs) - or just 11.    (latter is a muxed or scanned display - you trade pin-saving for significant code complexity)    I'm going to "duck" the mux operation for now...

    Once your display control has been properly test/verified you may wish to "load the digits" - as would be required when setting the clock.    Many find it annoying to be able "only" to advance the time - this may score you some "extra credit."    (clearly this is no commercial-bound product)

    Only after succeeding with the display - and its setting/adjustment - should you introduce interrupts.    And its best to do this (again) slowly, with tight limits, testing every step of the way.    Vendor's API includes several dedicated "interrupt" examples - and interrupts appear w/in your board's "demo program."     I'd measure (I mean read) first - and then cut (I mean code) second - to best succeed w/interrupts.

    Does this KISS approach (now) "blip your radar?"    (it should...)