智能仪器课程设计.docx
《智能仪器课程设计.docx》由会员分享,可在线阅读,更多相关《智能仪器课程设计.docx(27页珍藏版)》请在冰豆网上搜索。
智能仪器课程设计
智能仪器课程设计
班级:
姓名:
学号:
波形发生器
一.实验目的:
1.掌握动态LED显示及键盘设计原理,对智能仪器中最基本的输入输出设备具有感性认识
2.熟练掌握HC6800开发板的使用
3.通过一个相当对完整的程序编程,能够将单片机知识和智能仪器的设计融会贯通,同时掌握对智能仪器的软硬件构成及硬件软化方法。
二.实验要求:
1.显示亮度大致均匀。
2.按键需去抖
3.运行程序首先显示以下内容:
HELLO
4.通过按键显示相应的波形,通过DA输出。
5.输出波形时,数码管显示频率,发光管指示波形种类。
6.编写实验报告。
三.硬件原理
1.单片机最小系统:
cpu为STC89系列增强型8位单片机,频率高达80MHz,可工作于6Clock,32I/O,3定时器,内置WDT、EEPROM。
支持ISP,ESD。
晶振采用12M/11.0592(可更换)。
2.数码管
1.数码管功能使用:
有2组四位动态数码管和1个一位静态数码管。
当使用四位动态数码管时,用8位排线将J12与单片机的I/O口脚相连,当使用一位静态数码管时,有两种连接方式:
1.用8P排线将JP3与单片机的I/O口脚相连,实现用单片机I/O脚直接控制数码管。
2.用8P排线将JP2与JP3相连,然后将JP12用短路冒全部短接,此时为单片机控制74HC595,,7HC595再控制数码管的动态扫描。
2.数码管说明
数码管实际上是由7个发光管组成的8字形构成的,加上小数点就是8个,动态扫描显示接口是单片机中应用最为广泛的一种显示方式。
其接口电路是把所有显示器的8个笔划a-h同名端连在一起,而每一个显示器的公共极COM是各自独立地接受I/O口线控制。
CPU向各字段输出口送出字形码时,所有显示器均接收到相同的字形码,但究竟是那个显示器亮,取决于COM端所以就可以自行决定何时显示哪一位了。
所谓动态扫描就是指我们采用分时的方法,轮流控制各个显示器的COM端,使各个显示器轮流点亮。
每位显示器的点亮时间是极为短暂的(约1ms),但由于人的视觉暂留现象及发光二极管的余晖效应,尽管实际上各位显示器并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感。
3数码管原理图
3.LED灯
JP1为8路LED灯的接口,使用此功能时,将JP1与JP8-JP11中任何接口相连,即可实现单片机控制8路LED。
原理图
4.矩阵按键
1.矩阵键盘的功能使用
JP4为矩阵键盘的接口,p10—P13为行,p14-p16为列。
使用8P排线把JP4与JP8-JP11中任何接口相连,实现矩阵键盘的功能。
2.矩阵键盘的结构与工作原理
当键盘中按键数量较多时为了减少I/O口德占用,通常将按键排列成矩阵形式。
在矩阵键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。
这样一个端口就可以构成4*4个按键,比直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,在需要的键数较多时,采用矩阵法来做键盘是合理的。
矩阵式的键盘显然比直接法复杂一些,识别也要复杂一些。
原理图:
5.DA/AD转换PCF8591
Pcf8591使用I2C与单片机通信,(SDA)串行数据线,(SCL)串行时钟线。
AD0和AD1是两路模拟输入,改变AD0和AD1位置的电位器,实现了两路模拟输入,在数码管中可以看到数值变化。
当PCF8591数模端口数据变化时,DA位置的LED亮度随之改变。
PCF8591T介绍:
PCF8591是Philips生产的8位分辨率D/A、A/D转换集成芯片,有4路模拟输入,1路模拟输出,一个I2CBUS接口,3个给硬件编程的脚。
通过I2C总线与处理器通信,其价格低廉,接口简单,转换控制容易等优点,在单片机应用系统中得到了广泛的应用。
AIN0-AIN3:
模拟输出(A/D转换)
AOUT:
模拟输出(D/A转换)
A0-A2:
硬件设备地址
GND:
电源负极地
VREF:
参考电压输入
EXT:
振荡器输入时,内部/外部的切换开关
OSC:
振荡器输入/输出
SCL:
I2CBUS时钟输入
SDA:
I2CBUS数据输入输出
AGND:
模拟地,模拟信号和基准电源的参考地
原理图:
6.I2C总线
I2c总线是一种基于IC器件之间连接的二线制总线。
它通过SDA(串行数据线)及SCL(串行时钟线)两根线在连到总线上的器件之间传送信息,并根据地址识别每个器件:
不管是单片机,存储器,LCD驱动器还是键盘接口。
1.I2C总线基本结构:
采用I2C总线标准的单片机IC器件,其内部结构不仅有I2C接口电路,而且将内部各单元电路电路按功能划分为若干相对独立的模块,通过软件寻址实现片选,减少了器件片选的连接。
CPU不仅能通过指令将某个功能单元电路挂靠摘离总线,还可对该单元的工作状况进行检测,从而实现对硬件系统的既简单又灵活的扩展与控制。
I2C总线接口电路原理图:
2.双向传输的接口特性
传统的单片机串行接口的发送和接收一般都各用一条线,如MCS51系列的TXD和RXD。
而I2C总线则根据器件的功能通过软件程序使其可工作于发送接收方式。
当某个器件向总线上发送信息时,它就是发送器(也称主器件),而当其从总线上接收信息时,又成为接收器(也叫从器件)。
主器件用于启动总线上传送数据并产生时钟,以开放送的器件,此时,任何被寻址的器件均本人为是从器件。
I2C总线的控制完全由挂接在总线上的主器件送出的地址和数据决定。
在在总线上,既没有中心机,也没有优先机。
总线上主和从(即发送和接收)的关系不是一成不变的,而是取决于此时数据传送的方向。
SDA和SCL均为双向输入输出线,通过上拉电阻接正电源。
当总线空闲时,两根线都是高电平。
;连接总线的器件的输出级必须是集电极或漏极开路,以具有“线”与功能。
I2C总线的数据数据传送速率在标准工作方式下为100kbit/S,在快速方式下,最高传送速率可达400kbit/s.
在实际应用中,一般只有单片机能够发送CLK,因此,只有单片机能够作为主器件,其余I2C器件均为从器件。
多单片机系统通常很少应用。
I2C总线上的时钟信号在I2C总线上传送信息时的时间同步信号是由挂接在SCL时钟器件的逻辑与完成的。
SCl线上由高电平到低电平的跳变将影响这些器件,一旦某个器件的SCl线跳变为低电平,使SCL上的所有器件进入低电平期。
此时低电平周期短的器件的时钟由低至高的跳变不能影响SCL线的状态,于是这些器件将进入高电平等待的状态,当所有器件的时钟信号都跳变为高电平时,低电平期结束。
SCL线被释放SCL线被释放返回高电平,即所有的器件都同时开始它们的高电平期。
其后,第一个结束高电平期的器件又将SCL线拉成低电平。
这样就在SCL线上产生一个同步时钟。
可见,时钟低电平时间由时钟低电平期最长的器件确定,而时钟高电平时间由时钟高电平期最短的器件确定。
3.数据的传送
在数据传送过程中,必须确认数据传送的开始和结束。
在I2C总线技术规范中,开始和结束信号(也称启动和停止信号)的定义如图所示。
当时钟线SCL为高电平时,数据线SDA由高电平跳变为低电平定义为"开始"信号;当SCL线为高电平时,SDA线发生低电平到高电平的跳变为"结束"信号。
开始和结束信号都是由主器件产生。
在开始信号以后,总线即被认为处于忙状态;在结束信号以后的一段时间内,总线被认为是空
闲的。
4.I2C总线的数据传送格式:
在I2C总线开始信号后,送出的第一个字节数据是用来选择器件地址的,其中前七位为地址码,第八位为方向位,方向位为0表示发送,即主器件把信息写到所选择的从器件;方向位为1表示主器件将从从器件读信息。
开始信号后,系统中的各个器件将自己的地址和主器件送到总线上的地址进行比较,如果与主器件发送到总线上的地址一致,则该器件即为被主器件寻址的器件,其接收信息还是发送信息则由第八位确定。
在I2C总线上每次传送的数据字节数不限,但每一个字节必须为8位,而且每个传送的字节后面必须跟一个认可位,也叫应答位。
数据的传送过程:
每次都是先传最高位通常从器件在接收到每个字节后都会做出响应,即释放SCL线返回高电平,准备接受下一个数据字节,主器件可继续传送。
如果从器件正在处理一个实时事件而不能接收数据时,(例如正在处理一个内部中断,在这个中断处理完之前就不能接受I2C总线上的数据字节)可以使时钟SCl线保持低电平,从器件必须使SDA保持高电平,此时主器件产生1个结束信号,使传送异常结束,迫使主器件处于等待状态。
当从器件处理完毕时,释放SCL线,主器件继续传送。
当主器件发送完一个字节的数据时,接着发出对应于SCL线上的一个时钟(ACK)认可位,在此时钟内主器件释放SDA线一个字节传送结束,而从器件的响应信号将SDA线拉成低调平,使SDA在该时钟的高电平期间为稳定的低电平。
从器件的响应信号结束后,SDA线返回高电平,进入下一个传送周期。
5.总线竞争的仲裁:
总线上可能挂接有多个器件,有时会发生两个或多个主器件想同时占用总线的情况,例如:
多单片机系统中,可能在某一时刻有两个单片机要同时向总线发送数据,这种情况叫总线竞争。
I2C总线具有多主控能力,可对发生在SDA线上的总线竞争进行仲裁,其仲裁原则是:
当多个主器件同时想占用总线时,如果某个主器件发送高低阿平,而另一个主器件发送低电平,则发送电平与此时SDA总线电平不符合的那个器件将自动关闭其输出级。
总线竞争的仲裁是在两个层次上进行的。
首先是地址位的比较,从而确保了竞争仲裁的可靠性。
由于利用I2C总线上的信息进行仲裁,因此不会造成信息的丢失。
6.应用领域
I2C总线接口器件目前在视频处理,移动通信,等领域采用I2C总线接口器件已经比较普遍。
另外,通用的I2C总线接口器件,如带I2C总线的单片机,RAM,ROM,A/D,D/A,LCD
驱动器等器件,也越来越多的应用于计算机及自动控制系统中。
四.软件原理
1.LED动态显示
1.显示原理
LED的静态显示虽然有编程容易,管理简单等优点,但静态显示所要占用的IO口资源很多,所以在显示的LED较多的情况下,一般采用动态显示方式。
数码管实际上是由7个发光管组成的8字形构成的,加上小数点就是8个,动态扫描显示接口是单片机中应用最为广泛的一种显示方式。
其接口电路是把所有显示器的8个笔划a-h同名端连在一起,而每一个显示器的公共极COM是各自独立地接受I/O口线控制。
CPU向各字段输出口送出字形码时,所有显示器均接收到相同的字形码,但究竟是那个显示器亮,取决于COM端所以就可以自行决定何时显示哪一位了。
所谓动态扫描就是指我们采用分时的方法,轮流控制各个显示器的COM端,使各个显示器轮流点亮。
每位显示器的点亮时间是极为短暂的(约1ms),但由于人的视觉暂留现象及发光二极管的余晖效应,尽管实际上各位显示器并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感
显示子程序:
#include<>
#include<>
sbitLS138A=P2^2;//定义138译码器的输入A脚由控制
sbitLS138B=P2^3;//定义138译码器的输入脚B由控制
sbitLS138C=P2^4;//定义138译码器的输入脚C由控制
voiddelay(unsignedinti);//函数声名
charDelayCNT;
//此表为LED的字模,共阴数码管0-9-
unsignedcharcodeDisp_Tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
main()
{
unsignedinti,LedNumVal=1;
unsignedintLedOut[10];
DelayCNT=0;
while
(1)//进入循环状态
{
if(++DelayCNT>=50)
{
DelayCNT=0;//延时计数每扫描一次加一次
++LedNumVal;//每隔50个扫描周期加一次
}
LedOut[0]=Disp_Tab[LedNumVal%10000/1000];
LedOut[1]=Disp_Tab[LedNumVal%1000/100]|0x80;
LedOut[2]=Disp_Tab[LedNumVal%100/10];
LedOut[3]=Disp_Tab[LedNumVal%10];
LedOut[4]=Disp_Tab[LedNumVal%10000/1000];//千位
LedOut[5]=Disp_Tab[LedNumVal%1000/100]|0x80;//百位带小数点
LedOut[6]=Disp_Tab[LedNumVal%100/10];//十位
LedOut[7]=Disp_Tab[LedNumVal%10];//个位
for(i=0;i<9;i++)//实现8位动态扫描循环
{P0=LedOut[i];//将字模送到P0口显示
switch(i){
case0:
LS138A=0;LS138B=0;LS138C=0;break;
case1:
LS138A=1;LS138B=0;LS138C=0;break;
case2:
LS138A=0;LS138B=1;LS138C=0;break;
case3:
LS138A=1;LS138B=1;LS138C=0;break;
case4:
LS138A=0;LS138B=0;LS138C=1;break;
case5:
LS138A=1;LS138B=0;LS138C=1;break;
case6:
LS138A=0;LS138B=1;LS138C=1;break;
case7:
LS138A=1;LS138B=1;LS138C=1;break;
}
delay(150);
}
}
}
voiddelay(unsignedinti)
{
charj;
for(i;i>0;i--)
for(j=200;j>0;j--);
}
2.键盘
1.键盘扫描原理
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。
在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。
这样,一个端口就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键。
由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。
这样,当按键没有按下时,所有的输入端都是高电平,代表无键按下。
行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。
2.键盘扫描子程序
#include<>
#include<>
#defineucharunsignedchar
#defineuintunsignedint
uchardis_buf;//显示缓存
uchartemp;
ucharkey;//键顺序吗
voiddelay0(ucharx);//x*
#definedelayNOP();{_nop_();_nop_();_nop_();_nop_();};
unsignedcharcodeLED7Code[]={~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5E,~0x79,~0x71};
voiddelay(ucharx)
{ucharj;
while((x--)!
=0)
{for(j=0;j<125;j++)
{;}
}
}
voidkeyscan(void)
{temp=0;
P1=0xF0;//高四位输入行为高电平列为低电平
delay
(1);
temp=P1;//读P1口
temp=temp&0xF0;//屏蔽低四位
temp=~((temp>>4)|0xF0);
if(temp==1)//被拉低
key=0;
elseif(temp==2)//被拉低
key=1;
elseif(temp==4)//被拉低
key=2;
elseif(temp==8)//被拉低
key=3;
else
key=16;
P1=0x0F;//低四位输入列为高电平行为低电平
delay
(1);
temp=P1;//读P1口
temp=temp&0x0F;
temp=~(temp|0xF0);
if(temp==2)//被拉低
key=key+0;
elseif(temp==4)//被拉低
key=key+4;
elseif(temp==8)//被拉低
key=key+8;
else
key=16;
dis_buf=key;//键值入显示缓存
dis_buf=dis_buf&0x0f;
}
voidkeydown(void)
{
P1=0xF0;
if(P1!
=0xF0)//判断按键是否按下如果按钮按下会拉低P1其中的一个端口
{
keyscan();//调用按键扫描程序
}
}
main()
{
P0=0xFF;//置P0口
P1=0xFF;//置P1口
delay(10);//延时
while
(1)
{
keydown();//调用按键判断检测程序
P0=LED7Code[dis_buf%16]&0x7f;//LED70x7f为小数点共阴和共阳此处也是不一样;%16表示输出16进制
}
}
五.设计心得
通过这次课程设计,加深了对知识的理解,也非常的清楚的认识了这门课程的重要性,也意识到了自己在程序设计方面的薄弱性。
希望在以后的学习和工作中能进一部的加强自己专业素质和实践动手能力,并在单片机程序设计语言方面要实现从汇编语言到C语言的跳转。
六.参考文献
1.赵新民,王祁 智能仪器设计基础。
哈尔滨工业大学出版社
七.附录
1.程序
#include<>
#include<>
#define_Nop()_nop_()/*定义空指令*/
#defineucharunsignedchar
#defineuintunsignedint
ucharcodesaw_tab[]={//每隔数字8,采取一次
0xc0,0xbc,0xb8,0xb4,0xb0,0xac,0xa8,0xa4,0xa0,0x9c,0x98,0x94,
0x90,0x8c,0x88,0x84,0x80,0x7c,0x78,0x74,0x70,0x6c,0x68,0x64,0x60,0x5c,0x58,0x54,0x50,0x4c,0x48,0x44,0x40,0x3c,0x38,0x34,0x30,0x2c,0x28,0x24,0x20,0x1c,0x18,
0x14,0x10,0x0c,0x08,0x04,0x00};
ucharcodemaichong_tab[]={255,255,255,255,255,2550,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
uchardis_buf;//显示缓存
uchartemp;
ucharkey,flag=0;//键顺序吗
voiddelay0(ucharx);//x*
#definedelayNOP();{_nop_();_nop_();_nop_();_nop_();};
sbitLS138A=P2^2;//定义138译码器的输入A脚由控制
sbitLS138B=P2^3;//定义138译码器的输入脚B由控制
sbitLS138C=P2^4;//定义138译码器的输入脚C由控制
voiddelay9(unsignedinti);//函数声名
charDelayCNT;
//此表为LED的字模,共阴数码管0-9-
unsignedcharcodeDisp_Tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
unsignedcharcodeDisp_Tab1[]={0x76,0x79,0x38,0x38,0x3f};
bitack;/*应答标志位*/
sbitSCL=P2^1;//I2C时钟
sbitSDA=P2^0;//I2C数据
voidStart_I2c()
{
SDA=1;/*发送起始条件的数据信号*/
_Nop();
SCL=1;
_Nop();/*起始条件建立时间大于,延时*/
_Nop();
_Nop();
_Nop();
_Nop();
SDA=0;/*发送起始信号*/
_Nop();/*起始条件锁定时间大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0;/*钳住I2C总线,准备发送或接收数据*/
_Nop();
_Nop();
}
voidStop_I2c()
{
SDA=0;/*发送结束条件的数据信号*/
_Nop();/*发送结束条件的时钟信号*/
SCL=1;/*结束条件建立时间大于4μs*/
_Nop();