毕业设计论文基于CAN总线的温湿度及光感度测量.docx
《毕业设计论文基于CAN总线的温湿度及光感度测量.docx》由会员分享,可在线阅读,更多相关《毕业设计论文基于CAN总线的温湿度及光感度测量.docx(74页珍藏版)》请在冰豆网上搜索。
毕业设计论文基于CAN总线的温湿度及光感度测量
祝你成功
基于CAN总线的温湿度及光感度测量
摘要:
随着我国工业生产的发展和自动化程度的不断提高,迫切需要对各种生产过程中的物理量进行精确检测。
温度、湿度作为大多数生产过程中的重要物理量,对它们的精确检测和远传越来越受到人们重视。
因此,研制一种高精度、高稳定性、低成本的温湿度仪表将具有重要意义,必将拥有广阔的市场前景。
同时,由于工业现场对抗电磁干扰和传输距离有比较高的要求,所以本文设计了一种基于CAN(ControlAreaNetwork局域网控制)总线的远程实时温湿度数据采集系统。
该系统主要由两大模块构成,分别是数据现场采集模块、和显示处理模块。
本设计使用C语言进行了各个模块软件的设计,完成对传感器信号的处理和CAN模块报文的发送和接收。
关键词:
430CANDHT11温湿度光感度
1设计方案论证
1.1主控芯片选择
(1)用可编程逻辑器件设计。
可采用ALTERA公司的FLEX10K系列PLD器件。
设计起来结构清晰,各个模块,从硬件上设计起来相对简单,控制与显示的模块间的连接也会比较方便。
但是考虑到本设计的特点,EDA在功能扩展上比较受局限,而且EDA占用的资源也相对多一些。
从成本上来讲,用可编程逻辑器件来设计也没有什么优势。
(2)用MSP430F149作主控芯片,编程简单,功能丰富,速度很快,功耗很低。
因此选择430作为数据采集和显示处理的主控芯片。
2显示部分的方案选择
(1)数码管显示方式
采用八段数码管经济实惠,亮度高,对比度高,显示清晰;但操作很复杂,占用很多CPU时间。
(2)液晶显示方式
液晶显示效果出众,操作简单,输入完显示信息后不占用CPU时间,显示容量也大,因此采用1602液晶显示器。
3传感器选择
(1)采用DS18B20数字温度传感器,精度高,灵敏度高;但不能采集湿度信息;
(2)采用DHT11数字温度传感器,可同时测量温度和湿度,精度和灵敏度,转换速度也都能满足本次系统要求,而且DHT11采用单总线通信模式,占用IO口少。
因此选用DHT11数字温湿度传感器。
2系统设计
采用MSP430F149作为数据采集和接收处理显示模块的主控芯片,430和各种传感器通信读出各种测量参数,通过CAN控制器将信息发送到CAN总线上;数据接收模块从CAN总线上读取各种信息并通过显示模块显示出来。
3单元电路设计
3.1温湿度采集系统
由图2所示,温湿度数据采集模块的硬件由以下四部分构成:
传感器DHT11,微控制器MSP430F149,CAN控制器和CAN收发器。
微控制器MSP430F149主要负责对传感器输出的两路模拟信号进行循环采集并AD转换,SJAl000的初始化,通过控制JAl000实现数据的发送和接收。
SJAl000负责数据链路层的工作,把发送缓冲器的数据经过处理后送到TJAl050,信息经过处理后放到接收缓冲器等待微处理器的读取。
TJA1050提供SJA1000与物理总线之间的接口。
3.2数据处理显示模块
如图3所示TJA1050收发器将信号差分放大去除噪声后送给SJA1000控制器,控制器将接到的报文处理后提取数据给430,430将数据显示到1602显示器上。
4系统功能
本文设计的系统能实时测量远程温湿度及光强度。
测量范围:
温度0~50℃,湿度20~90%RH,光强1lx-65535lx;
分辨率:
温度1℃,湿度+/-2℃,光强1lx;
测量距离:
1km
5程序模块流程图
参考文献
[1]李正军编著.现场总线及其应用技术[M].北京机械工业出版社.2005.1
[2]任广永等.基于AT89C55和CAN总线的远程数据采集系统的设计[J].电脑学习.2007.2
[3]潘琢金,施国君.C8051FXXX高速SOC单片机原理及应用[M].北京:
北京航空航天大学出版社.2002
[4]吴文珍,韩玉祥,司光宇等.基于CAN总线智能检测仪的设计[D].大庆石油学院学报.2005,29(5)
[5]SJAl000独立CAN控制器数据手册.广州周立功单片机发展有限公司.
心得体会
谢广昊:
通过此次毕业设计,使我更加扎实的掌握了有关CAN总线方面的知识,在设计过程中虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足。
实践出真知,通过亲自动手制作,使我们掌握的知识不再是纸上谈兵。
过而能改,善莫大焉。
在毕业设计过程中,我们不断发现错误,不断改正,不断领悟,不断获取。
最终的检测调试环节,本身就是在践行“过而能改,善莫大焉”的知行观。
这次毕业设计终于顺利完成了,在设计中遇到了很多问题,最后在老师的指导下,终于游逆而解。
在今后社会的发展和学习实践过程中,一定要不懈努力,不能遇到问题就想到要退缩,一定要不厌其烦的发现问题所在,然后一一进行解决,只有这样,才能成功的做成想做的事,才能在今后的道路上劈荆斩棘,而不是知难而退,那样永远不可能收获成功,收获喜悦,也永远不可能得到社会及他人对你的认可!
马少波:
我认为,在这学期的实验中,不仅培养了独立思考、动手操作的能力,在各种其它能力上也都有了提高。
更重要的是,在实验课上,我们学会了很多学习的方法。
而这是日后最实用的,真的是受益匪浅。
要面对社会的挑战,只有不断的学习、实践,再学习、再实践。
这对于我们的将来也有很大的帮助。
以后,不管有多苦,我想我们都能变苦为乐,找寻有趣的事情,发现其中珍贵的事情。
就像中国提倡的艰苦奋斗一样,我们都可以在实验结束之后变的更加成熟,会面对需要面对的事情。
回顾起此毕业设计,至今我仍感慨颇多,从理论到实践,在这段日子里,可以说得是苦多于甜,但是可以学到很多很多的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。
通过这次毕业设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。
在设计的过程中遇到问题,可以说得是困难重重,但可喜的是最终都得到了解决。
张巨龙:
回顾起此次单片机毕业设计,至今我仍感慨颇多,的确,从选题到定稿,从理论到实践,在整整两星期的日子里,可以说得是苦多于甜,但是可以学到很多很多的的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。
通过这次毕业设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。
在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题。
最后在老师的辛勤指导下,终于游逆而解。
同时,在老师的身上我学得到很多实用的知识,在次我表示感谢!
同时,对给过我帮助的所有同学和各位指导老师再次表示忠心的感谢!
附录一
元件清单
器件
数量
MSP430F149芯片
2
SAJ1000CAN控制器
2
BH1750光强度传感器
1
DHT11温湿度传感器
1
1602液晶显示器
1
排线
5*8=40
排针
5*8=40
电阻2K
4
红色发光二级管
4
BUTTON(复位开关)
2
附录二
系统程序清单
Main.c
#include
#include"SJA1000.h"
#include"DHT11.h"
#include"BH1750.h"
#include"IIC.h"
//**************************精确延时**********************************
#defineCPU_F((double)8000000)
#definedelay_us(x)__delay_cycles((long)(CPU_F*(double)x/1000000.0))
#definedelay_ms(x)__delay_cycles((long)(CPU_F*(double)x/1000.0))
//********************************************************************
#defineuintunsignedint
#defineucharunsignedchar
#definercv_flag0x01//接收中断标志
#defineerr_flag0x02//错误中断标志
#defineOver_flag0x04//CAN总线超载标志
voidInit_BH1750();//BH1750初始化
voidSJA_Process(void);
voidinit_CPU(void);//初始化MSP430
ucharsend_flag=0;//CAN总线发送标志
unsignedcharCan_INT_DATA=0;//用于存储SJA1000的中断寄存器数据,430中不能位寻址
//--------------------------------------
ucharrcv_data[10];//接收数据数组
//--------------------------------------
voidmain(void)
{
WDTCTL=WDTPW+WDTHOLD;//Stopwatchdogtimertopreventtimeoutreset
ucharSJA_status;
init_CPU();//初始化MSP430
Init_BH1750();//初始化BH1750
do
{
delay_ms(10);//小延时
SJA_status=init_SJA1000();
}while(SJA_status);//初始化SJA1000
Can_INT_DATA=0;//CAN中断变量清零
delay_ms(1000);
_EINT();//开总中断
while
(1)
{
ucharRead_BUF[2]={0,0};//读回BH1750数据变量
read_TRH();//读取温湿度传感器
delay_ms(120);
Read_1Byte_currentaddress(Read_BUF);//读回BH1750数据
send_data[6]=Read_BUF[0];
send_data[7]=Read_BUF[1];
send_flag=1;
SJA_Process();//SJA最终处理
}
}
/********************************************
函数原型:
voidInit_BH1750();
函数功能:
BH1750初始化
*********************************************/
voidInit_BH1750()
{
Write_1Byte(0x01);//通电,等待测量指令
Write_1Byte(0x07);//通电后,重置数字寄存器
Write_1Byte(0x10);//连续H分辨率模式
}
/*********************************************************
函数功能:
SJA_1000最终处理函数
**********************************************************/
voidSJA_Process(void)
{
if((Can_INT_DATA&rcv_flag)==rcv_flag)//接收中断
{
Can_INT_DATA&=~rcv_flag;//清除接收标志位
SJA_rcv_data(rcv_data);//接收CAN总线数据到rcv_data数组
}
if(send_flag)//发送中断
{
send_flag=0;//清除发送标志位
SJA_send_data(send_data);//把send_data数组中数据写入到发送缓冲区
}
if((Can_INT_DATA&Over_flag)==Over_flag)//溢出中断
{
Can_INT_DATA&=~Over_flag;//清除溢出标志位
Can_DATA_OVER();
}
if((Can_INT_DATA&err_flag)==err_flag)//错误中断
{
Can_INT_DATA&=~err_flag;//清除错误标志位
Can_error();
}
}
/*********************************************************
函数功能:
初始化MSP430
**********************************************************/
voidinit_CPU(void)
{
/*下面六行程序关闭所有的IO口*/
P1DIR=0XFF;P1OUT=0XFF;
P2DIR=0XFF;P2OUT=0XFF;
P3DIR=0XFF;P3OUT=0XFF;
P4DIR=0XFF;P4OUT=0XFF;
P5DIR=0XFF;P5OUT=0XFF;
P6DIR=0XFF;P6OUT=0XFF;
//P6DIR|=BIT2;P6OUT&=~BIT2;//打开电平转换
//P2DIR|=BIT3;P2OUT&=~BIT3;//电平转换方向3.3V--->5V
//----------P1.7外部中断------------------//
P1DIR&=~BIT7;//设置P1.7为输入
P1IES|=BIT7;//设置为下降沿中断
P1IE|=BIT7;//允许P1.7中断
//-----------------------------------------//
//-----------切换时钟---------------------//
unsignedintj;
BCSCTL1&=~XT2OFF;//XT2on,maxRSEL
do
{
IFG1&=~OFIFG;
for(j=0xff;j>0;j--);
}
while(IFG1&OFIFG);
BCSCTL2|=SELS+DIVS_0;//SMCLK=XT2;SMCLK=8MHZ
BCSCTL2|=SELM_2+DIVM_0;//MCLK=XT2;MCLK=8MHZ
//--------------------------------------------*/
//----------------定时器设置-------------------//
/*TACCTL0=CCIE;//使能CCR0中断
CCR0=2048;//设定周期1S
TACTL=TASSEL_1+ID_3+MC_1;//定时器A的时钟源选择ACLK,增计数模式
_EINT();//开总中断*/
//---------------------------------------------//
}
#pragmavector=PORT1_VECTOR//P1口中断源
__interruptvoidP1_ISR(void)//中断名P1_ISR(void)
{
if(P1IFG&BIT7)
{
Can_INT_DATA=Read_Reg(INTERRUPT);
}
P1IFG=0;
}
SJA1000.c
#include
#include"SJA1000.h"
//**************************精确延时**********************************
#defineCPU_F((double)8000000)
#definedelay_us(x)__delay_cycles((long)(CPU_F*(double)x/1000000.0))
#definedelay_ms(x)__delay_cycles((long)(CPU_F*(double)x/1000.0))
//********************************************************************
ucharsend_data[10];//发送数据数组
/*********************************************************
函数原型:
unsignedcharRead_Reg(unsignedcharreg)
函数功能:
读取SJA1000寄存器中的值
参数说明:
reg:
寄存器地址
**********************************************************/
unsignedcharRead_Reg(unsignedcharreg)
{
unsignedcharReg_Data;
C_ALE;
S_RD;
S_WR;
S_CS;
S_ALE;
_NOP();
PortDIR=0xff;
//P2OUT&=~BIT3;//电平转换方向3.3V--->5V
PortOUT=reg;
_NOP();
C_ALE;
_NOP();
C_CS;
_NOP();
C_RD;
_NOP();_NOP();
//P2OUT|=BIT3;//电平转换方向5V--->3.3V
PortDIR=0x00;
Reg_Data=PortIN;
S_RD;
_NOP();
S_CS;
returnReg_Data;
}
/*********************************************************
函数原型:
voidWrite_Reg(unsignedcharreg,unsignedcharreg_data)
函数功能:
向SJA1000寄存器中写值
参数说明:
reg:
寄存器地址
reg_data:
要写入的值
**********************************************************/
voidWrite_Reg(unsignedcharreg,unsignedcharreg_data)
{
C_ALE;
S_CS;
S_RD;
S_WR;
S_ALE;
_NOP();
//P2OUT&=~BIT3;//电平转换方向3.3V--->5V
PortDIR=0xff;
PortOUT=reg;
_NOP();
C_ALE;
_NOP();
C_CS;
_NOP();
C_WR;
_NOP();
PortOUT=reg_data;
_NOP();
_NOP();
S_WR;
_NOP();
S_CS;
_NOP();
_NOP();
S_ALE;
}
/*********************************************************
函数原型:
charcreate_communication(void)
函数功能:
用于SJA1000在复位模式下,检测CAN控制器SJA1000的通信是否正常,只用于产品
的测试,如果在正常模式下使用这个寄存器进行测试,将导致设备不可预测的结果。
返回值说明:
0:
表示SJA1000建立通信正常
1:
表示SJA1000与处理器通信异常
**********************************************************/
charcreate_communication(void)
{
Write_Reg(TEST,0xaa);//向TEST寄存器中写入0xaa
if(Read_Reg(TEST)==0xaa)
{return0;}//读测试正确
else
{return1;}
}
/*********************************************************
函数原型:
charenter_RST(void)
函数功能:
用于SJA1000进入复位工作模式
返回值说明:
0:
表示SJA1000成功进入复位工作模式
1:
表示SJA1000进入复位模式失败
**********************************************************/
charenter_RST(void)
{
unsignedcharMID_DATA;//定义一个字节变量,用于存储从SJA1000控制寄存器读出的数据
MID_DATA=Read_Reg(CONTROL);//访问SJA1000控制寄存器,保存原始值
Write_Reg(CONTROL,MID_DATA|0x01);//置位复位请求
if((Read_Reg(CONTROL)&0x01)==1)//读SJA1000的控制寄存器数值,判断复位请求是否有效
{return0;}//表示SJA1000成功进入复位工作模式
else
{return1;}
}
/*********************************************************
函数原型:
charquit_RST(void)
函数功能:
用于SJA1000退出复位工作模式
返回值说明:
0:
表示SJA1000成功退出复位工作模式
1:
表示SJA1000退出复位模式失败
**********************************************************/
charquit_RST(void)
{
unsignedcharMID_DATA;//定义一个字节变量,用于存储从SJA1000控制寄存器读出的数据
MID_DATA=Read_Reg(CONTROL);//访问SJA1000控制寄存器,保存原始值
Write_Reg(CONTROL,MID_DATA&0xfe);//置位复位请求
if((Read_Reg(CONTROL)&0x01)==0)//读SJA1000的控制寄存