收藏 分销(赏)

基于嵌入式Linux的温度采集系统的设计与实现.docx

上传人:二*** 文档编号:4514452 上传时间:2024-09-26 格式:DOCX 页数:29 大小:354.17KB 下载积分:5 金币
下载 相关 举报
基于嵌入式Linux的温度采集系统的设计与实现.docx_第1页
第1页 / 共29页
本文档共29页,全文阅读请下载到手机保存,查看更方便
资源描述
. 课 程 设 计 论文题目 基于嵌入式Linux的温度采集系统 的设计与实现 学 院 专 业 班 级 学 号 学生姓名 指导教师 完成时间 2016 年 5 月   精品word文档 . 摘要 数据采集系统是信息科学的一个重要分支,它研究信息数据的采集、存储、处理以及控制等。本文提出采用嵌入式Linux作为操作系统,针对三星公司的S5PV210嵌入式处理器,设计一个嵌入式温度采集系统。论文在分析了Linux设备驱动程序的基本工作原理基础上,讨论了开发中经常会碰到的中断处理、拥塞处理、I/O端口,并在此基础上实现了基于S5PV210嵌入式处理器的开、读、写、关外部RAM的字符设备驱动和网络驱动。结合高精度温度传感器DS18B20,实现温度的正确采集,并通过以太网络将数据上传给上位服务器。 论文首先介绍了通信网络中各种设备特性、总线结构及传输技术,然后介绍根据单片机与PC机之间的串行通信原理,用ubantu完成数据采集系统的软件设计与实现,为用户提供一个友好的人机界面,对采集系统进行控制并显示采集后的数据。使用串口线传输数据,为数据采集系统和计算机之间的通讯开辟了新的道路。 关键词:数据采集系统;以太网络;S5PV210;DS18B20 精品word文档 . I Design and Implementation of an Embedded Temperature Acquisition System based on Linux Abstract Data Acquisition System is an important branch of information science, it studies the collection, storage, processing and control of information data. In this paper, the embedded Linux is used as the operating system, and the embedded S5PV210 processor is designed to design an embedded temperature acquisition system. Based on the analysis of the Linux device driver based on the basic working principle discussed development often encounter interruption congestion handling, processing, I / O ports, and on this basis, realized s5pv210 embedded processor open, read, write, outside the ram of the character set by driver and the network drive on. Combined with the high precision temperature sensor DS18B20, to achieve the correct temperature collection, and through the Ethernet network to upload data to the host server. At first, the paper introduces the communication network characteristics of various devices, bus structure and transmission technology, and then introduce according to the principle of serial communication between MCU and PC, ubantu completed software design and implementation of data acquisition system, to provide users with a friendly man-machine interface, to control the acquisition system and display after the collection of the data. The use of serial data transmission, for the data acquisition system and the communication between the computer has opened up a new path. Key words: Data acquisition system; Ethernet; S5PV210; DS18B20 精品word文档 . 目录 第一章 需求分析 1 1.1 总体设计 1 1.2 客户端界面设计(app:Linux_client) 1 1.3 服务器设计(linux) 1 1.4 硬件设计 2 第二章 详细设计 3 2.1 代码调用过程 3 2.2 文件IO (系统库函数) 3 2.3 网络编程 4 2.4 内核驱动开发:(模块编程) 6 2.5 注册字符设备驱动 7 2.6 操作硬件的过程:(裸奔代码) 8 第三章 测试过程 10 3.1 测试 10 第四章 项目拓展 11 4.1 项目拓展 11 附录 12 总结 23 精品word文档 . 精品word文档 . 第一章 需求分析 1.1 总体设计 图1-1 总体设计图 1.2 客户端界面设计(app:Linux_client) 1. 作为用户操作的简单界面 2. 用于发送命令控制硬件 3. 接收server传输的数据 4. 显示数据。 1.3 服务器设计(linux) 1. 用于接收(app)客户端发送的命令 2. 处理命令 3. 转发给硬件 4. 读取硬件传输数据 5. 把数据传回(app)客户端 精品word文档 . 1.4 硬件设计 1. Led灯 点亮灯:led1、led2。 2. 温度传感器 把温度数据读取到客户端。 3.蜂鸣器 用于报警以及音乐播放。 精品word文档 . 第二章 详细设计 2.1 代码调用过程 代码调用过程如图所示: 图2-1 代码调用图 分析代码调用过程: 0. 准备工作: 1. 先调用insmodled.ko插入模块 2. register_chrdev注册字符设备驱动 1. App: fd = open("/dev/led",O_RDONLY); 2. drivers: 2. sys_open("/dev/led",O_RDONLY) 3.由内核为我们匹配,看是否能够找到设备号为249的led-drivers 4.如果匹配成功,继续找到structfile_operationsled_fops结构体 5.通过结构体找到 open函数的入口led_fops.open 6.led_open 7.arm_init 2.2 文件IO (系统库函数) 精品word文档 . 1. Open 打开文件 返回一个文件描述符 2. Read 通过文件描述符fd,读取文件 3. Write 通过文件描述符fd,写文件 4. Close (进程结束的时候,会自动关闭,可以不必显示的调用close) 阻塞:poll机制解决 客户端如果要接收服务器回发的数据,则需要读取网络套接字,此时,客户端涉及到读终端和读服务器,而读终端和读服务器都是会阻塞的,所以调用poll机制解决。 int poll(structpollfd *fds, nfds_tnfds, int timeout); 功能:把所关心的文件描述符加入到structpollfd结构中,告诉内核我要非阻塞的读这个文件描述符,内核为我们判断,如果不阻塞,则相应的状态, 参数1 : structpollfd { intfd; /*所关心的文件描述符 */ short events; /* 告诉内核我要做什么:POLLIN:非阻塞的读*/ short revents; /*内核返回的状态 */ }; 参数2: 关心的描述符的个数 参数3:愿意等待多长时间 -1 : 一直等待 > 0 : 表示愿意等待的时间 返回值: 大于0 :表示至少有一个已经成功返回 == 0 : 表示超时 < 0 :  表示失败 2.3 网络编程 TCP(即传输控制协议):是一种面向连接的传输层协议,它能提供高可靠性通信(即数据无误、数据无丢失、数据无失序、数据无重复到达的通信)。 适用情况: 1.适合于对传输质量要求较高,以及传输大量数据的通信。 2.在需要可靠数据传输的场合,通常使用TCP协议 3.MSN/QQ等即时通讯软件的用户登录账户管理相关的功能通常采用TCP协议 项目需求: 1. Linux平台下 精品word文档 . a) 服务器(server) i. 等待连接客户端 ii. 接收客户端发送的数据[字符串和文件] iii. 处理客户端发送的数据和命令 iv. 发送处理结果给客户端 b) 客户端 i. 简单的界面 ii. 从键盘接收用户输入命令 iii. 发送数据或者命令给服务器 iv. 接收服务器返回的结果 c) 协议:tcp 2. 实现编程 a) TCP四次握手协议 b) TCP编程模型 图2-2 TCP编程模型图 3. 网络编程所需要的API函数 a) 服务器 i. Socket ii. Bind iii. Listen iv. Accept v. Read/read vi. Close b) 客户端 i. Socket ii. Connect iii. Read/read 精品word文档 . iv. Close 通用地址结构 structsockaddr { u_shortsa_family; // 地址族, AF_xxx char sa_data[14]; // 14字节协议地址 }; Internet协议地址结构 structsockaddr_in { sa_family_tsin_family; /*地址族: AF_INET */ in_port_tsin_port; /*端口号*/ structin_addrsin_addr; /* IPV4地址internet address */ }; /* IPv4地址结构*/ structin_addr { uint32_t s_addr; /* address in network byte order */ }; 2.4 内核驱动开发:(模块编程) 1. 模块入口moude_init 2. 模块出口module_exit 3. 语法 : c语言 4. 编译(Makefile) a) make install b) make c) cpled.ko /opt/filesystem/test 5. 执行: 驱动模块后缀:led.ko a) 插入内核: insmodled.ko b) 查看模块:lsmod c) 移除模块:rmmod led 精品word文档 . 2.5 注册字符设备驱动 static inline intregister_chrdev(unsigned int major, const char *name, conststructfile_operations *fops) 功能:把设备注册,添加到字符设备的表格中 图2-3 字符设备驱动图 insmodled.ko调用内核驱动模块注册设备到内核字符设备管理注册表中 精品word文档 . 图2-4 打开文件设备过程图 2.6 操作硬件的过程:(裸奔代码) 1. 找到外设(led),分析外设功能 a) 原厂提供 b) Google ,baidu 2. led原理图 图2-5 led点灯流程图 操作led的GPIO控制器,主要有以下两个: 精品word文档 . GPC0CON : 用于控制GPIO引脚输入还是输出 GPC0CON[32] LED1 ->GPC0CON[3] -> [15-12] --> 0001 = Output LED2 ->GPC0CON[4] -> [19-16] --> 0001 = Output GPC0DAT : 用于设置电平的高低 GPC0DAT[3] -->GPC0CON[15-12] àled1 à亮 ->高电平1 GPC0DAT[4] -->GPC0CON[19-16] àled2 ->灭 ->低电平 0 Led: GPC0CON寄存器地址0xE0200060 #define GPC0CON (*(volitale unsigned long *)0xE0200060) GPC0DAT 寄存器地址0xE0200064 #define GPC0DAT (*(volitale unsigned long *)0xE0200064) MMU 当开启了MMU之后,我们是不能直接访问到物理地址的。需要通过ioreamp把物 理地址映射为虚拟地址,我们只能通过虚拟地址操作硬件 Virt = ioremap(phy); intstrncasecmp(const char *s1, const char *s2, size_t n); 比较字符s1和s2的前n个字符是否相等,如果相等,则返回0 5. 裸奔代码操作硬件过程 图2-6 操作硬件流程图 精品word文档 . 第三章 测试过程 3.1 测试 1.用户登录 输入用户名和密码进行校验 2.登录成功进入到用户操作界面(如图3-1所示) 输入要控制硬件的命令:如:打开led1,则输入on1 关闭led1,则输入off1 打开音乐播放器,则输入song 获取温度,则输入get …… 退出,则输入quit 图3-1 用户操作界面 精品word文档 . 第四章 项目拓展 4.1 项目拓展 目前本项目实现了通过客户端操作硬件,实现了点亮灯/蜂鸣器报警/音乐播放/温度数据采集功能。除用于温度监测外,在系统中的ARM外围可接入控制电路、其他性能的传感器甚至摄像头等,还可以实现多种其他特殊需要的远程监测及控制,如水位监测、视频监控等,具有十分广阔的应用背景。智能硬件框架(如图4-1所示) 图4-1 智能硬件框架图 精品word文档 . 精品word文档 . 附录 服务器模块: /*1.调用socket函数创建套接字。 TCP协议:SOCK_STREAM*/ sockfd = socket(AF_INET,SOCK_STREAM,0); if(-1 == sockfd){ perror("socket"); return -1; } /*填充服务器信息*/ struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(servaddr)); servaddr.sin_family = AF_INET; //PF_INET servaddr.sin_port = htons(PORT); //端口号(5001-65536) servaddr.sin_addr.s_addr = inet_addr(SERVERIP); //ip地址 socklen_t adrlen = sizeof(servaddr); /*2.调用bind指定本地地址和端口。*/ ret = bind(sockfd,(struct sockaddr *)&servaddr,adrlen); if(-1 == ret){ perror("bind"); return -1; } /*3.调用listen启动监听。*/ ret = listen(sockfd,1000); if(-1 == ret){ perror("listen"); return -1; } printf("server init.d success...\n"); int newfd; char buf[BUFSZ] = {0}; pthread_t tid; while(1) { /*4.调用accept从已连接列队中提取客户连接。*/ 精品word文档 . newfd = accept(sockfd,NULL,NULL); if(newfd <= 0){ continue; } printf("%d connect success...\n",newfd); /*为每个客户创建线程去维护它 ==> tid : 用于存放新建线程ID ==> do_work : 新建线程从这里开始执行 ==> newfd : 传给执行函数的参数*/ ret = pthread_create(&tid,NULL,do_work,&newfd); if(0 != ret){ continue; } /*设置为可分离态*/ pthread_detach(tid); } /*6.调用close关闭连接。*/ close(sockfd); close(newfd); return 0; } /*执行函数 (void * 表示可以接收任意类型)*/ void *do_work(void *arg) { int ret; char buf[BUFSZ]; int newfd = *(int *)arg; char *strerr = "密码或者用户名输入有误!"; unsigned int cmd = -1; unsigned long val = -1; int i = 0; int n = 2; int dev_fd; /*5.调用I/O函数(read/write)与客户端通讯。*/ int fd_led; fd_led = open("/dev/led",O_RDWR); if(fd_led < 0){ perror("open"); 精品word文档 . return (void *)-1; } /*开辟一个线程不停的发送温度给客户*/ pthread_t tid1; ret = pthread_create(&tid1,NULL,do_temp,&newfd); pthread_detach(tid1); while(1) { /*读取客户端信息*/ memset(buf,0,sizeof(buf)); ret = read(newfd,buf,sizeof(buf)-1); if(ret > 0){ /*发送命令给硬件*/ if(!strncasecmp(buf,"on1",3)){ cmd = LED_ON; val = 3; }else if(!strncasecmp(buf,"on2",3)){ cmd = LED_ON; val = 4; }else if(!strncasecmp(buf,"off1",4)){ cmd = LED_OFF; val = 3; }else if(!strncasecmp(buf,"off2",4)){ cmd = LED_OFF; val = 4; }else if(!strncasecmp(buf,"onb",3)){ pwm_on(); }else if(!strncasecmp(buf,"song",4)){ pwm_music_fun(); } if(ioctl(fd_led,cmd,(unsigned long)val) < 0){ perror("ioctl failed\n"); exit(1); } } } 客户端模块: int main(int argc,char **argv) { 精品word文档 . int ret; char buf[BUFSZ] = {0}; char temp[BUFSZ] = "26.234000"; /*1.调用socket函数创建套接字。 TCP协议:SOCK_STREAM*/ sockfd = socket(AF_INET,SOCK_STREAM,0); if(-1 == sockfd){ perror("socket"); return -1; } /*填充服务器信息*/ struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); //端口号 servaddr.sin_addr.s_addr = inet_addr(SERVERIP); //ip地址 socklen_t adrlen = sizeof(servaddr); /*2.调用connect连接服务器端*/ ret = connect(sockfd,(struct sockaddr *)&servaddr,adrlen); if(-1 == ret){ perror("connect"); return -1; } printf("client connect success..\n"); struct pollfd pfd[2] = {0}; pfd[0].fd = 0; pfd[0].events = POLLIN; //不阻塞的读数据 pfd[1].fd = sockfd; pfd[1].events = POLLIN; //不阻塞的读数据 /*登录验证*/ if(-1 == login()){ printf("登录失败\n"); return -1; } printf("登录成功...\n"); interface_print(temp); 精品word文档 . /*5.调用I/O函数(read/write)与客户端通讯。*/ int i = 5; int pos; while(1) { ret = poll(pfd,2,-1); if(ret > 0){ if(pfd[0].revents == POLLIN){ interface_print(temp); /*从终端读取数据*/ memset(buf,0,sizeof(buf)); ret = read(pfd[0].fd,buf,sizeof(buf)-1); if(ret > 0){ /*发送数据给服务器*/ write(sockfd,buf,ret); } } if(pfd[1].revents == POLLIN){ if(!strncmp(buf,"get",3)){ /*接收服务器发送的信息*/ memset(temp,0,sizeof(temp)); ret = read(pfd[1].fd,temp,sizeof(temp)-1); if(ret > 0){ temp[ret-1] = '\0'; /*把信息显示到终端*/ interface_print(temp); } } } }else if(0 == ret){ printf("超时\n"); break; }else{ perror("poll"); break; } } /*6.调用close关闭连接。*/ 精品word文档 . close(sockfd); return 0; } int login(void) { char username[100] = {0}; char passwd[100] = {0}; int flags; int ret; char buf[100]; system("clear"); //清屏clear write(1,"username : ",strlen("username : ")); memset(username,0,sizeof(username)); ret = read(0,username,sizeof(username)-1); if(ret > 0){ write(sockfd,username,ret); } write(1,"passwd : ",strlen("passwd : ")); memset(passwd,0,sizeof(passwd)); ret = read(0,passwd,sizeof(passwd)-1); if(ret > 0){ write(sockfd,passwd,ret); } memset(buf,0,sizeof(buf)); ret = read(sockfd,buf,sizeof(buf)); if(ret > 0){ printf("%s\n",buf); if(!strncmp(buf,"ok",2)){ flags = 0; }else{ flags = -1; } } return flags; } 精品word文档 . 温度传感器驱动模块: static void Init_DS18B2O(void)//Init_DS18B2O { unsigned int retvalue=1; writel((readl(gph1con) & 0xFFFFFFF0) | 0x1, gph1con);//gph1_0,output writel(readl(gph1dat) | 0x1 , gph1dat); __udelay(1); writel(readl(gph1dat) &(0xFFFFFFFE), gph1dat); __udelay(500); writel(readl(gph1dat) | 0x1 , gph1dat); __udelay(20); writel(readl(gph1con) & 0xFFFFFFF0, gph1con);//gph1_0,input __udelay(100); if (!(readl(gph1dat)&0x01)) { retvalue=0; } } static int gpio_relrease(struct inode *inode, struct file *filp) { iounmap(gph1con); iounmap(gph1dat); iounmap(gph1pud); iounmap(gpc0con); iounmap(gpc0dat); iounmap(gpc0pud); return 0; } static unsigned char ReadOneChar(void) { unsigned char i=0; unsigned char dat=0; spin_lock(&lock); for (i=8;i>0;i--) { dat>>=1; writel((readl(gph1con) & 0xFFFFFFF0) | 0x1, gph1con);//gph1_0,output 精品word文档 . writel(readl(gph1dat) &(0xFFFFFFFE), gph1dat); __udelay(2);// writel(readl(gph1con) & 0xFFFFFFF0, gph1con);//gph1_0,input __udelay(1);// if((readl(gph1dat)&0x01)) { dat |=0x80;} __udelay(62); } spin_unlock(&lock); return (dat); } static void WriteOneChar(unsigned char dat) { unsigned char i=0; writel((readl(gph1con) & 0xFFFFFFF0) | 0x1, gph1con);//gph1_0,output spin_lock(&lock); for(i=0;i<8;i++) { writel(readl(gph1dat) &(0xFFFFFFFE), gph1dat); __udelay(15); if(dat&0x01) { writel(readl(gph1dat) | 0x1 , gph1dat); } else { writel(readl(gph1dat) &(0xFFFFFFFE), gph1dat); } __udelay(45); writel(readl(gph1dat) | 0x1 , gph1dat); __udelay(1); dat>>=1; } spin_unlock(&lock); } static unsigned int ReadTemp(void) { unsigned char T_h=0; unsigned char T_l=0; unsigned int temp=0; 精品word文档 . writel((readl(gph1pud) & 0xFFFc) | 0x02, gph1pud);//gph1_0,pull-up enabled spin_lock(&lock); Init_DS18B2O(); spin_unlock(&lock); __udelay(400); writel((readl(gph1con) & 0xFFFFFFF0) | 0x1, gph1con);//gph1_0,output writel(readl(gph1dat) | 0x1 , gph1dat); WriteOneChar(0xcc); WriteOneChar(0x44); mdelay(100); spin_lock(&lock); Init_DS18B2O(); spin_unlock(&lock); __udelay(400); writel((readl(gph1con) & 0xFFFFFFF0) | 0x1, gph1con);//gph1_0,output writel(readl(gph1dat) | 0x1 , gph1dat); WriteOneChar(0xcc); WriteOneChar(0xBE); T_l=ReadOneChar();//L T_h=ReadOneChar();//H temp=(unsigned int) (((unsigned int)T_h<<8)|T_l); return temp; } static int gpio_ioctl(struct file *filp, unsigned int cmd, unsigned int *arg) { unsigned int ret; switch(cmd) { case GPIO_ON: ret=ReadTemp(); arg=&ret; break; default: ret = -1; 精品word文档 . } return ret; } static struct file_operations gpio_fops = { .owner = THIS_MODULE, .open = gpio_open, .release = gpio_relrease, .unlocked_ioc
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 学术论文 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服