基于STC89C52单片机的模数转换
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//显示十位数
dual=1; P0=table[ge]; dual=0; P0=0xff; wela=1; P0=0x7b; wela=0; delay(5);
//显示个位数
} /*****************************系统初始化**************************************/
三:程序测试记录: 当 单 片 机 接 收 到 处 数 字 1 之 外 的 其 他 字 符 时 由 单 片 机 返 回 Erro! 给 上 位 机
基于 STC89C52RC 单片机的 A/D 转换测试及串口数据及数码管显示
安徽工业大学 自动化系 刘昌元
当单片机收到上位机发来的1时,单片机发送“Turn on AD!”,之后便开始显示对应的模量 电压值。例如,数码管上显示:117 ,上位机对应的显示“The voltage is 2.285156 V”
二:测试程序
#include<reg52.h>
// 头文件包含
#include<intrins.h>
#include<stdio.h>
#define uint unsigned int //宏替换定义
#define uchar unsigned char
sbit dual=P2^6;
//两个锁存器的控制端
}
/*************************启动 A/D 转换***************************************/
void AD_start()
{
WR=1; _nop_();
//通过送进低电平来启动 AD 转换 //延时
WR=0;
_nop_();
WR=1;
}
/**********************打开 AD 芯片,读取数值***********************************/
基于 STC89C52RC 单片机的 A/D 转换测试及串口数据及数码管显示
安徽工业大学 自动化系 刘昌元
一:测试目的: 在工业控制和检测等过程中经常会用到来自传感器或变送器等装置的模拟量信号,所有的这 些信号都需要经过模数转换后方能送进单片机处理获得后续系统控制的其他信号,因此模数 转换就显得尤为重要,现在很多单片机内部集成有 A/D 模块,直接利用它自带的模块和寄 存器编程就可以实现,但是对于有些价格比较便宜但性能优越,基本满足控制要求的控制器 却往往不自带 A/D 模块,此时就需要我们自己来组建 A/D 转换电路。此处本人采用的是 ADC0804LCN,售价一般在 6 元左右,性能还不错,搭建电路也比较方便,但此芯片使用 熟练后大家可以再去尝试多通道的 ADC0809,控制方式基本上差不多,在搭建电路时芯片的 时钟信号显得尤为重要,这是我在实际测试过程最大的体会,要保证转换器的可靠工作,它 的 CLCK 信号特别要注意,ADC0804 可以利用电阻和电容的自激振荡;来产生时钟信号, ADC0809 可以使用 51 系列单片的 ALE 引脚的 4 分频来提供时钟信号,具体情况需要参考 芯片的手册和自己搭建的电路,下面我就我自己测试的程序来大致讲一下转换采样过程。此 处我是将 0-5V 的模拟电压量转换成数字量后在数码管上显示出来,ADC0804 是 8 位的采样 芯片,对应的数字量应该为 0x00-0xFF,十进制的 0-255 同时将其运算成对应的模拟量通过 串行口发送回 PC 机显示出来,PC 机作为控制机发送字符来选择是否启动模数转换。
void delay(uint a)
{
uint i,j;
for(i=a;i>0;i--)
for(j=110;j>0;j--)
;
}
/**************三位数循环扫描显示函数***************************************/
void display(uchar bai,uchar shi,uchar ge)
{ RI=0;
//当单片机通过串行口收到 PC 机发来字符时进中断,清接收中断标志位
基于 STC89C52RC 单片机的 A/D 转换测试及串口数据及数码管显示
安徽工业大学 自动化系 刘昌元
data1=SBUF; //把数据缓冲器中数据存到变量 data1 中。
flag=1;
//自定义变量标志位置 1
}
/****************************主程序******************************************/
main()
{ Hale Waihona Puke Baiduys_initial();
//系统初始化
while(1)
//进入主循环
{
if(flag==1) //判断是否收到了上位机发来的启动信号即是否产生了接收中断
{
flag=0; //标志位清 0 ES=0; //关闭串口中断
TI=1;
//发送中断标志位置1准备向上位机发送字符串
switch(data1) //判断从上位机收到的数据是否是启动信号
{ case 1:puts("Turn on AD\n"); //接收到1,则启动 AD 转换
break;
default :puts("Erro!");
sbit wela=P2^7;
uchar data1,flag;
//全局变量定义
uchar i,j,bai,shi,ge,DATA,AD_flag;
uchar b;
uchar n=0;
float value;
/********************数码管显示对应的查表值*******************************/
break;
} while(!TI);
//等待字符串发送结束
基于 STC89C52RC 单片机的 A/D 转换测试及串口数据及数码管显示
安徽工业大学 自动化系 刘昌元
TI=0;
//发送标志位清0
} }
if(data1==1) //判断是否是启动 AD 转换信号
{
while(1)
{ AD_start();
//启动 AD 转换
delay(10); AD_get();
//延时100us左右等待 AD 转换接收 //读取 AD 转换结果
bai=DATA/100; //将转换后的十进制0-255分解成三位数
shi=(DATA%100)/10;
ge=DATA%10;
value=5.0*DATA/256; //将数字量换算成模拟量准备发送给上位机
uchar code table[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
/*********************延时函数********************************************/
void sys_initial()
{
EA=0;
//关闭总中断
TMOD=0x20; //启用定时器 1 做破特率发生器,工作于方式 2,计数初值自动重装
TH1=0xfd; TL1=0xfd;
//装定时器 1 高八位计数初值 //装定时器 1 低八位计数初值
TR1=1; SCON=0x50; ES=1; EA=1;
{
dual=1;
//显示百位数
基于 STC89C52RC 单片机的 A/D 转换测试及串口数据及数码管显示
安徽工业大学 自动化系 刘昌元
P0=table[bai]; dual=0; P0=0xff; wela=1; P0=0x7e; wela=0; delay(5);
dual=1; P0=table[shi]; dual=0; P0=0xff; wela=1; P0=0x7d; wela=0; delay(5);
void AD_get()
{ P1=0xff; RD=1;
//P1 口置 1,作为数据输入口使用 //通过送进低电平信号来打开 ADC0804 数据通道
_nop_();
RD=0;
_nop_(); DATA=P1;
//将 P1 口的数据存到变量 DATA 中
RD=1;
//关闭 ADC0804 数据通道
for(i=0;i<20;i++)
//数码管循环显示转换后的数值0-255
display(bai,shi,ge); TI=1;
//把模拟量电压发送回上位机显示
printf("The voltage is %f V\n",value);
while(!TI);
TI=0;
}
}
}
ES=1;
//打开串口中断,接收上位机发送来的字符
//启动定时器 1 //串行口选择方式 1 收发,8 位数据位,1 位起始位,1 位停止位。 //打开串口中断 //打开总中断
}
/*****************************接收中断函数**********************************/
void receive()interrupt 4