基于单片机的智能仪器综合设计实验
一、实验目的
在实验一~实验三的基础上,完成综合设计实验,学会信号采集、数据处理、键盘控制、LCD或LED显示等功能的智能仪器设计。
二、复习与参考
实验一~实验三
三、设计指标
利用K分度号热电偶进行温度检测,测温范围为500-1200?C,室温为20?C,用LCD或LED显示室温和测量温度。
具有4路温度信号循环检测功能,通道切换时间可调;具有任意指定通道显示功能。
四、实验要求
1.选择传感器,设计硬件电路,包括检测电路、信号调理电路、AD转换电路、单片机最小系统、LED显示(单号)、LCD显示(双号)、独立式按键,画出电路原理图。
2.画出软件流程图。
3.用Keil C51编写程序。
3.实验结果在LCD或LED上显示出来。
4.实验前完成第1、2项备查。
五、实验仪器设备和材料清单
PC机;单片机实验板、连接导线、ST7920图形液晶模块
Keil c51软件
六、实验成绩评定方法
实验成绩包括预习、实验完成质量、实验报告质量3部分组成,各部分所占比例分别为30%、40%、30%。
八、实验报告要求
实验报告格式:
? 实验名称
? 实验目的
1
? 实验内容
? 硬件设计
? 软件设计
? 调试过程
? 参考文献
? 附1:电路原理图
? 附2:程序清单
附录:实验程序源代码如下:(陈寅) #include "reg51.h"
#define THC0 0xee //5ms时间常数设置
#define TLC0 0x00
sbit ADWR=P3^6; /***WR*****/
sbit ADRD=P3^7; /***RD*****/
sbit ADCS=P2^7; /***CS*****/
sbit EOC=P3^3; /***EOC****/
sbit ADA=P1^3; //通道选择引脚
sbit ADB=P1^4;
sbit ADC=P1^5;
sbit CS =P1^0; /****************/
sbit SID=P1^1; /**液晶引脚定义**/
sbit SCLK=P1^2; /****************/
sbit MODE=P2^0; /*************************/
sbit UP=P2^1; /*四个按键接口,0表示按下*/
sbit DOWN=P2^2; /*************************/
sbit LED1=P2^3; /**4个LED灯引脚定义**/
sbit LED2=P2^4; /********************/
sbit LED3=P2^5; /********************/
sbit LED4=P2^6; /********************/
/***************500~1200°C范围的K分度表,间隔10*******************/ unsigned int code K_TABLE[71]={
20644,21066,21493,21919,22346,22772,23198,23624,24050,24476, 24902,25327,25751,26176,26599,27022,27445,27867,28288,28709, 29128,29547,29965,30383,30799,31214,31629,32042,32455,32866, 33277,33686,34095,34502,34909,35314,35718,36121,36524,36925,
2
37325,37725,38122,38519,38915,39310,39703,40096,40488,40897, 41296,41657,42045,42432,42817,43202,43585,43968,44349,44729,
45108,45486,45863,46238,46612,46985,47356,47726,48095,48462,48828}; unsigned char GetAdData[10]={0}; //存放获得AD值的数组变量
unsigned char ViewTemperature[4]={"0000"}; //显示温度缓冲数组变量 unsigned MODESelect=1;
int ChangeTime=2; //通道切换时间,单位S
int TongDao=1;
void delay(unsigned int j)
{
unsigned char i;
do{
for(i=0;i<100;i++);
}while(j--);
}
void send_command(unsigned char command_data) //发送命令
{
unsigned char i;
unsigned char i_data;
i_data=0xf8; //操作命令,可以查看资料
delay(10);
CS=1;
SCLK=0;
for(i=0;i<8;i++)
{
SID=(bit)(i_data&0x80);
SCLK=0;
SCLK=1;
i_data=i_data<<1;
}
i_data=command_data;
i_data&=0xf0;
for(i=0;i<8;i++)
{
SID=(bit)(i_data&0x80);
SCLK=0;
SCLK=1;
i_data=i_data<<1;
}
i_data=command_data;
i_data=i_data&0x0f;
i_data<<=4;
3
for(i=0;i<8;i++)
{
SID=(bit)(i_data&0x80);
SCLK=0;
SCLK=1;
i_data=i_data<<1;
}
CS=0;
}
void send_data(unsigned char command_data) //发送数据 {
unsigned char i;
unsigned char i_data;
i_data=0xfa; //操作命令,可以查看资料
delay(10);
CS=1;
for(i=0;i<8;i++)
{
SID=(bit)(i_data&0x80);
SCLK=0;
SCLK=1;
i_data=i_data<<1;
}
i_data=command_data;
i_data&=0xf0;
for(i=0;i<8;i++)
{
SID=(bit)(i_data&0x80);
SCLK=0;
SCLK=1;
i_data=i_data<<1;
}
i_data=command_data;
i_data=i_data&0x0f; //取低四位
i_data<<=4; //左移四位,从而变成高四位 for(i=0;i<8;i++)
{
SID=(bit)(i_data&0x80);
SCLK=0;
SCLK=1;
i_data=i_data<<1;
}
CS=0;
}
4
void InitLCD() //液晶初始化
{
send_command(0x30); //功能设置:一次送8位数据,基本指令集
send_command(0x06); //点设定:显示字符/光标从左到右移位,DDRAM地址加1 send_command(0x0c); //显示设定:开显示,显示光标,当前显示位反白闪动
send_command(0x04); //显示设定:开显示,显示光标,当前显示位反白闪动 send_command(0x01); //清DDRAM send_command(0x02); //DDRAM地址归位 send_command(0x80); //把显示地址设为0X80,即为第一行的首位 }
/* x,y为起始座标 x(0<=x<=3),y(0<=y<=7),x为行座标,y为列座标;
how为要显示汉字的个数;
style为显示字符的类型,0表汉字,1表字母; str是要显示汉字的地址 */
void Display(unsigned char x,unsigned char y,unsigned char how,bit style,unsigned char *stri) //液晶显示
{
unsigned char hi=0; if(x==0) send_command(0x80+y); else if(x==1) send_command(0x90+y); else if(x==2) send_command(0x88+y); else if(x==3) send_command(0x98+y); if(style==0) { for(hi=0;hi<how;hi++) } { } send_data(*(stri+hi*2)); send_data(*(stri+hi*2+1)); else for(hi=0;hi<how;hi++) send_data(*(stri+hi));
}
float LvBo(void)//复合滤波
{
unsigned char max,min,i; unsigned int sum=0;
float U1;
max=GetAdData[0];
min=GetAdData[0]; for(i=0;i<10;i++) { sum=sum+GetAdData[i]; if(max<GetAdData[i]) max=GetAdData[i]; 5
if(min>GetAdData[i]) min=GetAdData[i]; } sum=sum-max-min; U1=(float)sum/8; U1=10.0*((U1*5.0)/255); return U1; //换成mv
}
void search (void)//查表子函数
{
unsigned int da=0,max,min,mid,j; unsigned int var; da=LvBo()*1000; //u1扩大1000倍 da=da+798; max=71; min=0; var=0; while(1) { mid=(max+min)/2; //中心元素位置 //20度
if(K_TABLE[mid]==da) {var=mid*10;break;} //中心元素等于查表元素,计算相应温度
else if(K_TABLE[mid]>da) max=mid-1; else min=mid+1; if(max-min==1) /*线性插值计算温度值*/ { } j=(K_TABLE[max]-K_TABLE[min])/10; /*表中相邻两值对应温度相差j=(da-K_TABLE[min])/j; var=10*min+j; break; 10°C*/ if(max==min) { if(da>=K_TABLE[min]) { j=(K_TABLE[min+1]-K_TABLE[min])/10; j=(da-K_TABLE[min])/j; } else if(da<K_TABLE[min]) { j=(K_TABLE[min]-K_TABLE[min-1])/10; j=(da-K_TABLE[min-1])/j; min=min-1; 6
} } } var=10*min+j; break; var=var+500; ViewTemperature[0]=var/1000+0x30; ViewTemperature[1]=var/100%10+0x30; ViewTemperature[2]=var/10%10+0x30; ViewTemperature[3]=var%10+0x30;
}
void LcdDisplay(void)
{
unsigned char ViewMODESelect,ViewTongDao[5]={"0 "},ViewChangeTime[5]={"00(S)"};
ViewMODESelect=MODESelect+0x30;
ViewTongDao[0]=TongDao+0x30; if(MODESelect==1||MODESelect==2) { if(MODESelect==1) Display(0,3,5,0,":自动切换"); else if(MODESelect==2) Display(0,3,5,0,":手动切换"); } else if(MODESelect==3) { }
//AD通道设置 ViewChangeTime[0]=ChangeTime/10+0x30; ViewChangeTime[1]=ChangeTime%10+0x30; Display(0,0,2,0,"模式"); Display(0,2,1,1,&ViewMODESelect); Display(0,3,5,0,":设置时间"); Display(1,0,5,0,"切换时间:"); Display(1,5,5,1,ViewChangeTime); Display(2,0,14,1," "); //本行清屏 Display(0,0,2,0,"模式"); //液晶显示 Display(0,2,1,1,&ViewMODESelect); Display(1,0,5,0,"温度通道:"); Display(1,5,5,1,ViewTongDao); Display(2,0,4,0,"温度值:"); Display(2,4,4,1,ViewTemperature); Display(2,6,2,1,"℃"); } void TDSelect(void)
{
7
if(TongDao>=5) TongDao=1;
if(TongDao<=0) TongDao=4;
if(TongDao==1) {ADC=0;ADB=0;ADA=0;}
else if(TongDao==2) {ADC=0;ADB=0;ADA=1;}
else if(TongDao==3) {ADC=0;ADB=1;ADA=0;}
else if(TongDao==4) {ADC=0;ADB=1;ADA=1;}
}
main()
{
unsigned char AdCount=0; //用来存放AD采集次数
InitLCD();
TMOD=0x11; //定时器0初始化
TH0=THC0;
TL0=TLC0;
TR0=1;
ET0=1;
EA=1;
P2|=0x07; //按键初始为高
while(1)
{
ADWR=1; /************/
ADCS=0; /************/
ADWR=0; /**AD初始化**/
ADWR=1; /************/
while(!EOC); //等待转换结束
ADRD=0;
GetAdData[AdCount]=P0; //读取转换结果
AdCount++;
if(AdCount>=10) //连续采集10次值
{
AdCount=0;
search(); //查表
LED1=!LED1;
LcdDisplay(); //显示
}
}
}
void Timer0() interrupt 1
{
static unsigned char count=0,UPFlag=1,DOWNFlag=1; //按键标志位 static unsigned int TimeCount=0;
TH0=THC0;
TL0=TLC0;
8
if(MODE==0||UP==0||DOWN==0)
{
count++;
if(count>=30) //消抖处理
{
count=0;
if(MODE==0) //按键按下
{
MODESelect++;
if(MODESelect>=4) MODESelect=1; }
else if(UP==0)
{
UPFlag=0;
if(MODESelect==2)
{
TongDao++;
TDSelect();
}
}
else if(DOWN==0)
{
DOWNFlag=0;
if(MODESelect==2)
{
TongDao--;
TDSelect();
}
}
}
}
else count=0;
if(MODESelect==1)
{
TimeCount++;
if(TimeCount>=(ChangeTime*1000/5)) {
TimeCount=0;
TongDao++;
TDSelect();
}
}
else if(MODESelect==3)
9
{
if(UPFlag==0) {UPFlag=1;ChangeTime++;} else if(DOWNFlag==0)
{
DOWNFlag=1;
ChangeTime--;
if(ChangeTime<=0) ChangeTime=1; }
}
}
10
滨江学院微机原理与接口技术综合实验报告题目:简易电子琴设计学号:学生姓名:XXX院系:滨江学院专业:指导教师:二OXX年月日【摘要…
51单片机课程设计报告学院:专业班级:姓名:指导教师:设计时间:51单片机课程设计一、设计任务与要求1.任务:制作并调试51单片机…
08424020xx单片微型计算机原理学院班级学号姓名指导教师成绩120xx年6月08424020xx硬件实验实验一定时器中断实验…
08424020xx硬件实验实验一定时器中断实验实验内容fosc110592MHzT0方式2产生定时中断实现秒表功能数码管后两位显…
班级姓名学号单片机实验报告实验一CPU片内外清零1CPU片内RAM清零一实验目的掌握MCS51汇编语言的设计了解单片机的寻址方式以…
实验一AD转换实验实验目的1熟悉ADC0809与单片机的接口电路连接2掌握ADC0809AD转换的编程实验内容应用ICDE5208…
智能仪器设计实验报告题目生物医疗仪器实验姓名学号专业测控技术与仪器班级日期20xx1129地点12407A一实验目的1心电测试学习…