s3c2410测温

ARM 97浏览

温度测量实验设计总结

一.实验目的

1.了解DS18b20的功能以及熟练运用其测量温度。

2.运用74ls164驱动数码管来显示温度。

二.实验原理

运用Ds18b20测量温度,并通过ARM采集并显示到数码管上。

三.实验器材

Pc机一台,DS18B20,数码管1个,arm1个,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:  successn");

      
devicecount++;

      
return 0;

}

 

static int 
cw_release(structinode *inode, struct file *filp)

{

      
devicecount--;

      
printk("devicereleasen");

      
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 numbern");

      
  return ret;

      

      
}

       

      
led_init();

      
printk(DEVICE_NAME "initializedn");

   
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)程序的嵌套使用中的程序正确调用。

八.  总结

通过此次实验让我们懂得了团队的重要性,只有团队的相互协作才能够顺利的完成项目,只有大家共同的努力才能解决更多的问题,在相互的帮助下共同进步,促进各方面的成长。