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.

[参考译文] EK-TM4C123GXL:代码不会进入 ADC ISR

Guru**** 2524460 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/815856/ek-tm4c123gxl-code-does-not-enter-the-adc-isr

器件型号:EK-TM4C123GXL
主题中讨论的其他器件:TM4C123GH6PM

您好!

我正在努力制定一个具有以下功能的简单方案:

让周期性计时器>触发并完成采样后执行 ADC 序列>完成采样后调用 ADC0序列 ISR。

我们的想法是在稍后将其用于控制应用并进入中断、在中断中控制律将被定期执行并且采样已经完成。 我知道、仅仅使用周期性中断并从此处为 ADC 使用处理器触发器会更简单、但我认为最好在采样完成后进入中断。

在调试屏幕中、我可以看到 ADC0的 FIFO 0正在更新、并且寄存器 ADC_RIS 也设置为1。 这向我表明正在进行采样并且寄存器中的 ISR 标志正在被置位、但是我的代码永远不会进入中断处理程序。

请告诉我您是否检测到我的代码中存在错误或缺失可能导致这种情况发生的东西。 此外、我对 C 语言和嵌入式编程比较陌生、只会体验到 ARDUINOS、因此我的编码风格的任何评论也会非常受人的喜欢。

我不会放置 startup.c 代码、不会再执行 POST、但中断被声明为 extern 函数、并且也被声明在 ADC sequence0行中。

#include 
#include 
#include "inc/tm4c123gh6m.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/sysctl.h"
#include "driverlib/adc.h"
#include "driverlib/interrupt.ide"



#volatile rtiveatile r.id.idt.h
;"voltidtatile r.idtatile/id.id.idt.idt.idt.ide"#include "voltatile r.idtatile r.idt.idt.idt.idt.idt.idt.id.atilot



uint32_t ui32TimerLoad;

SysCtlClockSet (SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHz);

SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);
SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);

TimerConfigure (TIMER0_BASE、TIMER_CFG_PERIODICASE);
TimerADCEventSet (TIMER0_BASE、TIMER_ADC_TIMEOUT_A);
TimerControlTrigger (TIMER0_BASE、TIMER_A、TRUE);

ui32TimerLoad =(SysCtlClockGet ()/15000);
TimerLoadSet (TIMER0_BASE、TIMER_A、ui32TimerLoad -1);

GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_3);
ADCHardwareOversampleConfigure (ADC0_BASE、8);
ADCSequenceConfigure (ADC0_BASE、0、ADC_TRIGGER_TIMER、0);
ADCSequenceStepConfigure (ADC0_BASE、0、0、ADC_CTL_CH0|ADC_CTL_IE|ADC_CTL_END);
ADCSequenceEnable (ADC0_BASE、0);

GPIOPinTypeGPIOOutput (GPIO_Porte _BASE、GPIO_PIN_1);

ADCIntEnable (ADC0_BASE、0);
IntMasterEnable();

TimerEnable (TIMER0_BASE、TIMER_A);

GPIOPinWrite (GPIO_Porte _BASE、GPIO_PIN_1、0);
while (1){
SysCtlDelay (2000000);
GPIOPinWrite (GPIO_Porte _BASE、GPIO_PIN_1、2);
SysCtlDelay (2000000);
GPIOPinWrite (GPIO_Porte _BASE、GPIO_PIN_1、0);
}

}

void ADC0Sequence0IntHandler (void){
ADCIntClear (ADC0_BASE、0);
ADCSequenceDataGet (ADC0_BASE、1、ui32VoltageRead);
电压=(ui32VoltageRad[1]/4095.0)*3.3;
} 

我添加到 tm4c123gh6m_startup_ccs.c 中的代码、粗体显示:

extern void ADC0Sequence0IntHandler (void);

IntDefaultHandler、                     //正交编码器0
ADC0Sequence0IntHandler、                     // ADC Sequence 0
IntDefaultHandler、                     // ADC 序列1.

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

    您好 Ariel、

    您应该将 ADC0Sequence0IntHandler 放置在主函数之上、或者添加该行

    void ADC0Sequence0IntHandler (void); 

    在 main 函数上方,我知道对于未在 main()上方声明的编译函数,main()最终看不到这些函数,并且我从未实际测试过 ISR 的情况是否相同,但我怀疑它是这样的,所以也许这是根本原因。

    此外、我看不到 ADCClockConfigSet 的调用为了设置 ADC 外设时钟、也请添加该 API 调用。

    如果这些步骤不起作用、则要继续调试、请调整以下内容并告知我是否有任何更改。

    1) 1)我认为这不需要 TimerADCEventSet、我检查了一个由计时器触发的 ADC 示例、看不到它正在使用、因此请尝试将其注释掉。

    2) 2)我还会说、暂时注释掉过采样、除非您确实需要它来获得初始读数。 不确定这是否会影响任何内容(我自己没有使用过采样)、因此这是我们可以删除的另一个变量。

    如果没有这些工作、我可能需要在周一在办公室中进行处理、以便在我的结束时运行代码和进行调试

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

    您好、Ralph、

    在查看外设 dirverlib 文档的编程示例和工作簿中的示例后、我意识到主要问题是我缺少以下行

    IntEnable (INT_ADC0SS0);
    

    需要启用多少寄存器才能使用中断令人疯狂、但现在我不会再错过它、它是学习过程的全部部分。

    关于您的评论:

    实际上、不需要 TimerADCEventSet、但 TimerControlTrigger 似乎就足够了、我猜是什么时候应该使用 TimerADCEventSet。

    我已经将 ISR 移到了主函数的顶部、也将其在代码示例中的实现方式移到了顶部。 感谢您的提示。

    我从该手册引用后就没有使用 ADCClockConfigSet:在本实验中,我们只需允许 ADC12以其默认的1Msps 速率运行。  那么、如果不进行修改、那么它将已经以最大频率运行? 以较低的速度运行会有什么好处?

    如果它对任何人都有任何用处、我会在这里输入完整的工作代码。

    非常感谢您的帮助和提示

    #include 
    #include 
    #include "inc/tm4c123gh6m.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/adc.h"
    #idriverlib/interrupt.ide"
    
    #idvolatile rate.idt.idt.idr32h
    
    
    ;"idridridatile involtatile r.id.id.idt.idt.idt.idt.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.idr.id.id.id.
    
    
    ADCIntClear (ADC0_BASE、0);
    ADCSequenceDataGet (ADC0_BASE、0、\ui32VoltageRead);
    电压=(ui32VoltageRad/4095.0)*3.3;
    }
    
    int main (void){
    
    uint32_t ui32TimerLoad;
    
    SysCtlClockSet (SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHz);
    
    SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);
    SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);
    
    TimerConfigure (TIMER0_BASE、TIMER_CFG_PERIODICASE);
    //TimerADCEventSet (TIMER0_BASE、TIMER_ADC_TIMEOUT_A);
    TimerControlTrigger (TIMER0_BASE、TIMER_A、TRUE);
    
    ui32TimerLoad =(SysCtlClockGet ()/15000);
    TimerLoadSet (TIMER0_BASE、TIMER_A、ui32TimerLoad -1);
    
    GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_3);
    ADCHardwareOversampleConfigure (ADC0_BASE、8);
    ADCSequenceConfigure (ADC0_BASE、0、ADC_TRIGGER_TIMER、0);
    ADCSequenceStepConfigure (ADC0_BASE、0、0、ADC_CTL_CH0|ADC_CTL_IE|ADC_CTL_END);
    ADCSequenceEnable (ADC0_BASE、0);
    
    GPIOPinTypeGPIOOutput (GPIO_Porte _BASE、GPIO_PIN_1);
    
    ADCIntEnable (ADC0_BASE、0);
    IntEnable (INT_ADC0SS0);
    IntMasterEnable();
    
    TimerEnable (TIMER0_BASE、TIMER_A);
    
    GPIOPinWrite (GPIO_Porte _BASE、GPIO_PIN_1、0);
    while (1){
    if (Voltage>2.0){
    GPIOPinWrite (GPIO_Porte _BASE、GPIO_PIN_1、2);
    }
    否则{
    GPIOPinWrite (GPIO_Porte _BASE、GPIO_PIN_1、0);
    }
    }
    

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

    您好 Ariel、

    很高兴听到您让它正常工作。 很抱歉、我错过了在第一次审阅时的 API 调用、我看到了 ADCIntEnable 并且忘记了也需要 IntEnable。。。。 正如您说过的、许多要编程的寄存器。

    就 ADCClockConfigSet 而言、我不记得具体情况是什么、但客户在返回 ADC 获得不同结果时遇到了一个问题、该问题最终是因为未事先配置时钟、 因此、从那时起、我就一直在想、 作为最佳做法、还应该使用 ADCClockConfigSet API。 此外、我还必须检查默认设置的实际值以及它们是否特定于实验室使用的系统时钟配置。