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.

[参考译文] CCS/TM4C1294NCPDT:使用 ADC 中断通过 ADC0SS3读取温度数据

Guru**** 2606725 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/752803/ccs-tm4c1294ncpdt-read-temperature-data-via-adc0ss3-using-adc-interrupt

器件型号:TM4C1294NCPDT

工具/软件:Code Composer Studio

我正在处理一个项目、在该项目中、我尝试使用 ADC 模块0采样序列发生器3从外部温度传感器(TMP36)读取数据。

我将传感器连接到 AIN13的 PD2

第一个采样由处理器触发、然后我将其设置为在中断处理程序中持续采样。

我多次浏览数据表、不确定我的代码中出现了什么错误。 在我的代码中、我似乎从未进入中断处理程序、因此从传感器中获取数据、但我不确定如何修复。 我使用了一个测试值来查看我是否曾经进入过中断处理程序并且该值从未更新。

此时、我甚至不确定问题可能出在哪里、我已经在调试了一周多、也不确定接下来要做什么。

//此文件假设温度传感器
//使用模拟通道13进行 AD 转换
//反映测量温度的电压
//可以通过读取寄存器 ADC0_SSFIFO3_R 来计算//
其中只有最低的12位可访问
//因为 AN#13与 GPIO 引脚复用 D2
//因此需要相关的 GPIO 端口 D 配置

#include 
#include 
#include 

//为 GPIO 模块
#define SYSCTL_RCGCGPIO_R 提供时钟 (*(volatile unsigned long *) 0x400FE608)

//为 ADC 模块
#define SYSCTL_RCGCADC_R 提供时钟 (*(volatile unsigned long *) 0x400FE638)

// ADC0和 SS3
#define ADC0_ACTS_R (*(volatile unsigned long *) 0x40038000)//启用 SS3
#define ADC0_IM_R (*(volatile unsigned long *) 0x40038008)//中断屏蔽
#define ADC0_ISC_R (*(volatile unsigned long *) 0x4003800C)//中断清除
#define ADC0_EMUX_R (*(volatile unsigned long *) 0x40038014)
#define ADC0_PSSI_R (*(volatile unsigned long *) 0x40038028)
#define ADC0_SAC_R (*(volatile unsigned long *) 0x40038030)//过采样
#define ADC0_SSEMUX3_R (*(volatile unsigned long *) 0x400380B8)
)#define ADC0_SSMUX3_R (*(volatile unsigned long *) 0x400380A0)
#define ADC0_SSCTL3_R (*(volatile unsigned long *) 0x400380A4)
#define ADC0_SSFIFO3_R (*(volatile unsigned long *) 0x400380A8)
#define ADC0_PC_R (*(volatile unsigned long *) 0x40038FC4))

// GPIO 端口 D
#define GPIO_PORTD_AHB_DIR_R (*(volatile unsigned long *) 0x4005B400)#define
GPIO_PORTD_AHBLD_UNsigned LD_R (*(volatile NV5B1C)#define GPIO_#define GPIO_TR_AM420*


(0x400ORTD_AM420*

)#define GPIO_UNATTR_ANTRL (#define GPIO_UNATTR_ANTR_AM5ORTD_AM420*)#define GPIO_UNDP_ANTRL (#FR_ANTRL)*(0x400FALOORTD_AM420_ANTRUART_AFORTD_TRL)*(#FR_ANTR_TR_TR_TRUART_ANTRUART_ANTRUART_ANTRUART_TR
(*((volatile unsigned long *) 0xE000E100))
uint32_t TempData;
//uint32_t Test = 2;


//此函数生成延迟
空延迟(volatile unsigned int delay){
volatile unsigned int i、j;

对于(i = 0;i < delay;i++){
//在16MHz 时引入大约10us 的延迟
对于(j = 0;j < 12;j ++);
}
}//


序列发生器3
的 ADC0中断服务例程 void ADC0SS3_Handler (void){
//测试++;
ADC0_EMUX_R |= 0xF000;
ADC0_ISC_R |= 0x08;
TempData = ADC0_SSFIFO3_R;//& 0x0FFF;

}



// main 函数
int main (void){

易失性浮点温度;
// 1. 启用 ADC0的时钟
SYSCTL_RCGCADC_R |= 0x01;
// 2. 启用端口 D 的时钟
SYSCTL_RCGCGPIO_R |= 0x08;

//端口 D PIN2的配置
GPIO_PORTD_AHB_AFSEL_R |= 0x04;//作为模拟函数使 AIN13工作
GPIO_PORTD_AHB_DEN_R &= 0x00;//禁用数字使能模拟
GPIO_PORTD_AHB_AMSEL_R |= 0x04;//启用模拟
GPIO_PORTD_AHB_DIR_R &= 0x00;// 0表示输入

//启动序列发生器3
ADC0_PSSI_R |= 0x08;

//并通过调用延迟函数引入延迟
延迟(3);

//选择 AIN13 (PD2)作为模拟输入
//第1个采样是序列结束和中断源
ADC0_PC_R |= 0x03; //季度转换率;48*Tadc 周期暂停
ADC0_SAC_R |= 0x04; // 16x 过采样,然后取平均值

//取消屏蔽 ADC0序列3中断
ADC0_IM_R |= 0xF7; //步骤6.
//清除 ADC0序列发生器3的中断
ADC0_ISC_R |= 0x08;


//为序列发生器3启用 ADC0模块
ADC0_ACTSS_R &= 0x00;//步骤1禁用采样序列发生器3
ADC0_EMUX_R &= 0x0000;
ADC0_SSEMUX3_R = 0x0;
ADC0_SSMUX3_R |= 0x0D;//步骤4选择 AIN13
ADC0_SSCTL3_R |= 0x06;//步骤5
ADC0_IM_R |= 0x08; //步骤6.
ADC0_ACTSS_R |= 0x08;//步骤7启用采样序列发生器3
ADC0_ISC_R |= 0x08;


//在 NVIC 中断号中启用 ADC0序列发生器3中断为17
NVIC_EN0_R |= 0x020000;

//等待 ADC 模块执行转换的特定时间
延迟(100);

while (1){
}
}




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

    根据我们的 TM4C 论坛指南、我们不会像您在 E2E 上对 TM4C 器件所做的那样为直接寄存器编程提供支持(请参阅第4项): e2e.ti.com/.../695568

    您需要使用 TI 提供的 TivaWare 来消除您尝试执行的操作的复杂性。

    我们在 TivaWare 中有 ADC 示例、位于[安装路径]\TivaWare_C_Series-2.1.4.178\examples\peripheral\adc

    这将是开始工作的好地方。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Ralph、

    我查看了示例、其中的非示例在代码中实现了一个中断处理程序。 我看到它们确实使用 ADCIntStatus()并清除中断。
    我已经使用 TivaWare 实现了我的代码、它起作用了、但我没有实现我自己的中断处理程序。
    我想我的问题是、是否有方法使用 TivaWare 函数并实现您自己的中断处理程序?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Lubov、

    当然可以。 这始终是 TivaWare 的目标。 您要做的是为中断处理程序创建一个函数、例如"ADC0_ISR"、并在该函数中写入中断处理程序。

    然后、您将转到项目的 startup_ccs.c 文件、并使用如下所示的 extern 关键字将该函数包含在文件中:

    extern void ADC0_ISR (void); 

    然后、您需要在中断矢量表中找到相应的 ADC 中断、并将 IntDefaultHandler 替换为 ADC0_ISR、以将中断处理程序函数链接到中断矢量表。

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

    是的、我完成了所有这些、但它仍然不起作用。

    我在实现硬件或定时器触发的中断时从未遇到过问题、但出于某种原因、它不能与 ADC 配合使用

    如果我执行自己的中断处理程序,我是否需要调用 ADCIntStatus()?

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

    为什么您不发布您的代码、以便我可以查看它并查看是否可以识别任何缺失的 API 调用。 您可以通过使用"插入代码"、"附加文件"等操作来实现此操作。。 选项、然后上传文件或使用语法突出显示(由访问)粘贴代码 符号)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    好的、我希望我在这里做的是将第一个采样设置为处理器触发、其余采样设置为连续采样

    #include 
    #include 
    #include "hw_memmap.h"
    #include "hw_types.h"
    #include "Debug.h"
    #include "sysctl.h"
    #include "gpio.h"
    #include "adc.h"
    
    uint32_t TempData[1];
    volatile uint32_t value;
    
    void ADC0SS3_TempHandler (void){ADC32_t TempBase
    、ADC0
    (void);ADC0 (void)
    值= TempData[0];
    }
    
    int main (void)
    {
    
    
    SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000);
    
    SysCtlPeripheralEnable (SysCtl_Periph_PLD);SYSCTL_ADPEPTL
    (GPTOP_480)、120000000;SysCtlPeripheralEnable (SysCtlPeripheralEnable)
    
    GPIO_PIN_2);
    
    ADCSequenceConfigure (ADC0_BASE、3、ADC_TRIGGER_PROCESSOR、0);
    ADCSequenceStepConfigure (ADC0_BASE、3、0、ADC_CTL_CH1|ADC_CTL_IE|ADC_CTL_END);
    
    ADCSequenceEnable (ADC0_BASE、 3);
    
    ADCIntClear (ADC0_BASE、3);
    ADCIntEnable (ADC0_BASE、3);
    ADCProcessorTrigger (ADC0_BASE、3);
    
    while (1)
    {
    ADCIntClear (ADC0_BASE、3);
    ADCIntRegister (ADC0_BASE、 3、ADC0SS3_Handler);
    }
    } 

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

    感谢您发布该代码、非常有助于了解正在发生的情况。 这里有一些评论。

    1) 1) ADCIntRegister 需要在调用 ADCIntEnable 之前作为配置的一部分完成。

    2) 2)使用中断服务例程时、不应在 ISR 外部执行 ADCIntClear (有时可能会出现这样的情况、但会处理错误等)。 示例代码中 ADCIntClear 的用法是因为它们是轮询、而不是使用 ISR。

    3) 3)您需要通过以下命令启用全局中断:IntMasterEnable();-我建议在 ADCIntClear 之前执行此操作。

    4) 4)如果要执行连续采样、则需要在 ISR 中调用 ADCProcessorTrigger (ADC0_base、3);或者在配置序列时需要使用 ADC_TRIGGER_Always 标志、而不是 ADC_TRIGGER_PROCESSORR。 在这种情况下、您可能还需要移动 ADCSequenceEnable (ADC0_BASE、3);当您要触发第一个结果时调用、可能在您调用 ADCProcessorTrigger 的行中调用。