工具/软件:Code Composer Studio
关于 http://e2e.ti.com/support/microcontrollers/other/f/908/t/594823 、似乎仍然不清楚如何进行正确设置。
在一个应用中、ADC0以全速(2MHz)运行、ADC1也是如此。 ADC1仅用于内部温度测量。
通过使用为采样保持提供64个 ADC 时钟的配置、我们获得了一些远低于预期的测量值(使用热风枪时的测量范围为30-47°C、最高可达100°C)。
我们尝试读取3-10个连续读数(禁用全局中断)、但温度读数仍然很差。
只有添加过采样、我们才会获得有用的结果:ADCHardwareOversampleConfigure (ADC1_base、64);
这似乎很奇怪、因为与勘误表相比、这不符合逻辑。
有没有好的解释? 我们是否错过了什么?
代码如下所示:
初始化:
//
//设置两个 ADC 的时钟(ADC1_base 设置两个 ADC 的时钟)
// adc_clock_divider = 30 ->将 ADC 时钟设置为对应于1MSP/s 的16MHz
// adc_clock_divider = 15 ->将 ADC 时钟设置为对应于2MSP/s 的32MHz
//
ADCClockConfigSet (ADC0_BASE、ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL、ADC_CLOCK_DIVIDER);
///------------------
//
//初始化用于内部芯片温度测量的内部 ADC1外设。
//温度测量是在-in 另一个函数中完成的-参见下面的。
//
//
//设置序列发生器编号
//
uint32_t g_uisequencernum = 3;
静态空 ADC1Init (空)
{
//
//必须启用 ADC1外设才能使用。
//
MAP_SysCtlPeripheralEnable (SYSCTL_Periph_ADC1);
//
//等待 ADC1外设就绪。
//
while (!map_SysCtlPeripheralReady (SYSCTL_Periph_ADC1))
{}
//
//将自动平均值设定为64。
//
ADCHardwareOversampleConfigure (ADC1_base、64);
//
//在配置 ADC1采样序列发生器之前,确保其被禁用。
//
MAP_ADCSequenceDisable (ADC1_base、g_uisequencernum);
//
//使用处理器信号触发器启用采样序列。
//
MAP_ADCSequenceConfigure (ADC1_base、g_uisequencernum、ADC_TRIGGER_PROCESSORT0);
//
//按顺序配置步骤0。
//
///map_ADCSequenceStepConfigure (ADC1_base、3、0、ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END| ADC_CTL_SHOLD_16);
/*
* 设置 ADC 序列发生器的温度读数
*
* ADC_CTL_TS :温度传感器选择
* ADC_CTL_IE :中断使能
* ADC_CTL_shold_16 :采样保持16个 ADC 时钟
* ADC_CTL_END :序列结束选择
*
*
MAP_ADCSequenceStepConfigure (ADC1_base、g_uisequencernum、0、ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_SHOLD_64 | ADC_CTL_END);
//
//由于采样序列现在已配置,因此必须启用它。
//
MAP_ADCSequenceEnable (ADC1_base、g_uisequencernum);
//
//清除中断状态标志。 这样做是为了确保
//中断标志在我们进行采样之前被清除。
//
MAP_ADCIntClear (ADC1_BASE、ADCIntClear);
返回;
}
用于读取温度的函数:
{
uint32_t ui32Temperature = 0;//用于从 ADC 读取值
int32_t i32Temperature = 0;//用于计算实际温度
uint8_t i = 3;
#if defined (target_IS_TM4C129_RA0)|| defined (target_IS_TM4C129_RA1)
//如果平台是 TM4C129
/*uint32_t n;
taskENTER_critical (); //<---- 输入临界区!
IntMasterDisable(); //<--- 禁用中断!
对于(n=0;n<1000;n++)
{
MAP_ADCIntStatus (ADC1_BASE、3、false);
}*/
//while (!map_ADCIntStatus (ADC1_base、3、false)){}//等待转换完成,正常采样模式启动的乒乓队列中仍可能存在一些采样。
对于(i=3;i>0;i--)//运行3个循环以满足温度传感器内部的设置时间(请参阅勘误表: www.ti.com/.../spmz850c.pdf)
{
//请参阅中的 TivaWare 示例: /examples/peripherals/adc/temperature_sensor.c
MAP_ADCProcessorTrigger (ADC1_base、g_uisequencernum);//触发 ADC 转换。
while (!map_ADCIntStatus (ADC1_base、g_uisequencernum、false)){}//等待转换完成。
MAP_ADCIntClear (ADC1_base、g_uisequencernum);//清除 ADC 中断标志。
MAP_ADCSequenceDataGet (ADC1_base、g_uisequencernum、&ui32Temperature);//读取 ADC 值。
i32温度=(int32_t) ui32温度;
}
/*IntMasterEnable(); //<--- 启用中断!
taskEXIT_critical (); //<---- 退出临界区!*/
i32Temperature =(1475-(i32Temperature*2475)/4096)/10;//使用数据表中提供的非校准转换。
其他
//如果平台是 LM3S9D92
对于(i=3;i>0;i--)//运行3个循环以满足温度传感器内部的设置时间(请参阅勘误表)
{
ADCIntClear (ADC0_BASE、G_uisequencernum);//清除任何旧中断
ADCProcessorTrigger (ADC0_BASE、g_uisequencernum);//启动下一个 ADC 温度转换
while (!ADCIntStatus (ADC0_BASE、g_uisequencernum、false)){}//等待采样序列完成。
ADCSequenceDataGet (ADC0_BASE、g_uisequencernum、&ui32温度);
i32温度=(int32_t) ui32温度;
}
i32Temperature = 147-((i32Temperature*225)/1024);//计算腹腔
#endif
pushinteger (int32_t) i32温度;
返回1;
}