找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机AD采集光敏电阻 Proteus仿真可以但是板子上数值不变?

[复制链接]
跳转到指定楼层
楼主
ID:1068108 发表于 2023-4-13 19:47 来自手机 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
我想问一下,采用stc15芯片内部的adc进行光线采集,protues仿真可以随光源变化而变化,在板子上数值就不变是什么原因
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:883242 发表于 2023-4-13 23:33 | 只看该作者
先用万用表检查ADC输入引脚电压是否变化。
回复

使用道具 举报

板凳
ID:1068108 发表于 2023-4-14 09:04 来自手机 | 只看该作者
Hephaestus 发表于 2023-4-13 23:33
先用万用表检查ADC输入引脚电压是否变化。

变化的
回复

使用道具 举报

地板
ID:1068108 发表于 2023-4-14 09:39 来自手机 | 只看该作者
Hephaestus 发表于 2023-4-13 23:33
先用万用表检查ADC输入引脚电压是否变化。

lcd上显示也是光线最暗时显示的数值
回复

使用道具 举报

5#
ID:213173 发表于 2023-4-14 10:12 | 只看该作者
1234590qwehjm 发表于 2023-4-14 09:39
lcd上显示也是光线最暗时显示的数值

这是最基本的ADC运用,问题多在硬件电路和程序缺陷。上电路图与代码。
回复

使用道具 举报

6#
ID:1068108 发表于 2023-4-14 11:06 来自手机 | 只看该作者
wulin 发表于 2023-4-14 10:12
这是最基本的ADC运用,问题多在硬件电路和程序缺陷。上电路图与代码。

main.c
#include "STC15F2K60S2.h"
#include "LCD1602.h"
#include "ADC.h"

unsigned char str[5];
unsigned int backup=0;
unsigned char aa[]={'L','I','G','H','T',':'};
void main()
{       
        unsigned int result;
//write_com(0x01);
                init();
                Init_ADC();               
        while (1)
        {       
                         
                        result=ADC_Chang(7);
                result=result*0.0475;

         
                        while (result!=backup)
                        {
               
                                str[0]=result/1000+'0';       
                                str[1]=result%1000/100+'0';
                                str[2]=result%100/10+'0';
                                str[3]=result%10+'0';       
                                str[4]='\0';
                                               
                                LCD_Write_String(6,1,str);  
                LCD_Write_String(0,1,aa);       


                        }
        }

}



ADC.C


#include "STC15F2K60S2.h"
#include "ADC.h"
#include "LCD1602.h"

unsigned int ADC_DATE1,ADC_DATE2;
bit flag;

void delay(unsigned int sec)   //延时函数
{
        while(sec--);
}

void Init_ADC()                           //ADC初始化
{
        P1ASF=0X08;                         //将P1口设为ADC转换功能;
        ADC_RES=0X00;
        ADC_RESL=0X00;           //清除转换结果寄存器
  ADC_CONTR|=ADC_Power|ADC_Speed90;   //打开ADC电源,ADC转换速率90个机器周期,ADC通道为P1^7;111       
        delay(5000);
        EA=1;
        EADC=1;
}

unsigned int ADC_Chang(unsigned char ch)
{
        unsigned int result;
        EADC=1;
        delay(6000);
        ADC_CONTR|=ADC_Power|ADC_Speed90|ADC_Start|ch;        //启动AD转换
                 while(flag)
                {
                       
                        ADC_DATE1=ADC_DATE1<<2;
                        ADC_DATE2=ADC_DATE2&0x03;
                        result=ADC_DATE1|ADC_DATE2;
                        flag=0;
                }
        EADC=0;
        return result;       
}
void interrupt_ADC() interrupt 5
{
        ADC_CONTR&=(~ADC_flag);
           ADC_DATE1=ADC_RES;
        ADC_DATE2=ADC_RESL;
        flag=1;
}



ADC.H

#ifndef _ADC_H_
#define _ADC_H_

#include "STC15F2K60S2.h"
#define ADC_Power 0x80
#define ADC_Speed90 0x60
#define ADC_Speed180 0x40
#define ADC_Speed360 0x20
#define ADC_Speed540 0x00
#define ADC_Start 0x08
#define ADC_flag 0x10

void Init_ADC();
void delay(unsigned int sec);
unsigned int ADC_Chang(unsigned char ch);
void interrupt_ADC();


#endif
回复

使用道具 举报

7#
ID:1068108 发表于 2023-4-14 11:07 来自手机 | 只看该作者
wulin 发表于 2023-4-14 10:12
这是最基本的ADC运用,问题多在硬件电路和程序缺陷。上电路图与代码。

电路图

1681441603500.jpg (907.54 KB, 下载次数: 41)

1681441603500.jpg
回复

使用道具 举报

8#
ID:1034262 发表于 2023-4-14 11:14 | 只看该作者
光不稳定,加上别的干扰,造成输出信号不稳定,读数也就不稳定。加数字滤波,就可以得到稳定的结果。
回复

使用道具 举报

9#
ID:1068108 发表于 2023-4-14 11:29 来自手机 | 只看该作者
coody_sz 发表于 2023-4-14 11:14
光不稳定,加上别的干扰,造成输出信号不稳定,读数也就不稳定。加数字滤波,就可以得到稳定的结果。

不是不稳定,它数值直接不变化
回复

使用道具 举报

10#
ID:1068108 发表于 2023-4-14 11:40 来自手机 | 只看该作者
coody_sz 发表于 2023-4-14 11:14
光不稳定,加上别的干扰,造成输出信号不稳定,读数也就不稳定。加数字滤波,就可以得到稳定的结果。

板子展示。。

IMG_20230413_215056.jpg (642.5 KB, 下载次数: 36)

IMG_20230413_215056.jpg
回复

使用道具 举报

11#
ID:161164 发表于 2023-4-14 12:01 | 只看该作者
仿真接P14
初始化用P13(P1ASF=0X08;)
函数用P17(result=ADC_Chang(7);)
?????????????????????
回复

使用道具 举报

12#
ID:1068108 发表于 2023-4-14 12:10 来自手机 | 只看该作者
lkc8210 发表于 2023-4-14 12:01
仿真接P14
初始化用P13(P1ASF=0X08;)
函数用P17(result=ADC_Chang(7);)

初始化那个不是14吗,P1^0是0x80,,P1^1是0x40,,P1^2是0x20,,P1^3是0x10,,P1^4是0x08,对吗
回复

使用道具 举报

13#
ID:1068108 发表于 2023-4-14 13:30 来自手机 | 只看该作者
lkc8210 发表于 2023-4-14 12:01
仿真接P14
初始化用P13(P1ASF=0X08;)
函数用P17(result=ADC_Chang(7);)

不好意思,是我写错了,谢谢提醒
回复

使用道具 举报

14#
ID:213173 发表于 2023-4-14 13:58 | 只看该作者

你电路图的ADC输入是P1.4,ADC初始化中P1ASF=0X08;设置的是P1.3用作模拟输入通道,ADC转换中result=ADC_Chang(7);又是P1.7通道。怎么可能得到正确结果?另外还需要把模拟输入口设为高阻模式。否则获取的结果不准。不知你仿真结果是怎么来的?
回复

使用道具 举报

15#
ID:551638 发表于 2023-4-14 14:09 | 只看该作者
ADC没有初始化到
回复

使用道具 举报

16#
ID:1068108 发表于 2023-4-14 14:19 来自手机 | 只看该作者
wulin 发表于 2023-4-14 13:58
你电路图的ADC输入是P1.4,ADC初始化中P1ASF=0X08;设置的是P1.3用作模拟输入通道,ADC转换中result=ADC_C ...

修改过了,仿真结果是错的,现在好了
回复

使用道具 举报

17#
ID:1068108 发表于 2023-4-14 14:20 来自手机 | 只看该作者
wulin 发表于 2023-4-14 13:58
你电路图的ADC输入是P1.4,ADC初始化中P1ASF=0X08;设置的是P1.3用作模拟输入通道,ADC转换中result=ADC_C ...

修改过了,仿真结果是错的,现在好了
回复

使用道具 举报

18#
ID:1068108 发表于 2023-4-14 16:04 来自手机 | 只看该作者
wulin 发表于 2023-4-14 13:58
你电路图的ADC输入是P1.4,ADC初始化中P1ASF=0X08;设置的是P1.3用作模拟输入通道,ADC转换中result=ADC_C ...

那个我还想请问一下,前面的口改过了,我的板子加上光敏电阻后什么都不显示,是什么原因

1681459436449.jpg (642.48 KB, 下载次数: 36)

1681459436449.jpg
回复

使用道具 举报

19#
ID:213173 发表于 2023-4-14 16:39 | 只看该作者
1234590qwehjm 发表于 2023-4-14 16:04
那个我还想请问一下,前面的口改过了,我的板子加上光敏电阻后什么都不显示,是什么原因

首先要确保1602能够正常显示字符,然后再输入ADC结果。
回复

使用道具 举报

20#
ID:1068108 发表于 2023-4-14 16:53 来自手机 | 只看该作者
wulin 发表于 2023-4-14 16:39
首先要确保1602能够正常显示字符,然后再输入ADC结果。

我现在把lcd显示的字符放在了while(1)上面,可以显示字符,但是adc结果没有

1681462338880.jpg (674.67 KB, 下载次数: 30)

1681462338880.jpg
回复

使用道具 举报

21#
ID:1068108 发表于 2023-4-14 17:00 来自手机 | 只看该作者
wulin 发表于 2023-4-14 16:39
首先要确保1602能够正常显示字符,然后再输入ADC结果。

口都换成了p1.2

1681462643896.jpg (861.28 KB, 下载次数: 30)

1681462643896.jpg

1681462670755.jpg (970.21 KB, 下载次数: 30)

1681462670755.jpg

1681462764728.jpg (815.61 KB, 下载次数: 28)

1681462764728.jpg
回复

使用道具 举报

22#
ID:213173 发表于 2023-4-14 18:10 | 只看该作者
1234590qwehjm 发表于 2023-4-14 16:04
那个我还想请问一下,前面的口改过了,我的板子加上光敏电阻后什么都不显示,是什么原因

开ADC中断是蛇足
  1. ADC.C

  2. #include "STC15F2K60S2.h"
  3. #include "ADC.h"
  4. #include "LCD1602.h"

  5. //unsigned int ADC_DATE1,ADC_DATE2;
  6. //bit flag;

  7. void delay(unsigned int sec)   //延时函数
  8. {
  9.         while(sec--);
  10. }

  11. void Init_ADC()                           //ADC初始化
  12. {
  13.         P1M1 = 0x10;                                         //设置P1.4高阻
  14.         P1M0 = 0x00;                                         //设置P1.4高阻
  15.         P1ASF= 0x10;                    //将P1.4口设为ADC转换模拟输入
  16.         ADC_RES=0x00;
  17.         ADC_RESL=0x00;           //清除转换结果寄存器
  18.         ADC_CONTR=ADC_Power|ADC_Speed90;   //打开ADC电源,ADC转换速率90个机器周期
  19.         delay(5000);
  20. //        EA=1;
  21. //        EADC=1;
  22. }

  23. unsigned int ADC_Chang(unsigned char ch)
  24. {
  25. //        unsigned int result;
  26. //        EADC=1;
  27.         ADC_CONTR=ADC_Power|ADC_Speed90|ADC_Start|ch;        //启动AD转换
  28.         delay(4);//小延时
  29.         while(!(ADC_CONTR & ADC_flag));//等待ADC转换完成
  30.         ADC_CONTR &=~ADC_flag;//清ADC转换完成标志
  31.         return ADC_RES<<2|ADC_RESL;        //返回十位ADC结果
  32. }
  33. /*
  34. void interrupt_ADC() interrupt 5
  35. {
  36.         ADC_CONTR&=(~ADC_flag);
  37.         ADC_DATE1=ADC_RES;
  38.         ADC_DATE2=ADC_RESL;
  39.         flag=1;
  40. }*/



  41. ADC.H

  42. #ifndef _ADC_H_
  43. #define _ADC_H_

  44. #include "STC15F2K60S2.h"
  45. #define ADC_Power                 0x80//ADC电源控制位
  46. #define ADC_Speed90         0x60
  47. #define ADC_Speed180         0x40
  48. #define ADC_Speed360         0x20
  49. #define ADC_Speed540         0x00
  50. #define ADC_Start                 0x08//ADC启动控制位
  51. #define ADC_flag                 0x10

  52. void Init_ADC();
  53. void delay(unsigned int sec);
  54. unsigned int ADC_Chang(unsigned char ch);
  55. //void interrupt_ADC();


  56. #endif
复制代码
回复

使用道具 举报

23#
ID:1068108 发表于 2023-4-14 18:18 来自手机 | 只看该作者
wulin 发表于 2023-4-14 16:39
首先要确保1602能够正常显示字符,然后再输入ADC结果。

我用的光敏传感器是下面图片这种的,这种是不是只能用来接在3.3v电路里面,而我这个是5v电源,所以才不显示啊

2.jpg (34.23 KB, 下载次数: 32)

2.jpg

1.jpg (51.1 KB, 下载次数: 34)

1.jpg
回复

使用道具 举报

24#
ID:883242 发表于 2023-4-14 19:17 | 只看该作者
就是硫化镉光敏电阻跟一个电阻分压,不需要管什么3.3V或者5V电源。
回复

使用道具 举报

25#
ID:1068108 发表于 2023-4-14 19:19 来自手机 | 只看该作者
wulin 发表于 2023-4-14 18:10
开ADC中断是蛇足

真的很感谢啊,谢谢
回复

使用道具 举报

26#
ID:1068108 发表于 2023-4-14 19:22 来自手机 | 只看该作者
Hephaestus 发表于 2023-4-14 19:17
就是硫化镉光敏电阻跟一个电阻分压,不需要管什么3.3V或者5V电源。

嗯嗯,谢谢
回复

使用道具 举报

27#
ID:213173 发表于 2023-4-14 21:50 | 只看该作者
1234590qwehjm 发表于 2023-4-14 19:19
真的很感谢啊,谢谢

改写一下更易看懂
  1. #include <STC15F2K60S2.H>
  2. #include <intrins.h>
  3. #include "LCD1602.h"
  4. //宏定义ADC的操作命令
  5. #define ADC_POWER   0x80                        //ADC电源控制位 1000 0000
  6. #define ADC_START   0x08                        //ADC启动控制位 0000 1000
  7. #define ADC_FLAG    0x10                        //ADC完成标志位 0001 0000
  8. #define ADC_SPEEDLL 0x00                        //420时钟       0000 0000

  9. unsigned char str[5]="00.00";
  10. unsigned char aa[]={'L','I','G','H','T',':'};
  11. unsigned int result;

  12. void Init_ADC();
  13. void delay(unsigned int ms);
  14. unsigned int GetADCResult(unsigned char CHA);

  15. void main()
  16. {              
  17.         P0M0 = 0x00;
  18.         P0M1 = 0x00;
  19.         P1M1 = 0x04;   //设置P1.2高阻
  20.         P1M0 = 0x00;
  21.         P2M0 = 0x00;
  22.         P2M1 = 0x00;
  23.         P3M0 = 0x00;
  24.         P3M1 = 0x00;
  25.         P4M0 = 0x00;
  26.         P4M1 = 0x00;
  27.         P5M0 = 0x00;
  28.         P5M1 = 0x00;
  29.         P6M0 = 0x00;
  30.         P6M1 = 0x00;
  31.         P7M0 = 0x00;
  32.         P7M1 = 0x00;
  33.         Init_ADC();               
  34.         while (1)
  35.         {      
  36.                 result=GetADCResult(2);//P1.2
  37. //                result=result*0.0475;
  38.                 result=result*4.75;
  39.                 //显示数据范围00.00~48.64
  40.                 str[0]=result/1000%10+'0';      
  41.                 str[1]=result/100%10+'0';
  42. //                str[2]='.';
  43.                 str[3]=result/10%10+'0';     
  44.                 str[4]=result%10+'0';
  45.                 LCD_Write_String(6,1,str);
  46.                 LCD_Write_String(0,1,aa);      
  47.                 delay(100);//控制刷新周期约100ms
  48.         }
  49. }
  50. /*-------------------------------
  51.   ms延时子程序(11.0592MHz 1T)
  52. -------------------------------*/
  53. void delay(unsigned int ms)
  54. {
  55.         unsigned int i,j;
  56.         for(i=ms;i>0;i--)
  57.                 for(j=1150;j>0;j--);
  58. }
  59. /*-----------------------------------------------------------------------------
  60.   InitADC 初始化ADC
  61. -----------------------------------------------------------------------------*/
  62. void Init_ADC()
  63. {
  64.         P1ASF = 0x04;                    //将P1.2口设为ADC转换模拟输入
  65.         ADC_RES =0;                                                //清除ADC_RES存储器以前的结果
  66.         ADC_RESL=0;
  67.         ADC_CONTR=ADC_POWER|ADC_SPEEDLL;//ADC 开启电源、转换速度 1000 0000
  68.         delay(1);                                                //上电延时1ms                                                                                       
  69. }
  70. /*----------------------------------------------------------------------------
  71. Get ADC Result(获取ADC结果)
  72. ----------------------------------------------------------------------------*/
  73. unsigned int GetADCResult(unsigned char CHA)                                //获取ADC结果
  74. {
  75.         ADC_CONTR=ADC_POWER|ADC_SPEEDLL|CHA|ADC_START;//启动转换1000 1xxx
  76.     _nop_();_nop_();_nop_();_nop_();//小延时
  77.         while(!(ADC_CONTR & ADC_FLAG));        //等待ADC转换完成标志置位 1001 1000
  78.         ADC_CONTR &=~ADC_FLAG;                        //关闭ADC
  79.         return ADC_RES<<2 | ADC_RESL;        //返回十位ADC结果
  80. }
复制代码
回复

使用道具 举报

28#
ID:1068108 发表于 2023-4-14 22:31 来自手机 | 只看该作者
wulin 发表于 2023-4-14 21:50
改写一下更易看懂

感谢大佬,谢谢
回复

使用道具 举报

29#
ID:1068108 发表于 2023-4-15 15:03 来自手机 | 只看该作者
wulin 发表于 2023-4-14 21:50
改写一下更易看懂

大佬,我想请问一下把程序下载到板子上时,lcd屏总是显示下面的,是什么原因(我是用杜邦线接lcd和最小系统的

1681542147240.jpg (902.86 KB, 下载次数: 36)

1681542147240.jpg
回复

使用道具 举报

30#
ID:1068108 发表于 2023-4-15 15:10 来自手机 | 只看该作者
1234590qwehjm 发表于 2023-4-15 15:03
大佬,我想请问一下把程序下载到板子上时,lcd屏总是显示下面的,是什么原因(我是用杜邦线接lcd和最小系 ...

好了解决了,口不能用好像
回复

使用道具 举报

31#
ID:1068108 发表于 2023-4-16 12:24 来自手机 | 只看该作者
wulin 发表于 2023-4-14 21:50
改写一下更易看懂

我想问一下,后面想用adc获取的数值控制led亮暗,有没有什么可以学习的程序(pwm不会)
回复

使用道具 举报

32#
ID:213173 发表于 2023-4-17 11:03 | 只看该作者
本帖最后由 wulin 于 2023-4-17 13:59 编辑
1234590qwehjm 发表于 2023-4-16 12:24
我想问一下,后面想用adc获取的数值控制led亮暗,有没有什么可以学习的程序(pwm不会)

在上述程序的基础上加PWM控制即可,具体控制的占空百分比需要按实际需求调整。
  1. #include <STC15F2K60S2.H>
  2. #include <intrins.h>
  3. #include "LCD1602.h"
  4. //宏定义ADC的操作命令
  5. #define ADC_POWER   0x80                        //ADC电源控制位 1000 0000
  6. #define ADC_START   0x08                        //ADC启动控制位 0000 1000
  7. #define ADC_FLAG    0x10                        //ADC完成标志位 0001 0000
  8. #define ADC_SPEEDLL 0x00                        //420时钟       0000 0000

  9. unsigned char str[5]="00.00";
  10. unsigned char aa[]={'L','I','G','H','T',':'};
  11. unsigned int result;

  12. void Init_ADC();
  13. void delay(unsigned int ms);
  14. unsigned int GetADCResult(unsigned char CHA);
  15. void PWM_Init();

  16. void main()
  17. {              
  18.         P0M0 = 0x00;
  19.         P0M1 = 0x00;
  20.         P1M0 = 0x02;        //设置P1.1推挽模式
  21.         P1M1 = 0x04;        //设置P1.2高阻模式
  22.         P2M0 = 0x00;
  23.         P2M1 = 0x00;
  24.         P3M0 = 0x00;
  25.         P3M1 = 0x00;
  26.         P4M0 = 0x00;
  27.         P4M1 = 0x00;
  28.         P5M0 = 0x00;
  29.         P5M1 = 0x00;
  30.         P6M0 = 0x00;
  31.         P6M1 = 0x00;
  32.         P7M0 = 0x00;
  33.         P7M1 = 0x00;
  34.         Init_ADC();               
  35.         PWM_Init();
  36.         while (1)
  37.         {      
  38.                 result=GetADCResult(2);//P1.2
  39. //                result=result*0.0475;
复制代码
回复

使用道具 举报

33#
ID:1068108 发表于 2023-4-17 13:16 来自手机 | 只看该作者
wulin 发表于 2023-4-17 11:03
在上述程序的基础上加PWM控制即可,具体控制的占空百分比需要按实际需求调整。

谢谢大佬
回复

使用道具 举报

34#
ID:213173 发表于 2023-4-17 14:00 | 只看该作者

修改了一下百分比计算
回复

使用道具 举报

35#
ID:1068108 发表于 2023-4-17 14:57 来自手机 | 只看该作者
wulin 发表于 2023-4-17 14:00
修改了一下百分比计算

好的,,,
回复

使用道具 举报

36#
ID:1068108 发表于 2023-4-17 15:30 来自手机 | 只看该作者
wulin 发表于 2023-4-17 11:03
在上述程序的基础上加PWM控制即可,具体控制的占空百分比需要按实际需求调整。

大佬,后面是没有了吗,我不会调整百分比(_)
回复

使用道具 举报

37#
ID:213173 发表于 2023-4-17 15:32 | 只看该作者

代码重新编辑后怎么被阉割了?
回复

使用道具 举报

38#
ID:1068108 发表于 2023-4-17 15:49 来自手机 | 只看该作者
wulin 发表于 2023-4-17 15:32
代码重新编辑后怎么被阉割了?

嗯嗯,是的,,
回复

使用道具 举报

39#
ID:1068108 发表于 2023-4-17 16:33 来自手机 | 只看该作者
wulin 发表于 2023-4-17 15:32
代码重新编辑后怎么被阉割了?

大佬,我这个按照你一开始那个写的,protues仿真led变化奇怪,有一点点像闪,但是又不是,led亮暗没办法和光敏数值集合起来

1681720374770.jpg (942.41 KB, 下载次数: 33)

1681720374770.jpg
回复

使用道具 举报

40#
ID:1068108 发表于 2023-4-17 17:42 来自手机 | 只看该作者
1234590qwehjm 发表于 2023-4-17 16:33
大佬,我这个按照你一开始那个写的,protues仿真led变化奇怪,有一点点像闪,但是又不是,led亮暗没办法 ...

大佬,这个灯你是放在p几口的,我程序里面没看见在哪用了是p1.1吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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