《线程》中讨论的其他部件:EK-TM4C123GXL, TM4C123,
尝试使用计时器捕获模式捕获温度传感器 dht11的信号
如何捕获
中断无法正常工作
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.
尝试使用计时器捕获模式捕获温度传感器 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 延迟
}