找回密码
 立即注册
查看: 61|回复: 12

STC8G1K08 ADC读取问题

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:418
  • 最近打卡:2026-03-06 00:02:43

180

主题

246

回帖

579

积分

高级会员

积分
579
发表于 3 天前 | 显示全部楼层 |阅读模式
选用STC8G1K08 P1.5脚做ADC输入,P3.4-P3.7、P1.0-P1.3推挽输出,驱动对应的LED。 实现的功能是:根据P1.5脚ADC值的大小,点亮对应的LED, 程序实现不了,求指导
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:418
  • 最近打卡:2026-03-06 00:02:43

180

主题

246

回帖

579

积分

高级会员

积分
579
发表于 3 天前 | 显示全部楼层
#include <STC8G.h>

// 系统时钟定义12MHz
#define FOSC 12000000L
#define ADC_MAX 4095  // 12位ADC最大值

// LED引脚定义(共7个,高电平点亮)
sbit LED1 = P3^4;  // 最低ADC值对应点亮
sbit LED2 = P3^5;
sbit LED3 = P3^6;
sbit LED4 = P3^7;
sbit LED5 = P1^0;
sbit LED6 = P1^1;
sbit LED7 = P1^2;  // 最高ADC值对应点亮

// 函数声明
void System_Init(void);
unsigned int ADC_Read(unsigned char ch);
void LED_Control(unsigned int adc_val);
void Delay_ms(unsigned int ms);

void main(void)
{
    unsigned int adc_value;
   
    // 系统初始化(推挽输出+ADC配置)
    System_Init();
   
    while(1)
    {
        // 读取P1.5的ADC值(12位精度)
        adc_value = ADC_Read(5);  // 5对应P1.5通道
        
        // 根据ADC值阶梯点亮LED(高电平点亮)
        LED_Control(adc_value);
        
        // 延时稳定显示,避免闪烁
        Delay_ms(100);
    }
}

/**
* @brief 系统初始化:LED引脚配置为推挽输出,ADC初始化
* 适配12MHz时钟,移除P1ASF,兼容STC8G1K08
*/
void System_Init(void)
{
    // 1. 配置LED引脚为推挽输出(关键:P1M0/P3M0置1,P1M1/P3M1置0)
    // P1.0-P1.2推挽输出
    P1M0 |= 0x07;  // P1M0对应位=1:推挽/强推挽
    P1M1 &= ~0x07; // P1M1对应位=0:推挽输出模式
    // P3.4-P3.7推挽输出
    P3M0 |= 0xF0;  // P3.4-P3.7对应位(bit4-bit7)置1
    P3M1 &= ~0xF0; // P3.4-P3.7对应位清0
   
    // 初始状态:所有LED熄灭(低电平)
    LED1 = 0;
    LED2 = 0;
    LED3 = 0;
    LED4 = 0;
    LED5 = 0;
    LED6 = 0;
    LED7 = 0;
   
    // 2. ADC初始化(适配STC8G1K08,12MHz时钟下无需额外调整)
    ADC_CONTR = 0x80;  // 开启ADC电源(ADON=1)
    ADC_RES = 0;       // 清空ADC结果寄存器
    ADC_RESL = 0;
    Delay_ms(1);       // ADC电源稳定延时(必须)
}

/**
* @brief 读取指定通道的ADC值(12位精度,适配12MHz时钟)
* @param ch: ADC通道(0-7对应P1.0-P1.7)
* @return 12位ADC值(0-4095)
*/
unsigned int ADC_Read(unsigned char ch)
{
    unsigned int adc_result;
   
    // 设置ADC通道,启动转换(0x80=开启ADC,0x08=启动转换)
    ADC_CONTR = 0x80 | (ch & 0x07) | 0x08;
   
    // 等待转换完成(ADC_FLAG位(bit4)为1表示完成)
    while(!(ADC_CONTR & 0x10));
   
    // 拼接12位结果:ADC_RES(高8位) + ADC_RESL(低4位)
    adc_result = (unsigned int)ADC_RES << 4;
    adc_result |= (ADC_RESL & 0x0F);
   
    // 清除转换完成标志,准备下一次转换
    ADC_CONTR &= ~0x10;
   
    return adc_result;
}

/**
* @brief 根据ADC值阶梯点亮LED(高电平点亮)
* @param adc_val: ADC采集值(0-4095)
*/
void LED_Control(unsigned int adc_val)
{
    // 先熄灭所有LED(置低电平)
    LED1 = 0;
    LED2 = 0;
    LED3 = 0;
    LED4 = 0;
    LED5 = 0;
    LED6 = 0;
    LED7 = 0;
   
    // 阶梯点亮逻辑(阈值可根据实际需求调整)
    if(adc_val > 585)  LED1 = 1;  // 第1级:ADC>585,LED1高电平点亮
    if(adc_val > 1170) LED2 = 1;  // 第2级:ADC>1170,LED2点亮
    if(adc_val > 1755) LED3 = 1;  // 第3级:ADC>1755,LED3点亮
    if(adc_val > 2340) LED4 = 1;  // 第4级:ADC>2340,LED4点亮
    if(adc_val > 2925) LED5 = 1;  // 第5级:ADC>2925,LED5点亮
    if(adc_val > 3510) LED6 = 1;  // 第6级:ADC>3510,LED6点亮
    if(adc_val > 4000) LED7 = 1;  // 第7级:ADC接近最大值,LED7点亮
}

/**
* @brief 毫秒级延时函数(核心修改:适配12MHz时钟)
* @param ms: 延时毫秒数,12MHz下该函数延时精度约±1ms
*/
void Delay_ms(unsigned int ms)
{
    unsigned int i, j;
    // 12MHz时钟下,内层循环次数调整为1000(保证1ms延时)
    for(i = ms; i > 0; i--)
        for(j = 1000; j > 0; j--);
}
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:762
  • 最近打卡:2026-03-05 13:16:23

15

主题

73

回帖

3560

积分

论坛元老

积分
3560
发表于 3 天前 | 显示全部楼层
STC8G1K08没有ADC ?STC8G1K08A才有?
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:683
  • 最近打卡:2026-03-05 11:46:27
已绑定手机

49

主题

2640

回帖

2846

积分

荣誉版主

积分
2846
发表于 3 天前 | 显示全部楼层
合适一下单片机是否带ADC,另外main函数第一句加上:
P_SW2 |= 0x80;
试试
~~~
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:418
  • 最近打卡:2026-03-06 00:02:43

180

主题

246

回帖

579

积分

高级会员

积分
579
发表于 3 天前 | 显示全部楼层
原来设计的用DIP20 STCW15408AS,看DIP20 STC8G1K08便宜,结果后者无ADC
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:631
  • 最近打卡:2026-03-04 08:45:22

33

主题

2882

回帖

6465

积分

论坛元老

积分
6465
发表于 3 天前 | 显示全部楼层
贵有贵的道理
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:418
  • 最近打卡:2026-03-06 00:02:43

180

主题

246

回帖

579

积分

高级会员

积分
579
发表于 3 天前 | 显示全部楼层
设计的用STC15W408AS DIP20,就用它了
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:633
  • 最近打卡:2026-03-05 12:16:08
已绑定手机

52

主题

2463

回帖

8724

积分

论坛元老

积分
8724
发表于 3 天前 | 显示全部楼层
STC8G1K08-16/20PIN的芯片有ADC

截图202603031401565149.jpg
截图202603031404165449.jpg

STC8G1K08-8PIN的没有ADC,STC8G1K08A-8PIN的也有ADC。

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:12
  • 最近打卡:2026-03-03 15:09:38
已绑定手机

2

主题

15

回帖

108

积分

注册会员

积分
108
发表于 3 天前 | 显示全部楼层
cjt*** 发表于 2026-3-3 12:16
#include

// 系统时钟定义12MHz

ADC_Read函数中启动位错误,ADC_CONTR = 0x80 | 0x40 | ch ;,另外STC8G1K08是10位ADC。
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:12
  • 最近打卡:2026-03-03 15:09:38
已绑定手机

2

主题

15

回帖

108

积分

注册会员

积分
108
发表于 3 天前 | 显示全部楼层
cjt*** 发表于 2026-3-3 12:16
#include

// 系统时钟定义12MHz
  1. #include <STC8G.h>
  2. // 系统时钟定义12MHz
  3. #define FOSC 12000000L
  4. #define ADC_MAX 4095  // 12位ADC最大值
  5. #define ADCTIM  (*(unsigned char volatile xdata *)0xfea8)
  6. #define ADC_POWER   0x80                        //ADC power control dit (宏定义ADC电源控制位)1000 0000
  7. #define ADC_START   0x40                        //ADC start control dit (宏定义ADC启动控制位)0100 0000
  8. #define ADC_FLAG    0x20                        //ADC complete flag (宏定义ADC完成标志位)    0010 0000
  9. #define ADC_EPWMT   0x10                        //使能 PWM  实时触发 ADC                     0001 0000
  10. // LED引脚定义(共7个,高电平点亮)
  11. sbit LED1 = P3^4;  // 最低ADC值对应点亮
  12. sbit LED2 = P3^5;
  13. sbit LED3 = P3^6;
  14. sbit LED4 = P3^7;
  15. sbit LED5 = P1^0;
  16. sbit LED6 = P1^1;
  17. sbit LED7 = P1^2;  // 最高ADC值对应点亮
  18. // 函数声明
  19. void System_Init(void);
  20. unsigned int ADC_Read(unsigned char ch);
  21. void LED_Control(unsigned int adc_val);
  22. void Delay_ms(unsigned int ms);
  23. void main(void)
  24. {
  25.     unsigned int adc_value;
  26.    
  27.     // 系统初始化(推挽输出+ADC配置)
  28.     System_Init();
  29.    
  30.     while(1)
  31.     {
  32.         // 读取P1.5的ADC值(10位精度)
  33.         adc_value = ADC_Read(5);  // 5对应P1.5通道
  34.         
  35.         // 根据ADC值阶梯点亮LED(高电平点亮)
  36.         LED_Control(adc_value);
  37.         
  38.         // 延时稳定显示,避免闪烁
  39.         Delay_ms(100);
  40.     }
  41. }
  42. /**
  43. * @brief 系统初始化:LED引脚配置为推挽输出,ADC初始化
  44. * 适配12MHz时钟,移除P1ASF,兼容STC8G1K08
  45. */
  46. void System_Init(void)
  47. {
  48.     P1M0 = 0x07; P1M1 = 0x20;// P1.0~1.2推挽,P1.5高阻,其余准双向
  49.     P3M0 = 0xf0; P3M1 = 0x00;// P3.4~3.7推挽,其余准双向
  50.     P5M0 = 0xf0; P5M1 = 0x00;// 准双向
  51.     // 初始状态:所有LED熄灭(低电平)
  52.     LED1 = 0;
  53.     LED2 = 0;
  54.     LED3 = 0;
  55.     LED4 = 0;
  56.     LED5 = 0;
  57.     LED6 = 0;
  58.     LED7 = 0;
  59.    
  60.     // 2. ADC初始化(适配STC8G1K08,12MHz时钟下无需额外调整)
  61.         P_SW2 |= 0x80;                        //打开
  62.         ADCTIM = 0x3f;                        //设置 ADC 内部时序
  63.         P_SW2 &= 0x7f;                        //关闭
  64.         ADCCFG = 0x27;                        //设置ADC结果右对齐,速度为512系统时钟
  65.         ADC_RES=0;                                //清除ADC_RES存储器以前的结果
  66.         ADC_RESL=0;
  67.         ADC_CONTR=ADC_POWER;         //ADC 开启电源
  68.         Delay_ms(1);            // ADC电源稳定延时(必须)
  69. }
  70. /**
  71. * @brief 读取指定通道的ADC值(10位精度,适配12MHz时钟)
  72. * @param ch: ADC通道(0-7对应P1.0-P1.7)
  73. * @return 10位ADC值(0-1023)
  74. */
  75. unsigned int ADC_Read(unsigned char ch)
  76. {
  77.         ADC_CONTR=ADC_POWER|ADC_START|ch;//启动转换1100 1000
  78.         _nop_();_nop_();                                //小延时
  79.         while (!(ADC_CONTR & ADC_FLAG));//等待ADC转换完成标志置位 1010 0000
  80.         ADC_CONTR &=~ADC_FLAG;                        //清完成标志
  81.         return ADC_RES<<8|ADC_RESL;                //返回十位ADC结果
  82. }
  83. /**
  84. * @brief 根据ADC值阶梯点亮LED(高电平点亮)
  85. * @param adc_val: ADC采集值(0-4095)
  86. */
  87. void LED_Control(unsigned int adc_val)
  88. {  
  89.     // 阶梯点亮逻辑(阈值可根据实际需求调整)
  90.     if(adc_val > ( 585/4)) LED1 = 1; else LED1 = 0; // 第1级:ADC>585,LED1高电平点亮
  91.     if(adc_val > (1170/4)) LED2 = 1; else LED2 = 0; // 第2级:ADC>1170,LED2点亮
  92.     if(adc_val > (1755/4)) LED3 = 1; else LED3 = 0; // 第3级:ADC>1755,LED3点亮
  93.     if(adc_val > (2340/4)) LED4 = 1; else LED4 = 0; // 第4级:ADC>2340,LED4点亮
  94.     if(adc_val > (2925/4)) LED5 = 1; else LED5 = 0; // 第5级:ADC>2925,LED5点亮
  95.     if(adc_val > (3510/4)) LED6 = 1; else LED6 = 0; // 第6级:ADC>3510,LED6点亮
  96.     if(adc_val > (4000/4)) LED7 = 1; else LED7 = 0; // 第7级:ADC接近最大值,LED7点亮
  97. }
  98. /**
  99. * @brief 毫秒级延时函数(核心修改:适配12MHz时钟)
  100. * @param ms: 延时毫秒数,12MHz下该函数延时精度约±1ms
  101. */
  102. void Delay_ms(unsigned int ms)
  103. {
  104.     unsigned int i, j;
  105.     // 12MHz时钟下,内层循环次数调整为1000(保证1ms延时)
  106.     for(i = ms; i > 0; i--)
  107.         for(j = 1000; j > 0; j--);
  108. }
复制代码


点评

mark  发表于 前天 10:14
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-3-6 00:24 , Processed in 0.115731 second(s), 96 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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