成都理工大学微机原理课程设计邓泉铃.docx
《成都理工大学微机原理课程设计邓泉铃.docx》由会员分享,可在线阅读,更多相关《成都理工大学微机原理课程设计邓泉铃.docx(22页珍藏版)》请在冰豆网上搜索。
![成都理工大学微机原理课程设计邓泉铃.docx](https://file1.bdocx.com/fileroot1/2023-2/11/5cca605c-dd98-4293-bed3-2bd14775f746/5cca605c-dd98-4293-bed3-2bd14775f7461.gif)
成都理工大学微机原理课程设计邓泉铃
微控制器与接口课程设计(论文)
设计(论文)题目人体红外热释检测
学院名称信息科学与技术学院
专业名称电子信息科学与技术
学生姓名邓泉铃
学生学号201313020220
任课教师黄虎
设计(论文)成绩
教务处制
2015年12月28日
微控制器与接口课程设计
组员:
韩均雷,邓泉铃,雷凤智,周鹏
一、设计要求
1、基本要求
(1)设计一个基于人体热释电传感器的人体红外检测装置;
(2)电源用5V单电源,运放用单电源供电;
(3)放大指标在4000倍以上;
(4)用ADC0832采集波形,转换为数字信号,在LCD1602上显示幅度。
2、发挥部分
把显示设备换为12864,显示出时时幅度和波形。
二、设计方案
采用两级放大加滤波的方式,最终输出的波形输入到ADC0832,转换为数字信号,然后送入单片机,经处理转换后在液晶上显示。
3、主要器件介绍
LHI778:
该传感器采用热释电材料极化随温度变化的特性探测红外辐射,采用双灵敏元互补方法抑制温度变化产生的干扰,提高了传感器的工作稳定性。
LM324:
LM324系列器件带有真差动输入的四运算放大器,具有真正的差分输入。
与单电源应用场合的标准运算放大器相比,它们有一些显著优点。
该四放大器可以工作在低到3.0伏或者高到32伏的电源下,静态电流为MC1741的静态电流的五分之一。
共模输入范围包括负电源,因而消除了在许多应用场合中采用外部偏置元件的必要性。
ADC0832:
ADC0832为8位分辨率A/D转换芯片,其最高分辨可达256级,可以适应一般的模拟量转换要求。
其内部电源输入与参考电压的复用,使得芯片的模拟电压输入在0~5V之间。
芯片转换时间仅为32μS,据有双数据输出可作为数据校验,以减少数据误差,转换速度快且稳定性能强。
独立的芯片使能输入,使多器件挂接和处理器控制变的更加方便。
通过DI数据输入端,可以轻易的实现通道功能的选择。
STC89C52:
STC89C52是STC公司生产的一种低功耗、高性能CMOS8位微控制器,具有8K在系统可编程Flash存储器。
STC89C52使用经典的MCS-51内核,但做了很多的改进使得芯片具有传统51单片机不具备的功能。
在单芯片上,拥有灵巧的8位CPU和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。
具有以下标准功能:
8k字节Flash,512字节RAM,32位I/O口线,看门狗定时器,内置4KBEEPROM,MAX810复位电路,3个16位定时器/计数器,4个外部中断,一个7向量4级中断结构(兼容传统51的5向量2级中断结构),全双工串行口。
另外STC89C52可降至0Hz静态逻辑操作,支持2种软件可选择节电模式。
空闲模式下,CPU停止工作,允许RAM、定时器/计数器、串口、中断继续工作。
掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。
最高运作频率35MHz,6T/12T可选。
LCD12864液晶:
带中文字库的128X64是一种具有4位/8位并行、2线或3线串行多种接口方式,内部含有国标一级、二级简体中文字库的点阵图形液晶显示模块;其显示分辨率为128×64,内置8192个16*16点汉字,和128个16*8点ASCII字符集.利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面。
可以显示8×4行16×16点阵的汉字.也可完成图形显示.低电压低功耗是其又一显著特点。
由该模块构成的液晶显示方案与同类型的图形点阵液晶显示模块相比,不论硬件电路结构或显示程序都要简洁得多,且该模块的价格也略低于相同点阵的图形液晶模块。
四、电路部分设计
本装置由前级放大电路、滤波电路、AD转换电路、单片机处理显示电路。
1、前级运算放大器放大滤波电路:
前级放大滤波电路由LM324运算放大器作为主要部分,含有两级放大,每级放大放大倍数计算为100倍,含有低通滤波器,因为传感器输出的频率约为1Hz,交流信号的幅度约为100uV,所以低通截止频率设置为100Hz,最前级含有高通滤波器,主要是用来隔绝直流信号,传感器会输出0.2V至1V不等的直流成分,所以在放大之前必须把直流隔绝。
由于要求单电源供电,所以必须给运算放大器加直流偏置,为了有更大的信号增益,所以第一级加2.5V的直流偏置,第二级也是一样。
系统仿真用multisim软件仿真。
2、A\D转换电路
3、LCD1602显示电路
4、LCD12864液晶显示波形电路
由于仿真软件中没有带字库的的12864b2.0,所以不在进行仿真。
5、软件设计
12864流程图:
六、结果分析
1、放大滤波电路指标测试
第一级放大滤波电路:
由R1和R2可知,增益为100,由C5、R2和R1可知,低通截止频率为100Hz。
在实际测试中,用2mVpp,1.5Hz~20Hz的正弦波作为测试信号,由于电路的材料特性,每级放大电路1Hz增益约为60,且对于10Hz频率的衰减约为-10dB(相对于1Hz频率,以下相同),对于20Hz频率的信号衰减约为-40dB,由于传感器输出的交流信号在100uV左右,对于交流放大,两级放大滤波电路的增益约为3600,理论输出信号应为360mV,实际上,传感器的频率更低,输出的幅度更大,再加上传感器输出信号不是固定值,造成传感器输出幅度过大时,电路输出信号有时会造成失真,这是由于运放用的5V电源供电,再加上2.5V的直流偏置,实际输出交流信号的幅值最大只有2V左右(LM324在5V单电源供电的时候最大输出为4V左右),造成实际应用的时候,放大增益比测试时更大,测试距离更远。
经实际测试,在5M距离下,人正常走动时依然能造成失真,在7M的时候幅值较大,但未失真,且波形信噪比大。
唯一美中不足的是,由于放大增益太大,在未遮住传感器且没有人走动的时候,波形依旧有较大波动,虽然波动不大,但是依旧有时会造成错误信息,导致后续电路判断错误。
2、ADC采样及显示
ADC采用ADC0832,8位数字信号转换,由于数字信号波动小,不易受到外界噪声及干扰的影响,所以,这里不再分析噪声影响,连接电路都已在上图中给出,最主要的就是让给ADC0832供电的电源一定要稳定且准确,这样才能使ADC采集出来的值更加接近真实值,量化误差一定存在,由于采集到的电压值不同,单个量化误差也不同。
AD采样结果如图:
随着滑动变阻器的调节,液晶显示的数值与电压表测得的数值一致,此AD采样数据成功。
3、12864显示波形及幅值
我们知道在纸上画出一个点,我们要知道这个点在张纸上面的位置,也就是这个点在这张纸上面的坐标。
而在12864上面画点也是一样,我们要先知道这个点在液晶屏上面的坐标,然后我们该坐标点黑或是点白可以了。
而在这之前,我们要首先理解12864图形显示坐标。
需要注意的是它的水平位址并不是一个点有一个位址的,它是16个格才有一个位址。
它的垂直位址也分为上下两半部分。
当我们给出位址是X是0,Y是0的时候,其实里面包含了16个点,也就是说我们一次要操作16个点。
所有当我们要点亮一个点的时候,我们不仅要知道的位址,还要知道它在这个位址中是第几个位,也就是第几个点。
写入一个点的子程序。
具体步骤是:
计算出X轴、Y轴的地址、X轴中的第几位,然后读出该地址现在的值,因为一般写入新的点的时候,会覆盖掉16个点中其他点,当你要同时显示16个点中的两个点的时候就会冲突,所以先将显示中的点读出来,然后在或上要点亮的点,这样就可以同时点亮。
注意读取数据的时候读取的第一个数据不要,从第二数据开始取,也就是说要读取三次,只取后面两次的值。
还有就是读取数据之前要先写入你要读取数据的地址,读取数据之后的写入数据还要从新写入地址。
最后就是输入数据地址,先输入Y轴,再输入X轴,输入数据。
下图是实验时测得的有效数据。
用传感器进行测试,在12864上面显示出实时波形,波形每1S刷新一次,实时电压值跟随刷新。
AD采样到的数据为8位二进制数0--255与12864的纵向坐标相对应。
用每次采集到的电压值作为纵坐标,随着横坐标的不断增加从而绘制出波形。
由于AD采集到的电压值为0到5v,所以液晶屏上下分别代表0v和5v。
七、实验程序
12864显示程序:
#include
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineLCD_dataP0//数据端
sbitLCD_RS=P2^6;//为1表示数据,为0表示指令
sbitLCD_RW=P2^5;//为1表示写,为0表示读
sbitLCD_EN=P2^7;//使能端,高电平配合R进行读操作由高到低配合W进行写操作
sbitLCD_PSB=P3^2;//并行和串行选择;1表示并行模式,0表示串行模式
sbitRST=P3^7;//复位端,低电平有效
sbitclk=P1^5;//adc时钟
sbitcs=P1^4;//adc使能端
sbitdin=P1^7;//模拟信号输入端
sbitdout=P1^6;//数字信号输出端
unsignedintdataout=0,i,yout,flag=0;
unsignedcharadc_data_collect(void);
unsignedcharcodeC[]={"泉"};
unsignedcharA[]={"0.00V"};
unsignedcharxdatay_pre[128];
//***************ADC相关************************************
voidadc_init(void)//adc初始化
{clk=0;
cs=1;
din=0;
dout=1;}
unsignedcharadc_data_collect(void)//数据采集
{unsignedchardata_f=0,data_c=0,s;
clk=0;
din=1;
_nop_();
cs=0;//使能ADC
clk=1;
_nop_();
_nop_();
clk=0;
din=1;
clk=1;
_nop_();
_nop_();
clk=0;
din=1;
_nop_();
_nop_();
clk=1;
_nop_();
_nop_();
clk=0;
_nop_();
_nop_();
din=1;
for(s=0;s<8;s++)//数据获取
{
data_f|=dout;
data_f=data_f<<1;
clk=1;
_nop_();
_nop_();
clk=0;
_nop_();
_nop_();
};
for(s=0;s<8;s++)//数据获取
{
data_c|=dout;
data_c=data_c<<1;
clk=1;
_nop_();
_nop_();
clk=0;
_nop_();
_nop_();
}
clk=1;
din=1;
cs=1;//关闭ADC0832
_nop_();
returndata_f;}
//*************lcd12864相关*******************************
voiddelay_1ms(uintx)//延时1ms
{uinti,j;
for(j=0;jfor(i=0;i<10;i++);}
voidlcd_busy()//检测是否能写进数据或者指令
{LCD_RS=0;
LCD_RW=1;
P0=0XFF;//I/O口先写1后在读数据
LCD_EN=1;//E为高表示配合,rw=1进行读数据操作
delay_1ms
(1);
while((P0&0x80)==0x80);//或者等待12864可以接受数据或者指令
LCD_EN=0;}
ucharread_data()//读数据
{ucharread;
lcd_busy();
LCD_RS=1;
LCD_RW=1;
LCD_EN=0;
delay_1ms
(1);
LCD_EN=1;
delay_1ms
(1);
read=P0;
LCD_EN=0;
delay_1ms
(1);
returnread;}
voidwrite_com(ucharcmd)//写指令
{lcd_busy();
LCD_RS=0;//表示指令
LCD_RW=0;//进行写操作
LCD_EN=0;
P0=cmd;
delay_1ms
(1);
LCD_EN=1;//使能端由高到低表示执行加上Rw=0,将指令写入LCD
delay_1ms
(1);
LCD_EN=0;}
voidwrite_dat(uchardat)//写数据
{lcd_busy();
LCD_RS=1;//表示数据
LCD_RW=0;//进行写操作
LCD_EN=0;
P0=dat;
delay_1ms
(1);
LCD_EN=1;//使能端由高到低表示执行加上Rw=0,将数据写入LCD
delay_1ms
(1);
LCD_EN=0;}
voidclear_lcd(void)//绘图时清零函数
{uchari,j;
write_com(0x34);//使用扩展指令集//8bit控制界面绘图//
for(i=0;i<32;i++)//因为LCD有纵坐标32格所以写三十二次
{write_com(0x80+i);//先写入纵坐标Y的值(y的地址为0——31)
write_com(0x80);//再写入横坐标X的值(x的地址为0——15)
for(j=0;j<32;j++)//横坐标有16位,每位写入两个字节的的数据,也就写入32次
{//因为当写入两个字节之后横坐标会自动加1,所以就不用再次写入地址了。
write_dat(0x00);}}
write_com(0x36);//扩展指令集and绘图显示开
write_com(0x30);//退出扩展指令集,进入基本指令集
}
voidpaint_point(ucharx,uchary)//定点函数
{uintbt=0,read=0;
ucharx_adr,y_adr,h_bit,l_bit;
if(flag==1)//每一次都必须从起始位置开始扫描
{y_adr=0x9f-y_pre[i]%32;//计算Y轴的地址//初始Y轴的位置为液晶的最低//为上一个点的纵坐标
if(y_pre[i]<=31)
x_adr=0x88+x/16;//输入的Y地址小于31时在下半屏
else
x_adr=0x80+x/16;//输入的y地址大于31时在上半屏//确定在哪个子区
bt=~(0x8000>>(x%16));//确定在字区中的哪个点
write_com(0x34);
write_com(0x34);//进入扩展指令集
write_com(y_adr);//读取数据的时候要先写入所取数据的地址
write_com(x_adr);
read_data();//读取的第一个字节不要,
read=read_data();//从第二个字节开始接收。
read<<=8;//读出的第一个字节为高8位
read|=read_data();//第二次读出为低8位数据
bt=bt&read;//
h_bit=bt>>8;//高8位数据//再将值写入
l_bit=bt;//低8位数据
write_com(y_adr);//写入点的时候,重新写入地址,因为地址已经改变。
write_com(x_adr);
write_dat(h_bit);
write_dat(l_bit);
write_com(0x36);//开显示
write_com(0x30);//转回基本指令集
}
y_adr=0x9f-y%32;//计算Y轴的地址//初始Y轴的位置为液晶的最低
if(y<=31)
x_adr=0x88+x/16;//输入的Y地址小于31时在下半屏
else
x_adr=0x80+x/16;//输入的y地址大于31时在上半屏//确定在哪个子区
bt=0x8000>>(x%16);//确定在字区中的哪个点
write_com(0x34);
write_com(0x34);//进入扩展指令集
write_com(y_adr);//读取数据的时候要先写入所取数据的地址
write_com(x_adr);
read_data();//读取的第一个字节不要,
read=read_data();//从第二个字节开始接收。
read<<=8;//读出的第一个字节为高8位
read|=read_data();//第二次读出为低8位数据
bt=bt|read;//
h_bit=bt>>8;//高8位数据//再将值写入
l_bit=bt;//低8位数据
write_com(y_adr);//写入点的时候,重新写入地址,因为地址已经改变。
write_com(x_adr);
write_dat(h_bit);
write_dat(l_bit);
write_com(0x36);//开显示
write_com(0x30);//转回基本指令集
}
voidlcd_init()//初始化
{LCD_PSB=1;//并行口
write_com(0x30);//基本指令集
delay_1ms(5);
write_com(0x0c);//整体显示开,游标关,游标位置关
delay_1ms(5);
write_com(0x01);//基本指令集下清屏
delay_1ms(5);}
//****************主函数*****************************************
voidmain()
{unsignedinta,c,d;
adc_init();
lcd_init();
clear_lcd();
//write_com();
//write_dat();
//显示Y轴
for(i=0;i<64;i++)
{
paint_point(0,i);
if(i%5==0&&i>0)
paint_point(1,i-1);
}
paint_point(1,62);
paint_point(1,61);
paint_point(2,61);
//显示x轴
for(i=0;i<128;i++)
{
paint_point(i,0);
if(i%5==0&&i>0)
paint_point(i-1,1);
}
paint_point(127,1);
paint_point(126,2);
paint_point(126,1);
while
(1)
{
for(i=2;i<125;i++)
{
a=adc_data_collect();
d=a/4;
yout=d;
paint_point(i,yout);
y_pre[i]=yout;//描点的同时记录下该点的纵坐标
}
delay_1ms(5000);
c=d*125/16;
A[0]=c/100+'0';
A[2]=c/10%10+'0';
A[3]=c%10+'0';
write_com(0x00);
i=0;
while(C[i]!
='\0')
write_dat(C[i++]);
write_com(0x85);
i=0;
while(A[i]!
='\0')
write_dat(A[i++]);
clear_lcd();
}
}
学生学习心得
做完这个设计,确实感触好多。
来就不那么简单了。
设计中一些地方花费的时间太长,原因就是我们没有深刻的想问题,没有对一些芯片参数,电路连接进行基础的实验,导致出现问题了,不会解决,不知道问题出现在哪,还有一点就是编程之前一定要把流程图写出来,反复推敲,程序不对,就去看流程图不要一直在那死抠程序。
今后做电路板,一定要做好基础实验和流程图这两个方面。
学生(签名):
年月日
诚信承诺
本人郑重声明所呈交的课程报告是本人在指导教师指导下进行的研究工作及取得的研究成果。
据我所知,除了文中特别加以标注的地方外,论文中不包含其他人已经发表或撰写过的研究成果。
与我一同工作的同学对本文研究所做的贡献均已在报告中作了明确的说明并表示谢意。
学生(签名):
任课
教师
评语
成绩评定:
任课教师(签名):
年月日