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:计时器中断

Guru**** 2382250 points
Other Parts Discussed in Thread: EK-TM4C123GXL
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1075667/tm4c123gh6pm-dht11-timer-interrupt

部件号:TM4C123GH6PM
《线程》中讨论的其他部件:EK-TM4C123GXLTM4C123

尝试使用计时器捕获模式捕获温度传感器 dht11的信号

如何捕获

中断无法正常工作

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,

     您可能没有为希望计时器在其中运行的模式启用中断。  

     我不熟悉 DHT11。 但是,计时器模块可以在 多种模式下运行(例如,定期超时,边缘时间,边缘计数,PWM)。 蒂瓦尔库有生成中断的计时器示例。  您可以转至 C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\EK-tm4c123gxl\timers 以查看计时器中断的设置方式。 我还包括下面的 timers.c。  

    #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)
        {
        }
    }

    尽管此示例设置为生成定期中断,但如果您选择以边缘时间或其他模式运行计时器,则此想法将相同。 假设您要对应用程序使用边缘时间模式。 你会做如下所示的事情。 这只是在中断模式下使用边缘时间模式的另一个示例。 我不知道您要使用计时器的模式。 您可以参考这些示例创建自己的示例。  

    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 解决了我的问题,并成功地将 dth11与 CCS 中的 tm4c123连接

    #include <stdint.h>
    #include <stdio.h>
    #include <stdbool.h>
    #包括"inc/tm4c123gh6a.h"
    #include "inc/HW_memmap.h"(#include "inc/HW_memmap.h")
    #include "inc/HW_types.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/interrupe.h"
    #include "driverlib/GPIO.h"
    #include "driverlib/timer.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/UART.h"(#include "driverlib/UART.h")
    #include "driverlib/adc.h"
    #include "driverlib/FPC.h"
    #include "utils/uartstdi.h"(#include "utils/uartstdi.h")

    挥发性 int temp[43];
    挥发性 int diff [43];
    volatile unsigned int i=0;
    易失性无符号 int j=0;
    挥发性无符号 int hh = 0;
    挥发性无符号 int HL = 0;
    挥发性无符号 int th =0;
    volatile unsigned int tl = 0;
    易失性无符号 int 校验和=0;
    易失性无符号 int check =0;
    易失性无符号 int dataok =0;
    //函数原型
    void init_timer(void);
    void Duty_cycle (void);

    //全局变量
    UINT32_t sys_clock;
    UINT32_t start = 0,end = 0,length = 0;

    Int main (无效)

    //将系统时钟配置为40 MHz。
    Sysctl 时钟集(sysctl_SYSDIV_5|sysctl_use_PLL |sysctl_XT_16MHz|sysctl_OSC 主);
    sys_clock = SysClockGet();

    //使处理器能够响应中断。
    IntMasterEnable();
    SysPeripheralEnable (sysctl_Periph_GPIOB);//启用端口 B
    GPIOPinTypeGPIOOutput (GPIO _PORTB_BASE,GPIO _PIN_6);//连接 PB6处的传感器
    GPIOPinWrite (GPIO _PORTB_BASE,GPIO _PIN_6,0x00);//关闭 PB6 18毫秒
    delayMs (18);//18ms 延迟
    GPIOPinWrite (GPIO _PORTB_BASE,GPIO _PIN_6,0xff);//在 PB6上
    delayUS(40);//延迟40US
    init_timer();//计时器初始化并将 PB6作为输入计时器

    TimerEnable(TIMER0_base, timer_both );
    int k,l,mul = 1;

    While (1)(同时)

    如果(i >=42)

    对于(j = 1;j <= 8;j++)//第一个8位数据为第一个数组索引
    {//数组{0,0,1,0,0,1}
    如果(diff[j]=1)//整数值为41

    对于(l=0;l<8-j;l++)
    Mul=mul*2;
    hhh=hhh+mul;/hh=41 (如果高于数组)
    }
    MUL=1;//hh 是湿度整数
    }
    Mul=1;
    对于(j = 9;j <= 16;j++)

    IF (diff [j]=1)

    对于(l=0;l<16-j;l++)
    Mul=mul*2;
    HL=HL+mul;//HL 为0.1倍数后的湿度
    }
    Mul=1;
    }
    Mul=1;
    对于(j = 17;j <= 24;j++)

    IF (diff [j]=1)

    对于(l=0;l<24-j;l++)
    Mul=mul*2;
    th=th+mul;//th temp integer
    }
    Mul=1;
    }
    Mul=1;
    对于(j = 25;j <= 32;j++)

    IF (diff [j]=1)

    对于(l=0;l<32-j;l++)
    Mul=mul*2;
    tl=tl+mul;//tl 后。
    }
    Mul=1;
    }
    Mul=1;
    对于(j = 33;j <= 40;j++)

    IF (diff [j]=1)

    对于(l=0;l<40-j;l++)
    Mul=mul*2;
    checksum=checksum+mul;//最后8位(数组的最后8个索引)
    }//将最后8个索引转换为一个整数
    Mul=1;
    }
    Check = hhh+hl+th+tl;
    如果(check == checksum)//check parity (检查=校验和)//last 8 index (最后8个索引)组合整数//增加32个索引整数

    dataok = 1;
    休息;
    }
    否则
    dataok = 0;
    }
    }
    浮动湿度=hhh+(0.1*HL);//湿度值(以%为单位)
    浮点温度=TH+(0.1*tl);//温度值(以腹腔计)
    }


    void init_timer (void)(无效)

    //启用和配置 Timer0外围设备。
    SysPeripheralEnable (sysctl_Periph_TIMER0);

    //初始化计时器 A 以在边缘时间模式下计数
    TimerConfigure(TIMER0_base, Timer_CFG_Split_Pair| timer_CFG_A_CAP_TIME_UP ));

    //计时器 A 记录位置边缘时间
    TimerControlEvent(TIMER0_BASE,TIMER _A,TIMER EVENT_EVENT_POS_EDGE );

    //将计时器计数的值设置为最大0xFFFF
    TimerLoadSet (TIMER0_BASE,TIMER A,0xFFFF);

    //配置计时器读取的引脚(PB6)
    SysPeripheralEnable (sysctl_Periph_GPIOB);
    GPIOPinConfigure (GPIO _PB6_T0CCP0);
    GPIOPinTypeTimer (GPIO _PORTB_BASE,GPIO _PIN_6);

    //寄存器在计时器 A 遇到 Pos EDGE 事件时要调用的中断函数
    国际寄存器(INT_TIMER0A,占空比);//正边缘计时器
    //确保中断被清除
    TimerIntClear (TIMER0_BASE,TIMER CAP_EVENT);
    //启用指定的计时器中断源。
    TimerIntEnable(TIMER0_base, timer_CAP_event);
    //在中断控制器中启用指定的中断。
    IntEnable(INT_TIMER0A);
    }

    //当正值边缘被命中时,记录这些值并找到差异,找到的数据为0或1
    空占空比(空值)

    TimerIntClear (TIMER0_BASE,TIMER CAP_EVENT);
    开始=时间值集(TIMER0_BASE,TIMER _A);
    temp[i]=启动;
    i += 1;
    如果(i>=3)

    diff [I-2]= temp[i-1]- temp[i-2];//找到+ve 边时的计时器间隔
    如果(diff[I-2]<4000)//计时器间隔小于4000表示读取数据0
    diff [I-2]= 0;
    否则
    diff [I-2]= 1;
    }
    }
    无效 delayMs (int ui32M)

    SystlDelay((ui32MS * SysClockGet()/3/1000));/ms 延迟
    }

    作废 delayU (UINT32_t ui32U)

    SystlDelay(ui32U *(SystlClockGet()/3/1000000);//us 延迟
    }