找回密码
 立即注册
查看: 354|回复: 4

关于多路AD转换问题

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

19

主题

39

回帖

373

积分

中级会员

积分
373
发表于 2024-10-31 18:29:55 | 显示全部楼层 |阅读模式
我现在使用一块STC8H1K,芯片实验AD转换一路输入的时候可以,但增加一路,我想使用中断中改变引脚输入,无法实现,请高手指教,我的中断程序如下看看是什么原因:



void ADC_Isr() interrupt 5
{
   
                if(Fleg==0)
                                {
                                                Fleg=1;
                                                ADC_CONTR &= ~0x20;                         //清中断标志
                                                ADH = ADC_RES;                              //A存储ADC的12位结果的高8位
                                                ADL = ADC_RESL;                               //B[7:4]存储ADC的12位结果的低4位,B[3:0]为0
                                                AD  = ADH;
                                                AD  = AD << 2;
                                                AD |= (ADL>>6);                                       
                                                ADC_CONTR |= 0x41;                          //继续AD转换                                               
                                }
                else
                                {
                                                Fleg=1        ;
                                                ADC_CONTR &= ~0x20;                         //清中断标志
                                                ADH = ADC_RES;                              //A存储ADC的12位结果的高8位
                                                ADL = ADC_RESL;                               //B[7:4]存储ADC的12位结果的低4位,B[3:0]为0
                                                AD1  = ADH;
                                                AD1  = AD1 << 2;
                                                AD1 |= (ADL>>6);                                        
                                                ADC_CONTR |= 0x40;                          //继续AD转换
                                                                       
                                }       
}

我使用了一个标志位,实现改变输入引脚,但不能实现
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:468
  • 最近打卡:2025-05-12 07:36:42
已绑定手机
已实名认证

110

主题

2250

回帖

5566

积分

版主

积分
5566
发表于 2024-10-31 18:49:43 | 显示全部楼层
你切换adc使用的是ADC_CONTR |= 0x41;操作
这样是不对的。因为这样会造成0x40无法覆盖0x41.
所以应该在每个“//继续ad转换的语句前面”,加入一句
ADC_CONTR &= ~0x0f;
用以清除通道选择,这样就可以了
回复 支持 1 反对 0

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:434
  • 最近打卡:2025-05-12 09:01:08
已绑定手机

77

主题

4900

回帖

8564

积分

超级版主

DebugLab

积分
8564
发表于 2024-10-31 19:32:07 | 显示全部楼层
楼上对的,位或只能变1不能变0,操作一遍就全是1了
建议把使用的通道号声明为数组,然后就可以用++来自动扫描了

#define ADC_Num 2
ADC_Map[ADC_Num]={0xC0,0xC1}
中断函数中
ADC_Ch++
if(ADC_Ch==ADC_Num)
ADC_Ch=0
ADC_CONTR=ADC_Map[ADC_Ch]
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:426
  • 最近打卡:2025-05-12 21:51:09
已绑定手机

35

主题

2118

回帖

2289

积分

荣誉版主

积分
2289
发表于 2024-10-31 23:22:34 | 显示全部楼层
  1. void ADC_Isr() interrupt 5
  2. {
  3.         static unsigned char CH_sw;
  4.         ADC_CONTR &= ~0x20;                 //清完成标志       
  5.         switch(CH_sw)
  6.         {
  7.                 case 0:
  8.                         ADCRES[0] = ADC_RES;
  9.                         ADCRES[1] = ADC_RESL;
  10.                         CH_sw++;       
  11.                         ADC_CONTR &= 0xF0;
  12.                         ADC_CONTR |= 0x40 | 0x0B;            //启动AD转换        //ADC11 P03                       
  13.                 break;
  14.                 case 1:
  15.                         ADCRES[2] = ADC_RES;
  16.                         ADCRES[3] = ADC_RESL;
  17.                         CH_sw++;
  18.                         ADC_CONTR &= 0xF0;
  19.                         ADC_CONTR |= 0x40 | 0x00;            //启动AD转换        //ADC0 P10
  20.                 break;
  21.                 case 2:
  22.                         ADCRES[4] = ADC_RES;
  23.                         ADCRES[5] = ADC_RESL;
  24.                         CH_sw++;
  25.                         ADC_CONTR &= 0xF0;
  26.                         ADC_CONTR |= 0x40 | 0x01;            //启动AD转换        //ADC1 P11
  27.                 break;
  28.                 case 3:
  29.                         ADCRES[6] = ADC_RES;
  30.                         ADCRES[7] = ADC_RESL;
  31.                         CH_sw = 0;
  32.                         ADC_CONTR &= 0xF0;
  33.                         ADC_CONTR |= 0x0A;            //不启动AD转换        //ADC10 P02               
  34.                         ADC_over = 1;
  35.                 break;
  36.                 default:
  37.                         CH_sw        = 0;
  38.                         ADC_CONTR &= 0xF0;
  39.                         ADC_CONTR |= 0x0A;            //不启动AD转换        //ADC10 P02       
  40.                 break;
  41.         }       
  42. }
复制代码



睁开眼睛做场梦~~~
回复 支持 反对

使用道具 举报 送花

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

19

主题

39

回帖

373

积分

中级会员

积分
373
发表于 2024-11-1 10:09:36 | 显示全部楼层
王*** 发表于 2024-10-31 18:49
你切换adc使用的是ADC_CONTR |= 0x41;操作
这样是不对的。因为这样会造成0x40无法覆盖0x41.
所以应该在每个 ...

OK,谢谢,明白,昨晚我找到STC32G的例程看了看,就有这个语句,我又参考例程写了个程序,出现一个奇怪现象,我把P1.0口AD转换值在第一行显示,P1.1口AD转换值在第三行显示,运行时,结果正好相反,改变P1.0口电压值,第三行显示随着改变,改变P1.1口电压值,第一行显示随着改变,但如果把P1.0端口转换停止,改变P1.1口电压值,第三行变化正常,如果反之把p1.1口转换停止,改变p1.0端口电压,第一行随之改变,不知什么原因求解答,程序如下
/*****************************************************

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

#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模块       
}
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-12 23:56 , Processed in 0.147774 second(s), 79 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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