温度测量实验设计总结
一.实验目的
1.了解DS18b20的功能以及熟练运用其测量温度。
2.运用74ls164驱动数码管来显示温度。
二.实验原理
运用Ds18b20测量温度,并通过ARM采集并显示到数码管上。
三.实验器材
Pc机一台,DS18B20,数码管1个,arm板1个,74ls164一个,电阻,杜邦线若干。
四.部分器件原理图
74ls164
DS18B20
五.实验内容
//头文件
*******************************
#include <linux/module.h> //支持printk输出
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <mach/hardware.h>
#include <mach/regs-gpio.h>
//宏定义端口
****************************
#define DQ S3C2410_GPB7
#define bt_i S3C2410_GPB7_INP
#define bt_o S3C2410_GPB7_OUTP
#define AB S3C2410_GPF3
#define CLK S3C2410_GPG3
#define AB_s S3C2410_GPF3_OUTP
#define CLK_s S3C2410_GPG3_OUTP
#define com1_s S3C2410_GPG5_OUTP
#define com2_s S3C2410_GPG7_OUTP
#define com3_s S3C2410_GPG10_OUTP
#define com4_s S3C2410_GPG11_OUTP
#define com1 S3C2410_GPG5
#define com2 S3C2410_GPG7
#define com3 S3C2410_GPG10
#define com4 S3C2410_GPG11
#define bt_f S3C2410_GPB0
#define led_off 1
#define led_on 0
#define led1 S3C2410_GPB5
#define led2 S3C2410_GPB6
#define led3 S3C2410_GPB7
#define led4 S3C2410_GPB8
#define led1_s S3C2410_GPB5_OUTP
#define led2_s S3C2410_GPB6_OUTP
#define led3_s S3C2410_GPB7_OUTP
#define led4_s S3C2410_GPB8_OUTP
#define bt_c s3c2410_gpio_cfgpin
#define bt_s s3c2410_gpio_setpin
#define bt_g s3c2410_gpio_getpin
*****************************************************************
//定义变量
*************************************
#define DEVICE_NAME "cw" //设备号
#define cw_MAJOR 231 //设备号
static char devicecount=0; //计数器,防止被多个人多次打开
static int shi=0;
static int ge=0;
static int bai=0;
static int buf[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67}; //十进制与十六进制的转换
//LED灯驱动程序
***************************************************************
static void led_init(void) //初始化LED灯
{
bt_c(led1,led1_s); //设置端口
bt_s(led1,led_off); //初始化端口
bt_c(led2,led1_s);
bt_s(led2,led_off);
bt_c(led3,led1_s);
bt_s(led3,led_off);
bt_c(led4,led1_s);
bt_s(led4,led_off);
}
static void led_th(void) //设置LED灯的状态
{
bt_s(led1,led_on);
bt_s(led2,led_off);
bt_s(led3,led_off);
bt_s(led4,led_off);
}
//DS18B20的驱动程序
*******************************************
static void DS_reset_1(void)
{
int err;
bt_c(DQ,bt_o);
bt_s(DQ,1);
udelay(10); //设置端口为输出,拉高电平,释放总线
bt_s(DQ,0);
udelay(500); //拉低电平,并延迟500微妙
bt_s(DQ,1); //拉高电平,延迟30,设置端口为输入
udelay(30);
bt_c(DQ,bt_i);
err=bt_g(DQ); //判断高低电平,若为低电平,表示复位成功
if(err==0)
{printk("successful!\n");}
}
static void DS_write_1(unsigned char date) // 写入函数
{
unsigned char i;
bt_c(DQ,bt_o); //设置为输出状态
bt_s(DQ,1);
udelay(5);
for(i=0;i<8;++i) //按位输入
{
bt_s(DQ,0);
udelay(10);
if(date&0x01) //从第一位移位
bt_s(DQ,1);
udelay(60);
bt_s(DQ,1);
udelay(5);
date>>=1; //向右移位
}
}
static int DS_read_1()
{
char i;
char Temp=0;
for(i=0;i<8;++i)
{
Temp>>=1; //向右移位
bt_c(DQ,bt_o);
bt_s(DQ,0); //设置为输出口,并拉低电平
udelay(10);
bt_s(DQ,1);
bt_c(DQ,bt_i); //设置为输入口
udelay(1);
if(bt_g(DQ)) //判断输入的高低电平
Temp|=0x80; //读值
udelay(80);
bt_c(DQ,bt_o); //释放总线
bt_s(DQ,1);
udelay(5);
}
return Temp; //返回值
}
static int Temperture() //温度转换函数
{
char num;
char Temp1=0,Temp2=0;
DS_reset_1();
udelay(100); //复位并延迟
DS_write_1(0xcc); //跳过序列号
DS_write_1(0x44); //传入数值
udelay(300);
DS_reset_1();
udelay(100);
DS_write_1(0xcc);
DS_write_1(0xbe);
udelay(300);
Temp1=DS_read_1(); //读取低八位
Temp2=DS_read_1(); //读取高八位
num=Temp1/16 +Temp2*16; //转化成十进制数字
if(num>32) //温度大于32时,报警
{
led_th();
bt_s(bt_f,1);
}
else
{
bt_s(bt_f,0);
}
return num;
}
//数码管驱动程序
******************************************************************
static void lsd(void) //初始化
{
bt_c(AB,AB_s); //设置端口
bt_c(CLK,CLK_s);
bt_c(com1,com1_s);
bt_c(com2,com2_s);
bt_c(com3,com3_s);
bt_c(com4,com4_s);
bt_s(AB,0); //设置端口状态
bt_s(CLK,0);
bt_s(com1,1);
bt_s(com2,1);
bt_s(com3,1);
bt_s(com4,1);
}
static void date(int n)
{
int i;
for(i=0;i<8;i++) / /按位传值
{
bt_s(CLK,0);
bt_s(AB,n&0X01);
bt_s(CLK,1);
n>>=1;
}
udelay(10);
}
static int shuma(int num)
{
int i=0;
ge=num%10;
shi=num/10;
bai=num/100;
for(i=0;i<100;++i) //刷新数据流
{
date(buf[ge]); //设置个位数值
bt_s(com1,1);
bt_s(com2,1);
bt_s(com3,1);
bt_s(com4,0);
mdelay(3);
date(buf[shi]); //设置十位数值
bt_s(com1,1);
bt_s(com2,1);
bt_s(com3,0);
bt_s(com4,1);
mdelay(3);
date(buf[bai]); //设置百位数值
bt_s(com1,1);
bt_s(com2,0);
bt_s(com3,1);
bt_s(com4,1);
mdelay(3);
if(num<0) //判断正负
{
date(0x40);
}
bt_s(com1,0);
bt_s(com2,1);
bt_s(com3,1);
bt_s(com4,1);
mdelay(3);
}
udelay(1000);
return 0;
}
/*************************************************************************************/
static int cw_write(struct file*file, const char __user *buffer, size_t count, loff_t * ppos)
{
return 0;
}
/*************************************************************************************/
static int cw_read(struct file*filp, char __user *buffer, size_t count, loff_t *ppos)
{
return 0;
}
/*************************************************************************************/
/****************************************************************/
static int cw_open(struct inode *inode,struct file *file)
{
if(devicecount >0)return -ERESTARTSYS;
printk("device open: success\n");
devicecount++;
return 0;
}
static int cw_release(structinode *inode, struct file *filp)
{
devicecount--;
printk("devicerelease\n");
return 0;
}
/******************************************************************/
static int cw_ioctl(struct inode *inode,struct file *file,unsigned intcmd,unsigned long arg)
{ unsigned int Temp;
Temp= Temperture();
shuma(Temp);
udelay(500);
return 0;
}
static struct file_operations cw_fops = {
.owner = THIS_MODULE,
.ioctl = cw_ioctl,
.write = cw_write,
.read = cw_read,
.open = cw_open,
.release = cw_release,
};
static int __init cw_init(void)
{
int ret;
ret =register_chrdev(cw_MAJOR, DEVICE_NAME, &cw_fops);
if (ret < 0) {
printk(DEVICE_NAME " can't registermajor number\n");
return ret;
}
led_init();
printk(DEVICE_NAME "initialized\n");
lsd();
return 0;
}
static void __exit cw_exit(void)
{
unregister_chrdev(cw_MAJOR,DEVICE_NAME);
}
module_init(cw_init);
module_exit(cw_exit);
MODULE_LICENSE("Dual BSD/GPL");
六.工作原理图
DS18B20原理图
七.实验结果分析以及遇到并解决的问题
1.设计的整个逻辑非常重要,从硬件设计到软件的驱动到最后的调试都需要一个很好的逻辑。最基础都要保证硬件焊接以及电路的正确性。
2.对于程序的驱动最好要一块一块编写和调试,最后再结合来驱动整个功能。
3.最大的问题
(1)硬件的接口松动,接触不良,以及相互之间靠的太近发生短路,更甚设置的端口插错,导致不能正确驱动。
(2)程序中返回值不正确,以及变量的错误定义。
(3)对延时的不确定性,设置延时不够正确,导致不能够正确显示和驱动,以及出现乱码。
(4)程序的嵌套使用中的程序正确调用。
八. 总结
通过此次实验让我们懂得了团队的重要性,只有团队的相互协作才能够顺利的完成项目,只有大家共同的努力才能解决更多的问题,在相互的帮助下共同进步,促进各方面的成长。