找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1266|回复: 18
打印 上一主题 下一主题
收起左侧

STC8G1K0A单片机为什么接收不对ADC值?

[复制链接]
跳转到指定楼层
楼主
#include "STC8G.h"
#define uint unsigned int
#define uchar unsigned char
#define FOSC 1105920L //系统频率
#define BAUD 11520 //串口波特率
uint ADC1_DATA;
uchar ADC1_H;
uchar ADC1_L;

void Delay1us() //@11.0592MHz
        {
        unsigned char i;
        i = 3;
        while (--i);
        }

void Delay100ms() //@11.0592MHz
{
        unsigned char i, j, k;
        i = 6;
        j = 157;
        k = 59;
        do
                {
                do
                        {
                        while (--k);
                        }
                while (--j);
                } while (--i);
}

void Timer0Init() //1毫秒@11.0592MHz
        {
                AUXR |= 0x80; //定时器时钟1T模式
                TMOD &= 0xF0; //设置定时器模式
                TL0 = 0xCD; //设置定时初值
                TH0 = 0xD4; //设置定时初值
                ET0 = 1; //开启定时器0
                TR0 = 1; //定时器0开始计时
        }

void UartInit() //可变波特率设置
        {
         SCON = 0x50; //8位可变波特率
         AUXR |= 0x14; //T2为1T模式
         T2L = (65536 - (FOSC/4/BAUD)); //设置波特率重装值
         T2H = (65536 - (FOSC/4/BAUD))>>8;
         ES=1;
         EA=1;
        }

void time0() interrupt 1
        {
                TL0 = 0xCD; //设置定时初值
                TH0 = 0xD4; //设置定时初值
        }

void Uart() interrupt 4 using 1
        {
         unsigned char temp;
                 if (RI)
                 {
                 RI = 0; //清除RI位
                 temp = SBUF; //缓存串口数据
                 }
                 else
                 {
                 TI = 0; //清除TI位
                 }
        }
        
void send_byte(uchar by)
        {
        TI = 0;
        SBUF = by;
        while(!TI);
        TI = 0;
        }
        
void main()
        {
                 P3M0=0x00; P3M1=0x00;

                 P5M0=0x00; P5M1=0x00;
                        
                 Timer0Init();
                 UartInit();
               
                 P3M0=0x00; //设置P30为ADC口,高阻输入模式
                 P3M1=0x01;
               
                 P_SW2 |=0x80;
                 ADCTIM=0x3f; //设置ADC内部时序
                 P_SW2 &=0x7f;
                 ADCCFG=0x2f; //右对齐,设置ADC时间系总统时间/2/16/16 和数据输出格式
                 ADC_CONTR=0x80; //使能 ADC 模块
               
                 Delay100ms(); //等待系统稳定
               
                        while(1)
                                 {
                                 ADC_CONTR |=0x40;//启动AD交换 后4位表示采集的通道 ADC0口
                                 Delay1us();
                                while(!(ADC_CONTR&0x20));//查询ADC完成标志
                                 ADC_CONTR &=~0x20;//清完成标志
                                         
                                 ADC1_H=ADC_RES;
                                 ADC1_L=ADC_RESL;
                                         
                                 ADC1_DATA=ADC1_H*256 + ADC1_L;
                                         
                                 send_byte(ADC1_DATA/1000 + 0x30);
                                 send_byte(ADC1_DATA%1000/100 + 0x30);
                                 send_byte(ADC1_DATA%100/10 + 0x30);
                                 send_byte(ADC1_DATA%10 + 0x30);
                                 send_byte(0x0a);
                                 Delay100ms();
                                 }
        }

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:226055 发表于 2024-1-11 09:43 | 只看该作者
    1、没有看到你用到哪个IO口作为ADC口。需要选择通道打开。
    2、这里也用到了串口,当然需要保证串口部分程序也是没问题的。


    3、上面是ADC部分STC8H单片机的配置参考。程序应该都是通用的,你看下自己的ADC选择通道修改下。附件我把艾克姆的例程正好是ADC采集串口发送的发你参考下。






ADC.rar

41.61 KB, 下载次数: 6

回复

使用道具 举报

板凳
ID:213173 发表于 2024-1-11 10:47 | 只看该作者
用不到的函数屏蔽掉
  1. #include "STC8G.h"
  2. #include "intrins.h"
  3. #define uint unsigned int
  4. #define uchar unsigned char
  5. #define FOSC 1105920L //系统频率
  6. #define BAUD 11520 //串口波特率
  7. uint ADC1_DATA;
  8. uchar ADC1_H;
  9. uchar ADC1_L;

  10. void Delay1us() //@11.0592MHz
  11. {
  12.         unsigned char i;
  13.         i = 3;
  14.         while (--i);
  15. }

  16. void Delay100ms() //@11.0592MHz
  17. {
  18.         unsigned char i, j, k;
  19.         i = 6;
  20.         j = 157;
  21.         k = 59;
  22.         do
  23.         {
  24.                 do
  25.                 {
  26.                         while (--k);
  27.                 }
  28.                 while (--j);
  29.         } while (--i);
  30. }
  31. /*
  32. void Timer0Init() //1毫秒@11.0592MHz
  33. {
  34.         AUXR |= 0x80; //定时器时钟1T模式
  35.         TMOD &= 0xF0; //设置定时器模式
  36.         TL0 = 0xCD; //设置定时初值
  37.         TH0 = 0xD4; //设置定时初值
  38.         ET0 = 1; //开启定时器0
  39.         TR0 = 1; //定时器0开始计时
  40. }*/

  41. void UartInit() //可变波特率设置 115200bps@11.0592MHz
  42. {
  43.         SCON = 0x50; //8位可变波特率
  44.         AUXR |= 0x14; //T2为1T模式
  45.         T2L = (65536 - (FOSC/4/BAUD)); //设置波特率重装值
  46.         T2H = (65536 - (FOSC/4/BAUD))>>8;
  47. //        ES=1;
  48. //        EA=1;
  49. }
  50. /*
  51. void time0() interrupt 1
  52. {
  53.         TL0 = 0xCD; //设置定时初值
  54.         TH0 = 0xD4; //设置定时初值
  55. }*/
  56. /*
  57. void Uart() interrupt 4 using 1
  58. {
  59. //        unsigned char temp;
  60.         if (RI)
  61.         {
  62.                 RI = 0; //清除RI位
  63. //                temp = SBUF; //缓存串口数据
  64.         }
  65.         else
  66.         {
  67.                 TI = 0; //清除TI位
  68.         }
  69. }*/
  70.       
  71. void send_byte(uchar by)
  72. {
  73.         SBUF = by;
  74.         while (!TI);
  75.         TI = 0;
  76. }
  77.       
  78. void main()
  79. {
  80.         P3M0=0x00; P3M1=0x01;//设置P30为ADC口,高阻输入模式
  81.         P5M0=0x00; P5M1=0x00;
  82. //        Timer0Init();
  83.         UartInit();
  84. //        P3M0=0x00;
  85. //        P3M1=0x01;
  86.         P_SW2 |=0x80;
  87.         ADCTIM=0x3f; //设置ADC内部时序
  88.         P_SW2 &=0x7f;
  89.         ADCCFG=0x2f; //右对齐,设置ADC时间系总统时间/2/16/16 和数据输出格式
  90.         ADC_CONTR=0x80; //使能 ADC 模块
  91.         Delay100ms(); //等待系统稳定
  92.         while(1)
  93.         {
  94.                 ADC_CONTR |=0x40;//启动AD交换 后4位表示采集的通道 ADC0口
  95.                 Delay1us();
  96.                 while(!(ADC_CONTR&0x20));//查询ADC完成标志
  97.                 ADC_CONTR &=~0x20;//清完成标志               
  98.                 ADC1_H=ADC_RES;
  99.                 ADC1_L=ADC_RESL;
  100.                 ADC1_DATA=ADC1_H*256 + ADC1_L;
  101.                 send_byte(ADC1_DATA/1000 + 0x30);
  102.                 send_byte(ADC1_DATA%1000/100 + 0x30);
  103.                 send_byte(ADC1_DATA%100/10 + 0x30);
  104.                 send_byte(ADC1_DATA%10 + 0x30);
  105.                 send_byte(0x0a);
  106.                 Delay100ms();
  107.                 Delay100ms();
  108.                 Delay100ms();
  109.         }
  110. }
复制代码
回复

使用道具 举报

地板
ID:72649 发表于 2024-1-11 14:41 来自手机 | 只看该作者
cocolala 发表于 2024-1-11 09:43
1、没有看到你用到哪个IO口作为ADC口。需要选择通道打开。
    2、这里也用到了串口,当然需要保证串 ...

谢谢啦,有空我试一下
回复

使用道具 举报

5#
ID:72649 发表于 2024-1-11 14:42 来自手机 | 只看该作者
wulin 发表于 2024-1-11 10:47
用不到的函数屏蔽掉

定时器后面还有代码要用的。先谢谢了
回复

使用道具 举报

6#
ID:213173 发表于 2024-1-11 16:02 | 只看该作者
hjx5548 发表于 2024-1-11 14:42
定时器后面还有代码要用的。先谢谢了

上面改过的程序实测串口可以正常发送ADC转换值。问题可能是你串口中断与send_byte(uchar by)函数TI处理冲突。
回复

使用道具 举报

7#
ID:72649 发表于 2024-1-11 20:37 | 只看该作者
wulin 发表于 2024-1-11 16:02
上面改过的程序实测串口可以正常发送ADC转换值。问题可能是你串口中断与send_byte(uchar by)函数TI处理冲 ...

#include "STC8G.h"
#include "intrins.h"
#define uint unsigned int
#define uchar unsigned char
#define FOSC 1105920L //系统频率
#define BAUD 11520 //串口波特率
uint ADC1_DATA;
uchar ADC1_H;
uchar ADC1_L;

void Delay1us() //@11.0592MHz
{
        unsigned char i;
        i = 3;
        while (--i);
}

void Delay100ms() //@11.0592MHz
{
        unsigned char i, j, k;
        i = 6;
        j = 157;
        k = 59;
        do
        {
                do
                {
                        while (--k);
                }
                while (--j);
        } while (--i);
}
/*
void Timer0Init() //1毫秒@11.0592MHz
{
        AUXR |= 0x80; //定时器时钟1T模式
        TMOD &= 0xF0; //设置定时器模式
        TL0 = 0xCD; //设置定时初值
        TH0 = 0xD4; //设置定时初值
        ET0 = 1; //开启定时器0
        TR0 = 1; //定时器0开始计时
}*/

void UartInit() //可变波特率设置 115200bps@11.0592MHz
{
        SCON = 0x50; //8位可变波特率
        AUXR |= 0x14; //T2为1T模式
        T2L = (65536 - (FOSC/4/BAUD)); //设置波特率重装值
        T2H = (65536 - (FOSC/4/BAUD))>>8;
//        ES=1;
//        EA=1;
}
/*
void time0() interrupt 1
{
        TL0 = 0xCD; //设置定时初值
        TH0 = 0xD4; //设置定时初值
}*/
/*
void Uart() interrupt 4 using 1
{
//        unsigned char temp;
        if (RI)
        {
                RI = 0; //清除RI位
//                temp = SBUF; //缓存串口数据
        }
        else
        {
                TI = 0; //清除TI位
        }
}*/
      
void send_byte(uchar by)
{
        SBUF = by;
        while (!TI);
        TI = 0;
}
      
void main()
{
        P3M0=0x00; P3M1=0x04;//设置P32为ADC口,高阻输入模式
        P5M0=0x00; P5M1=0x00;
//        Timer0Init();
        UartInit();
//        P3M0=0x00;
//        P3M1=0x01;
        P_SW2 |=0x80;
        ADCTIM=0x3f; //设置ADC内部时序
        P_SW2 &=0x7f;
        ADCCFG=0x2f; //右对齐,设置ADC时间系总统时间/2/16/16 和数据输出格式
        ADC_CONTR=0x80; //使能 ADC 模块
        Delay100ms(); //等待系统稳定
        while(1)
        {
                ADC_CONTR |=0x42;//启动AD交换 后4位表示采集的通道 ADC0口 P30 0000 P31  0001 P32  0010  P33  0011  P54  0100   P55   0101
                Delay1us();
                while(!(ADC_CONTR&0x20));//查询ADC完成标志
                ADC_CONTR &=~0x20;//清完成标志               
                ADC1_H=ADC_RES;
                ADC1_L=ADC_RESL;
                ADC1_DATA=ADC1_H*256 + ADC1_L;
                send_byte(ADC1_DATA/1000 + 0x30);
                send_byte(ADC1_DATA%1000/100 + 0x30);
                send_byte(ADC1_DATA%100/10 + 0x30);
                send_byte(ADC1_DATA%10 + 0x30);
                send_byte(0x0a);
                Delay100ms();
                Delay100ms();
                Delay100ms();
        }
}  

我怎么接收不到,已经改为P32  ADC

2222.png (65.83 KB, 下载次数: 67)

2222.png
回复

使用道具 举报

8#
ID:72649 发表于 2024-1-11 20:41 | 只看该作者
cocolala 发表于 2024-1-11 09:43
1、没有看到你用到哪个IO口作为ADC口。需要选择通道打开。
    2、这里也用到了串口,当然需要保证串 ...

代码是什么型号单片机?
回复

使用道具 举报

9#
ID:72649 发表于 2024-1-11 20:49 | 只看该作者
hjx5548 发表于 2024-1-11 14:41
谢谢啦,有空我试一下

ADC_CONTR |=0x40;//启动AD交换 后4位表示采集的通道 ADC0口 P30 0000 P31  0001 P32  0010  P33  0011  P54  0100   P55   0101
回复

使用道具 举报

10#
ID:213173 发表于 2024-1-11 22:12 | 只看该作者
hjx5548 发表于 2024-1-11 20:37
#include "STC8G.h"
#include "intrins.h"
#define uint unsigned int


回复

使用道具 举报

11#
ID:384109 发表于 2024-1-12 08:25 | 只看该作者
#define BAUD 11520 //串口波特率,先单独测试串口吧
回复

使用道具 举报

12#
ID:72649 发表于 2024-1-12 13:25 | 只看该作者

设置P32为ADC口,需要修改哪里?
回复

使用道具 举报

13#
ID:72649 发表于 2024-1-12 13:31 | 只看该作者
wulin 发表于 2024-1-11 22:12

#include "STC8G.h"
#include "intrins.h"
#define uint unsigned int
#define uchar unsigned char
#define FOSC 1105920L //系统频率
#define BAUD 11520 //串口波特率
uint ADC1_DATA;
uchar ADC1_H;
uchar ADC1_L;

void Delay1us() //@11.0592MHz
{
        unsigned char i;
        i = 3;
        while (--i);
}

void Delay100ms() //@11.0592MHz
{
        unsigned char i, j, k;
        i = 6;
        j = 157;
        k = 59;
        do
        {
                do
                {
                        while (--k);
                }
                while (--j);
        } while (--i);
}
/*
void Timer0Init() //1毫秒@11.0592MHz
{
        AUXR |= 0x80; //定时器时钟1T模式
        TMOD &= 0xF0; //设置定时器模式
        TL0 = 0xCD; //设置定时初值
        TH0 = 0xD4; //设置定时初值
        ET0 = 1; //开启定时器0
        TR0 = 1; //定时器0开始计时
}*/

void UartInit() //可变波特率设置 115200bps@11.0592MHz
{
        SCON = 0x50; //8位可变波特率
        AUXR |= 0x14; //T2为1T模式
        T2L = (65536 - (FOSC/4/BAUD)); //设置波特率重装值
        T2H = (65536 - (FOSC/4/BAUD))>>8;
//        ES=1;
//        EA=1;
}
/*
void time0() interrupt 1
{
        TL0 = 0xCD; //设置定时初值
        TH0 = 0xD4; //设置定时初值
}*/



void send_byte(uchar by)
{
        SBUF = by;
        while (!TI);
        TI = 0;
}

void main()
{
        P3M0=0x00; P3M1=0x04;//设置P32为ADC口,高阻输入模式
        P5M0=0x00; P5M1=0x00;
//        Timer0Init();
        UartInit();
        P_SW2 |=0x80;
        ADCTIM=0x3f; //设置ADC内部时序
        P_SW2 &=0x7f;
        ADCCFG=0x2f; //右对齐,设置ADC时间系总统时间/2/16/16 和数据输出格式
        ADC_CONTR=0x82; //使能 ADC 模块
        Delay100ms(); //等待系统稳定
        while(1)
        {
                ADC_CONTR |=0x42;//启动AD交换 后4位表示采集的通道 ADC0口
                Delay1us();
                while(!(ADC_CONTR&0x20));//查询ADC完成标志
                ADC_CONTR &=~0x20;//清完成标志               
                ADC1_H=ADC_RES;
                ADC1_L=ADC_RESL;
                ADC1_DATA=ADC1_H*256 + ADC1_L;
                                       
                send_byte(ADC1_DATA/1000 + 0x30);
                send_byte(ADC1_DATA%1000/100 + 0x30);
                send_byte(ADC1_DATA%100/10 + 0x30);
                send_byte(ADC1_DATA%10 + 0x30);
                send_byte(0x0a);
                Delay100ms();
                Delay100ms();
                Delay100ms();
        }
}
//单片机为STC8G1K08A-8PIN的,ADC采集P32 就是不能发送什么原因?

51hei图片_20240112133125.png (70.28 KB, 下载次数: 63)

51hei图片_20240112133125.png
回复

使用道具 举报

14#
ID:72649 发表于 2024-1-12 13:52 | 只看该作者
wulin 发表于 2024-1-11 22:12

#include "STC8G.h"
#include "intrins.h"
#define uchar unsigned char     
#define uint unsigned int     
#define ADCTIM  (*(unsigned char volatile xdata *)0xfea8)
#define ADC_POWER   0x80                        //ADC电源控制位1000 0000
#define ADC_START   0x40                        //ADC启动控制位0100 0000
#define ADC_FLAG    0x20                        //ADC完成标志位0010 0000
#define ADC_EPWMT   0x10                        //ADC使能控制位0001 0000   

#define FOSC 1105920L //系统频率
#define BAUD 11520 //串口波特率

uint ADC_A,ADC_B;

void Delay1ms()                //@11.0592MHz
{
        unsigned char i, j;

        i = 15;
        j = 90;
        do
        {
                while (--j);
        } while (--i);
}
/*-----------------------------
  初始化ADC
------------------------------*/
void UartInit() //可变波特率设置 115200bps@11.0592MHz
{
        SCON = 0x50; //8位可变波特率
        AUXR |= 0x14; //T2为1T模式
        T2L = (65536 - (FOSC/4/BAUD)); //设置波特率重装值
        T2H = (65536 - (FOSC/4/BAUD))>>8;
}

void send_byte(uchar by)
{
        SBUF = by;
        while (!TI);
        TI = 0;
}

void Init_ADC()
{        //ADC 控制器  电源  启动  完成  --   15通道模拟选择位  单片机STC8G1K08A-8PIN   P30 0000 P31  0001 P32  0010  P33  0011  P54  0100   P55   0101
        //ADC_CONTR    B7    B6    B5   B4   B3   B2   B1   B0
        P_SW2 |= 0x80;                        //打开
        ADCTIM = 0x3f;                        //设置 ADC 内部时序
        P_SW2 &= 0x7f;                        //关闭
        ADCCFG = 0x27;                        //设置ADC结果右对齐,速度为512系统时钟
        ADC_RES=0;                                //清除ADC_RES存储器以前的结果
        ADC_RESL=0;
        ADC_CONTR=ADC_POWER; //ADC 开启电源
        Delay1ms();                                //上电延时1ms
}
/*----------------------------
        读取ADC结果
----------------------------*/
uint GetADCResult(uchar CH)
{
        ADC_CONTR=ADC_POWER|ADC_START|CH;//启动转换1100 1000   STC8G1K08A-8PIN的CH   P30 0000 P31  0001 P32  0010  P33  0011  P54  0100   P55   0101
        _nop_();_nop_();                                //小延时
        while (!(ADC_CONTR & ADC_FLAG));//等待ADC转换完成标志置位 1010 0000
        ADC_CONTR &=~ADC_FLAG;                        //清完成标志
        return ADC_RES<<8|ADC_RESL;                //返回十位ADC结果
}

void main ()
{         
        P3M0 = 0x00;
        P3M1 = 0x04;

        P5M0 = 0x00;
        P5M1 = 0x00;
        Init_ADC();
        while(1)
        {
                ADC_A=GetADCResult(2);
//                ADC_B=GetADCResult(1);
                //添加显示/控制代码
                                        send_byte(ADC_A/1000 + 0x30);
                send_byte(ADC_A%1000/100 + 0x30);
                send_byte(ADC_A%100/10 + 0x30);
                send_byte(ADC_A%10 + 0x30);
                send_byte(0x0a);
                Delay100ms();
                Delay100ms();
                Delay100ms();        
        }
}
//这个是你以前帖子,加入了串口发送,也是无法发送ADC  ,芯片为8脚的STC8G1K08A ,ADC采集口P32

回复

使用道具 举报

15#
ID:72649 发表于 2024-1-12 15:49 | 只看该作者
hjx5548 发表于 2024-1-11 14:41
谢谢啦,有空我试一下

STC8G1H08A-PIN8 单片机的P32
回复

使用道具 举报

16#
ID:72649 发表于 2024-1-12 20:14 来自手机 | 只看该作者
wulin 发表于 2024-1-11 22:12

能不能把你的代码发上来参考一下,STC8H1K08A的8脚单片机,ADC采集是P32。
回复

使用道具 举报

17#
ID:72649 发表于 2024-1-12 21:55 | 只看该作者
cocolala 发表于 2024-1-11 09:43
1、没有看到你用到哪个IO口作为ADC口。需要选择通道打开。
    2、这里也用到了串口,当然需要保证串 ...

首先要谢谢你,根据的代码,我修改成功了。就是判断ADC值不能改变LED灯的电平变化。
     if((HandleADC()>0)&&(HandleADC()<500))
                        {
                                        LED1=1;//灯亮
                                        LED2=0;//灯灭
                                        LED3=0;//灯灭
                           }

           if((HandleADC()>500)&&(HandleADC()<1024))  

                                               {
                                        LED1=0;//灯灭
                                        LED2=1;//灯亮
                                        LED3=1;//灯亮
                           }


{26581886-06A1-4d03-A0F0-F85E9B71EF97}.png (81.44 KB, 下载次数: 50)

{26581886-06A1-4d03-A0F0-F85E9B71EF97}.png
回复

使用道具 举报

18#
ID:213173 发表于 2024-1-13 06:11 | 只看该作者
hjx5548 发表于 2024-1-12 20:14
能不能把你的代码发上来参考一下,STC8H1K08A的8脚单片机,ADC采集是P32。

首先要说清楚所选用的MCU具体型号,你标题写STC8G1K0A,在15、16楼又说是STC8G1H08A。实际上你说的型号都不存在。估猜实际型号是STC8G1K08A-PIN8。那么问题就非常明确了。STC8G1K08A只有定时器0和定时器1,没有定时器2。你用定时器2作波特率发生器怎么能成功?
回复

使用道具 举报

19#
ID:72649 发表于 2024-1-13 09:20 | 只看该作者
wulin 发表于 2024-1-13 06:11
首先要说清楚所选用的MCU具体型号,你标题写STC8G1K0A,在15、16楼又说是STC8G1H08A。实际上你说的型号都 ...

把定时器2修改为定时器1后,可以发送数据了,谢谢
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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