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:GPIO 中断

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/614851/tm4c123gh6pm-gpio-interrupt

器件型号:TM4C123GH6PM
主题中讨论的其他器件:LM393

 大家好、

     使用  GPIO 输入 上升沿 中断时遇到问题。  

工具: IAR Embedded Workbench。

应用: 使用  LM393 电机 速度 测量 传感器  获取    直流 电机的速度。

计划:  

  • PF3  被配置 为  具有 上升 沿 中断的输入。  它  与       速度 传感器的数字输出相连。  “ 1” 对应  于~1.25V, “0” <0.25V。
  • 还有    一 个计时器中断: Timer0 、子计时 器 A;   带有 中断  的周期性中断、用于超时。     显示红色 LED。

   代码如下

  • main.c:

#define PART_TM4C123GH6PM

//
#include
#include
#include
#include "inc/hw_gpio.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/sysctl.h"
#include "driverlib/timer.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"

//#include "inc/tm4c123ghp6.h"

#define GPIO_PORTF_DATA_R 0x400253FC //  (*(volatile UINT32_t *) 0x400073FC)

//
//
//! 此项目根据红外传感器信号计算电机速度。
//! 用于产生周期性中断的计时器定义采样时间。
//! 用于在 DO 为高电平时生成中断的 GPIO 端口计算 RPM
//! rpm = count/TS/20 (20条带)*60 (s/min)
//! 速度 v (mm/s)= pi*d (单位:mm)*RPM/60
//

//
//
//包含中断指示符当前值的标志。
//
//
uint32_t g_ui32Flags = 0;
uint32_t red_led = 0;

//
//
//包含传感器 GPIO 输入/执行中断值的标志。
//
//
uint32_t PortFIntFlags = 0;
INT 计数= 0;

int v;//速度;单位:mm/s;= pi*d*count/TS (20ms)/20*1000
浮点 PI = 3.14;// 3.14
int d = 66;//单位:mm
int T = 1000;//单位:mm;对应于1/s
int pulsesperturn = 20;
uint32_t 周期= 32000000;

//
//
//驱动程序库遇到错误时调用的错误例程。
//
//
#ifdef 调试
无效
_error__(char * pcFilename、uint32_t ui32Line)


#endif

//
//
//计时器中断的中断处理程序。
//
//
无效
Timer0IntHandler (空)

   //
   //清除计时器中断。
   //
   TimerIntClear (TIMER0_BASE、TIMER_TINA_TIMEOUT);

   G_ui32Flags = 1;
   //
   //切换计时器的标志。
   //
//   HWREGBITW (&g_ui32Flags、0)^= 1;
   red_led =~red_led;
   
   GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_1、RED_LED);


void PortFIntHandler (void){
 
// PortFIntFlags++;
//
// uint32_t status=0;
//  
// status = GPIOIntStatus (GPIO_PORTF_BASE、true);
//
// GPIOIntClear (GPIO_PORTF_BASE、STATUS);
//
// if (((status & GPIO_INT_PIN_3)== GPIO_INT_PIN_3)
// {
//   count ++;
// }
 
 if (GPIO_PORTF_DATA_R & 0x08!= 0)
 {
   count++;
 }
 
 GPIOIntClear (GPIO_PORTF_BASE、GPIO_INT_PIN_3);

//
//
//此 应用程序计算直流电机的速度
//通过红外传感器。
//
//
内部
main (空)

 
 //将时钟设置为80MHz
 SysCtlClockSet (SYSCTL_SYSDIV_1_SYSCTL_USE_OSC|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHz);

 //
 // GPIO:PF3 -上升沿
 SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
 SysCtlDelay(3);
 GPIOPinTypeGPIOInput (GPIO_PORTF_BASE、GPIO_PIN_3);
// GPIOPadConfigSet (GPIO_PORTF_BASE、GPIO_PIN_3、GPIO_Strength _2mA、GPIO_PIN_TYPE_STD_WPD);
 GPIOIntRegister (GPIO_PORTF_BASE、PortFIntHandler);
 GPIOIntTypeSet (GPIO_PORTF_BASE、GPIO_PIN_3、GPIO_FALLING_EDGE);
 GPIOIntEnable (GPIO_PORTF_BASE、GPIO_INT_PIN_3);
 GPIOIntClear (GPIO_PORTF_BASE、GPIO_INT_PIN_3);

 GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_1);
 
 //Timer0  
 SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);
 SysCtlDelay(3);
 TimerConfigure (TIMER0_BASE、TIMER_CFG_PERIODICASE);
 TimerLoadSet (TIMER0_BASE、TIMER_A、PERIOD);
 //设置计时器超时的中断。
 TimerIntEnable (TIMER0_BASE、TIMER_TINA_TIMEOUT);
 //启用计时器。
 TimerEnable (TIMER0_BASE、TIMER_A);
 
 IntEnable (INT_GPIOF);
 IntEnable (INT_TIMER0A);
 IntMasterEnable();

 while (1)
 {
   如果(g_ui32Flags = 1)
   {
           
     //在计算过程中不处理中断  
     GPIOIntDisable (GPIO_PORTF_BASE、GPIO_INT_PIN_3);
     
     v =(int)1000*pi*d*count/pulsesperturn;
  
     printf ("count =%d\n"、count);
     printf ("v =%d\n"、v);

     计数= 0;
     G_ui32Flags = 0;
     
     GPIOIntEnable (GPIO_PORTF_BASE、GPIO_INT_PIN_3);

   }
 }

  • startup_ewarm.c (部分):

 //
//
//应用程序的 int 处理程序。
//
//
空 Timer0IntHandler (空);
void PortFIntHandler (void);

  IntDefaultHandler、                     //看门狗计时器
   // IntDefaultHandler,                     //计时器0子计时器 A
   Timer0IntHandler、                      //计时器0子计时器 A
   IntDefaultHandler、                     // Timer 0子计时器 B
 

   IntDefaultHandler、                     //闪存控制
//   IntDefaultHandler,                     // GPIO 端口 F
   PortFIntHandler、                       // GPIO 端口 F
   IntDefaultHandler、                     // GPIO 端口 G

问题:

 变量 计数  始终为  但   绿色 LED 随着   旋转 的电机闪烁。

 

我 真的  不知道    问题是什么...

感谢    您的建议和  帮助。

 

 此致。

 

Meidan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    根据实践经验-公司/我(Long)发现、在"一次性"模式下使用一个计时器(而非"周期性")将会"快速、轻松和增强"您的结果。 一个计时器用作"一次性"(即、此"门控"累积计数-由第二个计时器记录(设置为"边沿计数")。

    您可以设置计时器1的(单次触发)持续时间、以便计时器2可以检测到"足够"的脉冲数。 (边沿计数)仅当定时器1 "有效"为定时器2 -能够计数时。 "单次触发"的持续时间越长、测量精度越高...

    ARM MCU 具有多个计时器-通过"单个计时器"尝试执行此任务-增加了极大的复杂性-不建议...
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    非常感谢您的帮助。

    我发现它是一个硬件问题。 LM393 DO 的电压(也是 Tiva c 的 PF3输入)现在可以高达大约5V,因此被识别为“高电平”,从而进入上升沿中断。

    因为我需要在速度移动时获取速度、所以我宁愿选择周期。

    现在、程序可以正常运行、但效果不好、因为变量"count"不是那么稳定。 也许我应该修复电机编码器。 可能是因为我的程序。 代码如下:
    #define PART_TM4C123GH6PM

    //
    #include
    #include
    #include
    #include "inc/hw_gpio.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/sysctl.h"
    #include "driverlib/timer.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"

    //
    //
    //! 此项目根据红外传感器信号计算电机速度。
    //! 用于产生周期性中断的计时器定义采样时间。
    //! 用于在 DO 为高电平时生成中断的 GPIO 端口计算 RPM
    //! rpm = count/TS/20 (20条带)*60 (s/min)
    //! 速度 v (mm/s)= pi*d (单位:mm)*RPM/60
    //! 因此 v (mm/s)= pi*d*count*1000/TS/20
    //

    //
    //
    //包含中断指示符当前值的标志。
    //
    //
    uint32_t g_ui32Flags = 0;

    //
    //
    //包含传感器 GPIO 输入/执行中断值的标志。
    //
    //
    INT 计数= 0;

    //
    int v;//速度;单位:mm/s;= pi*d*count/TS (20ms)/20*1000
    浮点 PI = 3.14;// 3.14
    int d = 65;//单位:mm
    int T = 1000;//单位:ms;对应于1/s
    int pulsesperturn = 20;
    uint32_t period = 16000000;
    int TS = 1000;//单位:ms

    //
    //
    //驱动程序库遇到错误时调用的错误例程。
    //
    //
    #ifdef 调试
    无效
    _error__(char * pcFilename、uint32_t ui32Line)


    #endif

    //
    //
    //计时器中断的中断处理程序。
    //
    //
    空 Timer0IntHandler (空)

    //清除计时器中断。
    TimerIntClear (TIMER0_BASE、TIMER_TINA_TIMEOUT);

    G_ui32Flags = 1;




    空 PortFIntHandler (空)


    GPIOIntClear (GPIO_PORTF_BASE、GPIO_INT_PIN_3);
    count++;


    //
    //
    //此应用程序计算直流电机的速度
    //通过红外传感器。
    //
    //
    int main (空)


    //将时钟设置为16MHz
    SysCtlClockSet (SYSCTL_SYSDIV_1_SYSCTL_USE_OSC|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHz);

    //
    // GPIO:PF3 -上升沿;PF1 -定时器显示
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
    SysCtlDelay(3);
    GPIOPinTypeGPIOInput (GPIO_PORTF_BASE、GPIO_PIN_3);
    GPIOIntRegister (GPIO_PORTF_BASE、PortFIntHandler);
    GPIOIntTypeSet (GPIO_PORTF_BASE、GPIO_PIN_3、GPIO_RISE_EDGE);
    GPIOIntEnable (GPIO_PORTF_BASE、GPIO_INT_PIN_3);
    GPIOIntClear (GPIO_PORTF_BASE、GPIO_INT_PIN_3);

    GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_1);

    //Timer0
    SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);
    SysCtlDelay(3);
    TimerConfigure (TIMER0_BASE、TIMER_CFG_PERIODICASE);
    TimerLoadSet (TIMER0_BASE、TIMER_A、PERIODE-1);
    //设置计时器超时的中断。
    TimerIntEnable (TIMER0_BASE、TIMER_TINA_TIMEOUT);
    //启用计时器。
    TimerEnable (TIMER0_BASE、TIMER_A);

    IntEnable (INT_GPIOF);
    IntEnable (INT_TIMER0A);
    IntMasterEnable();

    while (1)


    如果(g_ui32Flags = 1)

    GPIOIntDisable (GPIO_PORTF_BASE、GPIO_INT_PIN_3);

    v =(int ) pi*d*count*t/pulsesperts/ts;

    计数= 0;

    G_ui32Flags = 0;

    GPIOIntEnable (GPIO_PORTF_BASE、GPIO_INT_PIN_3);






    您是否有任何改进的想法?

    谢谢。

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

    [引用用户="Meidan Zhao ]Tiva c 的 PF3输入电压现在可以高达大约5V

    我的朋友-您必须检查 MCU 的规格以确定该端口和该引脚是否接受~5V!   我记得您的简单电压比较器芯片-输出为"集电极开路"-因此您可以将其恢复为3V3 -消除了"约5V"所引入的任何损坏电势。


    您注意到的关键读数几乎总是源于您(和其他人)选择的"周期定时器"、它会在您的程序上强制执行更多的"时间关键型控制"。   (和-用于什么?)

    单次触发要简单/快得多-一旦"停止"、您就可以优化它的"响应速度"。

    单次触发模式是"kiss Approved (已批准 kiss)"-周期不是-您"创建了"高于所需障碍"-拒绝建议的方法可能不公平-并要求更复杂的努力...