单片机开发之ADC0808/9信号采集

简介: 本文主要介绍了单片机开发之ADC0808/9信号采集


一、实验题目
3.8 ADC0808信号采集实验

二、实验要求
1、画出实验的流程图

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

3、记录实验过程

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

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

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

image.png

图1:实验电路图 

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

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

实验结果如下:

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

image.png

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

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

image.png

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

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

image.png

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

四、实验流程图
image.png

图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 理论计算值和实际输出值可能也会有一定的差距,也要进行调整。

五、实验源代码

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=1,S=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;
    }
}

}

目录
相关文章
|
7月前
|
物联网
STC51单片机-实验开发装置仿真-物联网应用系统设计
STC51单片机-实验开发装置仿真-物联网应用系统设计
151 0
|
6月前
技术心得记录:单片机开发过程中使用结构体简化程序
技术心得记录:单片机开发过程中使用结构体简化程序
37 0
|
7月前
|
IDE 开发工具 C++
【51单片机】开发板&开发软件(Keil5&STC-ISP)简介&下载安装破译传送门(1)
【51单片机】开发板&开发软件(Keil5&STC-ISP)简介&下载安装破译传送门(1)
|
7月前
|
缓存 编译器 程序员
嵌入式开发环境Vscode开发STM32单片机程序
嵌入式开发环境Vscode开发STM32单片机程序
180 0
|
7月前
|
传感器 测试技术 数据处理
单片机开发|基于单片机的婴儿睡眠监测系统设计
单片机开发|基于单片机的婴儿睡眠监测系统设计
114 0
|
7月前
|
传感器 监控 测试技术
单片机开发|基于51单片机的全自动黑板檫粉尘清除装置设计与实现
单片机开发|基于51单片机的全自动黑板檫粉尘清除装置设计与实现
|
7月前
|
传感器 人工智能 Java
单片机开发|基于单片机的婴儿睡眠监测系统设计
婴儿一天中的大多数时间都处于睡眠状态,如何对婴儿进行睡眠监测、及时安抚婴儿,以及如何解决婴儿的尿湿问题,这些都是新妈妈们最关心的问题。大部分的家庭都会选择方便的纸尿裤,但是纸尿裤不仅价格昂贵,而且吸水性很强,如果不及时更换,很可能会长出红疹等皮肤疾病,对婴儿的身体也是有威胁的;婴儿醒了就会大哭,家长没有及时的听见,造成婴儿很长一段时间没有人照料。所以,为婴儿设计一个适合婴儿的睡眠监测系统,对于新手家长来说是很有帮助的。本论文采用STC89C52单片机为核心,采用声控、语音播报、湿度采集电路采集各种场景的数据,并通过 LED灯光、语音播报等方式来实现对幼儿进行实时监测。
|
7月前
|
传感器 人工智能 Java
单片机开发|基于51单片机的全自动黑板檫粉尘清除装置设计
教师常年在课堂上上课,粉笔的灰尘会对学生的健康造成很大的危害,很多教师都会患上肺部疾病。教师在课堂教学中,如何有效地消除粉尘对教师的身体造成的不良影响,是一个亟待解决的问题。本文以51单片机为核心,实现并设计一种全自动黑板檫粉尘清除装置。由黑板擦上的压力传感器进行检测,由51单片机来控制吸尘器(吸尘风机),以完成清理。本系统的主要功能包括:压力检测、按键控制、灯光显示、电扇除尘等。本文在对国内外有关文献进行整理和归纳的基础上,首先介绍了全自动黑板檫粉尘清除装置的研制背景和研究意义,并结合国内外的研究情况,提出了本文的主要研究内容和系统的设计思路。接着,对系统的硬件电路进行了详细的设计,并编写了
|
传感器 监控 测试技术
单片机开发|基于51单片机的全自动黑板檫粉尘清除装置设计与实现
教师常年在课堂上上课,粉笔的灰尘会对学生的健康造成很大的危害,很多教师都会患上肺部疾病。教师在课堂教学中,如何有效地消除粉尘对教师的身体造成的不良影响,是一个亟待解决的问题。本文以51单片机为核心,实现并设计一种全自动黑板檫粉尘清除装置。由黑板擦上的压力传感器进行检测,由51单片机来控制吸尘器(吸尘风机),以完成清理。本系统的主要功能包括:压力检测、按键控制、灯光显示、电扇除尘等。本文在对国内外有关文献进行整理和归纳的基础上,首先介绍了全自动黑板檫粉尘清除装置的研制背景和研究意义,并结合国内外的研究情况,提出了本文的主要研究内容和系统的设计思路。接着,对系统的硬件电路进行了详细的设计,并编写了
195 0
单片机外围模块漫谈之五,USB开发,这个错误你犯了吗?
单片机外围模块漫谈之五,USB开发,这个错误你犯了吗?