资源描述
本科生毕业设计报告
学 院 物理与电子工程学院 专 业 电子信息工程
设计题目: 基于51单片机的
简易逻辑分析仪设计
学生姓名
指导教师
(姓名及职称)
班 级
学 号
完成日期: 年 月
基于51单片机的简易逻辑分析仪设计
物理与电子工程学院 电子信息工程
[摘要]本设计完成了一种能进行数字电路中多路数据测试的简易逻辑分析仪。它以51单片机控制核心,数模转换器为逻辑信号门限电平控制电路,用按键和 12864LCD作为人机交互界面,采用C51进行模块化编程,实现了四路信号的测试,具有成本低,使用方便等特点。
[关键词]数字电路 单片机 数模转换器 逻辑分析仪
1 设计任务与要求
本设计的主要任务及参数指标是:数据位数4位,存储深度80字;数据速率最高1kHz;输入阻抗大于50kΩ;逻辑信号门限电平在1.0V~4.0V 范围内按8级任意设定。
2 设计方案
本系统采用51单片机为控制核心,系统由单片机系统、逻辑电平控制、按键、LCD显示、系统电源等模块构成。被测数据输入到逻辑电平控制模块,然后进行单片机进行测试,按键用于控制逻辑信号门限电平的大小,系统电源为各模块供电,各模块的供电电压为5V。
图1 系统框图
3 设计原理分析
3.1 单片机系统电路设计
图2 单片机系统电路
单片机系统为逻辑分析仪的核心,负责控制逻辑分析仪的逻辑电平、检测按键并驱动LCD进行显示。单片机系统电路如图2所示,由晶体振荡器Y1、电容C3和C4构成振荡器电路,为单片机提供时钟信号。电容C1、电阻R2和R1、按键KEY1构成单片机复位电路,高电平复位,当按键KEY1按下的时间超过2个机器周期以上时,单片机就执行复位操作。EA接高电平,单片机首先访问内部程序存储器。J1为1KΩ的排阻,作为P0口的外部上拉电阻。在硬件制作时为了方便单片机的测试和功能的扩展,把所有的I/O口均通过排针引出。
3.2 人机界面电路设计
图3 按键控制电路
按键控制电路如图3所示,用于控制逻辑分析仪的工作状态,如采样率改变、逻辑电平的调整等等,单片机通过检测按键对应的I/O口是否为低电平来判断按键是否按键,为了防止干扰,应在单片机的按键检测程序中加入延时函数。
图4 LCD显示接口电路
LCD显示接口电路如图4所示,此模块用来显示需要显示的数据,电位器R3用于调节液晶的对比度。LCD采用采用字符式FM12864M-12L型LCD,为节约I/O口,以串行方式与单片机连接。
图5 蜂鸣器驱动电路
蜂鸣器驱动电路如图5所示,选用三极管Q1为PNP型三极管,三极管基极电阻R11为1kΩ,因为单片机的灌电流能力强于拉电流能力,因此采用PNP型三极管,蜂鸣器采用5V有源蜂鸣器。三极管连接到单片机的P17口,当P17输出为低电平时,蜂鸣器响。
3.3 逻辑电平控制电路设计
逻辑分析仪主要作用在于时序判定,通常只显示两个电压(逻辑1和0),因此设定了参考电压后,逻辑分析仪将被测信号通过比较器进行判定,高于参考电压者为高电平,低于参考电压者为低电平,在高电平与低电平之间形成数字波形。逻辑电平控制电路用于控制输入信号的门限电平,输入信号经过逻辑电平控制电路以后再连接到单片机的I/O口,主要有电压比较器和数模转换器构成,电路如图6所示。逻辑分析仪被测信号路数为4路,采用4个电压比较器和一片数模转换器实现逻辑电平控制,电压比较器采用LM393,因为采用OC输出,所以输出端均连接上了5.1kΩ的上拉电阻。4路输入信号的门限电平由数模转换器控制,为了使4路输入信号的门限电平一致,四片电压比较器的反向输入端接在一起,并连接到数模转换器的输出端。数模转换器U2换用TLC5615来实现,TCL5615为十位串行数模转换器,控制方便,并节约单片机的I/O口,数模转换器的参考电压由U2的6脚输入,稳定的参考电压为2.5V,由TL431产生。
图6 逻辑电平控制电路
3.4 供电电源电路设计
图7 供电电源电路
系统采用5V供电,供电电源电路由LM7805完成,电路如图7所示。J11为供电电源电路的输入端,D3为了防止反接,C6、C7为输入滤波电容,C8、C9为输出滤波电容,D5为电源指示灯,R8为电源指示灯的限流电阻。
4 系统软件设计
图8 设计流程图
设计流程图如图8所示,电路焊接完成先进行硬件的调试,然后进行程序的编译和软硬联合调试。硬件调试先不放置芯片,通过万用表验证PCB与原理图的一致性,如果发现有不一致的地方,查找原因,直到解决问题为止。然后进行加电测试,分别测试主要关键点的电压是否和原理一致,单独验证每个模块电路的正确性。硬件验证通过后进行程序的编辑与调试,直到最终设计作品工作为止。
4.1 设计过程所用仪器
1、DF1731SC2A直流稳压电源
2、UT805A万用表
3、PC机
4.2 软件设计工具和平台
采用Keil uVision4集成开发环境作为软件开发平台,用C语言对单片机编程实现系统各功能,并进行整体软件系统调试。采用RS232串口为单片机进行程序下载,由于电脑没有RS232串口,因此使用CH341T完成USB转RS232,RS232连接到单片机串口完成程序的下载。
4.3 软件设计思想
系统采用分模块编程的思想,然后通过标志位来实现各个模块之间的协调运行。此逻辑分析仪的模块程序主要有数据采集模块、逻辑电平控制模块、按键检测模块、采样率控制模块、LCD显示驱动程序等。
4.4 软件设计流程图
图9 程序流程图
5 设计的结果
图10 逻辑分析仪PCB布线图
原理图的绘制和PCB的设计使用Protel 99se来完成,PCB板的制作采用快速热转印技术来完成。
在原理图的绘制及PCB的设计过程中特别注意规范性,特别是PCB布线的一些规则,注意PCB走线、线距、线宽、空间布局等,合理选取接口,如图10所示为逻辑分析仪PCB布线图。
图11 多路数据逻辑分析图
图12 逻辑电平设定测试图
由于此逻辑分析仪为四通道,测试过程中,分别为每个通道加入被测逻辑电平,分别验证,然后四个通道同时验证,并测试逻辑电平设定等。测试结果表明,符合设计要求。
6 总结
采用51单片机为控制核心,数模转换器加电压比较器构成逻辑电平控制电路,LCD组成显示界面等,可以有效的构成简易逻辑分析仪的硬件系统,使用EDA开发工具可以缩短建议逻辑分析仪设计的时间,使用模块化编程的思想有利于程序的调试和可读。通过对简易逻辑分析仪的设计,可以加深对系统设计思想的认知,初步具备电子设计的能力。
[参考文献]
[1] 庞利会,邓先荣,王军锋等.逻辑分析仪的设计与实现[J].电力自动化设备,2012,32(9):149-152.
[2] 朱震华,储婉琴.简易逻辑分析仪的设计与实现[J].实验室研究与探索,2001,20(2):123-124.
[3] 江波,叶丽.基于51单片机的简易逻辑分析仪[J].广西大学学报(自然科学版),2008,33(z1):128-130.
[4] 朱震华,储婉琴.简易逻辑分析仪设计[J].电子工程师,2000,26(5):31-32,36.
[5] 贾奕,黄劲松,沈鹏程等.简易逻辑分析仪设计[J].电子测试,2008,(10):70-75.
[6] 朱更军,彭永供,项安等.串行10位D/A转换器TLC5615原理及与DSP的接口[J].电子质量,2003,(10):59-60.
[7] 左现刚,余周,侯志松等.基于SPI总线的TLC5615在AVR 单片机中的应用[J].河南科技学院学报(自然科学版),2011,39(4):94-97.
[8] 李建波,高立新.串行数模转换器TLC5615的原理及其Proteus仿真设计[J].福建电脑,2008,(10):21,3.
[9] 孙凌燕,黄允千.Proteus与Keil软件的整合在单片机实验开发中的应用[J].实验室研究与探索,2008,27(4):59-61,68.
[10] 马刚,李向仓.用Proteus与Keil整合构建单片机虚拟仿真平台[J].现代电子技术,2006,29(24):129-131.
[11] 伍冯洁,谢陈跃,谢斌等.Proteus与Keil在单片机开放性实验中的应用[J].电子测量技术,2008,31(6):100-103,107.
[12] 黄克亚.浅谈自制51单片机编程器方法和策略[J].黑龙江科技信息,2009,(25):11.
[13] 邱宁.利用USB总线的虚拟逻辑分析仪[J].自动化仪表,2003,24(9):21-24.
[14] 胡昆霖,李冶,左向利等.基于LabVIEW和FPGA的多通道虚拟逻辑分析仪的设计[J].电子技术应用,2012,38(11):91-93.
[15] 李丽焕.电压比较器电压传输特性的绘制[J].中国科技纵横,2013,(2):212.
[16] 周宦银,吕子勇,马果花等.电压比较器实验研究[J].实验技术与管理,2012,29(3):42-44.
[17] 陈旦花.单片机最小系统的设计与应用[J].无线互联科技,2012,(10):103-104.
[18] 景小健,尹清华,陈清林等.MG-12864液晶显示器在智能仪表中的应用[J].化工自动化及仪表,2003,30(6):62-64.
[19] 李志广,李晓泉,淮俊霞等.中文图形12864点阵液晶显示模块与51单片机的并行接口电路及C51程序设计[J].现代显示,2008,(7):41-44.
[20] 潘大伟,黄璞.基于12864 LCD的波形显示系统的研制[J].仪器仪表用户,2008,15(3):28-29.
The design of simple logic analyzer based on 51 single chip
Wang Shu
Shool of physics and electronic engineering 1230S007
[Abstract]In this paper,a simple logic analyzer which can multiplex data in digital circuit test is designed. It takes 51 single-chip microcomputer to control the core.The digital to analog converter is used as a logic signal threshold level control circuit.The analyzer uses keyboard and 12864LCD as the man-machine interface, and modular programming with C51.It can test quadruplex signal with low cost,and uses conveniently.
[Keywords]Digital circuit SCM Microcontroller DAC Logic Analyzer
附一: 源程序
#include <reg52.h>
#include "lcd.h"
#include "tlc5615.h"
#include "tlc1549.h"
#define count 50000
#define TH_M1 (65536-count)/256 //T0 (Mode 1)计数高8位
#define TL_M1=(65536-count)%256 //T0 (Mode 1)计数低8位
code uchar Display1[8]={"门限电平"};
code uchar Display2[10]={"输出电压为"};
sbit KEY1 = P0^3;
sbit KEY2 = P0^4;
sbit KEY3 = P0^5;
sbit KEY4 = P0^6;
sbit P13=P1^3;
sbit P14=P1^4;
sbit P15=P1^5;
sbit P16=P1^6;
unsigned int uiVoltage_ADC,uiVoltage_DAC; //uiVoltage:LCD显示用,无小数点
float fVoltage_DAC; //定义实际需要输出的电压
xdata unsigned char iCount=0; // 采样个数设置,这里设置为16次
xdata unsigned char result_Port1[4][16]={0};
xdata char port1_Flag=0;
xdata char key12Flag=0;
xdata char TR0Flag=0;
xdata unsigned char key1=0; //控制显示屏上的列标记
xdata unsigned char port_1[4]={1,2,3,4};
char flay_a = 1;
unsigned int Sample_Voltage(void);
void Delay_1ms(int); //毫秒级延时函数
void Control_DAC(void); //声明调整输出电压函数
void displayPort1_in_LCD(unsigned char p, unsigned char i,unsigned char j);
void displayPort1_in_LCD_by_Flush(unsigned char *p,unsigned char key);
void put_and_Display_Voltage(); //当DA的电压设定发生改变时调用该函数
void control_TR0_By_KEY3(); //通过按键KEY3控制采样的结束
void display_Sample_Result(); //显示16次采样的结果函数
void Sys_key();
/********************************************************************************
函 数 名:主函数
功能说明:
调用函数:
入口参数:
出口参数:
说 明:
********************************************************************************/
void main()
{
LCD_init(); //初始化LCD
LCD_Clear(); //LCD清屏
// T0_init();
port1_Flag=0;
key12Flag=0;//禁止按键key1和key2工作
TR0Flag=0;// 禁止Time0工作
TR0=1; //开启Time0工作
fVoltage_DAC = 2.5;
// put_and_Display_Voltage();
// Delay_1ms(20);
DAC_TLC5615_Voltage(fVoltage_DAC);
while(1)
{
if(flay_a==0)
{
port_1[0]=(char)P13;
port_1[1]=(char)P15;
port_1[2]=(char)P14;
port_1[3]=(char)P16;
displayPort1_in_LCD_by_Flush(&port_1,key1%8);
key1++;
key1=key1%128;
// Delay_1ms(500);
// flay_a=1;
// Sys_key();
if(KEY1==0) //增加DAC电压,
{
Delay_1ms(10);
if(KEY1==0)
{
while(!KEY1);
fVoltage_DAC=fVoltage_DAC+0.5;
if(fVoltage_DAC>4.0)
{
fVoltage_DAC = 1.0;
}
// IE=0x00;
flay_a=1;
// TR0Flag=1; //按一次就开始采样,再按一次就结束采样;
}
}
if(KEY3==0) //减DAC电压,
{
Delay_1ms(10);
if(KEY3==0)
{
while(!KEY3);
fVoltage_DAC=fVoltage_DAC-0.5;
if(fVoltage_DAC<1.0)
{
fVoltage_DAC = 4.0;
}
flay_a=1;
// IE=0x00;
// key12Flag=1;
}
}
}
if(flay_a==1)
{
put_and_Display_Voltage();
flay_a=0;
}
}
}
/********************************************************************************
函 数 名:Display_Voltage
功能说明:显示电压,整数
调用函数:LCD_Pos Send_Data Write_LCD
入口参数:Voltage(带显示电压*1000倍以后的值) x,y(从LCD的坐标x,y处开始显示)
出口参数:无
说 明:显示范围为0-9999 列:当Voltage=1234时,显示1.234V
********************************************************************************/
void Display_Voltage(unsigned int Voltage,char x,char y)
{
code uchar Display_Dot[1]={"."};
code uchar Display_Unit[1]={"V"};
LCD_Pos(x,y);
Write_LCD(Voltage/1000+0x30,1);
Send_Data(Display_Dot,1); //显示小数点
Write_LCD(Voltage%1000/100+0x30,1);
Write_LCD(Voltage%100/10+0x30,1);
Write_LCD(Voltage%10+0x30,1);
Send_Data(Display_Unit,1); //显示单位
}
/********************************************************************************
函 数 名:Sample_Voltage
功能说明:带有滤波功能的电压测量
调用函数:ADC_TLC1549
入口参数:无
出口参数:Votlage(测量滤波后的电压)
说 明:
********************************************************************************/
unsigned int Sample_Voltage(void)
{
double Filt_Tab[3]={0};
char Flag_Filt_Tab = 0;
unsigned int Tab_Vol[30] ={0},k=0,Votlage = 0;
double Sum = 0;
char i=0,j=0;
///////////////////////平均值 滤波////////////
for(i=0;i<30;i++)
{
Tab_Vol[i]= ADC_TLC1549();
}
for(j=0;j<30;j++)
for(i=0;i<30-j;i++)
if(Tab_Vol[i]>Tab_Vol[i+1])
{
k=Tab_Vol[i];
Tab_Vol[i]=Tab_Vol[i+1];
Tab_Vol[i+1]=k;
}
for(i=0;i<10;i++)
{
Sum +=Tab_Vol[i+10]; //取中间二十组数据
}
Sum = Sum/10; //平均滤波后的值
Votlage =(unsigned)(Sum/1024.0*3770); //扩大1000 //需要一阶滞后滤波时把Sum修改成Filt_Tab[2]并取消屏蔽
return Votlage;
}
/********************************************************************************
函 数 名:Delay_1ms
功能说明:毫秒级延时函数
调用函数:
入口参数:x:延时x毫秒
出口参数:
说 明:
********************************************************************************/
void Delay_1ms(int x)
{
int i,j;
for(i=0;i<x;i++)
for(j=0;j<120;j++);
}
//把p1.3,p1.4,p1.5,p1.6在液晶中进行显示,每行显示一组数据
void displayPort1_in_LCD(unsigned char p, unsigned char i,unsigned char j)
{
LCD_Pos(i,j); //设置显示位置为第i行的第j个字符
Write_LCD(p+0x30,1);
}
//一次显示四个电平值,显示在一列。 P13,P15,P14,P16
// 参数p[0]=P13,p[1]=P14,p[2]=P15,p[3]=P16;
//参数key是要显示的列标,最大是15,最小是0;
void displayPort1_in_LCD_by_Flush(unsigned char *p,unsigned char key)
{ // LCD_Clear();
displayPort1_in_LCD(p[0],0,key);
displayPort1_in_LCD(p[1],1,key);
displayPort1_in_LCD(p[2],2,key);
displayPort1_in_LCD(p[3],3,key);
}
//输出并显示电压函数
void put_and_Display_Voltage()
{ //把DA变换的初始电压显示在LCD上,也可以换成提示输入按键
LCD_Clear(); //LCD清屏
LCD_Pos(1,1);
Send_Data(Display1,8);
DAC_TLC5615_Voltage(fVoltage_DAC); //DAC输出电压
uiVoltage_DAC = fVoltage_DAC*1000; //uiVoltage_DAC:LCD显示用
Display_Voltage(uiVoltage_DAC,2,5); //显示输出电压
Delay_1ms(1000);
LCD_Clear(); //LCD清屏
}
void control_TR0_By_KEY3()
{
if(KEY3==0) //增加DAC电压,
{
Delay_1ms(10);
if(KEY3==0)
{
while(!KEY3);
TR0Flag=1; //按一次就开始采样,再按一次就结束采样;
}
}
}
void display_Sample_Result()
{
//表示采样结束,可以进行显示
port_1[0]=result_Port1[0][key1];
port_1[1]=result_Port1[1][key1];
port_1[2]=result_Port1[2][key1];
port_1[3]=result_Port1[3][key1];
// key1=key1%16;
displayPort1_in_LCD_by_Flush(&port_1,key1%8) ;
Delay_1ms(500);
key1++;
if(key1==8)
{// 刷屏一次
LCD_Clear();
}
if(key1==16) //刷屏一次
{
// port1_Flag=0;
LCD_Clear();
key1=0;
//数据显示完毕,可以进行下一次采样,启动Time0中断
// IE=0x82;
}
}
void Sys_key()
{
if(KEY1==0) //增加DAC电压,
{
Delay_1ms(10);
if(KEY1==0)
{
while(!KEY1);
fVoltage_DAC=fVoltage_DAC+0.5;
// IE=0x00;
flay_a==1;
// TR0Flag=1; //按一次就开始采样,再按一次就结束采样;
}
}
if(KEY3==0) //减DAC电压,
{
Delay_1ms(10);
if(KEY3==0)
{
while(!KEY3);
fVoltage_DAC=fVoltage_DAC-0.5;
flay_a==1;
// IE=0x00;
// key12Flag=1;
}
}
}
#include"lcd.h"
/********************************************************************************
函 数 名:LCD_init
功能说明:LCD初始化子程序
调用函数:Write_LCD
入口参数:
出口参数:
说 明:
********************************************************************************/
void LCD_init(void)
{
CS =1;
SID =0;
CLK=0;
// RST = 1;
// PSB = 0;
Write_LCD( 0x30,0 );//功能设置,一次送8位数据,基本指令集
// delay( 50 );
Write_LCD( 0x30,0 );//功能设置,一次送8位数据,基本指令集
// delay( 40 );
Write_LCD( 0x0c,0 );//0000,1100 整体显示,游标off,游标位置off
// delay( 50 );
Write_LCD( 0x01,0 );//0000,0001 清DDRAM
// delay( 10000 );
Write_LCD( 0x02,0 );//0000,0010 DDRAM地址归位
// delay( 50 );
// delay( 50 );
Write_LCD( 0x80,0 );//1000,0000 设定DDRAM 7位地址000,0000到地址计数器AC//
// delay( 150 );
Write_LCD( 0x06,0 );
}
/********************************************************************************
函 数 名:Write_LCD
功能说明:写液晶子程序
调用函数:
入口参数:word(要写的内容) dat(1为数据,0为指令)
出口参数:
说 明:
********************************************************************************/
void Write_LCD(uchar word,uchar dat)
{
uchar lcddat[3];
uchar i,j,k;
lcddat[0] = ( 0xf8+(dat<<1) );//第一个字节
lcddat[1] = ( word&0xf0 ) ; //第二个字节 内容的高四位+0000
lcddat[2] = ( (word<<4)&0xf0 ) ;//第三个字节 内容的第四位+0000
CS = 0;
CS = 1;
CLK = 0;
for(i=0;i<3;i++)
{
j = lcddat[i];
for(k=0;k<8;k++)
{
if( (j<<k)&0x80 )SID = 1;
else SID = 0;
/**时钟下降沿写入数据**/
CLK = 1;
CLK = 0;
}
}
}
/********************************************************************************
函 数 名:Send_Data
功能说明:一次写多个字符
调用函数:Write_LCD
入口参数:*data(要显示的字符) num(显示的字符个数)
出口参数:
说 明:需要编程者自行判断显示的字符个数
********************************************************************************/
void Send_Data(unsigned char *date,char num)
{
char j;
for(j = 0;j<num;j++)
{
Write_LCD(date[j],1); //显示字符
}
}
/********************************************************************************
函 数 名:LCD_pos
功能说明:设定LCD显示定位
调用函数:Write_LCD
入口参数:X,Y分别为液晶上行和列坐标
出口参数:
说 明:12864液晶一共可以显示4行,每行可以显示八个汉子或16个字符,都有固定的地址
参照郭天祥《51单片机C语言教程》第174页
********************************************************************************/
void LCD_Pos(unsigned char X, unsigned char Y)
{
unsigned char pos;
if(X==0)
{X = 0x80;}
else if(X==1)
{X = 0x90;}
else if(X==2)
{X = 0x88;}
else if(X==3)
{X = 0x98;}
pos = X + Y;
Write_LCD(pos,0);
}
/********************************************************************************
函 数 名:LCD_Clear
功能说明:LCD显示清屏
调用函数:Write_LCD
入口参数:
出口参数:
说 明:不能清屏游标等。
********************************************************************************/
void LCD_Clear()
{
Write_LCD(0x01,0 );//0000,0001 清DDRAM
Write_LCD(0x02,0 );//0000,0010 DDRAM地址归位
}
/********************************************************************************
函 数 名delay(uint t)
功能说明:延时子程序
调用函数:
入口参数:
出口参数:
说 明:
********************************************************************************/
//void delay( uint t )
//{
// while( t-- );
//}
#include "tlc5615.h
展开阅读全文