基于80c51单片机的数据采集和显示系统设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
题目:数据采集及显示系统设计
设计基本功能:
利用TLC549做A/D转换器,外界提供模拟电压输入信号,将模拟量转化成数字量,在单片机控制下实现对外部输入信号的数据采集,并将采集数据结果在LED数码管上显示,显示结果为实际输入电压数值。
要求能够实现单次触发存储显示方式,即每按动一次“单次触发”键,能对被测信号进行一次采集和显示。
系统在不采集信号时,显示当前时间。
一、硬件设计
本方案分为三个模块:单片机模块、AD模块、I2C模块,其中I2C模块有时钟、键盘和LED三部分组成。
1、单片机模块
该模块设计实现单片机最小系统和和其他模块的接口。
电路图见图一。
图一
2、AD模块
该模块是TLC549的电路连接。
见图二。
图二 TLC549
3、I2C模块
本模块是由时钟芯片PCF8563和由ZLG7290连接的键盘、6位LED组成。
实现时钟设置、读取,键盘识别,以及显示功能。
电路连接见图三、四。
图三 ZLG7290
图四 PCF8563
二、软件设计
1、流程图见图五。
图五流程图2程序
#include <REG51.h>
#include <intrins.h>
#include <absacc.h>
#include "VIIC_C51.h"
#include "ZLG7290.h"
#define PCF8563 0xA2 //定义器件地址
#define WRADDR 0x00 //定义写单元首地址
#define RDADDR 0x02 //定义读单元首地址
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define ZLG7290 0x70 //定义器件地址
//定义TLC549串行总线操作端口
sbit CLK=P1^0;
sbit DAT=P1^1;
sbit CS=P1^2;
//定义I2C总线控制端口
sbit SDA=P1^7;
sbit SCL=P1^6;
//显示缓冲区初始化:DP-51PRO
unsigned char disp_buf[8]={0,0,0,0,0,0,0,0};//显示缓存uchar bdata ADCdata;
sbit ADbit=ADCdata^0;
sbit KEY_INT=P3^2;
sbit RST=P1^0;
unsigned char KEY; //保存键值
/***************************************************
**函数名称: TLC549ADC()
**函数功能: 读取上一次A/D转换的数据,启动下一次A/D转换****************************************************/ uchar TLC549ADC(void)
{
uchar i;
CLK=0;
DAT=1;
CS=0;
for(i=0;i<8;i++)
{
CLK=1;
_nop_();
_nop_();
ADCdata<<=1;
ADbit=DAT;
CLK=0;
_nop_();
}
return (ADCdata);
}
/****************************************
**函数名称: delay()
**函数功能: 硬件延时程序
**入口参数: i
****************************************/ unsigned char DelayNS(unsigned char no)
{
unsigned char i,j; //延时参数for(; no>0; no--)
for(i=0; i<100; i++)
for(j=0; j<100; j++);
return 0;
}
/*A/D数据转换处理和输出显示功能函数*/
/*******************************************
**函数名称: display()
**函数功能: 处理A/D转换后的数据并输出显示
********************************************/ void display(uchar advalue)
{
ulong ad_disp;
ad_disp=((ulong)advalue)*500/255;
disp_buf[2] =(uchar)(ad_disp/100%10)+0x80; disp_buf[1] =(uchar)(ad_disp/10%10);
disp_buf[0] =(uchar)(ad_disp/1%10);
disp_buf[3] = 31;
disp_buf[4] = 31;
disp_buf[5] = 31;
disp_buf[6] = 31;
disp_buf[7] = 31;
ZLG7290_SendBuf(disp_buf,8);
}
unsigned char display_time(unsigned char *sd) {
sd[0]=sd[0]&0x7f;//秒屏蔽保留位
sd[1]=sd[1]&0x7f;//分屏蔽保留位
sd[2]=sd[2]&0x3f;//时屏蔽保留位
disp_buf[0] =(sd[0]%16);
disp_buf[1] =(sd[0]/16);
disp_buf[2] = 31;
disp_buf[3] =(sd[1]%16);
disp_buf[4] =(sd[1]/16);
disp_buf[5] = 31;
disp_buf[6] =(sd[2]%16);
disp_buf[7] =(sd[2]/16);
ZLG7290_SendBuf(disp_buf,8);
return 0;
}
unsigned char display_date(unsigned char *sd)
{
sd[0]=sd[0]&0x3f;//日屏蔽保留位
sd[2]=sd[2]&0x1f;//月屏蔽保留位
disp_buf[0] =(sd[0]%16);
disp_buf[1] =(sd[0]/16);
disp_buf[2] =(sd[2]%16)+0x80;//后面加小数点
disp_buf[3] =(sd[2]/16);
disp_buf[4] =(sd[3]%16)+0x80;//后面加小数点
disp_buf[5] =(sd[3]/16);
disp_buf[6] =0;
disp_buf[7] =2;
ZLG7290_SendBuf(disp_buf,8);
return 0;
}
void main()
{
uchar ad_sample;
uchar key1_count=0,key2_count=0,key3_count=0;
unsigned char code
td[9]={0x00,0x12,0x00,0x15,0x12,0x13,0x05,0x01,0x11};//定义初始化字unsigned char rd[7]; //定义接收缓冲区
RST=0;
DelayNS(1);
RST=1;
ISendStr(PCF8563,WRADDR,td,0x5); //初始化PCF8563
DelayNS(1);
ISendStr(PCF8563,WRADDR+5,&td[5],0x4);//初始化PCF8563 ZLG7290_SendBuf(disp_buf,8);
ZLG7290_SendData(0X15,0X02);
disp_buf[7] =0x1f;
disp_buf[6] =0x1f;
disp_buf[5] =0x1f;
disp_buf[4] =0x1f;
disp_buf[3] =0x1f;
DelayNS(50);
IRcvStr(PCF8563,RDADDR,rd,0x7); //读现在的时、分、秒
DelayNS(1);
while(1)
{
if(KEY_INT==0)
{
KEY=ZLG7290_GetKey();
if(KEY==1) //显示切换
{
key1_count++;
if(key1_count>2)
key1_count=0;
}
if(KEY==2) //调整日期
{
key2_count++;
if(key2_count>3)
key2_count=0;
}
if(KEY==3) //调整时间
{
key3_count++;
if(key3_count>2)
key3_count=0;
}
if(KEY==5) //采集电压
{
ad_sample=TLC549ADC();
}
/*修改日期*/
if(key2_count==1) //调整年
{
disp_buf[5] =31;
disp_buf[4] =31;
ZLG7290_SendBuf(disp_buf,8);
DelayNS(2);
if(KEY==4)
{rd[6]++;
if((rd[6]&0x0f)>=0x0a)
{
rd[6]&=0xf0;
rd[6]+=0x10;
}
}
}
else if(key2_count==2) //调整月
{
disp_buf[2] =31;
ZLG7290_SendBuf(disp_buf,8);
DelayNS(2);
if(KEY==4)
{rd[5]++;
if((rd[5]&0x0f)>=0x0a)
{
rd[5]&=0xf0;
rd[5]+=0x10;
}
if(rd[5]>=0x13)
rd[5]=0x01;
}
}
else if(key2_count==3) //调整日{ disp_buf[1] =31;
disp_buf[0] =31;
ZLG7290_SendBuf(disp_buf,8);
DelayNS(2);
if(KEY==4)
{
rd[3]++;
if((rd[3]&0x0f)>=0x0a)
{
rd[3]&=0xf0;
rd[3]+=0x10;
}
if(rd[3]>=0x32)
}
}
/*修改时间*/
if(key3_count==1) //修改小时
{
disp_buf[6] =31;
disp_buf[7] =31;
ZLG7290_SendBuf(disp_buf,8);
DelayNS(2);
if(KEY==4)
{
rd[2]++;
if((rd[2]&0x0f)>=0x0a)
{
rd[2]&=0xf0;
rd[2]+=0x10;
}
if(rd[2]>=0x24)
rd[2]=0x00;
}
}
else if(key3_count==2) //修改分钟
{ disp_buf[3] =31;
disp_buf[4] =31;
ZLG7290_SendBuf(disp_buf,8);
DelayNS(2);
if(KEY==4)
{rd[1]++;
if((rd[1]&0x0f)>=0x0a)
{
rd[1]&=0xf0;
rd[1]+=0x10;
}
if((rd[1]&0xf0)>=0x60)
rd[1]=0x00;
}
}
}
if(key1_count==0)
{
display_date(rd+3); //调用显示日期子程序}
else if(key1_count==1)
display_time(rd);
else
{
display(ad_sample);
DelayNS(1);
}
}
}。