找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC8G1K08单片机P1.0ADC测量电压问题

[复制链接]
跳转到指定楼层
楼主
ID:92556 发表于 2020-9-5 02:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
官方例程改的,vcc的电压显示是正常的,P1.0,除了接地,是00,输入什么电压都是显示都是65,,
自己看不出问题在哪,,



int *BGV; //内部 1.19V 参考信号源值存放在 idata 中
//idata 的 EFH 地址存放高字节
//idata 的 F0H 地址存放低字节
//电压单位为毫伏(mV)
unsigned int   v1; v2; v3; pv1; pv2; pv3;  //voltage;        

int vcc; voltage;         

int res; res2;

/* void DelayMS(xg)

{ unsigned char i, j;

        i = 12;
        j = 169;
        do
        {
                while (--j);
        } while (--i);
}          //延时子程序
*/

void ADCInit()
{
P_SW2 |= 0x80;
ADCTIM = 0x3f; //设置 ADC 内部时序
P_SW2 &= 0x7f;
ADCCFG = 0x2f; //设置 ADC 时钟为系统时钟/2/16/16
ADC_CONTR = 0x8f; //使能 ADC 模块,并选择第 15 通道
DelayMS(20) ;
}
int ADCRead()
{ int res ;

ADC_CONTR |= 0x40; //启动 AD 转换
_nop_();
_nop_();
while (!(ADC_CONTR & 0x20)); //查询 ADC 完成标志
ADC_CONTR &= ~0x20; //清完成标志
res = (ADC_RES << 8) | ADC_RESL; //读取 ADC 结果

return res;
}


void ADCInit2()
{

P_SW2 |= 0x80;
ADCTIM = 0x3f; //设置 ADC 内部时序
P_SW2 &= 0x7f;
ADCCFG = 0x2f; //设置 ADC 时钟为系统时钟/2/16/16
ADC_CONTR =0x80; //使能 ADC 模块,并选择第 0 通道
DelayMS(20);
}
int ADCRead2()
{  int res2        ;

  ADC_RES=0;
  ADC_RESL=0;

    P1M0=0xFE;
        P1M1=0x01;//P1.0高阻态
ADC_CONTR |= 0x40; //启动 AD 转换
_nop_();
_nop_();
while (!(ADC_CONTR & 0x20)); //查询 ADC 完成标志
ADC_CONTR &= ~0x20; //清完成标志
res2 = (ADC_RES << 8) | ADC_RESL; //读取 ADC 结果

return res2;
}


void dy (void)
{


int i;
int m ;
BGV = (int idata *)0xef;
ADCInit(); //ADC 初始化

//ES = 1;
//EA = 1;

// ADCRead();
// ADCRead(); //前两个数据建议丢弃
res = 0;
for (i=0; i<8; i++)
{
res += ADCRead(); //读取 8 次数据
}
res >>= 3; //取平均值

        

ADCInit2();

ADCRead2();
ADCRead2(); //前两个数据建议丢弃

  res2 = 0;
for (m=0; m<8; m++)
{
res2 += ADCRead2(); //读取 8 次数据
}
res2 >>= 3; //取平均值




vcc = (int)(1024L * *BGV / res); //(10 位 ADC 算法)计算 VREF 管脚电压,即电池电压
pv3=vcc+270;
voltage= (int)(vcc*res2/1024L);
v=voltage*10;  //100k/10k分压

// vcc = (int)(4096L * *BGV / res); //(12 位 ADC 算法)计算 VREF 管脚电压,即电池电压
//注意,此电压的单位为毫伏(mV)
}

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

使用道具 举报

沙发
ID:337139 发表于 2022-3-26 11:08 | 只看该作者
这里有一个问题,取值平均应用流水串的思想要准确一些。
回复

使用道具 举报

板凳
ID:115923 发表于 2022-3-26 13:03 | 只看该作者
P1M0=0xFE;
        P1M1=0x01;//P1.0高阻态

没有设置P1.0为 ADC, 还是IO模式, 所以读不到ADC数据
回复

使用道具 举报

地板
ID:950349 发表于 2022-8-15 09:57 | 只看该作者
voltage= (int)(vcc*res2/1024L);
--》 int 是两个字节,还是有符号的;vcc*res2相乘溢出了符号位,v 是无符号int。
回复

使用道具 举报

5#
ID:1034262 发表于 2022-8-15 12:04 | 只看该作者
应该监控原始的ADC值,如果ADC只正确,则是你计算的问题,通常要用32位来计算避免溢出。如果ADC值不正常,则是初始化或硬件连接的问题。
回复

使用道具 举报

6#
ID:213173 发表于 2022-8-15 13:46 | 只看该作者
给你一个示例参考,根据你的硬件电路修改端口定义。
  1. //4位数码管电压表示例
  2. //适用STC8G1K08-20
  3. #include <STC8G.H>
  4. #include "intrins.h"
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. //宏定义ADC的操作命令
  8. #define ADCTIM  (*(unsigned char volatile xdata *)0xfea8)
  9. #define ADC_POWER   0x80                        //ADC power control dit (宏定义ADC电源控制位)1000 0000
  10. #define ADC_START   0x40                        //ADC start control dit (宏定义ADC启动控制位)0100 0000
  11. #define ADC_FLAG    0x20                        //ADC complete flag (宏定义ADC完成标志位)    0010 0000
  12. #define ADC_EPWMT   0x10                        //使能 PWM  实时触发 ADC                     0001 0000
  13. #define VCC_mV      5000                        //VCC

  14. uchar code table[]={//共阴数码管段码"0~f-."
  15.                 0x3f,0x06,0x5b,0x4f,
  16.                 0x66,0x6d,0x7d,0x07,
  17.                 0x7f,0x6f,0x77,0x7c,
  18.                 0x39,0x5e,0x79,0x71,0x40,0x80};
  19. uchar data dis_buf[4];                //缓存数组
  20. uchar num=0;
  21. uint ADC_mV;                                                //测量结果
  22. uint ADC_data;                                                //ADC转换结果

  23. /*-------------------------------
  24.   1ms延时子程序(11.0592MHz 1T)
  25. -------------------------------*/
  26. void delayms(uint k)
  27. {
  28.         uint i,j;
  29.         for(i=k;i>0;i--)
  30.                 for(j=1110;j>0;j--);
  31. }
  32. /*-------------------------------------------------------
  33.   InitADC 初始化ADC
  34. -------------------------------------------------------*/
  35. void Init_ADC()
  36. {        //ADC 控制器  电源  启动  完成  --   15通道模拟选择位
  37.         //ADC_CONTR    B7    B6    B5   B4   B3   B2   B1   B0
  38.         P_SW2 |= 0x80;                                        //打开
  39.         ADCTIM = 0x3f;                                        //设置 ADC 内部时序
  40.         P_SW2 &= 0x7f;                                        //关闭
  41.         ADCCFG = 0x27;                                        //设置ADC结果右对齐,速度为512系统时钟
  42.         ADC_RES=0;                                                //清除ADC_RES存储器以前的结果
  43.         ADC_RESL=0;
  44.         ADC_CONTR=ADC_POWER;                         //ADC 开启电源
  45.         delayms(1);                                                //上电延时1ms
  46. }
  47. /*---------------------------------------------------
  48.         读取ADC结果
  49. ----------------------------------------------------*/
  50. uint GetADCResult(uchar CH)
  51. {
  52.         ADC_CONTR=ADC_POWER|ADC_START|CH;//启动转换1100 1000
  53.         _nop_();_nop_();                                //小延时
  54.         while (!(ADC_CONTR & ADC_FLAG));//等待ADC转换完成标志置位 1010 0000
  55.         ADC_CONTR &=~ADC_FLAG;                        //清完成标志
  56.         return ADC_RES<<8|ADC_RESL;                //返回十位ADC结果
  57. }

  58. /*----------------------
  59.   main主程序
  60. ----------------------*/
  61. void main()                                                       
  62. {
  63.         P1M1 = 0x01;                                         //设置P1.0高阻其余双向
  64.         P1M0 = 0x00;                                         //设置P1.0高阻其余双向
  65.         P3M1 = 0x00;                                         //设置P3双向
  66.         P3M0 = 0x00;                                         //设置P3双向
  67.         P5M0 = 0x00;                                         //设置P5双向
  68.         P5M1 = 0x00;                                         //设置P5双向
  69.         Init_ADC();
  70.         while(1)
  71.         {
  72.                 ADC_data = GetADCResult(0);
  73.                 ADC_mV=VCC_mV*(long)ADC_data/1024;//强制转换数据类型(32位)运算,得到结果mV
  74.                 dis_buf[0]=table[ADC_mV/1000%10];
  75.                 dis_buf[1]=table[ADC_mV/100%10];
  76.                 dis_buf[2]=table[ADC_mV/10%10];
  77.                 dis_buf[3]=table[ADC_mV%10];
  78.                 P3=0x00;                                //消隐
  79.                 P1&=0x0f;                        //清位码
  80.                 P1|=~(0x10<<num); //送位码
  81.                 if(num==0)P3=dis_buf[num]|0x80;//送段码+小数点
  82.                 else P3=dis_buf[num];  //送段码
  83.                 num=++num%4;
  84.         }
  85. }
复制代码

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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