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
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.
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
}