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 引脚中断不#39;更改类型

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/588636/tm4c123gh6pm-gpio-pin-interrupt-wont-change-type

器件型号:TM4C123GH6PM

这位于 Tiva C LaunchPad 上。

我尝试使用1个引脚作为过零检测引脚、并触发中断。  我希望中断类型为高级检测类型、以便在过零时立即获得中断。  但是、我尝试使用的引脚仅用作下降沿检测。  以下是引脚和中断的配置代码(完整初始化例程如下所示):

//将端口 E 的引脚1配置为具有高电平检测中断的输入。
//这用于过零检测
GPIOPinTypeGPIOInput (GPIO_Porte _BASE、GPIO_PIN_1);
IntEnable (INT_GPIOE);
GPIOIntEnable (GPIO_Porte _BASE、GPIO_INT_PIN_1);
GPIOIntRegister (INT_GPIOE、零交叉);
GPIOIntTypeSet (INT_GPIOE、GPIO_INT_PIN_1、GPIO_HIGH_LEVEL);
Dummie=GPIOIntTypeGet (INT_GPIOE、GPIO_INT_PIN_1);

我添加了'dmie' int 以查看中断类型的实际值是多少、无论我在其中放置的类型是什么(_low_level 或_rising_edge 等)、它始终为65、536 (十进制)。  我还将一个万用表连接到该引脚、以确认何时处于0V 以及何时进入3.3V (由 LaunchPad 引脚提供)。  中断部分工作正常、但仅下降沿工作。

有没有关于我在这里可能会做些什么的想法?

Int Initialize (空)

//将系统时钟初始化为40MHz
SysCtlClockSet (SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHz|SYSCTL_OSC_MAIN);

//启用外设
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);
SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);
SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);
SysCtlPeripheralEnable (SYSCTL_Periph_ADC1);
//我们必须等待几个时钟周期才能启用外设
//在继续之前,此 while 循环将允许启用外设
while (!SysCtlPeripheralReady (SYSCTL_Periph_ADC1))

//将 Timer0配置为一次性计时器
TimerConfigure (TIMER0_BASE、TIMER_CFG_ONE_SHOT);
//使能并将 Timer0上的中断配置为超时
IntEnable (INT_TIMER0A);
TimerIntEnable (TIMER0_BASE、TIMER_TINA_TIMEOUT);

//将 GPIO 端口 E 引脚2、3初始化为模拟引脚
GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_2|GPIO_PIN_3);

//将端口 F 的引脚1配置为输出。 这是连接红色 LED 的位置
GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_1);

//将端口 E 的引脚1配置为具有高电平检测中断的输入。
//这用于过零检测
GPIOPinTypeGPIOInput (GPIO_Porte _BASE、GPIO_PIN_1);
IntEnable (INT_GPIOE);
GPIOIntEnable (GPIO_Porte _BASE、GPIO_INT_PIN_1);
GPIOIntRegister (INT_GPIOE、零交叉);
GPIOIntTypeSet (INT_GPIOE、GPIO_INT_PIN_1、GPIO_LOW_LEVEL);
Dummie=GPIOIntTypeGet (INT_GPIOE、GPIO_INT_PIN_1);


//为 ADC 0和1配置序列发生器
ADCSequenceConfigure (ADC0_BASE、0、ADC_TRIGGER_PROCESSOR、0);
ADCSequenceConfigure (ADC1_base、0、ADC_TRIGGER_PROCESSOR、0);

//配置 ADC 步骤
ADCSequenceStepConfigure (ADC0_BASE、0、0、ADC_CTL_CH0|ADC_CTL_IE|ADC_CTL_END);
ADCSequenceStepConfigure (ADC1_base、0、0、ADC_CTL_CH1|ADC_CTL_IE|ADC_CTL_END);

//启用 ADC 序列发生器0和1
ADCSequenceEnable (ADC0_BASE、0);
ADCSequenceEnable (ADC1_BASE、0);

//启用中断
IntMasterEnable();

返回(0);

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Shane、
    1) 1)是否确定您是指过零? GPIO 是逻辑输入、其读数为"是"或"否" 表示是的最小电压不是一个完美的阈值、大约为0.7 x VDD (在数据表中进行检查和确认)。 表示 NO 的最大电压也不是一个理想值、数据表中也对此进行了说明。 如果您正在寻找过零(例如、在测量市电交流频率/相位时)、您将需要额外的电路、并且需要让我们知道这如何将您的逻辑电平修改为 GPIO。
    2) 2)请使用粘贴您的代码 界面的按钮、或者用户尝试提供帮助变得太混乱了。
    此致
    布鲁诺
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我的问题不在于信号到达引脚、所以我们忽略外部电路、假设我在过零时在引脚上获得+3.3至5Vdc 信号。 我的问题是我做了什么 
    引脚配置不正确、因为它只能提供下降沿检测。 我已将下面的代码与粘贴在一起 但下面是专门处理该引脚和中断的代码:

    //将端口 E 的引脚1配置为输入。 这表示0交叉检测 GPIOPinTypeGPIOInput (GPIO_Porte _BASE、GPIO_PIN_1); //在端口 E 引脚1上启用中断 IntEnable (INT_GPIOE); 内部寄存器(INT_GPIOE、零交叉); GPIOIntEnable (GPIO_Porte _BASE、GPIO_INT_PIN_1); GPIOIntTypeSet (INT_GPIOE、GPIO_INT_PIN_1、GPIO_HIGH_LEVEL);






    //
    // 声明头文件
    #include 
    #include 
    #include "inc/tm4c123gh6m.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"
    #define "driverlib/driver.h"#define "driverlib"#define "driverlib.cd/driverlib"#define "driver.h"#define "driverlib.cd/driverlib"#define #include "driver.h"#define "driverlib"#define "driver.h"#define "driverlib.
    
    
    
    
    //系统时钟周期数/触发角的度数
    //结果来自:
    //40MHz (系统时钟频率)
    ///------------------
    //[60 (线路频率)*2 (我们只对半个周期感兴趣)*180 (半个周期中的度数)
    //= 1851.8周期/ 1/2线频正弦波的触发角
    
    
    //*********
    
    //
    // 声明函数
    int Initialize (void);
    int Sample (void);
    int Control (void);
    int manipulation (void);
    void ZerCrossing (void);
    空 Timer0 (空);
    //*********
    
    //
    // 声明/初始化变量
    uint32_t Theta=0;
    uint32_t FireTime=0;
    uint32_t Reference=0;
    uint32_t VelocityFB=0;
    int32_t Error=0;
    
    
    //
    
    
    int main (void)
    {
    //初始化外设(I/O、ADC 等)
    initialize();
    
    //运行一个无限循环,我们在其中进行采样、计算控制和输出操作
    while (1)
    {
    //对 ADC 引脚进行采样
    sample ();
    
    //根据计算操作
    control();
    
    }
    }
    
    
    //*********
    //********* 功能声明
    //
    
    
    //
    // Initialize()函数
    int Initialize(void){
    
    
    //将系统时钟初始化为40MHz
    SysCtlClockSet (SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHz|SYSCTL_OSC_MAIN);
    
    //启用外设
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);
    SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);
    SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);
    SysCtlPeripheralEnable (SYSCTL_Periph_ADC1);
    //我们必须等待几个时钟周期才能启用外设
    //在继续之前,此 while 循环将允许启用外设
    while (!SysCtlPeripheralReady (SYSCTL_Periph_ADC1))
    {
    }
    
    //将 Timer0配置为一次性计时器
    TimerConfigure (TIMER0_BASE、TIMER_CFG_ONE_SHOT);
    //使能并将 Timer0上的中断配置为超时
    IntEnable (INT_TIMER0A);
    TimerIntEnable (TIMER0_BASE、TIMER_TINA_TIMEOUT);
    
    //将 GPIO 端口 E 引脚2、3初始化为模拟引脚
    GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_2|GPIO_PIN_3);
    
    //将端口 F 的引脚1配置为输出。 这是连接红色 LED 的位置
    GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_1);
    
    //将端口 E 的引脚1配置为输入。 这表示0交叉检测
    GPIOPinTypeGPIOInput (GPIO_Porte _BASE、GPIO_PIN_1);
    
    //在端口 E 引脚1上启用中断
    IntEnable (INT_GPIOE);
    内部寄存器(INT_GPIOE、零交叉);
    GPIOIntEnable (GPIO_Porte _BASE、GPIO_INT_PIN_1);
    GPIOIntTypeSet (INT_GPIOE、GPIO_INT_PIN_1、GPIO_HIGH_LEVEL);
    
    
    //为 ADC 0和1配置序列发生器
    ADCSequenceConfigure (ADC0_BASE、0、ADC_TRIGGER_PROCESSOR、0);
    ADCSequenceConfigure (ADC1_base、0、ADC_TRIGGER_PROCESSOR、0);
    
    //配置 ADC 步骤
    ADCSequenceStepConfigure (ADC0_BASE、0、0、ADC_CTL_CH0|ADC_CTL_IE|ADC_CTL_END);
    ADCSequenceStepConfigure (ADC1_base、0、0、ADC_CTL_CH1|ADC_CTL_IE|ADC_CTL_END);
    
    //启用 ADC 序列发生器0和1
    ADCSequenceEnable (ADC0_BASE、0);
    ADCSequenceEnable (ADC1_BASE、0);
    
    //启用中断
    IntMasterEnable();
    
    退货(0);
    }
    //*********
    
    //
    // sample ()函数
    int Sample (void){
    
    //清除 ADC 中断状态标志
    ADCIntClear (ADC0_BASE、0);
    ADCIntClear (ADC1_BASE、0);
    
    //触发 ADC
    ADCProcessorTrigger (ADC0_BASE、0);
    while (!ADCIntStatus (ADC0_BASE、0、false))
    {
    }
    
    ADCProcessorTrigger (ADC1_base、0);
    while (!ADCIntStatus (ADC1_base、0、false))
    {
    }
    
    //获取样本并将其放入缓冲区
    ADCSequenceDataGet (ADC0_BASE、0、参考);
    ADCSequenceDataGet (ADC1_base、0、VelocityFB);
    
    退货(0);
    }
    //********
    
    
    //
    // control()函数
    int Control (void)
    {
    
    //计算误差
    error=(Reference-VelocityFB);
    
    //如果误差大于0,则计算 Theta
    if (Error>0){
    //Calculate the firing time by getting the % error and 乘以180
    //获得我们需要的触发度数。 然后乘以
    //循环/度数,以获得被输入 Timer0的触发时间。
    //公式看起来很奇怪,因为我们处理整数,所以是除法
    //将导致截断,因此需要最后进行。
    FireTime=(SYSCYC_DEG*(4095-Error)*180)/4095;
    }
    //如果错误小于0,则我们将触发时间设置为333,361,比最大值高1
    //上面的 FireTime 方程式
    其他
    {FireTime=333361;
    
    }
    
    退货(0);
    }
    //*********
    
    
    //
    // ZeroCrossing() ISR
    void ZerCrossing(vo){
    
    
    //清除中断
    GPIOIntClear (GPIO_Porte _BASE、GPIO_INT_PIN_1);
    
    //确定如果出现正错误,是否应加载/启用 Timer0
    //(即如果基准大于反馈)
    
    if (FireTime<333361){
    //加载最新的操作
    TimerLoadSet (TIMER0_BASE、TIMER_A、FireTime-1);
    //启用和启动计时器
    TimerEnable (TIMER0_BASE、TIMER_A);
    }
    }
    //*********
    
    //
    // Timer0 () ISR
    void Timer0 (void){
    //清除中断
    TimerIntClear (TIMER0_BASE、TIMER_TINA_TIMEOUT);
    //禁用计时器以将其复位
    TimerDisable (TIMER0_BASE、TIMER_A);
    //将1写入 PF1
    GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_1、0x02);
    //延迟时钟周期
    SysCtlDelay (FireTime*100);
    //将0写入 PF1
    GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_1、0x00);
    
    }
    //*********
    
    
    
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    不知道为什么当我按"返回"时、RTF 格式无法识别、但下面是我尝试以普通格式发布的第一部分:

    我的问题不在于信号到达引脚、所以我们忽略外部电路、假设我在过零时在引脚上获得+3.3至5Vdc 信号。 我的问题是、我在引脚配置方面做了哪些不当操作、因为它只能提供下降沿检测。 我已将下面的代码与粘贴在一起 但下面是专门处理该引脚和中断的代码:
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在 GPIOIntTypeSet()上使用 GPIO_both _edge;
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    请相信您的代码“未命中”对“GPIOPinIntEnable()”的(必需的)调用。  实际上-有如此多的此类(GPIO Int)调用!

    这种"GPIOPinIntEnable() "添加应该使您的"rising Edge"正常工作。

    我也担心您设置的"Timer0"

    TimerConfigure (TIMER0_BASE、TIMER_CFG_ONE_SHOT); // CB1 -我认为"TIMER_CFG_A_ONE_SHOT"更好。  (与您的 IntEnable 更好的配合)  

    //使能并将 Timer0上的中断配置为超时

      IntEnable (INT_TIMER0A);

    因此、我要用 TimerConfigure (TIMER0_BASE、 TIMER_CFG_SPLIT_PAIR |  TIMER_CFG_A_ONE_SHOT)替换上述内容; // CB1版本

    此外、您的"设置/配置"的单次计时器似乎缺少几个(正常)计时器函数调用...   这是我所在公司的此类计时器呼叫(已知正常!)列表

    ROM_TimerDisable (Timer1_base、timer_B);

    ROM_TimerConfigure (Timer1_base、TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_ONE_SHOT);

    ROM_TimerLoadSet (Timer1_base、timer_B、25000);// 500uS

    ROM_TimerIntEnable (Timer1_base、TIMER_TIMB_TIMEOUT);

    ROM_IntEnable (INT_TIMER1B);

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

    哇,我不知道我是这么少了。  我一直在关注 LaunchPad 技术讲座练习,我的电路一直运行良好,因此我没有在必要时深入研究 PDL。

    我更改了计时器的配置语句,并禁用了每个计时器的未使用部分。  我猜我可以单独使用计时器0的 A 和 B 部分,而不是使用计时器0的 A 部分和计时器1的 A 部分?

    感谢您指出这些内容。  是否有任何资源建议您了解有关 PDL 的更多信息以及如何使用它?

    就引脚中断而言,我注意到当我触摸导线时,会有一个电压尖峰触发中断。  所以,也许 MCU 工作正常,但我测试的房间里有噪音?  当我触摸电线和假层压木工作台并连接一个仪表时、我会得到高达700mV 交流电压和400mVdc 的电压尖峰。  连接的仪表似乎改变了电路的行为、因此我认为电压尖峰大于未连接仪表的电压尖峰。  我还将 LaunchPad 板插入桌面上的计算机(如果这会产生影响)。

    我添加了一个上拉电阻器(1k)和去耦电容器(330n)、但幸运的是、它除了下降沿之外还能执行任何操作。

    哇,我不知道我是这么少了。  我一直在关注 LaunchPad 技术讲座练习,我的电路一直运行良好,因此我没有在必要时深入研究 PDL。
     
    我更改了计时器的配置语句,并禁用了每个计时器的未使用部分。  我猜我可以单独使用计时器0的 A 和 B 部分,而不是使用计时器0的 A 部分和计时器1的 A 部分?
    感谢您指出这些内容。  是否有任何资源建议您了解有关 PDL 的更多信息以及如何使用它?
    就引脚中断而言,我注意到当我触摸导线时,会有一个电压尖峰触发中断。  所以,也许 MCU 工作正常,但我测试的房间里有噪音?  当我触摸电线和假层压木工作台并连接一个仪表时、我会得到高达700mV 交流电压和400mVdc 的电压尖峰。  连接的仪表似乎改变了电路的行为、因此我认为电压尖峰大于未连接仪表的电压尖峰。  我还将 LaunchPad 板插入桌面上的计算机(如果这会产生影响)。
    我添加了一个上拉电阻器(1k)和去耦电容器(330n)、但幸运的是、它除了下降沿之外还能执行任何操作。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢您-欢迎您的参与。   API 如此强大和广泛的"缺点"(如果有)是它的深度、以及获得熟悉程度所需的时间/精力之后才掌握。

    我不喜欢您(可能)通过"手指测试"将 ESD 引入电路板的想法。  请注意、虽然您的仪表报告"低于1000mV 的尖峰"、但很少有这样的仪表响应足够快、可以捕获并显示"真实结果!"   (实际需要的示波器)  在执行这些测试时、特定的 MCU 输入可能会损坏(过压)、因此"盲目"进一步"上升沿"。  (这种有限的损坏-可能允许相同的输入-感应"下降沿!"  (让您更加疯狂)

    建议您暂时采用:

    • 更改为另一个方便访问的 MCU GPIO (一个出现在电路板接头上)重新配置(通过您的新知识)-"避免手指测试"-并进行测试和观察。
    • 您的外部电路必须"过零检测"并为该"上升沿"敏感型 GPIO 提供" MCU 正确"~3V3或~0V。   您的电路的"上升时间"是否证明 MCU 的(上升)边沿检测器无法正确识别"过长"(因此过慢)?  (EDGE 表示一些最小 dV/dT)  再次-示波器极大地帮助了-在这方面。  此外、如果过零检测电路很粗糙、则可能会产生损坏的瞬态-您的仪表将(从不)注意到这一点。  (请注意海报-示波器预算- ASAP) 如果零交叉检测电路由"单极3V3"供电、则会更安全-这会降低超出 MCU 接受范围的电压瞬变的可能性。  (如果改为-由>5V 电源供电-尤其是通过"双极"(±双电源)供电-必须采用附加的输出电压"限制"-以"节省"您的 MCU。
    • 您已添加1K 上拉电阻-它应该"拉"至3V3 (不是更高!)   并且-您的过零电路是否具有驱动所需灌电流能力的输出能力-以创建有效的"低电平?"  (1K 的值可能太低- 4K7附近-建议)  请务必重复测试-以确认您确实在向 MCU 的 GPIO "馈送3V3和0V 电压"。
    • 产生这样的结果:MCU 和"过零"组件之间存在一种出色的测试方法-临时"断开""边缘检测"连接-并从(另一个) MCU GPIO 驱动您的新 MCU 输入-设置为输出。  然后、您只需"切换"该输出-低速率-(甚至)您的慢响应仪表就可以保持正常工作。  当然、这可用作"上升沿检测"的有效输入-前提是您已按照前面有关"上升沿"的 MCU 输入设置/配置的指导进行操作。

    留出足够的时间阅读、浏览、摘要以及与 PDL 进行交互(加载、运行、单步执行-多个代码示例)。  (外设驱动程序库)  该文档的广度是"双刃"(值得一看)-需要大量的努力-但真正"物有所值"。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    所有好建议。 今天我已经开始这个项目、但我将在下周早些时候尝试您的建议。 感谢您的回答、并解释了我不知道的周围细节。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Shane M"]所有很好的建议。[/引用]

    我认为是这样-但所有的信用都必须流过"亲吻"-这经常(阻止或大大减少)我们进入"死胡同"的路径/尝试。

    您已创建(许多)位/段的"交错"-已将它们全部连接在一起-然后(然后)按下"运行!"   这与“亲吻!”的规则是不一样的!  (通常会导致系统故障!)

    KISS -与之形成鲜明对比-指示:

    • 仅关注目标的一小部分
    • 实施并测试/观察该部分-如果很复杂、则应早于而不是晚于此。   对其余所有部分重复上述2个步骤。
    • 仅当项目的所有此类"部分/部分"已(连续)测试/验证-尝试加入-但要"智能"(一次仅加入2个)
    • 测试项目"部分/部分"的所有可能(实际)的"接合或耦合"
    • 只有这样-在确认每个/每个"部分/部分"的情况下、按"运行"。

    请注意、"方法"(通常在此处)-构建所有内容-然后(开始)测试-为用户带来了巨大的挑战。  一切都是可疑的!   从何处开始探查/检查?    并非所有这些(过早实施)"部分/部分"互连(现在非常重要)都阻碍了这一目标?   这(方法)是否有意义?

    KISS (长期)已经证明、"快速、轻松、增强"了大部分工作-跨多个领域。   遗憾的是(单词)很少(即从不)在此处"发挥作用"(由供应商的小程序)。  (远离莫特利)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    好的、我终于回到了这个项目。 我稍微清理了代码/注释、并将过零中断引脚更改为 E5、然后将 C5更改为相同的结果。 我还尝试将中断类型更改为任何其他类型的中断、但没有效果。 是否需要将引脚设置为灌电流或拉电流? 我将通读 GPIO 的整个 PDL、看看我是否缺少任何内容。

    最后、我尝试了您建议的关于将另一个引脚配置为输出的技巧、但它似乎不是很好。 我的代码肯定是问题所在、但在尝试不同的中断引脚后、我很确定这些引脚是否正常、我只是缺少了一些东西。

    我将在下面发布我的更新代码。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    //
    // 声明头文件
    #include 
    #include 
    #include "inc/tm4c123gh6m.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"
    #define "driverlib/driver.h"#define "driverlib"#define "driverlib.cd/driverlib"#define "driver.h"#define "driverlib.cd/driverlib"#define #include "driver.h"#define "driverlib"#define "driver.h"#define "driverlib.
    
    
    
    
    //系统时钟周期数/触发角的度数
    //结果来自:
    //40MHz (系统时钟频率)
    ///------------------
    //[60 (线路频率)*2 (我们只对半个周期感兴趣)*180 (半个周期中的度数)
    //= 1851.8周期/ 1/2线频正弦波的触发角
    
    
    //*********
    
    //
    // 声明函数
    int Initialize (void);
    void Sample (void);
    int Control (void);
    int manipulation (void);
    void ZerCrossing (void);
    空 Timer0 (空);
    //*********
    
    //
    // 声明/初始化变量
    uint32_t Theta=0;
    uint32_t FireTime=0;
    uint32_t Reference=0;
    uint32_t VelocityFB=0;
    int32_t Error=0;
    uint32_t SampleFreq=0;
    
    
    //*********
    
    
    int main (void)
    {
    Initialize();//Initialization 例程
    
    //运行无限循环并让中断完成困难的工作
    while (1)
    {
    }
    }
    
    
    //*********
    //********* 功能声明
    //
    
    
    //
    // Initialize()函数
    int Initialize(void){
    
    
    //将系统时钟初始化为40MHz
    SysCtlClockSet (SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHz|SYSCTL_OSC_MAIN);
    
    //启用外设
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOC);
    SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);
    SysCtlPeripheralEnable (SYSCTL_Periph_Timer1);
    SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);
    SysCtlPeripheralEnable (SYSCTL_Periph_ADC1);
    while (!SysCtlPeripheralReady (SYSCTL_Periph_ADC1))//等待最后一个外设被启用
    {
    }
    
    //配置 Timer0A
    TimerConfigure (TIMER0_BASE、TIMER_CFG_A_ONE_SHOT);//将 Timer0配置为一次性(用于 ZCD)
    TimerDisable (TIMER0_BASE、TIMER_B); //禁用 Timer0B
    IntEnable (INT_TIMER0A); //为 Timer0A 启用中断
    TimerIntEnable (TIMER0_BASE、TIMER_TINA_TIMEOUT);//为 Timer0A 超时启用中断
    
    
    //Timer1A 设置
    TimerConfigure (Timer1_base、timer_CFG_A_PERIODICRACRACASE); //配置计时器1A 以进行周期性计时
    SampleFreq=(SysCtlClockGet ()/5); //根据系统时钟计算采样频率
    TimerLoadSet (Timer1_base、timer_A、SampleFreq -1); //加载 Timer1A,具有采样频率
    TimerDisable (Timer1_base、timer_B); //禁用 Timer1B
    IntEnable (INT_TIMER1A); //为 Timer1A 启用中断
    TimerIntEnable (Timer1_base、timer_TINA_TIMEOUT); //在超时时为 Timer1A 启用中断
    TimerEnable (Timer1_base、timer_A); //启用 Timer1A
    
    GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_1);//将 PF1配置为输出(红色 LED)
    
    //配置 PC5
    GPIOPinTypeGPIOInput (GPIO_PORTC_BASE、GPIO_PIN_5); //将 PC5配置为输入
    IntEnable (INT_GPIOC); //在端口 C 上启用中断
    GPIOIntRegister (INT_GPIOC、零交叉); //为 Porte 注册中断
    GPIOIntEnable (GPIO_PORTC_BASE、GPIO_INT_PIN_5); //启用 PC5的中断
    GPIOIntTypeSet (INT_GPIOC、GPIO_INT_PIN_5、GPIO_RISING _EDGE);//为上升电平配置 PC5中断
    
    //配置 ADC
    GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_2|GPIO_PIN_3); //将 GPIO 端口 E 引脚2、3初始化为模拟引脚
    ADCSequenceConfigure (ADC0_BASE、0、ADC_TRIGGER_PROCESSOR、0); //为 ADC0配置序列发生器
    ADCSequenceConfigure (ADC1_base、0、ADC_TRIGGER_PROCESSOR、0); //为 ADC1配置序列发生器
    ADCSequenceStepConfigure (ADC0_BASE、0、0、ADC_CTL_CH0|ADC_CTL_IE|ADC_CTL_END);//配置 ADC0步骤0
    ADCSequenceStepConfigure (ADC1_base、0、0、ADC_CTL_CH1|ADC_CTL_IE|ADC_CTL_END);//配置 ADC1步骤1
    ADCSequenceEnable (ADC0_BASE、0); //为 ADC0启用序列发生器
    ADCSequenceEnable (ADC1_BASE、0); //为 ADC1启用序列发生器
    
    //启用所有中断
    IntMasterEnable();
    
    退货(0);
    }
    //*********
    
    //
    // sample ()函数
    void Sample (void){
    
    //清除 ADC 中断状态标志
    ADCIntClear (ADC0_BASE、0);
    ADCIntClear (ADC1_BASE、0);
    
    //触发 ADC
    ADCProcessorTrigger (ADC0_BASE、0);
    SysCtlDelay(3);
    ADCProcessorTrigger (ADC1_base、0);
    SysCtlDelay(3);
    
    //获取样本并将其放入缓冲区
    ADCSequenceDataGet (ADC0_BASE、0、参考);
    ADCSequenceDataGet (ADC1_base、0、VelocityFB);
    
    //计算误差
    error=(Reference-VelocityFB);
    
    //如果误差大于0,则计算 Theta
    if (Error>0){
    //通过得到%误差并将其乘以180来计算触发时间
    //获得我们需要的触发度数。 然后乘以
    //循环/度数,以获得被输入 Timer0的触发时间。
    //公式看起来很奇怪,因为我们处理整数,所以是除法
    //将导致截断,因此需要最后进行。
    FireTime=(SYSCYC_DEG*(4095-Error)*180)/4095;
    }
    //如果错误小于0,则我们将触发时间设置为333,361,比最大值高1
    //上面的 FireTime 方程式
    其他
    {FireTime=333361;
    
    }
    
    }
    //********
    
    
    
    //
    // ZerCrossing() ISR
    //检测过零,如果错误>0 (即 FireTime<3333361)
    ,则启用 Timer0A void ZerCrossing(vo){
    
    GPIOIntClear (GPIO_PORTC_BASE、GPIO_INT_PIN_5);//清除 PC5的中断
    
    if (FireTime<333361){
    TimerLoadSet (TIMER0_BASE、TIMER_A、FireTime-1);//加载最新操作
    TimerEnable (TIMER0_BASE、TIMER_A); //启用 Timer0A
    }
    }
    //*********
    
    //
    // Timer0 () ISR
    //此 ISR 将在等待一定的时间(
    //更改触发角)后激发 SCR。
    
    空 Timer0 (空){
    TimerIntClear (TIMER0_BASE、TIMER_TINA_TIMEOUT);//清除 Timer0A 的中断
    TimerDisable (TIMER0_BASE、TIMER_A); //禁用 Timer0A 以将其复位
    SysCtlDelay (FireTime); //在触发 SCR 之前等待
    GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_1、0x02);//Fire SCR
    SysCtlDelay (1000000); //testing:允许我们查看用于测试的 LED
    GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_1、0x00);//关闭引脚
    
    }
    //*********
    
    
    
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Shane、
    按照 CB1先前关于此帖子的建议:KIS,S
    忘记过零检测、只需在此处放置一个开关:您是否获得中断?
    您实际上能通过示波器看到从低 TTL 电平到高 TTL 电平的上升沿吗?
    (顺便说一下、不要只清除 ISR 内部的一个引脚中断-如果意外情况下另一个引脚在该端口上触发中断、您的代码将被卡住)。
    KISS:一次解决一位、然后尝试将火箭发射到火星。
    布鲁诺
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我终于找到了我的问题并使其正常工作。 问题代码是:
    GPIOIntTypeSet (INT_GPIOE、GPIO_INT_PIN_1、GPIO_HIGH_LEVEL);

    相反、它应该是:
    GPIOIntTypeSet (GPIO_PORTC_BASE、GPIO_INT_PIN_5、GPIO_RISE_EDGE);

    我现在正在获取上升沿中断检测。 我想仔细阅读 PDL 可以得到回报、哈哈
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    对您来说很好-然而-变化如此剧烈-(端口和引脚)-您的(过去)"下降沿"中断是如何成功的?"

    另请注意-我先前建议的"TimerConfigure()"更正帮助您成功。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我对它为什么以前也起作用很好奇。 也许由于编译器接受了具有匹配数据类型的参数、中断已进行了半配置? 但我认为、除非一切配置正确、否则中断将无法正常工作。 中断可能默认为下降沿检测? 或者、我的错误代码中某个参数的十六进制值与函数所需的值相匹配? 如果我找到原因、我将在该主题中发帖。

    无论原因如何,如果没有 。 您打开了我对 PDL 功能的关注、而不仅仅是对 LaunchPad 专题讨论会中列出的已修改例程进行编码。 你真的应该得到"Guru"头衔。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢、Shane -非常感谢。 (我的最佳埃尔维斯)

    并非所有员工都同意您的实物评估(注意-您的支票是"邮寄")。   你在“战斗的雾”中一路前进——坚持下去——解决了你的问题。

    也就是说,在(两种)制度下,改变港口和引脚以及以某种形式"工作"是很难的。   (我感到惊讶/悲伤的是,我没有足够的亮度-为你捕捉到“IntTypeSet()”。)

    正如您和我(两者)意识到的那样- PDL "以金牌方式值得其重量"-您现在似乎(非常)非常适合"赢得更多 MCU 战斗"。