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.

TM4C123GH6PM: dht11: timer interrupt

Part Number: TM4C123GH6PM
Other Parts Discussed in Thread: EK-TM4C123GXL,

trying to capture signals from temperature sensor dht11 using timer capture mode

How to capture

interrupt is not working

  • Hi,

      It is probably that you didn't enable the interrupt for the mode that you want the timer to operate in. 

      I'm not familiar with DHT11. However, the timer module can operate in various modes (e.g. periodic timeout, edge time, edge count, PWM). The TivaWare library has timer example to generate interrupt.  You can go to C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c123gxl\timers to look at how the timer interrupt is setup. I also include the timers.c below. 

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "driverlib/fpu.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/timer.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    //*****************************************************************************
    //
    //! \addtogroup example_list
    //! <h1>Timer (timers)</h1>
    //!
    //! This example application demonstrates the use of the timers to generate
    //! periodic interrupts.  One timer is set up to interrupt once per second and
    //! the other to interrupt twice per second; each interrupt handler will toggle
    //! its own indicator on the display.
    //!
    //! UART0, connected to the Virtual Serial Port and running at 115,200, 8-N-1,
    //! is used to display messages from this application.
    //
    //*****************************************************************************
    
    //*****************************************************************************
    //
    // Flags that contain the current value of the interrupt indicator as displayed
    // on the UART.
    //
    //*****************************************************************************
    uint32_t g_ui32Flags;
    
    //*****************************************************************************
    //
    // The error routine that is called if the driver library encounters an error.
    //
    //*****************************************************************************
    #ifdef DEBUG
    void
    __error__(char *pcFilename, uint32_t ui32Line)
    {
    }
    #endif
    
    //*****************************************************************************
    //
    // The interrupt handler for the first timer interrupt.
    //
    //*****************************************************************************
    void
    Timer0IntHandler(void)
    {
        char cOne, cTwo;
    
        //
        // Clear the timer interrupt.
        //
        MAP_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    
        //
        // Toggle the flag for the first timer.
        //
        HWREGBITW(&g_ui32Flags, 0) ^= 1;
    
        //
        // Use the flags to Toggle the LED for this timer
        //
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, g_ui32Flags << 1);
    
        //
        // Update the interrupt status on the display.
        //
        MAP_IntMasterDisable();
        cOne = HWREGBITW(&g_ui32Flags, 0) ? '1' : '0';
        cTwo = HWREGBITW(&g_ui32Flags, 1) ? '1' : '0';
        UARTprintf("\rT1: %c  T2: %c", cOne, cTwo);
        MAP_IntMasterEnable();
    }
    
    //*****************************************************************************
    //
    // The interrupt handler for the second timer interrupt.
    //
    //*****************************************************************************
    void
    Timer1IntHandler(void)
    {
        char cOne, cTwo;
    
        //
        // Clear the timer interrupt.
        //
        MAP_TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    
        //
        // Toggle the flag for the second timer.
        //
        HWREGBITW(&g_ui32Flags, 1) ^= 1;
    
        //
        // Use the flags to Toggle the LED for this timer
        //
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, g_ui32Flags << 1);
    
        //
        // Update the interrupt status on the display.
        //
        MAP_IntMasterDisable();
        cOne = HWREGBITW(&g_ui32Flags, 0) ? '1' : '0';
        cTwo = HWREGBITW(&g_ui32Flags, 1) ? '1' : '0';
        UARTprintf("\rT1: %c  T2: %c", cOne, cTwo);
        MAP_IntMasterEnable();
    }
    
    //*****************************************************************************
    //
    // Configure the UART and its pins.  This must be called before UARTprintf().
    //
    //*****************************************************************************
    void
    ConfigureUART(void)
    {
        //
        // Enable the GPIO Peripheral used by the UART.
        //
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
        //
        // Enable UART0
        //
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    
        //
        // Configure GPIO Pins for UART mode.
        //
        MAP_GPIOPinConfigure(GPIO_PA0_U0RX);
        MAP_GPIOPinConfigure(GPIO_PA1_U0TX);
        MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        //
        // Use the internal 16MHz oscillator as the UART clock source.
        //
        UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    
        //
        // Initialize the UART for console I/O.
        //
        UARTStdioConfig(0, 115200, 16000000);
    }
    
    //*****************************************************************************
    //
    // This example application demonstrates the use of the timers to generate
    // periodic interrupts.
    //
    //*****************************************************************************
    int
    main(void)
    {
        //
        // Enable lazy stacking for interrupt handlers.  This allows floating-point
        // instructions to be used within interrupt handlers, but at the expense of
        // extra stack usage.
        //
        MAP_FPULazyStackingEnable();
    
        //
        // Set the clocking to run directly from the crystal.
        //
        MAP_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                           SYSCTL_XTAL_16MHZ);
    
        //
        // Initialize the UART and write status.
        //
        ConfigureUART();
    
        UARTprintf("\033[2JTimers example\n");
        UARTprintf("T1: 0  T2: 0");
    
        //
        // Enable the GPIO port that is used for the on-board LED.
        //
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    
        //
        // Enable the GPIO pins for the LED (PF1 & PF2).
        //
        MAP_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_1);
    
    
        //
        // Enable the peripherals used by this example.
        //
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    
        //
        // Enable processor interrupts.
        //
        MAP_IntMasterEnable();
    
        //
        // Configure the two 32-bit periodic timers.
        //
        MAP_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
        MAP_TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
        MAP_TimerLoadSet(TIMER0_BASE, TIMER_A, MAP_SysCtlClockGet());
        MAP_TimerLoadSet(TIMER1_BASE, TIMER_A, MAP_SysCtlClockGet() / 2);
    
        //
        // Setup the interrupts for the timer timeouts.
        //
        MAP_IntEnable(INT_TIMER0A);
        MAP_IntEnable(INT_TIMER1A);
        MAP_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
        MAP_TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    
        //
        // Enable the timers.
        //
        MAP_TimerEnable(TIMER0_BASE, TIMER_A);
        MAP_TimerEnable(TIMER1_BASE, TIMER_A);
    
        //
        // Loop forever while the timers run.
        //
        while(1)
        {
        }
    }

    Although this example is setup to generate a periodic interrupt but the idea will be the same if you choose to operate timer in Edge Time or other modes. Let's say you want to use Edge Time mode for your application. You would do something like below. This is just another example for using edge time mode in interrupt mode. I don't know which mode you want to use the timer for. You can reference these examples to create your own. 

    void init_timer(void)
    {
        // Enable and configure Timer0 peripheral.
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    
        // Initialize timer A and B to count up in edge time mode
        TimerConfigure(TIMER0_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP | TIMER_CFG_B_CAP_TIME_UP));
    
        // Timer a records pos edge time and Timer b records neg edge time
        TimerControlEvent(TIMER0_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);
        TimerControlEvent(TIMER0_BASE, TIMER_B, TIMER_EVENT_NEG_EDGE);
    
        //set the value that the timers count to
        TimerLoadSet(TIMER0_BASE, TIMER_BOTH, PRELOAD);
        TimerSynchronize(TIMER0_BASE,TIMER_0A_SYNC|TIMER_0B_SYNC );
    
        //Configure the pin that the timer reads from (PB6)
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        GPIOPinConfigure(GPIO_PB6_T0CCP0);
        GPIOPinConfigure(GPIO_PB7_T0CCP1);
        GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    
        TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT|TIMER_CAPB_EVENT);
        // Enable the indicated timer interrupt source.
        TimerIntEnable(TIMER0_BASE, TIMER_CAPA_EVENT|TIMER_CAPB_EVENT);
        // The specified interrupt is enabled in the interrupt controller.
        IntEnable(INT_TIMER0A);
        IntEnable(INT_TIMER0B);
    
    }
    
    //When negative edge is hit, record the values and find the difference, output to putty
    void Timer0AIntHandler(void)
    {
        TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT);
        start = TimerValueGet(TIMER0_BASE, TIMER_A);
    }
    
    void Timer0BIntHandler(void)
    {
        TimerIntClear(TIMER0_BASE, TIMER_CAPB_EVENT);
        end = TimerValueGet(TIMER0_BASE, TIMER_B);
        length = end - start;
        int_flag = 1;
    
    }

  • //I solve my issue and connect dth11 with tm4c123 in ccs successfully

    #include <stdint.h>
    #include <stdio.h>
    #include <stdbool.h>
    #include "inc/tm4c123gh6pm.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/gpio.h"
    #include "driverlib/timer.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/uart.h"
    #include "driverlib/adc.h"
    #include "driverlib/fpu.h"
    #include "utils/uartstdio.h"

    volatile int temp[43];
    volatile int diff[43];
    volatile unsigned int i=0;
    volatile unsigned int j=0;
    volatile unsigned int hh = 0;
    volatile unsigned int hl = 0;
    volatile unsigned int th = 0;
    volatile unsigned int tl = 0;
    volatile unsigned int checksum = 0;
    volatile unsigned int check = 0;
    volatile unsigned int dataok = 0 ;
    // function prototypes
    void init_timer(void);
    void duty_cycle(void);

    // global variables
    uint32_t sys_clock;
    uint32_t start = 0, end = 0, length = 0;

    int main(void)
    {
    // Configure system clock at 40 MHz.
    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
    sys_clock = SysCtlClockGet();

    // Enable the processor to respond to interrupts.
    IntMasterEnable();
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); //enable port B
    GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_6); //connect sensor at PB6
    GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_6, 0x00); //off PB6 for 18 ms
    delayMs(18) ; //18ms delay
    GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_6, 0xff); //on PB6
    delayUs(40) ; //delay 40us
    init_timer(); // timer initialisation and make PB6 as a input timer

    TimerEnable(TIMER0_BASE, TIMER_BOTH);
    int k,l,mul=1;

    while(1)
    {
    if (i >= 42)
    {
    for (j = 1; j <= 8; j++) //first 8bit data is of first array index
    { // array {0,0,1,0,1,0,0,1}
    if(diff[j]==1) //integer value is 41
    {
    for(l=0;l<8-j;l++)
    mul=mul*2;
    hh=hh+mul; //hh=41 when above array
    }
    mul=1; //hh is humidity integer
    }
    mul=1;
    for (j = 9; j <= 16; j++)
    {
    if(diff[j]==1)
    {
    for(l=0;l<16-j;l++)
    mul=mul*2;
    hl=hl+mul; //hl is humidity after . with 0.1 multiple
    }
    mul=1;
    }
    mul=1;
    for (j = 17; j <= 24; j++)
    {
    if(diff[j]==1)
    {
    for(l=0;l<24-j;l++)
    mul=mul*2;
    th=th+mul; //th temp integer
    }
    mul=1;
    }
    mul=1;
    for (j = 25; j <= 32; j++)
    {
    if(diff[j]==1)
    {
    for(l=0;l<32-j;l++)
    mul=mul*2;
    tl=tl+mul; //tl after .
    }
    mul=1;
    }
    mul=1;
    for (j = 33; j <= 40; j++)
    {
    if(diff[j]==1)
    {
    for(l=0;l<40-j;l++)
    mul=mul*2;
    checksum=checksum+mul; //last 8bit(last 8 index of array)
    } //convert last 8 index into one integer
    mul=1;
    }
    check = hh+hl+th+tl;
    if (check == checksum) //check parity//last 8 index combined integer//addition of 32 index integer
    {
    dataok = 1;
    break;
    }
    else
    dataok = 0;
    }
    }
    float humidity=hh+(0.1*hl); //humidity value in %
    float temparature=th+(0.1*tl); //temp value in celsious
    }


    void init_timer(void)
    {
    // Enable and configure Timer0 peripheral.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

    // Initialize timer A to count up in edge time mode
    TimerConfigure(TIMER0_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP ));

    // Timer A records pos edge time
    TimerControlEvent(TIMER0_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);

    //set the value that the timers count to max 0xffff
    TimerLoadSet(TIMER0_BASE, TIMER_A, 0xffff);

    //Configure the pin that the timer reads from (PB6)
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    GPIOPinConfigure(GPIO_PB6_T0CCP0);
    GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_6);

    // Registers a interrupt function to be called when timer A hits a Pos edge event
    IntRegister(INT_TIMER0A, duty_cycle); //positive edge timer
    // Makes sure the interrupt is cleared
    TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT);
    // Enable the indicated timer interrupt source.
    TimerIntEnable(TIMER0_BASE, TIMER_CAPA_EVENT);
    // The specified interrupt is enabled in the interrupt controller.
    IntEnable(INT_TIMER0A);
    }

    //When positive edge is hit record the values and find the difference, and found data is 0 or 1
    void duty_cycle(void)
    {
    TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT);
    start = TimerValueGet(TIMER0_BASE, TIMER_A);
    temp[i] = start;
    i += 1;
    if (i>=3)
    {
    diff[i-2]=temp[i-1]-temp[i-2]; //timer interval when +ve edge found
    if(diff[i-2]<4000) //when timer interval is less than 4000 means data 0 read
    diff[i-2]=0;
    else
    diff[i-2]=1;
    }
    }
    void delayMs(int ui32Ms)
    {
    SysCtlDelay((ui32Ms * SysCtlClockGet() /3/ 1000)); //ms delay
    }

    void delayUs(uint32_t ui32Us)
    {
    SysCtlDelay(ui32Us * (SysCtlClockGet() / 3 / 1000000)); //us delay
    }