找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC8H1k28单片机自带adc跳来跳去 求分析

  [复制链接]
跳转到指定楼层
楼主
对,就是跳来跳去……我都没想到这么不准……
用来测热敏电阻的,用的电阻分压,原理图见下。
万用表测量在1.65-1.75之间,但是用单片机adc就跳来跳去,一会零点几,一会一点几……
如果把单片机静置,单片机就会保持在一个不确定的数值上。动两下,就会跳来跳去好久
甚至,断开电阻分压的供电和地(我设计了跳线),依然显示有电压,还是跳来跳去。
神奇。。
STC8H1k28自带adc,adc参考电压直接连了vcc,用ams1117和两节7号电池都是如此。
即使参考电压再不准,也不至于这样吧……
总而言之,言而总之,跳变没有任何规律。
如下是程序,原理图和实拍。tm1640驱动没有问题,非常好用(在别人基础上改的,最近学的多了才知道是iic)。
adc程序是在datasheet里复制的,有改动,后续处理是参考了数十个程序融合而成的。

单片机源程序如下:
  1. //头文件-----------------------------------------------
  2. #include <stc8.h>
  3. #include<stdio.h>  
  4. #include <intrins.h>
  5. #define ADCTIM (*(unsigned char volatile xdata *)0xfea8)
  6. //端口声明----------------------------------------------
  7. sbit led1=P1^6;
  8. sbit led2=P1^7;
  9. sbit DIN=P3^4;
  10. sbit CLK=P3^5;
  11. sbit key1=P3^2;
  12. sbit key2=P3^3;
  13. unsigned char ah;
  14. unsigned char al;


  15. //端口声明----------------------------------------------

  16. unsigned int i;
  17. unsigned char code nbr[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x39};  //共阳数码管段码数据

  18. void delay(unsigned z)
  19. {
  20.    unsigned x,y;
  21.         for(x=z;x>0;x--)
  22.                 for(y=300;y>0;y--);
  23. }

  24. //IIC协议start通讯开始函数-----------------------------------
  25. void I2CStart()
  26. {
  27.     DIN=1;
  28.     CLK=1;
  29.         delay(2);

  30.         DIN=1;
  31.         delay(2);

  32.         DIN=0;
  33.         delay(4);

  34.         CLK=0;
  35.         delay(2);
  36. }



  37. //IIC协议stop通讯结束函数-----------------------------------
  38. void I2CStop()
  39. {
  40.         CLK=1;
  41.         delay(2);

  42.         DIN=0;
  43.         delay(2);

  44.         DIN=1;
  45.         delay(2);

  46.         CLK=0;
  47.         DIN=0;

  48. }

  49. //发送8bit数据,从低位开始-----------------------------
  50. void I2CWritebyte(unsigned char oneByte)
  51. {
  52.   unsigned char i;
  53.   for(i=0;i<8;i++)
  54.   {
  55.     CLK=0;
  56.         if(oneByte&0x01)
  57.           DIN=1;
  58.         else
  59.           DIN=0;
  60.         delay(3);
  61.         CLK=1;
  62.         oneByte=oneByte>>1;
  63.         }
  64.         CLK=0;
  65.         delay(4);
  66.         DIN=0;
  67.         delay(2);
  68. }
  69. //TM1640写数据,再次封装,简化程序----------------------------
  70. void tmw(int ha,hb)
  71. {
  72.         I2CStart();
  73.                 I2CWritebyte(ha);        //地址命令设置:初始地址00H
  74.                 for(i=0;i<1;i++)        //发送16位显示数据
  75.                         {
  76.                                 I2CWritebyte(hb);         //显示值
  77.                         }
  78.                 I2CStop();
  79. }        
  80. //TM1640开启显示便捷函数-------------------------------------
  81. void tms()
  82. {
  83.                 I2CStart();
  84.                 I2CWritebyte(0x8c);        //显示控制:显示开,脉冲宽度设为11/16
  85.                 I2CStop();

  86. }

  87. //adc中断-----------------------------------------------------        

  88. void ADC_Isr() interrupt 5
  89. {
  90.         ADC_CONTR &= ~0x20; //清中断标志
  91.         ah = ADC_RES; //读取 ADC 结果
  92.         al = ADC_RESL; //读取 ADC 结果
  93.         delay(2);//必要的延时
  94.         ADC_CONTR |= 0x40; //继续 AD 转换
  95. }
  96. //adc采样函数-----------------------------------------------------        
  97. void ad()
  98. {
  99.         unsigned int ab = 0;
  100.         int ac = 0;
  101.         float ad;
  102.   ab = ah*4+al;//两个寄存器(adc结果)合并
  103.         ad = ab*10000/1024*3.2;//计算电压(无小数点)
  104.         ac = ad;
  105.         tmw(0xc0,nbr[ac/1000%10]);//每一位依次显示在数码管上
  106.         delay(10);
  107.         tmw(0xc1,nbr[(ac/100)%10]);
  108.         delay(10);
  109.         tmw(0xc2,nbr[(ac/10)%10]);
  110.         delay(10);
  111.         tmw(0xc3,nbr[ac%10]);
  112.         delay(10);
  113.         tms();
  114.         delay(20);
  115.         
  116. }
  117. //main函数-----------------------------------------------------        
  118. void main()
  119. {
  120.         //uart_init();

  121.         P0M0 = 0x00; //配置io口寄存器为双向口
  122.         P0M1 = 0x01; //设置 P0.0 为 ADC 口
  123.         P1M0 = 0x00;
  124.         P1M1 = 0x00;
  125.         P2M0 = 0x00;
  126.         P2M1 = 0x00;
  127.         P3M0 = 0x00;
  128.         P3M1 = 0x00;
  129.         P4M0 = 0x00;
  130.         P4M1 = 0x00;
  131.         P5M0 = 0x00;
  132.         P5M1 = 0x00;
  133.         P_SW2 |= 0x80;
  134.         ADCTIM = 0x3f; //设置 ADC 内部时序
  135.         P_SW2 &= 0x7f;
  136.         ADCCFG = 0x0f; //设置 ADC 时钟为系统时钟/2/16/16
  137.         ADC_CONTR = 0x88; //使能 ADC 模块
  138.         EADC = 1; //使能 ADC 中断
  139.         EA = 1;
  140.         ADC_CONTR |= 0x40; //启动 AD 转换
  141.         led1 = 0;
  142.         while(1){
  143.                         ad();
  144.                 }
  145. }
复制代码

数码管用的tm1640驱动。热敏电阻10k,分压电阻10k(实测9.2k)
没有连锡,焊接没问题,热敏电阻拆下来量了没坏
神奇,完全可以改造成随机数生成器……

屏幕截图 2020-11-28 221606.png (341.69 KB, 下载次数: 124)

屏幕截图 2020-11-28 221606.png

bddffe23f2bc904eff58aa17b8dfea9.jpg (123.17 KB, 下载次数: 128)

bddffe23f2bc904eff58aa17b8dfea9.jpg

c58d7fcc0290232c475601ea61eb1ac.jpg (81.63 KB, 下载次数: 130)

c58d7fcc0290232c475601ea61eb1ac.jpg

5f760ec717cebdefd393f39d489d754.jpg (94.64 KB, 下载次数: 128)

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

使用道具 举报

沙发
ID:837101 发表于 2020-11-28 22:29 | 只看该作者
就离谱
回复

使用道具 举报

板凳
ID:420836 发表于 2020-11-29 02:25 | 只看该作者
添加数字滤波器以平均模拟变量采样; 此外,请检查模拟参考电压是否稳定。
回复

使用道具 举报

地板
ID:213173 发表于 2020-11-29 07:26 | 只看该作者
出现问题不要轻易怀疑单片机问题,首先要确认特殊功能寄存器的配置是否正确。
仔细核对通道选择,转换速度选择,转换结果格式选择(合并转换结果高低位的方式不同)。
正确选择电压换算公式的数据类型,楼主采用的公式错误,运算过程数据溢出。
十二位ADC结果换算成10进制(4舍5入)公式
毫伏=(参考电压*十二位ADC结果*10000/4096+5)/10
依据楼主程序配置建议算法:
void ad()
{
        unsigned int ab = 0;
        unsigned int ac = 0;
        unsigned int ad;
        ab = ((unsigned int)ah<<4)|(al>>4);//两个寄存器(adc结果)合并
        ad = (long)ab*10000/4096*3.2;//计算电压(无小数点)
        ac = ad;
        ......

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

5#
ID:687694 发表于 2020-11-29 14:40 | 只看该作者
本帖最后由 lovexulu 于 2020-11-29 14:45 编辑

刚没仔细看。。。发现是采用中断读取adc的这个应该就是问题所在了,假如恰好正在执行运算时,中断并改变了ah,al值,那得到的结果就不知道是啥了。
流程改一下,开启转换,中断读取,读取一次,刷新一次 开启转换,这样应该不会有问题了。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

6#
ID:401564 发表于 2020-11-30 09:25 | 只看该作者
ab = ah*4+al
这个什么意思?
ADCCFG = 0x2f,这个寄存器改一下,ADC结果就直接取高位和低位运算就可以了
你参考一下楼上的几位,先把ADC部分的资料看一下再修改
这没有什么难度的
回复

使用道具 举报

7#
ID:226055 发表于 2020-12-1 11:28 | 只看该作者
本人用了STC8H系列的另外一款芯片STC8H8K64U,使用了2.5V基准电压,测试ADC效果很好。不过用的是TB上买的现成的板子,我把原理图ADC部分和实验源码发你参考下,都是STC8H系列的应该参考意义比较大。同意楼上见解,STC芯片依然出库不会有那么大问题的。





实验2-9-2:ADC电位器实验(P0.4读取电压值).rar

49.48 KB, 下载次数: 118

评分

参与人数 2黑币 +50 收起 理由
REwilliam + 20 很给力!
admin + 30 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

8#
ID:837101 发表于 2020-12-4 21:20 | 只看该作者
lovexulu 发表于 2020-11-29 14:40
刚没仔细看。。。发现是采用中断读取adc的这个应该就是问题所在了,假如恰好正在执行运算时,中断并改变了a ...

51官方的datasheet就是个大坑呀!用的51官方的中断程序……发现了好几个错误
回复

使用道具 举报

9#
ID:837101 发表于 2020-12-4 23:24 | 只看该作者
wulin 发表于 2020-11-29 07:26
出现问题不要轻易怀疑单片机问题,首先要确认特殊功能寄存器的配置是否正确。
仔细核对通道选择,转换速度 ...

谢谢!
回复

使用道具 举报

10#
ID:790408 发表于 2020-12-4 23:31 来自手机 | 只看该作者
可以做个卡尔曼滤波器,或是把采到的数据放到matlab中曲线拟合一下
回复

使用道具 举报

11#
ID:837101 发表于 2020-12-5 00:10 | 只看该作者
wulin 发表于 2020-11-29 07:26
出现问题不要轻易怀疑单片机问题,首先要确认特殊功能寄存器的配置是否正确。
仔细核对通道选择,转换速度 ...

解决了!谢谢大佬!
回复

使用道具 举报

12#
ID:837101 发表于 2020-12-5 00:11 | 只看该作者
1922323908 发表于 2020-12-4 23:31
可以做个卡尔曼滤波器,或是把采到的数据放到matlab中曲线拟合一下

已经解决了!根据楼上大佬的回复,确实是使用了不正确的公式导致数据溢出。谢谢!
回复

使用道具 举报

13#
ID:292876 发表于 2021-1-12 14:04 | 只看该作者
经常用AD,实际使用中出现的问题点,简单总结下,参考下。
AD取样,没有特殊情况啥的,两个算法必须,不然不专业!
1:注意输入阻抗问题。电源要稳定做好滤波处理,电源很重要,片内AD一般都用电源当基准。
2:头两次取样建议丢弃,速度允许,尽可能慢档位
3:加【中位值平均滤波】 【全程区间线性插值】
4:如果不使用595或者1650 1638之类LED驱动芯片,MCU频率尽可能提高!
5:尽可能用外部晶振。
回复

使用道具 举报

14#
ID:584288 发表于 2021-3-2 14:41 | 只看该作者
你好,楼主,你有么有用STC8H1K28这个单片机做PWM波形输出的程序。这款单片机刚出来不久,找不到相关例程。如果有能不能分享一下。
回复

使用道具 举报

15#
ID:111280 发表于 2021-8-31 02:28 | 只看该作者
cocolala 发表于 2020-12-1 11:28
本人用了STC8H系列的另外一款芯片STC8H8K64U,使用了2.5V基准电压,测试ADC效果很好。不过用的是TB上买的现 ...

请问STC8H8K64U支持USB硬件接口仿真吗?
回复

使用道具 举报

16#
ID:1101600 发表于 2023-11-28 19:27 | 只看该作者
楼主你测出来精度多少,0.01v吗,还是0.1v
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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