找回密码
 立即注册
查看: 717|回复: 14

关于AD转换引脚问题奇怪现象,求解

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:47
  • 最近打卡:2025-04-10 06:42:19

19

主题

39

回帖

373

积分

中级会员

积分
373
发表于 2024-11-4 11:25:40 | 显示全部楼层 |阅读模式
本帖最后由 dongfang 于 2024-11-4 11:25 编辑

我参考例程写了个程序,出现一个奇怪现象,我把P1.0口AD转换值在第一行显示,P1.1口AD转换值在第三行显示,运行时,结果正好相反,改变P1.0口电压值,第三行显示随着改变,改变P1.1口电压值,第一行显示随着改变。
但是如果把程序中,P1.0端口转换停止,运行后,改变P1.1口电压值,第三行变化正常,如果反之把程序中,p1.1口转换停止,改变p1.0端口电压,第一行随之改变,非常正常,但在程序中再同使用两个端口,显示位置就反了,我又改变使用其他p1端口,都存在这个现象,不知程序出了什么问题,求高手解答,程序如下:

/*****************************************************

******************************************************/

#include "STC8H.H"
#include <intrins.h>
#include "12864.h"


typedef         unsigned char        u8;
typedef         unsigned int        u16;


#define MAIN_Fosc        24000000UL

uchar yi,er,san,si,wu ,liu,qi,ba;
uchar num=0;
unsigned int          AD,AD1;
float ADF;



u16        Get_ADC12bitResult(u8 channel);
void delay_ms(u8 ms);
void ADC_Init(void);  //初始化

/**************************************************
函数:void STC_Init()
描述:STC8H 初始化
**************************************************/

void STC_Init()
{
    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口               
}
/*********************************************************
*                                                        *
* 主函数                                                 *
*                                                        *
*********************************************************/
void main()
{
                STC_Init();                    //初始化STC8H
                lcdinit();                     //初始化LCD
                ADC_Init();                                                 //初始化ADC
/******************************************/      

                photodisplay(Photo1);     //显示图片1
                delay(4000);
         
                write(0,0x30);          //基本指令操作
                write(0,0x01);          //清屏
      
        /*************************************/  
   while(1)
   {
               

                 AD=Get_ADC12bitResult(0);
                 AD=Get_ADC12bitResult(0);
                 AD=Get_ADC12bitResult(0);
               
//                ADF=AD*4.88;
//                delay(2);
//                AD=ADF;

                wu  = AD/1000;
                liu = AD%1000/100;
                qi  = AD%100/10;
                ba  = AD%10;        
               
                write(0,0x80);
                write(1,DIS5[wu]);
                write(1,DIS5[liu]);
                write(1,DIS5[qi]);
                write(1,DIS5[ba]);
                 
                AD1=Get_ADC12bitResult(1);
                AD1=Get_ADC12bitResult(1);
                AD1=Get_ADC12bitResult(1);      
               
                yi  = AD1/1000;
                er  = AD1%1000/100;
                san = AD1%100/10;
                si  = AD1%10;        
               
                write(0,0x88);
                write(1,DIS5[yi]);
                write(1,DIS5[er]);
                write(1,DIS5[san]);
                write(1,DIS5[si]);

        /*********************************************/         
                 
   }
}
//========================================================================
// 函数: u16 Get_ADC12bitResult(u8 channel))        //channel = 0~15
// 描述: 查询法读一次ADC结果.
// 参数: channel: 选择要转换的ADC, 0~15.
// 返回: 12位ADC结果.
// 版本: V1.0, 2016-4-28
//========================================================================
u16        Get_ADC12bitResult(u8 channel)        //channel = 0~15
{
                ADC_RES = 0;
                ADC_RESL = 0;

    ADC_CONTR = (ADC_CONTR & 0xf0) | channel; //设置ADC转换通道
    ADC_CONTR |= 0x40;    //启动AD转换
    _nop_();
    _nop_();
    _nop_();
    while(!(ADC_CONTR&0xDF));   //wait for ADC finish
                ADC_CONTR &= ~0x20;                         //清中断标志
//    ADC_FLAG = 0;     //清除ADC结束标志
    return (((u16)ADC_RES << 8) | ADC_RESL);
}

//========================================================================
// 函数: void delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
void delay_ms(u8 ms)
{
        u16 i;
        do
        {
                i = MAIN_Fosc / 6000;
                while(--i);
        }while(--ms);
}



//========================================================================
// 函数: void Timer0_Init(void)
// 描述: ADC初始化函数。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2022-6-2
// 备注:
//========================================================================
void ADC_Init(void)  // Timer0初始化
{
   
                P1M0 = 0x00;           //设置P1.0,P1.1为高阻
                P1M1 = 0x03;
                ADCTIM = 0x3f;
                ADCCFG = 0x2f;         //设置ADC时钟为系统时钟/2/16,右对齐
                ADC_CONTR = 0x80;      //使能ADC模块      
}


回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2024-11-4 12:16:19 | 显示全部楼层
AD=Get_ADC12bitResult(0);
AD=Get_ADC12bitResult(0);
AD=Get_ADC12bitResult(0);

为什么要重复3次
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:456
  • 最近打卡:2025-05-02 11:32:34

15

主题

57

回帖

2101

积分

金牌会员

积分
2101
发表于 2024-11-4 12:36:26 | 显示全部楼层
Debu*** 发表于 2024-11-4 12:16
AD=Get_ADC12bitResult(0);
AD=Get_ADC12bitResult(0);
AD=Get_ADC12bitResult(0);

曾有COODY先生教导:切换ADC通道后,电容充放电有时间... ,检测新的ADC通道前二三个数据丢弃...

点评

对于STC8、STC32系列,有采样时间设置,不需要转换丢弃。 之前的STC15系列、STC12系列,ADC不能设置采样时间,当使用主频较高、转换速度较快时,切换通道之后就要先转换丢弃次。  详情 回复 发表于 2024-11-5 10:33
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:47
  • 最近打卡:2025-04-10 06:42:19

19

主题

39

回帖

373

积分

中级会员

积分
373
发表于 2024-11-4 12:45:16 | 显示全部楼层
wjhh*** 发表于 2024-11-4 12:36
曾有COODY先生教导:切换ADC通道后,电容充放电有时间... ,检测新的ADC通道前二三个数据丢弃... ...

我看stc32的例程他丢弃了2个,我这也去第三次的值吗,我再增加几次试试
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:47
  • 最近打卡:2025-04-10 06:42:19

19

主题

39

回帖

373

积分

中级会员

积分
373
发表于 2024-11-4 12:55:40 | 显示全部楼层
wjhh*** 发表于 2024-11-4 12:36
曾有COODY先生教导:切换ADC通道后,电容充放电有时间... ,检测新的ADC通道前二三个数据丢弃... ...

我又增加几次,但结果依旧,只开单个端口,就正常说明程序真的没有问题呀,百思不得其解

点评

你可以直接测试官方例子,串口返回ADC结果的,一般都是单路返回的。 或者,请说出你用的型号,我发一个给你。  详情 回复 发表于 2024-11-5 10:35
回复 支持 反对

使用道具 举报 送花

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

73

主题

5883

回帖

1万

积分

超级版主

积分
12079
发表于 2024-11-5 10:33:00 | 显示全部楼层
wjhh*** 发表于 2024-11-4 12:36
曾有COODY先生教导:切换ADC通道后,电容充放电有时间... ,检测新的ADC通道前二三个数据丢弃... ...

对于STC8、STC32系列,有采样时间设置,不需要转换丢弃。
之前的STC15系列、STC12系列,ADC不能设置采样时间,当使用主频较高、转换速度较快时,切换通道之后就要先转换丢弃次。
回复 支持 反对

使用道具 举报 送花

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

73

主题

5883

回帖

1万

积分

超级版主

积分
12079
发表于 2024-11-5 10:33:50 | 显示全部楼层
从未发现过这种问题,你可以直接测试官方例子,串口返回ADC结果的。
回复 支持 反对

使用道具 举报 送花

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

73

主题

5883

回帖

1万

积分

超级版主

积分
12079
发表于 2024-11-5 10:35:29 | 显示全部楼层
dong*** 发表于 2024-11-4 12:55
我又增加几次,但结果依旧,只开单个端口,就正常说明程序真的没有问题呀,百思不得其解 ...

你可以直接测试官方例子,串口返回ADC结果的,一般都是单路返回的。
或者,请说出你用的型号,我发一个给你。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:456
  • 最近打卡:2025-05-02 11:32:34

15

主题

57

回帖

2101

积分

金牌会员

积分
2101
发表于 2024-11-5 11:10:36 | 显示全部楼层
本帖最后由 wjhhhhh 于 2024-11-5 11:12 编辑
梁*** 发表于 2024-11-5 10:33
对于STC8、STC32系列,有采样时间设置,不需要转换丢弃。
之前的STC15系列、STC12系列,ADC不能设置采样 ...

这三处需要用户设置的是哪些才能不用丢弃?已有默认值就可以不需丢弃吗?谢谢
无标题.png

点评

SMPDUTY就是采样时间,一般2~5us就足够了。 比如主频24MHz,ADC时钟为4MHz,SMPDUTY设置为11,则为3us采样(采样时间为SMPDUTY+1个ADC时钟)。  详情 回复 发表于 2024-11-5 12:31
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:47
  • 最近打卡:2025-04-10 06:42:19

19

主题

39

回帖

373

积分

中级会员

积分
373
发表于 2024-11-5 11:25:29 | 显示全部楼层
本帖最后由 dongfang 于 2024-11-5 11:28 编辑

我用的是STC8H1K28-36I-LQFP32,我参考了STC32G屠龙刀的例程,首先感谢你的回复指导,我看了例程里是丢弃两个转换结果,(现在知道可以不用丢弃),现在这个问题好像已经解决,又好像没有解决,很奇怪?????,听我解释:刚开始我写完程序,全部在main中,运行结果就是反着,昨天我把程序按照模块化编程方式进行了整理(正在学习模块化编程),程序语句没有变化。运行的结果依旧反着,但是:::我无意修改了结果显示位置,他正常显示了,我又改回原显示位置,他还是正常显示,我怀疑以前搞错了,我又把模块化编程以前的程序运行(以前的程序还保留着),可是还是显示结果反着,我又修改结果显示位置,显示结果还是反着。我反复试了几次显示结果都是反着,不存在失误,我碰到薛定谔的猫了

点评

请测试“03-STC8H1K28-LQFP32-12路10位ADC转换-串口1(P3.1)返回结果-C语言”。 /************* 功能说明 ************** 用户请先别修改程序, 直接下载"03-STC8H1K28-LQFP32-12路10位ADC转换-串口1(P3.1)返回结果  详情 回复 发表于 2024-11-5 13:03
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-5-2 13:06 , Processed in 0.256372 second(s), 112 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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