找回密码
 立即注册
查看: 8909|回复: 20

STC8H1K28 ADC采样查询 与 STC8H8K64 区别

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:186
  • 最近打卡:2025-05-02 21:24:26

12

主题

58

回帖

940

积分

高级会员

积分
940
发表于 2023-1-13 15:48:44 | 显示全部楼层 |阅读模式
本帖最后由 ldc521 于 2023-1-13 15:51 编辑

问题如下:

1.用STC8H8K64U,通道8,P00口进行ADC采样,数据准确
2.用STC8H1K28, 同1的程序,通道8,P00口采样,数据只有1023,511,····等规律数字,而且不准,与外部电压不对应

程序如下:

/******************* IO配置函数 *******************/
void        GPIO_config(void)
{
        GPIO_InitTypeDef        GPIO_InitStructure;                //结构定义
        //AD口设置为输入口
        GPIO_InitStructure.Pin  = GPIO_Pin_0;                //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
        GPIO_InitStructure.Mode = GPIO_HighZ;        //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
        GPIO_Inilize(GPIO_P0,&GPIO_InitStructure);        //初始化

        GPIO_InitStructure.Pin  = GPIO_Pin_0 | GPIO_Pin_1;                //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
        GPIO_InitStructure.Mode = GPIO_PullUp;        //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
        GPIO_Inilize(GPIO_P3,&GPIO_InitStructure);        //初始化
}

/******************* AD配置函数 *******************/
void        ADC_config(void)
{
        ADC_InitTypeDef                ADC_InitStructure;                //结构定义
        ADC_InitStructure.ADC_SMPduty   = 31;                //ADC 模拟信号采样时间控制, 0~31(注意: SMPDUTY 一定不能设置小于 10)
        ADC_InitStructure.ADC_CsSetup   = 0;                //ADC 通道选择时间控制 0(默认),1
        ADC_InitStructure.ADC_CsHold    = 1;                //ADC 通道选择保持时间控制 0,1(默认),2,3
        ADC_InitStructure.ADC_Speed     = ADC_SPEED_2X1T;                //设置 ADC 工作时钟频率        ADC_SPEED_2X1T~ADC_SPEED_2X16T
        ADC_InitStructure.ADC_Power     = ENABLE;                                //ADC功率允许/关闭        ENABLE,DISABLE
        ADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED;        //ADC结果调整,        ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIED
        ADC_InitStructure.ADC_Priority    = Priority_0;                        //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
        ADC_InitStructure.ADC_Interrupt = DISABLE;                        //中断允许        ENABLE,DISABLE
        ADC_Inilize(&ADC_InitStructure);                                        //初始化
        ADC_PowerControl(ENABLE);                                                        //单独的ADC电源操作函数, ENABLE或DISABLE
}

/***************  串口初始化函数 *****************/
void        UART_config(void)
{
        COMx_InitDefine                COMx_InitStructure;                                        //结构定义
        COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;                //模式,   UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
        COMx_InitStructure.UART_BRT_Use   = BRT_Timer1;                        //选择波特率发生器, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2, 所以不用选择)
        COMx_InitStructure.UART_BaudRate  = 115200ul;                        //波特率,     110 ~ 115200
        COMx_InitStructure.UART_RxEnable  = ENABLE;                                //接收允许,   ENABLE或DISABLE
        COMx_InitStructure.UART_Interrupt = ENABLE;                                //中断允许,   ENABLE或DISABLE
        COMx_InitStructure.UART_Priority    = Priority_0;                        //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
        COMx_InitStructure.UART_P_SW      = UART1_SW_P30_P31;        //切换端口,   UART2_SW_P10_P11,UART2_SW_P46_P47
        UART_Configuration(UART1, &COMx_InitStructure);                //初始化串口2 USART1,USART2,USART3,USART4

        PrintString1("STC8 AD to UART2 Test Programme!\r\n");        //UART2发送一个字符串
}

/**********************************************/
void main(void)
{
        u8        i = 8;
        u16        j;

        GPIO_config();
        UART_config();
        ADC_config();
        EA = 1;

        while (1)
        {

                //for(i=0; i<9; i++)
                {
                        delay_ms(250);

                        //Get_ADCResult(i);                //参数0~15,查询方式做一次ADC, 丢弃一次
                        j = Get_ADCResult(8);        //参数0~15,查询方式做一次ADC, 返回值就是结果, == 4096 为错误
                        TX1_write2buff('A');
                        TX1_write2buff('D');
                        TX1_write2buff(8+'0');
                        TX1_write2buff('=');
                        TX1_write2buff(j/1000 + '0');
                        TX1_write2buff(j%1000/100 + '0');
                        TX1_write2buff(j%100/10 + '0');
                        TX1_write2buff(j%10 + '0');
                        TX1_write2buff(' ');
                        TX1_write2buff(' ');
                }
                PrintString1("\r\n");
        }
}

原理图如下:
STC8H1K28 ADC采样查询 与 STC8H8K64 区别-1.png
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6843

积分

论坛元老

积分
6843
发表于 2023-1-13 18:18:45 | 显示全部楼层
硬件部分:
用示波器测量ADC_Vref脚基准电压与采样脚P00电压是否稳定,并提供MCU相关电路的原理图。
软件部分:
将 ADC_Speed 的参数 ADC_SPEED_2X1T 改成 ADC_SPEED_2X16T,增加ADC采样时间试试。
  • 打卡等级:偶尔看看III
  • 打卡总天数:51
  • 最近打卡:2025-05-02 10:07:51

73

主题

5883

回帖

1万

积分

超级版主

积分
12079
发表于 2023-1-13 23:16:03 | 显示全部楼层
检查VCC、AVREF和ADC输入电压,是否正常。
  • 打卡等级:常住居民III
  • 打卡总天数:186
  • 最近打卡:2025-05-02 21:24:26

12

主题

58

回帖

940

积分

高级会员

积分
940
发表于 2023-1-14 11:21:13 | 显示全部楼层
梁*** 发表于 2023-1-13 23:16
检查VCC、AVREF和ADC输入电压,是否正常。

VCC---3.3V正常
VREF---直连VCC---3.3V正常
ADC输入电压用直连可调电源输出正常,采样不对
ADC输入电压采用分压电阻方式,万用表测量电压正确,采样不对

点评

STC8H1K28 ADC与 STC8H8K64操作一模一样,没有区别,仅仅是ADC位数不同,前者是10位,后者是12位,如果你有计算,注意不要溢出。直接监测ADC值看看。  详情 回复 发表于 2023-1-14 13:31
  • 打卡等级:常住居民III
  • 打卡总天数:186
  • 最近打卡:2025-05-02 21:24:26

12

主题

58

回帖

940

积分

高级会员

积分
940
发表于 2023-1-14 11:22:17 | 显示全部楼层
乘风*** 发表于 2023-1-13 18:18
硬件部分:
用示波器测量ADC_Vref脚基准电压与采样脚P00电压是否稳定,并提供MCU相关电路的原理图。
软件部 ...

硬件方面,使用万用表测试基准电压与采样电压均准确

软件部分  两款不同内存同型号的单片机,8K64就可以用
  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-05-02 08:32:59

718

主题

1万

回帖

1万

积分

管理员

积分
15632
发表于 2023-1-14 11:54:34 | 显示全部楼层
贴你完整的原理图的PDF, 软件将采样时间先设置到最长,用最新的STC-ISP软件, 看最新的数据手册

1.png
  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-05-02 08:32:59

718

主题

1万

回帖

1万

积分

管理员

积分
15632
发表于 2023-1-14 11:55:37 | 显示全部楼层
1.png

1.png
  • 打卡等级:偶尔看看III
  • 打卡总天数:51
  • 最近打卡:2025-05-02 10:07:51

73

主题

5883

回帖

1万

积分

超级版主

积分
12079
发表于 2023-1-14 13:31:52 | 显示全部楼层
ldc*** 发表于 2023-1-14 11:21
VCC---3.3V正常
VREF---直连VCC---3.3V正常
ADC输入电压用直连可调电源输出正常,采样不对

STC8H1K28 ADC与 STC8H8K64操作一模一样,没有区别,仅仅是ADC位数不同,前者是10位,后者是12位,如果你有计算,注意不要溢出。直接监测ADC值看看。
  • 打卡等级:常住居民III
  • 打卡总天数:186
  • 最近打卡:2025-05-02 21:24:26

12

主题

58

回帖

940

积分

高级会员

积分
940
发表于 2023-1-14 13:40:04 | 显示全部楼层
梁*** 发表于 2023-1-14 13:31
STC8H1K28 ADC与 STC8H8K64操作一模一样,没有区别,仅仅是ADC位数不同,前者是10位,后者是12位,如果你 ...

我直接打印ADC的寄存器值,程序如下:
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) | ADC_START | channel;
        NOP(10);                        //对ADC_CONTR操作后等待会儿再访问

        for(i=0; i<250; i++)                //超时
        {
                if(ADC_CONTR & ADC_FLAG)
                {
                        ADC_CONTR &= ~ADC_FLAG;
                        if(ADCCFG &  (1<<5))                //转换结果右对齐。
                        {
                                adc = ((u16)ADC_RES << 8) | ADC_RESL;
                                TX1_write2buff(ADC_RES);
                                TX1_write2buff(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
3
7
F
1F
3F
7F
FF
1FF
3FF
可以随着电压的变化数据在变化,但是范围很小,到2V+就是3FF,到1.7V-就是000
但是同样的程序,同样的操作,放到8K64里,ADC采样的数据跟实际电压是同步的,而且通过公式可算

点评

感觉还是电路有问题,做至少3块样板,测试看看是否一直。STC8系列的ADC性能是非常高的,我基本没遇到这种很离谱的投诉,问的都是怎么处理跳动等等。 如果依旧不能解决,过年后寄一块样板给STC公司,能帮你快速找出原  详情 回复 发表于 2023-1-14 13:50
  • 打卡等级:常住居民III
  • 打卡总天数:186
  • 最近打卡:2025-05-02 21:24:26

12

主题

58

回帖

940

积分

高级会员

积分
940
发表于 2023-1-14 13:43:19 | 显示全部楼层
神*** 发表于 2023-1-14 11:54
贴你完整的原理图的PDF, 软件将采样时间先设置到最长,用最新的STC-ISP软件, 看最新的数据手册

现在已经把外围分压电路去掉了, 用可调电源直连MCU引脚
微信截图_20230114134229.png
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-3 05:26 , Processed in 0.137375 second(s), 111 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表