2017届大作业论文
《Proteus原理图设计与电路仿真》
作业论文
学生姓名杨静
学号5011213318
所属学院信息工程学院
专业计算机科学与技术
班级17-3班
指导教师孟洪兵
教师职称讲师
塔里木大学教务处制
目录
前言-------------------------------------------------------------------- 1 1.1背景和意义----------------------------------------------------------- 1 正文-------------------------------------------------------------------- 1 2.1设计的目的和意义----------------------------------------------------- 1 2.2目标与总体方案------------------------------------------------------- 1
2.2.1目标----------------------------------------------------------- 1
2.2.2总体方案------------------------------------------------------- 1 2.3设计方法和内容------------------------------------------------------- 1
2.3.1硬件电路构成--------------------------------------------------- 1
2.3.2软件环境说明--------------------------------------------------- 2
2.3.3设计流程图----------------------------------------------------- 2
图2系统设计流程图--------------------------------------------------- 2
2.3.4设计内容------------------------------------------------------- 2 2.4设计创新与关键技术--------------------------------------------------- 3
2.4.1设计特点与难点------------------------------------------------- 3
2.4.2调试结果------------------------------------------------------- 3
2.4.3结果分析------------------------------------------------------- 4 2.5结论----------------------------------------------------------------- 4 致谢-------------------------------------------------------------------- 5 参考文献---------------------------------------------------------------- 5 附录-------------------------------------------------------------------- 5
前言
1.1背景和意义
随着生活条件的不断改善,人们更关注自身的健康,绿色蔬菜尤其受到重视。大棚种植充分满足了人们的需求,但对于和农作物生长密切相关的大棚温度的控制。对于大棚种植而言,良好的物种、本地适合种植的物种及土地酸碱度都是可以通过农民长期的种植经验获得的。但是温度是农民不能轻易解决的问题,而且温度的变化幅度大,不易人工控制,对于农民来说时刻关注作物的生长温度是个庞大的工作量。所以研究应用于大棚种植的温度控制系统解决了长期以来困扰农民的问题,它的制作成本低廉,应用广泛,对农民自身的素质要求不高,便于农民操作。更重要的是,它不仅帮助农民节约了大量的时间,还在无形之中提高了作物的产量,增加了农民的收入,满足了人们对大棚蔬菜的需求。基于单片机的大棚温度控制系统是个小型的软硬件结合的产品,它针对个体农民的需要设计,适于中小面积的大棚种植。
正文
2.1设计的目的和意义
随着单片机和传感技术的迅速发展,自动检测领域发生了巨大变化,温室环境自动监测控制方面的研究有了明显的进展,并且必将以其优异的性能价格比,逐步取代传统的温度控制措施.但是,目前应用于温室大棚的温度检测系统大多采用模拟温度传感器、多路模拟开关、A/D转换器及单片机等组成的传输系统。这种温湿度度采集系统需要在温室大棚内布置大量的测温电缆,才能把现场传感器的信号送到采集卡上,安装和拆卸繁杂,成本也高。同时线路上传送的是模拟信号,易受干扰和损耗,测量误差也比较大。为了克服这些缺点,本文参考了一种基于单片机并采用数字化单总线技术的温度测控系统应用于温室大棚的的设计方案。
本文介绍的温度测控系统就是基于单总线技术及其器件组建的。该系统能够对大棚内的温度进行采集,利用温度传感器将温室大棚内温度的变化,变换成数字量,其值由单片机处理,最后由单片机去控制液晶显示器,显示温室大棚内的实际温湿度,同时通过与预设量比较,对大棚内的温度进行自动调节。这种设计方案实现了温度实时测量、显示和控制。该系统抗干扰能力强,具有较高的测量精度,不需要任何固定网络的支持,安装简单方便,性价比高,可维护性好。这种温度测控系统可应用于农业生产的温室大棚,实现对温度的实时控制,是一种比较智能、经济的方案,适于大力推广,以便促进农作物的生长,从而提高温室大棚的亩产量,以带来很好的经济效益。
2.2目标与总体方案
2.2.1目标
希望通过自己的学习,利用AT89C51、DS18B20、LCD1602、步进电机、ULN2003A、I2C总线完成温度的测量、显示及其控制。
2.2.2总体方案
首先根据要设计的温度控制系统将其分为五个模块,然后根据每一个模块的不同特点,选择各自的芯片,通过查阅资料掌握其功能,并通过keil软件实现代码的编程、在proteus中绘制电路图,最后将图和代码相结合,并完成测试。
2.3设计方法和内容
2.3.1硬件电路构成
图1系统整体框图
2.3.2软件环境说明
采用的编程软件是keil软件,Keil是美国Keil Software公司出品的51系列兼容单片机C 语言软件开发系统。Keil提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(uVision)将这些部分组合在一起。首先安装keil,安装完成后,打开keil新建工程、新建文件,利用所学的C语言知识及单片机编程原理,进行各模块代码的编程,最后将软硬件结合,完成系统的集成。
2.3.3设计流程图
图2系统设计流程图
2.3.4设计内容
1.DS18B20
1>.DS18B20简介
DS18B20数字温度传感器采用DS18B20可组网数字温度传感器芯片封装而成,具有耐磨耐碰,体积小,使用方便,封装形式多样等优点,适用于各种狭小空间设备数字测温和控制领域。
2>. DS18B20的使用
DS18B20对时序的要求比较高,首先进行的是初始化,主要是检测DS18B20是否存在,主机总线在to时刻发送一复位脉冲(最短为480us的低电平信号)接着在tl时刻释放总线并进入接收状态DSl820在检测到总线的上升沿之后等待15-60us接着DS1820在t2时刻发出存在脉冲(低电平持续60-240 us),当检测到DS18B0存在后,主机发出ROM操作,主要执行的是Skip ROM(跳过ROM)——[CCH] ,之后便是RAM操作,主要执行Read Scratchpad(读暂存存储器)——[BEH] 和Convert Temperature(温度变换) ——[44H],最后进行数据的处理,所需要掌握和书写的函数是初始化函数——写数据函数——读数据函数——读温度的函数,而DS18B20的每一次操作都必须经过初始化(代码见附录1)。
2.LCD1602
1>.LCD1602简介
LCD1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用。
2>.LCD1602的使用
LCD1602主要用于显示测量的温度,所需要掌握和书写的函数是忙检测——写指令——写数据——初始化——显示指令和数据(代码见附录1)。
3.24C02
1>.24C02简介
24C02是电可檫除PROM,采用256x8-bit的组织结构以及两线串行接口。电压可允许地址1.8v,待机电流和工作电流分别为1uA和1mA,24C02具有页写能力,每页为8字节。
2>.24C02使用
24C02支持I2C总线传输协议。I2C是一种双向、两线串行通讯接口,分别是串行数据线SDA串行时钟线SCL。所需要掌握和书写的函数是开始函数——停止函数——检测应答函数——写I2C函数——读I2C函数——向24c02写入数据函数——从24C02读出数据函数(代码见附录2)。
4.步进电机
1>.步进电机简介
该系统使用的步进电机为一四相步进电机,采用单极性直流电源供电,只要对步进电机的各相绕组按合适的时序通电,就能使步进电机步进转动。四相步进电机按照通电顺序的不同,可分为单四拍、双四拍、八拍三种工作方式。单四拍与双四拍的步距角相等,但单四拍的转动力矩小。八拍工作方式的步距角是单四拍与双四拍的一半,因此,八拍工作方式既可以保持较高的转动力矩又可以提高控制精度。
2>.步进电机使用
本系统采用的是八拍的工作方式以提高控制精度,所需要掌握和书写的函数是步进电机的正转和反转函数及步进电机的转速设置函数(代码见附录3)。
2.4设计创新与关键技术
2.4.1设计特点与难点
1.设计特点:
主要利用了单片机体积小、功耗低、价格低廉、抗干扰能力强且可靠性高等特点,及DS18B20对温度测量的方便性、LCD1602的显示功能等特点,将温度的测量进行数字化的转变,而且通过对步进电机的控制使系统功能得到了完善,方便用于实际应用中。
2.设计难点:
主要是软件的设计,对各个模块的芯片选择,还有芯片的功能掌握是此次设计的重点难点,只要熟悉和掌握了芯片的工作原理及特点,编出代码,硬件设计相对而言比较简单,我觉得最难的模块是温度的测量和显示比较难以掌握,但只要细心研究还是会取的成功的。
2.4.2调试结果
图3电路原理图
2.4.3结果分析
先在24C02中存入数字0x10和0x0f,在经过DS18B20测量温度,所测量的温度在LCD602液晶屏上显示,当DS18B20测得温度达到这两个值时控制步进电机运转,当值小于0x10时步进电机正转,当值大于0x0f时步进电机反转,以上软件和硬件设计基本上实现了此项操作。
2.5结论
经过长达两周的课程设计,我基本上完成了此次设计所要求的内容,而本系统主要是进行测温和控制,当温度过高或过低时,控制步进电机进行工作。改进的地方,可以对步进电机的控制加以修改,当温度超过设定温度时,温度每增加(减少)五度或其它温度,步进电机的速度相应的增加或减少。对此设计系统的意见,可以加入对湿度的测量,可以更好地运用与实际生活中,增加运用
的范围。
致谢
经过两个星期的努力,大三也接近了尾声,回头看看自己的作业设计,感触颇深。通过此次作业设计,掌握了单片机的基本使用方法,提高了自身学习的效率,发展了个人思维,还培养了我主动学习的能力。
在本次作业设计的过程中,我感觉到自己知识、技能的不断增加,在作业分析及设计的时候,有时候自己的考虑还很不周全,但通过与同学和老师进行沟通后一般都能找到更好的设计方法,有时候学会的一个小技巧可以使我的付出达到事半功倍的效果,致使我按时完成了本次课程设计。在设计的过程中我也积累了不少的经验,在硬件设计和软件编程方面都取得了一定的进步。设计的时候,在借鉴别人的创意的时候也要将自己的设计思想融入其中,在大多情况下他人的设计并不一定完美,我们不能因为别人的设计方法而局限了自己的思想。因此我坚持设计一定要有新思想,在参考他人的设计方法时也要求有灵活的变动性和接受能力。总体来说这次的作业设计使我的综合素质得到了锻炼和提高。
此次作业设计进行了两个星期,在这两个星期中,我在完成的过程中发现了知识灵活应用的重要性,感谢在此次作业设计中帮助我解决问题的老师和同学,在你们的的帮助下我很好的完成了本次的课程设计。
参考文献
[1]孙育才.《单片微型计算机及其应用》.东南大学出版社.2004 .[6]阎石.数字电子技
术基础(第三版).北京:高等教育出版社
[2]沈德金,陈粤初.《单片机接口电路与应用程序实例》.北京航天航空大学出版
社.1990.
[3]LCD1602液晶完整中文资料.pdf
[4]李朝青.单片机原理及接口技术(简明修订版).杭州:北京航空航天大学出版社,
1998 .
[5]李广弟.单片机基础[M].北京:北京航空航天大学出版社,1994.
[624C02中文资料.pdf
[7]24c02中文资料1.pdf
[8]DS18B20中文资料.pdf
[9] MAXIM NEW Releases Data Book. volum 1998.
[10] omas https://www.doczj.com/doc/d69479516.html,puter Architecture and Logic Design[J].McGraw-Hil
l Inc.1991.9.
[11]DS18b20数据手册。
[12] 求是科技编著8051系列单片机C程序设计完全手册北京: 人民邮电出版社, 2006.
[13] 余发山,王福忠.单片机原理及应用技术.徐州:中国矿业大学出版社,2003.
[14]贾好来.MCS-51单片机原理及应用.北京:机械工业出版社,2007.
附录
#include
#include
#define uint unsigned int
#define uchar unsigned char
#define LCD_DB P0
#define uchar unsigned char //定义一下方便使用
#define uint unsigned int
#define ulong unsigned long
#define WriteDeviceAddress 0xa0 //定义器件在IIC 总线中的地址
#define ReadDviceAddress 0xa1
void save();
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_E=P2^2;
void LCD_init(void);//初始化函数
void LCD_write(unsigned char dat);//写指令函数
void LCD_write_data(unsigned char dat);//写数据函数
void LCD_disp_char(unsigned char x,unsigned char y,unsigned char dat);//在某个屏幕位置上显示一个字符,X(0-16),y(1-2)
//void LCD_check_busy(void);//检查忙函数。我没用到此函数,因为通过率极低。
void delay_n40us(int n);//延时函数
void LED_show(unsigned char x,unsigned char y,unsigned char z);
int bu(int a);
uchar i,j,a;
uchar code TAB[9]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};
uchar code TAB1[9]={0x01,0x09,0x08,0x0c,0x04,0x06,0x02,0x03};
char code dx516[3] _at_ 0x003b;//这是为了仿真设置的
void Start();
void DelayMs(uint number) ;
void Stop() ;
bit TestAck() ;
void NoAck() ;
void delete();
void Write8Bit(uchar input);
uchar read8Bit();
void Write24c02(uchar ch,uchar address);
uchar read24c02(uchar ch);
sbit SCL=P2^6;
sbit SDA=P2^7;
uchar read8bit();
sbit P10=P1^0;
uchar Ltem,Ttem;
unsigned char tmp_h,tmp_l;
//
sbit DQ = P2^3;
unsigned char tmp_h,tmp;
bit flag = 0;_l;
void init18b20();
void L18b20open();
void write_ROM(unsigned char instr);
void write_inst(unsigned char instr);
char read_20();
void delayms1(int num);
void main()
{
unsigned char str[]={"+00.0"};
LCD_init(); //lcd初始化
// P1_0=1;
save();
while(1)
{
L18b20open();
str[1] = tmp_h/10 + 48;
str[2] = tmp_h%10 + 48;
str[4] = tmp_l/10 + 48;
if(flag==0)
str[0] = '-';
else
str[0] = '+';
LED_show(1,1,str[0]);
LED_show(2,1,str[1]);
LED_show(3,1,str[2]);
LED_show(4,1,str[3]);
LED_show(5,1,str[4]);
// 步进电机转动
if(tmp_h>=Ltem&&tmp_h<=Ttem)
{
bu(2);
}
else if(tmp_h>=Ttem)
{
bu(0);
}
else
{
bu(1);
}
}
}
//延时函数————————————————————————————————————————————
void delay(unsigned int i){
while(i--);
}
void delayms1(int num){
int i;
for(;num>0;num--)
{ for(i=0;i<124;i++)
{;}
}
}
//初始化——————————————————————————————————————————————
void init18b20()
{
uint i;
//int judge;
DQ = 0;
i=100; //可以不写
while(i>0) i--;
DQ = 1;
i=4;
while(i>0) i--; //主机总线to时刻发送一复位脉冲(最短为480us的低电平信号)此延时略微延时约600微秒//在t1时刻释放总线进入接收状态
//18b20在检测到总线的上升沿之后,等待15-60us 此延时约为30us
while(DQ); //18b20在t2时刻发送从在脉冲(低电平,持续为存在脉冲输出时间60-240us)判断是否为低电平
while(~DQ);
i=4;
while(i>0) i--;
}
//写函数——————————————————————————————————————————————
void write_inst(unsigned char instr)
{
int i;
for(i=0;i<8;i++)
{
DQ = 0; //在t0时刻从高拉至低电平,产生写时间间隙(由c51拉低原来为高电平)
DQ = instr & 0x01; // 从t0时刻开始15us之内讲所需要写的位送到总线(DQ)上,
delay(4); //18B20在15-60us间对总线采样(也就是这里的延时45us)采样结果中
如果为高电平则写入的位为一反之
DQ = 1; // 主机重新将总线DQ制1 为下次写入总线做准备
delay(1);//连续写入2位间的间隙应该大于1us。
instr >>= 1; //数据右移一位为下次数据传入做准备(数据的写入是从低位开始的所以要从地位读入)
}
delay(1);//不确定是否需要
}
//读函数——————————————————————————————————————————————
char read_20()
{
unsigned char i = 0, read_Dt=0;
for(i=0;i<8;i++)
{
DQ = 0; // 主机总线t0时刻从高拉到低电平总线必须保持低电平17ts,
read_Dt >>= 1;
_nop_(); //总线必须保持低电平17ts,
DQ = 1; //之后在t1时刻将总线拉高,产生读时间隙,读时间在t1时刻到t2时刻前有效,t2距离t1为15us
if(DQ==1) //此时主机开始从总线中读出最低位一次读一位如果为1则运行if
read_Dt |= 0x80;
delay(4); //释放总线
//有点乱
}
return read_Dt;
}
void L18b20open()
{
unsigned char temp1=0,temp2=0,low=0,tall=0,pri=0;
init18b20();//初始化并判断
write_inst(0xcc); //跳过ROM 只有一个18b20 不用验证
write_inst(0x44); //发送启动温度转换指令//分别在ROM和内存中写入两条指令
delayms1(50); //延时50ms 每次执行完读写指令后都要初始化
init18b20() ;
write_inst(0xcc);
write_inst(0xbe); // 读取暂存器内容(内存中)
temp1 = read_20();//先接收低八位数据其中高四位为整数部分低四位小数部分
temp2 = read_20(); //再接收高八位数据其中高四位为s 低四位中有1位为符号为另外3位为温度数值
if(temp2 & 0x80) //负温度
{
flag = 0;
low = temp1 >> 4;
tall = temp2 << 4;
pri = low | tall;//取反后加1
tmp_h = ~pri;
low = ( ~temp1+1) ; //16位数据的低8位取反加1 后取低4位位小数部分
tmp_l = (float)(low & 0x0f)*6.25f;
}
else //正温度
{
flag = 1;
low = temp1 >> 4; //取出整数部分的低四位
tall = temp2 << 4; //取出整数部分的高四位
pri = low | tall;
tmp_h = pri;
tmp_l = (float)(temp1 & 0x0f)*6.25f; //w0 & 0x0f 取低4位*6.25 扩大10倍}
}
//2402c
//定时函数
void DelayMs(uint number)
{
uchar temp;
for(;number!=0;number--)
{
for(temp=112;temp!=0;temp--) ;
}
}
//开始总线
void Start()
{
SDA=1;
SCL=1;
SDA=0;
SCL=0;
}
//结束总线
void Stop()
{
SCL=0;
SDA=0;
SCL=1;
SDA=1;
}
//测试ACK //测试应答信号
bit TestAck()
{
bit ErrorBit;
SDA=1; //防止1干扰
SCL=1; //拉高传输数据
ErrorBit=SDA; //判断是否产生应答信号SDA已拉低
SCL=0; //为下一次做准备
return(ErrorBit);
}
void NoAck()
{
SDA=1;
SCL=1;
SCL=0;
}
void delete()
{
int i;
for(i=1;i<=9;i++)
{
SDA=1;
SCL=1;
}
}
//写入8 个bit 到24c02
void Write8Bit(uchar input)
{
uchar temp;
for(temp=8;temp!=0;temp--)
{
SDA=(bit)(input&0x80);
SCL=1; //拉高存入数据//写入时一位一位写入高位SCL=0; //准备下一次//读出时一位一位从高位读出input=input<<1;
}
}
uchar read8Bit()
{
uchar a=0;
int i;
for(i=0;i<8;i++)
{
// SCL=1;
a=a<<1;
a=a|((unsigned char)(SDA));
SCL=1; //拉高存入数据
SCL=0;
}
return a;
}
//写入一个字节到24c02 中
塔里木大学信息工程学院课程设计void Write24c02(uchar ch,uchar address)
{
Start();
Write8Bit(WriteDeviceAddress);
TestAck();
Write8Bit(address);
TestAck();
Write8Bit(ch);
TestAck();
Stop();
DelayMs(10);
}
uchar read24c02(uchar ch)
{
uchar c;
Start();
Write8Bit(WriteDeviceAddress);
TestAck();
Write8Bit(ch);
TestAck();
Start();
Write8Bit(ReadDviceAddress);
TestAck();
c=read8Bit();
NoAck();
Stop();
return c;
}
//本课试验写入一个字节到24c02 中
void save()// 主程序
{
Write24c02(0x05,0x00);// 将0x05 写入到24c02 的第0 个地址空间存入温度
Ltem=read24c02(0x00); //读出低温
Write24c02(0x14,0x01);
Ttem=read24c02(0x01); //读出高温
}
//bujin
void Delay()
{
uchar k=65535;
uint s;
do
{
for( s = 0;s < 100;s ++);
}while(--k);
}
int speed(int i){
uchar speed=100;
if(i==1){
speed++;
}else{
speed--;
}
}
int bu(int a){
P1=0x0f;
if(a==0){
for(i=0;i<9;i++){
P1=TAB[i];
speed();
Delay();
}
}else if(a==1){
for(i=0;i<9;i++){
P1=TAB1[i];
speed();
Delay();
}
}
else{
P1=0xa0;
//speed=0;
}
}
//lcd
void LCD_write(unsigned char dat) //写指令
{
LCD_DB = dat;//指令放引角上
LCD_RS = 0; // 指令输入
LCD_RW = 0; // 向LCD写入指令或数据
LCD_E = 1;//给一个下降沿只想指令
LCD_E = 0;
delay_n40us(1);// 循环一次完成写指令
}
void LCD_Write_data(unsigned char dat) //将数据输入{
LCD_DB = dat;
LCD_RS = 1;//1写入数据0写入指令
LCD_RW = 0;// 向LCD写入指令或数据
LCD_E = 1;
LCD_E = 0;
delay_n40us(1);
}
void LCD_init ()
{
LCD_write(0x38); //设置8位格式,2行,5x7 6号
LCD_write(0x0d);//整体显示,关光标,不闪耀4号
LCD_write(0x06);// 新数据输入后光标右移写入新数据后屏幕不动3号
LCD_write(0x01);//清除屏幕上的显示
delay_n40us(100);//至少40us
}
void LCD_disp_char(unsigned char x,unsigned char y,unsigned char dat)
{
unsigned char address;
if(y == 1) //在第一行显示
{
address = 0x80+x;
}
else
{
address = 0xc0+x; //在第二行显示
}
LCD_write(address); // 写入的所在行位置地址指令写入LCD中LCD_Write_data(dat);
}
void delay_n40us(int n){ //1就是延迟40us
int i,j;
for(i= n;i>0;i--)
for(j=0;j<2;j++);
}
void LED_show(unsigned char x,unsigned char y,unsigned char z)
{
LCD_disp_char(x,y,z);
}