Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >山东大学单片机原理与应用实验 3.8 ADC0808/9信号采集实验

山东大学单片机原理与应用实验 3.8 ADC0808/9信号采集实验

作者头像
timerring
发布于 2022-07-20 06:18:58
发布于 2022-07-20 06:18:58
96600
代码可运行
举报
文章被收录于专栏:TechBlogTechBlog
运行总次数:0
代码可运行

目录

一、实验题目

二、实验要求

三、实验过程及结果分析

四、实验流程图

五、实验源代码


一、实验题目

3.8 ADC0808信号采集实验

二、实验要求

1、画出实验的流程图

2、编写源程序并进行注释

3、记录实验过程

4、记录程序运行结果截图

三、实验过程及结果分析

利用LCD1602和AD0808实现简单的交流信号过零检测与频率分析。要求信号幅度变化时(满量程的5%—95%),不影响检测到结果。频率检测的结果通过LCD1602的第一行显示出来,信号过零时,能够通过P2.6输出一个脉冲宽度为5μs的脉冲信号。

1. 根据上述实验内容,在Proteus 环境下建立图1所示原理图,并将其保存为ADC0808_self.DSN 文件。

图1:实验电路图 

2. 编写源程序,将其保存为ADC0808_self.c,运行Keil开发环境,建立工程ADC0808_self.uV2,CPU 为AT89C51,包含启动文件STARTUP.A51。

3. 将C 语言源程序ADC0808_self.c 加入工程ADC0808_self.uV2,并设置工程ADC0808_self.uV2 属性,将其晶振频率设置为12MHz,选择输出可执行文件,仿真方式为选择硬仿真,并选择其中的“PROTEUS VSM MONITOR 51 DRIVER”仿真器。

4.构造(Build)工程ADC0808_self.uV2。如果输入有误进行修改,直至构造正确,生成可执行程序ADC0808_self.hex 为止。为AT89C51 设置可执行程序ADC0808_self.hex。

5. 运行程序,观察计算结果,并验证其是否正确。改变RV1 的抽头位置,从而改变输入信号的幅值,观察计算结果是否正确。更改信号发射器的频率,再次验证其功能是否正确。(注意:因为是软仿真,所以信号采集的速度受到限制,因此所输入的交流信号频率也不能太高,可以在200Hz以内尝试)。

实验结果如下:

1)将电位器至于满量程的90%,此时信号的幅值就是最大值的90%

图2:电位器调整到满量程的90%

2)将电位器至于满量程的50%,此时信号的幅值为最大值的一半

图3:电位器调整到满量程的50%

3)电位器调整到满量程的10%,此时信号的幅值为最大值的10%

图4:电位器调整到满量程的10%

四、实验流程图

图5:实验流程图

        LCD1602的控制方法按3.7节所示方法进行ADC0808的控制方法按3.8.1所示方法进行。这里主要是过零点的检测方法如何实现。不能采用判断所采集到的数据是否为 0 的方法来实现,因为你的采集时刻不一定能够严格对准过零时刻。但是,我们注意到在 0 点的两边信号的极性是发生变化的,我们可以利用这一特点来实现过零检测。正弦波每个周期有两个过零点,因此,1s 内过零次数除以 2 就是信号的频率。

        因此,在程序中可以这样实现。当每次采集到一个新的数据之后都要看一下这个数据是正数还是负数。当这个数大于 128 时是正数,当它小于 128 时是负数。判断当前数据的正负极性和上一个数据的正负极性是否一致,如果不一致,则说明经过了一次过零点,将其记录入次数计数器。

        ADC0808 的 CLK 仍然用定时器 T1 来实现,可以将其设置为 50kHz(硬件实现时可以更高,软件仿真再高将难以实现)。利用定时器 T0 实现 50ms 定时,并配合软件实现 1s 钟定时。采用 12M 晶振时,T0 采用方式 1,则处置应为(TH0=0x3C,TL0=0xB0)。

        但是,由于中断处理函数需要一定的响应时间,因此这个参数只是理论计算结果,要根据实测情况稍作调整。 同样 T1 理论计算值和实际输出值可能也会有一定的差距,也要进行调整。

五、实验源代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "reg51.h"    //  单片机寄存器头文件
#include "intrins.h"  // _ nop_()等函数定义的头文件
sbit LCD_RS=P2^0;  //寄存器选择位,将RS位定义为P2.0引脚
sbit LCD_RW=P2^1; // 读写选择位,将RW位定义为P2.1引脚
sbit E=P2^2;     //使能信号位,将E位定义为P2.2引脚
sbit BF=P1^7;    // P0.7为忙碌标志位

sbit CLK=P2^3;   // 设置时钟端口
sbit start=P2^4; 
sbit oe=P2^5;  
sbit eoc=P2^7; 

sbit out_pulse=P2^6;  // P2^6端口输出5us脉冲

sbit p30=P3^0; 
#define uchar unsigned char
#define uint unsigned int

uchar n=0;
uchar flag=0; 

void delay1ms()// 定义延时1ms函数
{
   		unsigned char i,j;	
	 	for(i=0;i<10;i++)
	  	for(j=0;j<33;j++);		 
 }

 void delay(unsigned int n)	//定义延时nms函数
 {
   	unsigned int i;
	for(i=0;i<n;i++)
	delay1ms();
 }

 bit BusyTest(void) //检查子程序,为1时繁忙,为0时不忙
  {
    	bit result;
		LCD_RS=0;       
    	LCD_RW=1;
    	E=1;       
    	_nop_();   
    	_nop_();
    	_nop_(); 
   		_nop_();   
    	result=BF;  
		E=0;
    	return result;
  }


void Write_com (uchar cmd)		//写命令子程序
{   
    while(BusyTest()==1); 
	 LCD_RS=0;             
	 LCD_RW=0;       // RS/RW都是0的时,写指令
	 E=0;                  
                             
	 _nop_();
	 _nop_();            
	 P1=cmd;   // 写指令操作   
	 _nop_();//运行一个机器周期
	 _nop_();  
	 _nop_();
	 _nop_();               
	 E=1;                   
	 _nop_();
	 _nop_();
	 _nop_();
	 _nop_();               
	  E=0;  // E由高跳低写入
 }


 void WriteAddress(unsigned char x)
 {
     Write_com(x|0x80); //显示位置为"80H+地址码x"	
 }



 void WriteData(unsigned char y)   //写数据子程序
 {
    while(BusyTest()==1);  
	  LCD_RS=1; 
	  LCD_RW=0;
	  E=0;            
                      
	  P1=y;   // 执行操作
	  _nop_(); //运行一个机器周期
	  _nop_();
 	  _nop_();
    	nop_();     
	  E=1;         
	  _nop_(); 
	  _nop_();
	  _nop_();
	  _nop_();       
	  E=0;         
 }

void LcdInt(void) //初始化LCD
{
   	delay(15);  // 延时15ms,让电源稳定
   	Write_com(0x38);  //设置显示,即16×2显示,5×7点阵,8位数据接口
	delay(5);   //延时5ms 
	Write_com(0x0c);  //设置显示:显示开,有光标,光标闪烁
	delay(5);
	Write_com(0x06);  D=1S=0地址自加1
	delay(5);											  
	Write_com(0x01);  // 清屏幕操作
	delay(5);
 }
void sysinit()			   //系统初始化
{                             
	TMOD = 0x21;  //  设定定时器T1工作方式为自动重装8位计数器,T0工作方式为方式1(16位计数器)
	TH1=0xfd;  //利用中断产生CLK信号
	TL1=0xfd;  

	EA=1;     //开总中断  	
	ET1=1;  	//T1中断允许
	TR1=1;     //启动定时器T1

	TH0=0x45;    // 置初值
	TL0=0x00;  //50MS定时	
	ET0=1;	 //T0中断允许
	TR0=1;	 //启动定时器T0
	start=0;  //A/D转换启动信号起始为0
	oe=0;   //数据输出允许信号起始为0
}

void t0(void) interrupt 1	//T0中断服务程序
{
	ET0=0;     // 关中断
	TH0=0X45;  
	TL0=0X00; 
	n++;
	if(n==20) {flag=1;n=0;}		 //循环20次,即完成1S定时
	
	ET0=1;						//开T0中断允许
	
}
void t1(void) interrupt 3		// 定时器T1中断服务程序
{
	ET1=0;    // 关闭中断
	CLK=~CLK;  // 每中断一次,取上一次clk信号的反,如此便产生了50KHz的周期性方波信号
	ET1=1;    //开启中断
}
unsigned char adc()//数据采集子程序
{
   unsigned  char  Temp;
   start=1;
   start=0;  //启动信号
   while (!eoc); // A/D转换结束信号,0代表转换完成,可以输出
   P0=0xff; // 读之前先写入1 
   oe=1;	
   Temp=P0; //读取采集数据
   oe=0;
   return(Temp); 
}

void display(uint a)//显示子函数
{
	uint bai,shi,ge;
	bai=a/100;
	shi=(a-bai*100)/10;
	ge=a%10;
	WriteAddress(2);
	WriteData(0x30+bai);    //显示百位
	WriteData(0x30+shi);     //显示十位
	WriteData(0x30+ge);     //显示个位
}
void main()    // 定义主程序
{
	uint temp1,temp2;
	uchar f=0;
	LcdInt();
	delay(5);
	sysinit()CLK=0;
	WriteAddress(0); //从第0行开始显示
	WriteData('f');   //显示 f ; 等
	WriteData(':');  
	WriteAddress(5);     //从第5行开始显示
	WriteData('H');	    //显示H
	WriteData('z');      //显示z
	while(1)           //一直循环
	{		
		temp2=temp1;
		temp1=adc();//ad采集
		if(((temp1>=128)&&(temp2<=128))||((temp1<=128)&&(temp2>=128)))	//过零时两次采集极性相反
		{
			f++;
			out_pulse=1;   //过零时输出脉冲信号
			_nop_();	   //运行一个机器周期
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			out_pulse=0;     //产生5us的脉冲信号
		}
		if(flag==1)      //1s后计算频率
		{
			flag=0;     // 标志位清0
			f=f/2;     // 一个周期两次过零点
			display(f);     //显示频率
			f=0;
		}
	}
}

初学单片机,可能存在错误之处,还请各位不吝赐教。

受于文本原因,本文相关实验工程无法展示出来,现已将资源上传,可自行下载。

山东大学单片机原理与应用实验工程文件3.8ADC0808/9信号采集实验-单片机文档类资源-CSDN下载山东大学单片机原理与应用实验工程文件3.8ADC0808/9信号采集实验详解博客地址:http更多下载资源、学习资料请访问CSDN下载频道.

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
51单片机LCD1602程序详解[通俗易懂]
LCD1602 工业字符型液晶。1602是指LCD显示的内容为16X2,即可以显示两行,每行16个字符.
全栈程序员站长
2022/09/13
2.1K0
基于51单片机的 智能路灯系统 纯原创
2024/10/09
1020
基于51单片机的 智能路灯系统 纯原创
基于单片机设计的电子柜锁
随着现代社会的不断发展,电子柜锁的应用越来越广泛。传统的机械柜锁存在一些不便之处,例如钥匙容易丢失、密码容易泄露等问题。设计一款基于单片机的电子柜锁系统成为了一个有趣而有意义的项目。
DS小龙哥
2023/11/01
2800
基于单片机设计的电子柜锁
(十四)51单片机——LCD1602实现滚动效果
目录 学习目标 成果展示  硬件知识 LCD1602介绍  引脚定义 内部结构 DDRAM 字模库 时序结构 指令集 操作流程 代码  总结  ---- 学习目标         今天我们要学习的是LCD1602液晶显示屏。首先,我们会编写显示各种数据的函数,比如显示字符串、十进制数、二进制数等等,之后我们会让LCD1602显示屏动起来,形成我们日常看到的广告牌的样子。 成果展示  https://live.csdn.net/v/embed/229030 LCD1602 硬件知识 LCD1602介绍 
小点点
2022/12/12
2.6K0
(十四)51单片机——LCD1602实现滚动效果
基于单片机设计的大气气压检测装置(STC89C52+BMP180实现)
本项目设计一个大气气压检测装置,该装置以单片机为基础,采用STC89C52作为核心控制芯片,结合BMP180模块作为气压传感器。大气气压,也就是由气体重力在大气层中产生的压力,其变化与天气预报、气象观测以及高度测量等方面密切相关。
DS小龙哥
2023/11/24
6160
基于单片机设计的大气气压检测装置(STC89C52+BMP180实现)
基于单片机的数字温度计设计
数字温度计是一种用于测量和显示环境温度的设备。本文章介绍基于STC89C52主控芯片的数字温度计的设计过程和实现原理。该设计采用DS18B20温度传感器进行温度采集,使用LCD1602显示屏进行温度显示,通过按键设置温度的上限和下限阀值,并通过蜂鸣器进行报警。
DS小龙哥
2023/09/01
9980
基于单片机的数字温度计设计
基于51单片机的自动浇花器电路
自动浇水灌溉系统设计方案,以AT89C51单片机为控制核心,采用模块化的设计方法。
芯动大师
2024/05/16
1550
基于51单片机的自动浇花器电路
1602 c语言驱动程序,51单片机驱动LCD1602程序设计(C语言)很详细的教程
delay_n40us(1);//实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。
全栈程序员站长
2022/09/13
1.3K0
1602 c语言驱动程序,51单片机驱动LCD1602程序设计(C语言)很详细的教程
【51单片机】配置定时器
​ 那么我们先创建一个子函数 void Timer0_Init() ⇥ 对定时器进行初始化。 那么首先是TMOD的一个配置,定时器1我们先不管(高四位定时器全部给上0),只管低四位的一个定时器0的一个配置。 在前面的定时器工作有介绍过,STC89C52 的 T0 和 T1 一共有四种工作模式:在这里我们选择最常用的工作模式1。 Ⅰ:工作模式①的话,我们只需要把 M1 = 0,M0 = 1 就是定时器模式①的配置了。 Ⅱ:C/T(取反):这个我们只需要给C/T(取反) = 0即可,SYSclk⇢系统时钟。 Ⅲ:GATE(门控端),GATE = 0,这里当中都是数字电路当中的一些基础逻辑门,TR0 = 1。
謓泽
2022/12/12
7400
【51单片机】配置定时器
LCD1602
LCD1602是我们常用的一种显示屏,一直想写一些关于元器件的介绍和使用。今天就来从LCD1602开始。
跋扈洋
2021/02/02
1.1K0
LCD1602
基于单片机设计的防煤气泄漏装置
煤气泄漏是一个严重的安全隐患,可能导致火灾、爆炸以及对人体健康的威胁。为了提高家庭和工业环境中煤气泄漏的检测和预防能力,设计了一种基于单片机的防煤气泄漏装置。
DS小龙哥
2023/10/27
2910
基于单片机设计的防煤气泄漏装置
单片机补充案例--I2C和AD使用PCF8591
上电位器:从大变小!(2.49-1.64-0.42-0.33)另一个不变(0.01附近)
zhangrelay
2021/03/03
4470
基于51单片机+SHT30设计的环境温度与湿度检测设备(IIC模拟时序)
当前文章介绍基于51单片机和SHT30传感器设计的环境温度与湿度检测设备。设备采用IIC模拟时序通信协议,能够实时监测环境的温度和湿度,并将数据通过LCD显示屏显示出来;可以广泛应用于室内环境监测、气象观测、农业温室监测等领域。
DS小龙哥
2023/07/11
8160
基于51单片机+SHT30设计的环境温度与湿度检测设备(IIC模拟时序)
蓝桥杯单片机必备知识—–(3)pcf8591–ADC
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/100131.html原文链接:
全栈程序员站长
2021/04/15
6330
MCS-51单片机温度控制系统的设计
注塑机是一种常用的制造设备,用于生产塑料制品。在注塑机的工作过程中,溶胶必须达到一定的温度才能被注入模具中进行成型。因此,在注塑机的生产过程中,温度控制是非常重要的一环。
DS小龙哥
2023/09/07
3590
MCS-51单片机温度控制系统的设计
设计分享|基于单片机LCD数字测速仪的设计
51单片是一种低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash 存储器。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得STC89C51为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。具有以下标准功能:8k字节Flash,512字节RAM,32 位I/O 口线,看门狗定时器,内置4KB EEPROM,MAX810复位电路,三个16 位 定时器/计数器,一个6向量2级中断结构,全双工串行口。另外 STC89X51 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU 停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。最高运作频率35Mhz,6T/12T可选。
电子工程师成长日记
2022/07/27
4510
设计分享|基于单片机LCD数字测速仪的设计
山东大学单片机原理与应用实验 3.7LCD 1602显示实验
要求利用LCD1602和16个按键实现简单的十进制数的加减乘除四则运算。其中按键KEY0-KEY9代表数字0-9,按键KEY10-KEY13分别代表运算符+、-、*、/,按键KEY15代表=,按键KEY14代表清除命令。不管什么时候按下清除按键,计算过程均将停止,两个输入变量清零,屏幕将清屏。
timerring
2022/07/20
8930
山东大学单片机原理与应用实验 3.7LCD 1602显示实验
【51单片机】矩阵键盘
独立按键它是把按键的公共的一端全部连接在了低电平上,然后另一端连接到了 IO 口上。 矩阵按键它是我们把①行④个单独的去拿出来看一下(S1、S2、S3、S4)这一行它的公共端它如果说把它连接到GND(P17~P14)如果不要了的话。会发现这个矩阵键盘其实就是和我们说的独立按键是一模一样的!
謓泽
2022/12/12
1K0
【51单片机】矩阵键盘
蓝桥杯单片机必备知识—–(9)超声波测距
超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。超声波在空气中的传播速度为340m/s,根据计时器记录的时间t,就可以计算出发射点距障碍物的距离(s),即:s=340t/2 。这就是所谓的时间差测距法。 超声波测距的原理是利用超声波在空气中的传播速度为已知,测量声波在发射后遇到障碍物反射回来的时间,根据发射和接收的时间差计算出发射点到障碍物的实际距离。由此可见,超声波测距原理与雷达原理是一样的。 测距的公式表示为:L=C×T 式中L为测量的距离长度;C为超声波在空气中的传播速度;T为测量距离传播的时间差(T为发射到接收时间数值的一半)。 超声波测距主要应用于倒车提醒、建筑工地、工业现场等的距离测量,虽然目前的测距量程上能达到百米,但测量的精度往往只能达到厘米数量级。 由于超声波易于定向发射、方向性好、强度易控制、与被测量物体不需要直接接触的优点,是作为液体高度测量的理想手段。在精密的液位测量中需要达到毫米级的测量精度,但是目前国内的超声波测距专用集成电路都是只有厘米级的测量精度。
全栈程序员站长
2021/04/16
8110
蓝桥杯单片机必备知识—–(9)超声波测距
别怕!51 单片机从入门到应用,小白也能轻松吃透
这篇教程专为单片机小白打造,从 51 单片机基础讲起,带你搭建开发环境,学习汇编与 C 语言编程。通过 LED 灯闪烁、按键控制、数码管显示等基础实验,以及简易电子钟、温度检测系统等应用案例,结合代码实操,助你快速掌握 51 单片机开发。
羑悻的小杀马特.
2025/03/24
4840
相关推荐
51单片机LCD1602程序详解[通俗易懂]
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验