论坛里有可以达到16位的方法
现在的问题不是精度的问题,是adc采样转换无法得到成功的标志
这是官方例程里的获取成功标志位的方法,一样是输出4096
for(i=0; i<250; i++) //超时返回,正常i等于10以内就可以转换完成
{
if(ADC_CONTR & ADC_FLAG)
{
ADC_CONTR &= ~ADC_FLAG;
if(ADCCFG &(1<<5)) //转换结果右对齐。
{
adc = ((u16)ADC_RES << 8) | ADC_RESL;
}
else //转换结果左对齐。
{
#if ADC_RES_12BIT==1
adc = (u16)ADC_RES;
adc = (adc << 4) | ((ADC_RESL >> 4)&0x0f);
#else
adc = (u16)ADC_RES;
adc = (adc << 2) | ((ADC_RESL >> 6)&0x03);
#endif
}
return adc;
}
}
return 4096; //错误,返回4096,调用的程序判断 Emmetttttt 发表于 2024-11-22 09:57
现在的问题不是精度的问题,是adc采样转换无法得到成功的标志
这是官方例程里的获取成功标志位的方法,一 ...
你的单片机具体型号是什么? 梁工 发表于 2024-11-22 10:00
你的单片机具体型号是什么?
8G1K08A Emmetttttt 发表于 2024-11-22 10:10
8G1K08A
用户请先别修改程序, 直接下载“ADC相关程序-STC8G1K08A-8PIN”里的"02-5路ADC转换-BandGap-串口1(P3.1)返回结果-C语言"里的"ADC.hex"测试. 下载时选择主频11.0592MHZ。
测试时, 电脑的串口助手设置115200,8,n,1.
本程序演示4路ADC(P3.0 P3.2 P3.3 P5.4 P5.5)和bandgap查询采样,通过串口1(P3.1)发送给上位机,波特率115200,8,n,1.
0~3通道对应P3.0~P3.3, 4通道-->P5.4, 5通道-->P5.5, 15通道为内部1.19V基准电压做输入的ADC值.
本帖最后由 Emmetttttt 于 2024-11-22 11:57 编辑
梁工 发表于 2024-11-22 11:32
用户请先别修改程序, 直接下载“ADC相关程序-STC8G1K08A-8PIN”里的"02-5路ADC转换-BandGap-串口1(P3.1) ...
这样的测试是好的
接收←
ADC00=1023
接收←ADC02=0000
接收←ADC03=0000
接收←ADC04=0000
接收←ADC05=0234
接收←ADC15=0249
那种收不到转换成功的标志位是偶尔出现的,而且是运行挺久才有可能出现,这样的测试感觉有些难复现那种情况
我不确定是不是电压采集频率过快导致的了,或者说是母线电压出现了波动,因为将这个电压采集出来显示再数码管的时候,平常会有540v跳到490v这样的情况
本帖最后由 梁工 于 2024-11-22 12:25 编辑
Emmetttttt 发表于 2024-11-22 11:48
这样的测试是好的
接收←
ADC00=1023
ADC是硬件外设,一旦启动,就会自动转换直至完成,绝对不会出现卡死的情况。
ADC设置采样时间要要合适,不知道你说的“电压采集频率过快”指的什么?
你可能程序中将ADC关闭了,所以等不来ADC转换完成标志,否则一旦启动,必然会完成。
我的例子没有超时处理,你可以连续通电一个月(要保证电源可靠哦),看看会不会出现你说的问题。我用过无数ADC场合,没有遇到ADC会完成不了的情况。
梁工 发表于 2024-11-22 12:22
ADC是硬件外设,一旦启动,就会自动转换直至完成,绝对不会出现卡死的情况。
ADC设置采样时间要要合适,不 ...
if(div_01ms) //0.1ms任务
{
GetVinValue();
div_01ms = 0;
}
if(div_1ms) //1ms任务
{
GetTempValue();
Get_BrkFanFlag();
div_1ms = 0;
}
电压采集ADC开启转换频率是10KHz,温度是1KHz,ADC采样时间设置的是最大的
程序里没有关闭ADC的代码,应该不是这个问题
按照官方例程里的代码也是由于获取不到标志位导致函数输出4096
//========================================================================
// 函数: u16 Get_ADCResult(u8 channel)
// 描述: 查询法读一次ADC转换结果.
// 参数: channel: 选择要转换的ADC通道.
// 返回: ADC转换结果.
// 版本: V1.0, 2012-10-22
//========================================================================
u16 Get_ADCResult(u8 channel) //channel = 0~15
{
u16 adc;
u8 i;
if(channel > ADC_CH15) return 4096; //错误,返回4096,调用的程序判断
ADC_RES = 0;
ADC_RESL = 0;
ADC_CONTR = (ADC_CONTR & 0xf0) | channel;
ADC_CONTR |= ADC_START; //启动转换
NOP(10);
for(i=0; i<250; i++) //超时返回,正常i等于10以内就可以转换完成
{
if(ADC_CONTR & ADC_FLAG)
{
ADC_CONTR &= ~ADC_FLAG;
if(ADCCFG &(1<<5)) //转换结果右对齐。
{
adc = ((u16)ADC_RES << 8) | ADC_RESL;
}
else //转换结果左对齐。
{
#if ADC_RES_12BIT==1
adc = (u16)ADC_RES;
adc = (adc << 4) | ((ADC_RESL >> 4)&0x0f);
#else
adc = (u16)ADC_RES;
adc = (adc << 2) | ((ADC_RESL >> 6)&0x03);
#endif
}
return adc;
}
}
return 4096; //错误,返回4096,调用的程序判断
}
页:
1
[2]