找回密码
 立即注册
查看: 1287|回复: 1

如何关闭ADC电源?

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-05-02 13:47:50

6

主题

13

回帖

232

积分

中级会员

积分
232
发表于 2023-10-22 10:33:33 | 显示全部楼层 |阅读模式
在使用STC8G1k08中,如要在ADC采集一次后,关闭ADC一段时间再开启,应该如何关闭ADC呢?用了ADC_CONTR &= ~0x80;这个语句,并没有关闭ADC,一直在采样。请教一下:1.如何关闭ADC??
2.关闭ADC后串口输出的是不是都为0000??
本次借用梁工的例程,做测试。
  1. /*------------------------------------------------------------------*/
  2. /* --- STC MCU International Limited -------------------------------*/
  3. /* --- STC 1T Series MCU RC Demo -----------------------------------*/
  4. /* --- Mobile: (86)13922805190 -------------------------------------*/
  5. /* --- Fax: 86-0513-55012956,55012947,55012969 ---------------------*/
  6. /* --- Tel: 86-0513-55012928,55012929,55012966 ---------------------*/
  7. /* --- Web: www.GXWMCU.com -----------------------------------------*/
  8. /* --- QQ:  800003751 ----------------------------------------------*/
  9. /* If you want to use the program or the program referenced in the  */
  10. /* article, please specify in which data and procedures from STC    */
  11. /*------------------------------------------------------------------*/
  12. #define MAIN_Fosc                11059200L        //定义主时钟
  13. #define        UART_BaudRate1        115200UL         /* 波特率 */
  14. #include        "STC8xxxx.h"
  15. /*************        功能说明        **************
  16. 用户请先别修改程序, 直接下载"01-15路ADC转换-BandGap-串口1(P3.7)返回结果-C语言"里的"ADC.hex"测试. 下载时选择主频11.0592MHZ。
  17. 测试时, 电脑的串口助手设置115200,8,n,1.
  18. 本程序演示16路ADC(P1.0~P1.7, P3.0~P3.6)和bandgap查询采样,通过串口1(P3.7)发送给上位机,波特率115200,8,n,1.
  19. 0~7通道对应P1.0~P1.7, 8~14通道对应P3.0~P3.6, 15通道为内部1.19V基准电压做输入的ADC值.
  20. 初始化时先把要ADC转换的引脚设置为高阻输入.
  21. ADC模块是一个硬件模块, 由ADC时钟驱动, 一旦触发ADC转换, 硬件会在ADC时钟驱动下自动完成.
  22. CLK为ADC时钟, 是系统时钟的SysClk/2/(n+1)分频, ADC转换由下列操作完成:
  23. 通道选择时间     1或2个CLK (默认1)
  24. 通道选择保持时间 1~4个CLK (默认2)
  25. 模拟信号采样时间 1~32个CLK (默认11)
  26. ADC转换时间      10个CLK(固定).
  27. ******************************************/
  28. /*************        本地常量声明        **************/
  29. #define ADC_START        (1<<6)        /* 自动清0 */
  30. #define ADC_FLAG        (1<<5)        /* 软件清0 */
  31. #define        ADC_SPEED        1                /* 0~15, ADC时钟 = SYSclk/2/(n+1) */
  32. #define        RES_FMT                (1<<5)        /* ADC结果格式 0: 左对齐, ADC_RES: D9 D8 D7 D6 D5 D4 D3 D2, ADC_RESL: D1 D0 0  0  0  0  0  0 */
  33.                                                         /*             1: 右对齐, ADC_RES: 0  0  0  0  0  0  D9 D8, ADC_RESL: D7 D6 D5 D4 D3 D2 D1 D0 */
  34. #define CSSETUP                (0<<7)        /* 0~1,  ADC通道选择时间      0: 1个ADC时钟, 1: 2个ADC时钟,  默认0(默认1个ADC时钟) */
  35. #define CSHOLD                (1<<5)        /* 0~3,  ADC通道选择保持时间  (n+1)个ADC时钟, 默认1(默认2个ADC时钟)                */
  36. #define SMPDUTY                20                /* 10~31, ADC模拟信号采样时间  (n+1)个ADC时钟, 默认10(默认11个ADC时钟)                                */
  37.                                                         /* ADC转换时间: 10位ADC固定为10个ADC时钟, 12位ADC固定为12个ADC时钟.                                 */
  38. /*************        本地变量声明        **************/
  39. bit        B_TX1_Busy;        // 发送忙标志
  40. /*************        本地函数声明        **************/
  41. u16                Get_ADC10bitResult(u8 channel);
  42. void        delay_ms(u8 ms);
  43. void        UART1_config(void);
  44. void         Uart1_TxByte(u8 dat);
  45. void         PrintString1(u8 *puts);
  46. void        ADC_convert(u8 chn);        //chn=0~7对应P1.0~P1.7, chn=8~14对应P3.0~P3.6, chn=15对应BandGap电压
  47. /**********************************************/
  48. void main(void)
  49. {
  50.         u8        i;
  51.         UART1_config();   //初始化串口
  52.         EA = 1;
  53.         B_TX1_Busy  = 0;
  54.         P1n_pure_input(0xff);        //设置要做ADC的IO做高阻输入
  55. //        P3n_pure_input(0x7f);        //设置要做ADC的IO做高阻输入
  56.         ADC_CONTR = 0x80 + 0;        //ADC on + channel
  57.         ADCCFG = RES_FMT + ADC_SPEED;
  58.         P_SW2 |=  0x80;        //访问XSFR
  59.         ADCTIM = CSSETUP + CSHOLD + SMPDUTY;
  60.         while (1)
  61.         {
  62.                 for(i=0; i<16; i++)
  63.                 {
  64.                         delay_ms(120);
  65.                         ADC_convert(i);
  66.                         if(i == 7)
  67.                         {
  68.                                 Uart1_TxByte(0x0d);
  69.                                 Uart1_TxByte(0x0a);
  70.                         }
  71.                         ADC_CONTR = ~0x80;
  72.                 }
  73.                         Uart1_TxByte(0x0d);
  74.                         Uart1_TxByte(0x0a);       
  75.        
  76.         }
  77. }
  78. //========================================================================
  79. // 函数: u16        Get_ADC10bitResult(u8 channel))        //channel = 0~15
  80. // 描述: 查询法读一次ADC结果.
  81. // 参数: channel: 选择要转换的ADC, 0~15.
  82. // 返回: 10位ADC结果.
  83. // 版本: V1.0, 2018-11-28
  84. //========================================================================
  85. u16        Get_ADC10bitResult(u8 channel)        //channel = 0~15
  86. {
  87.         ADC_RES = 0;
  88.         ADC_RESL = 0;
  89.         ADC_CONTR = 0x80 | ADC_START | channel;
  90.         NOP(5);                        //
  91.         while((ADC_CONTR & ADC_FLAG) == 0)        ;        //等待ADC结束
  92.         ADC_CONTR &= ~ADC_FLAG;
  93.         return        ((u16)ADC_RES * 256 + (u16)ADC_RESL);
  94. }
  95. #define                SUM_LENGTH        16        /* 平均值采样次数 最大值16 */
  96. /***********************************
  97. 查询方式做一次ADC, chn为通道号, chn=0~7对应P1.0~P1.7, chn=8~14对应P3.0~P3.6, chn=15对应BandGap电压.
  98. ***********************************/
  99. void        ADC_convert(u8 chn)
  100. {
  101.         u16        j;
  102.         u8        k;                //平均值滤波时使用
  103. //        Get_ADC10bitResult(chn);                //参数i=0~11,15,查询方式做一次ADC, 切换通道后第一次转换结果丢弃. 避免采样电容的残存电压影响.
  104. //        Get_ADC10bitResult(chn);                //参数i=0~11,15,查询方式做一次ADC, 切换通道后第二次转换结果丢弃. 避免采样电容的残存电压影响.
  105.         for(k=0, j=0; k<SUM_LENGTH; k++)        j += Get_ADC10bitResult(chn);        // 采样累加和   参数0~15,查询方式做一次ADC, 返回值就是结果
  106.         j = j / SUM_LENGTH;                // 求平均
  107.         Uart1_TxByte('A');
  108.         Uart1_TxByte('D');
  109.         Uart1_TxByte('C');
  110.         Uart1_TxByte(chn/10+'0');
  111.         Uart1_TxByte(chn%10+'0');
  112.         Uart1_TxByte('=');                                //发送ADC读数
  113.         Uart1_TxByte(j/1000 + '0');
  114.         Uart1_TxByte(j%1000/100 + '0');
  115.         Uart1_TxByte(j%100/10 + '0');
  116.         Uart1_TxByte(j%10 + '0');
  117.         Uart1_TxByte(' ');
  118.         Uart1_TxByte(' ');
  119. }
  120. //========================================================================
  121. // 函数: void  delay_ms(u8 ms)
  122. // 描述: 延时函数。
  123. // 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
  124. // 返回: none.
  125. // 版本: VER1.0
  126. // 日期: 2013-4-1
  127. // 备注:
  128. //========================================================================
  129. void  delay_ms(u8 ms)
  130. {
  131.      u16 i;
  132.          do
  133.          {
  134.                  i = MAIN_Fosc / 10000;
  135.                 while(--i)        ;
  136.      }while(--ms);
  137. }
  138. //========================================================================
  139. // 函数: void        UART1_config(u8 brt)
  140. // 描述: UART1初始化函数。
  141. // 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  142. // 返回: none.
  143. // 版本: VER1.0
  144. // 日期: 2016-4-28
  145. // 备注:
  146. //========================================================================
  147. void        UART1_config(void)        //
  148. {
  149.         TR1 = 0;
  150.         AUXR &= ~0x01;                //S1 BRT Use Timer1;
  151.         AUXR |=  (1<<6);        //Timer1 set as 1T mode
  152.         TMOD &= ~(1<<6);        //Timer1 set As Timer
  153.         TMOD &= ~0x30;                //Timer1_16bitAutoReload;
  154.         TH1 = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate1) / 256;
  155.         TL1 = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate1) % 256;
  156.         ET1 = 0;        //禁止中断
  157.         TR1  = 1;
  158.         SCON = (SCON & 0x3f) | (1<<6);        // 8位数据, 1位起始位, 1位停止位, 无校验
  159.         REN = 1;        //允许接收
  160. //        PS  = 1;        //高优先级中断
  161.         ES  = 1;        //允许中断
  162. //        P_SW1 = P_SW1 & 0x3f;                                P3n_standard(0x03);        //头文件定义的宏, 切换到 P3.0 P3.1
  163.         P_SW1 = (P_SW1 & 0x3f) | (1<<6);        P3n_standard(0xc0);        //头文件定义的宏, 切换到 P3.6 P3.7
  164. //        P_SW1 = (P_SW1 & 0x3f) | (2<<6);        P1n_standard(0xc0);        //头文件定义的宏, 切换到 P1.6 P1.7 (必须使用内部时钟)
  165.         B_TX1_Busy  = 0;
  166. }
  167. //========================================================================
  168. // 函数: void Uart1_TxByte(u8 dat)
  169. // 描述: 串口1发送一个字节函数.
  170. // 参数: none.
  171. // 返回: none.
  172. // 版本: VER1.0
  173. // 日期: 2016-4-28
  174. // 备注:
  175. //========================================================================
  176. void Uart1_TxByte(u8 dat)
  177. {
  178.         B_TX1_Busy = 1;                //标志发送忙
  179.         SBUF = dat;                        //发一个字节
  180.         while(B_TX1_Busy);        //等待发送完成
  181. }
  182. //========================================================================
  183. // 函数: void UART1_int (void) interrupt UART1_VECTOR
  184. // 描述: 串口1中断函数
  185. // 参数: none.
  186. // 返回: none.
  187. // 版本: VER1.0
  188. // 日期: 2016-4-28
  189. // 备注:
  190. //========================================================================
  191. void UART1_int (void) interrupt UART1_VECTOR
  192. {
  193.         if(RI)
  194.         {
  195.                 RI = 0;
  196.         }
  197.         if(TI)
  198.         {
  199.                 TI = 0;
  200.                 B_TX1_Busy = 0;
  201.         }
  202. }
复制代码


1.PNG
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:108
  • 最近打卡:2025-06-30 11:50:20

75

主题

6167

回帖

1万

积分

超级版主

积分
12956
发表于 2023-10-23 12:17:24 | 显示全部楼层
ADC_CONTR = 0x00;   //即可关闭ADC模块,一定可以关闭。
再次打开ADC电源,要至少延时1ms再启动ADC转换,模拟电路需要一点时间稳定。
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-6-30 16:46 , Processed in 0.115266 second(s), 54 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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