LeoringYang 发表于 6 天前

ADC模数转换中断程序,一天也没做出来

ADC模数转换中断程序,我用了一天的时间也没有做出来,我的要求:启动ADC,触发中断,这就这么简单!我认为这是极简单的事,然而做了一天也没有成功。我认为是触发ADC转换的条件应该没满足。文档中只提取一下可以用PWM触发或是P5.4触发。

我的程序如下:
MOV 0xDE,#0x2F
0x7EFEA8设置为0x1F

MOV 0xBC,#0x80
延时>1ms(100000以上循环)
ORL IE,#0x20
ORL 0xBC,#0x40

然后在中断程序中写到:
MOV P6,#0x55
ANL 0xBC,#0xDF
ORL 0xBC,#0x40
实验箱是用P6做跑马灯的,P6一直是初始亮的那几个LED,一直没有变化。

以上程序没有触发中断,我想到了一种可能:ADC需要上升或下降沿来触发,估计是这个没有满足。

_奶咖君_ 发表于 6 天前

不然呢,,STC这个大部分的片子就只有一个ADC,没什么其他的花样了,

不太看得懂 汇编,但是从0xDE 和 0x7EFEA8这两个寄存器上来看,一个是 ADCCFG,一个是ADCTIM。并没有使用ADC_CONTR,,看起来你只配置了ADC的参数,但是没有启动ADC,emmmm我不好你手册里都看了什么。。


lcwswust 发表于 6 天前

ADC_START位似乎没有置位;
POWER是上电,只需置位1次;
START是启动转换,完成后START自动清零,再次转换则需再次置位。


LeoringYang 发表于 6 天前

lcwswust 发表于 2026-7-16 16:27
ADC_START位似乎没有置位

我估计还没写完,你就回复了。多谢这么及时。

LeoringYang 发表于 6 天前

_奶咖君_ 发表于 2026-7-16 16:21
不然呢,,STC这个大部分的片子就只有一个ADC,没什么其他的花样了,

不太看得懂 汇编,但是从0xDE 和 0x7 ...

MOV 0xBC,#0x80 ;打开ADC电源

LeoringYang 发表于 6 天前

_奶咖君_ 发表于 2026-7-16 16:21
不然呢,,STC这个大部分的片子就只有一个ADC,没什么其他的花样了,

不太看得懂 汇编,但是从0xDE 和 0x7 ...

ORL 0xBC,#0x40 ;启动ADC,即ADC_START=1

_奶咖君_ 发表于 6 天前

LeoringYang 发表于 2026-7-16 16:29
我估计还没写完,你就回复了。多谢这么及时。

啊,,我再瞅瞅你后面的。。。{:4_167:}

LeoringYang 发表于 6 天前

lcwswust 发表于 2026-7-16 16:27
ADC_START位似乎没有置位;
POWER是上电,只需置位1次;
START是启动转换,完成后START自动清零,再次转换 ...
我把官方文档中《22.6.2 ADC基本操作(中断方式)》代码放到keil中编译,不管是keil调试还是实验箱下载运行,都没有触发中断。
我将yxra代码全部发出来吧,AsmCode.executeAsmCode(...):汇编嵌入yxra编译,其他你可以当c来看。

//-----------------------------------程序------------------------------//

package yxra.chip.stc32g;

/**
* 模数转换
*/
public class ADC_CONVERTER{

    /**
   * 模数转换初始化
   */
    public static void initialDevice(){
      //ADC配置寄存器
      AsmCode.executeAsmCode("MOV 0xDE,#0x2F");

      //ADC时序控制
      AsmCode.saveInto08AsmCode(0x1F,0x7EFEA8);

      //ADC扩展配置寄存器
      AsmCode.saveInto08AsmCode(0x00,0x7EFEAD);

      //ADC控制寄存器
      AsmCode.executeAsmCode("MOV 0xBC,#0x80");
      AsmCode.delayAsmCodeTime(100);

      //启用ADC模数转换中断
      AsmCode.executeAsmCode("ORL IE,#0x20");

      //启动ADC模数转换
      AsmCode.executeAsmCode("ORL 0xBC,#0x40");
    }

    /**
   * 模数转换中断号
   */
    public static int getDevInterNo(){
      return 5;
    }

    /**
   * 模数转换中断处理
   */
    public static void handleInterrupt(){
      //保护各个寄存器
      InterEnter.protectScence();
      
      P6=P6+1;

      //获取ADC转换结果
      AsmCode.executeAsmCode("MOV R3,0xBE");
      AsmCode.executeAsmCode("MOV R2,0xBD");
      int adcResult=AsmCode.moveFromAsmCode();

      //清除ADC中断标识
      AsmCode.executeAsmCode("ANL 0xBC,#0xDF");

      //启动ADC模数转换
      AsmCode.executeAsmCode("ORL 0xBC,#0x40");

      //恢复各个寄存器
      InterEnter.restoreScence();
    }

    //左对齐结果转为右对齐
    //    ADC转换结果在R2+R3(WR2)中,复制程序而不是调用
    //    R2=R2 >> 4
    //    R3=(R2 << 4) | (R3 >> 4)
    private static void changeAlignResult(){
      AsmCode.executeAsmCode("MOV R0,R2");
      AsmCode.executeAsmCode("SRL R2");
      AsmCode.executeAsmCode("SRL R2");
      AsmCode.executeAsmCode("SRL R2");
      AsmCode.executeAsmCode("SRL R2");
      AsmCode.executeAsmCode("SRL R3");
      AsmCode.executeAsmCode("SRL R3");
      AsmCode.executeAsmCode("SRL R3");
      AsmCode.executeAsmCode("SRL R3");
      AsmCode.executeAsmCode("SLL R0");
      AsmCode.executeAsmCode("SLL R0");
      AsmCode.executeAsmCode("SLL R0");
      AsmCode.executeAsmCode("SLL R0");
      AsmCode.executeAsmCode("ORL R3,R0");
    }
}

梁工 发表于 6 天前

哪个型号的?

LeoringYang 发表于 6 天前

梁工 发表于 2026-7-16 16:41
哪个型号的?
型号:STC32G12K128
如果ADC_EPWMT=0,禁用PWM实时触发ADC功能,ADC是不是默认会用P5.4触发ADC功能,还是要设置ADCEXCFG.ADCETRS?
页: [1] 2 3
查看完整版本: ADC模数转换中断程序,一天也没做出来