天嵌 ARM开发社区

 找回密码
 注册
查看: 1424|回复: 0

自己研究DS18B20在2440上的驱动

[复制链接]
冫叮叮猫 发表于 2014-5-9 01:20:46 | 显示全部楼层 |阅读模式
驱动加载无问题、  就是读不出来温度,全是0。
网上找的DS18B20的驱动程序,研究并make modules成ko文件,下载到开发板测试,却读不出来温度,没看出什么问题,请大神们发表下意见。

/*程序说明:1.数据引脚为GPG0
            2.使用的开发板为TQ2440,已经包含了相关的头文件。与时钟设置有关的没有包含,所以接下来用cal_cpu_bus_clk()void Set_Clk();针对你使用的开发板设置下即可。测温部分逻辑无问题
*/
#define GLOBAL_CLK 1  

#include <stdlib.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "mmu.h"
#include "profile.h"
#include "memtest.h"

#define   DQ_IN     rGPGCON &= 0xFFFFFFFC
#define   DQ_OUT    rGPGCON = (rGPGCON & 0xFFFFFFFC)|0x01
#define   DQ_DOWN   rGPGUP |= (1 << 0)
#define   DQ_UP     rGPGUP &= ~(1 << 0)
#define   DQ_H      rGPGDAT |= (1 << 0)
#define   DQ_L      rGPGDAT &= ~(1 << 0)
#define   DQ_STAT   (rGPGDAT >> 0) & 0x1

//定义DS18B20ROM指令
#define    DS18B20_ReadROM        0x33    //读ROM
#define    DS18B20_MatchROM       0x55    //匹配ROM
#define    DS18B20_SkipROM        0xCC    //跳过ROM
#define    DS18B20_SearchROM      0xF0    //搜索ROM
#define    DS18B20_AlarmROM       0xEC    //报警搜索

//定义DS18B20存储器操作命令
#define    DS18B20_WriteSCR       0x4E    //写暂存存储器
#define    DS18B20_ReadSCR        0xBE    //读暂存存储器
#define    DS18B20_CopySCR        0x48    //复制暂存存储器
#define    DS18B20_ConvertTemp    0x44    //温度变换
#define    DS18B20_RecallEP       0xB8    //重新调出
#define    DS18B20_ReadPower      0xB4    //读电源

static void cal_cpu_bus_clk(void);
void Set_Clk(void);


/*************************************************
Function name: Set_Clk()
Parameter    : void
Description     : 设置CPU的时钟频率
Return          : void
Argument     : void
Autor & date : Daniel
**************************************************/
void Set_Clk(void)
{
     int i;
     U8 key;
     U32 mpll_val = 0 ;
     i = 2 ;                  //don't use 100M!
                           //boot_params.cpu_clk.val = 3;
     switch ( i ) {
     case 0:     //200
          key = 12;
          mpll_val = (92<<12)|(4<<4)|(1);
          break;
     case 1:     //300
          key = 13;
          mpll_val = (67<<12)|(1<<4)|(1);
          break;
     case 2:     //400
          key = 14;
          mpll_val = (92<<12)|(1<<4)|(1);
          break;
     case 3:     //440!!!
          key = 14;
          mpll_val = (102<<12)|(1<<4)|(1);
          break;
     default:
          key = 14;
          mpll_val = (92<<12)|(1<<4)|(1);
          break;
     }

     //init FCLK=400M, so change MPLL first
     ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);   //set the register--rMPLLCON
     ChangeClockDivider(key, 12);    //the result of rCLKDIVN [0:1:0:1] 3-0 bit
     cal_cpu_bus_clk();    //HCLK=100M   PCLK=50M
}
/*************************************************
Function name: cal_cpu_bus_clk
Parameter    : void
Description     : 设置PCLK\HCLK\FCLK的频率
Return          : void
Argument     : void
Autor & date : Daniel
**************************************************/
static void cal_cpu_bus_clk(void)
{
     static U32 cpu_freq;
     static U32 UPLL;

     U32 val;
     U8 m, p, s;

     val = rMPLLCON;
     m = (val>>12)&0xff;
     p = (val>>4)&0x3f;
     s = val&3;

     //(m+8)*FIN*2 不要超出32位数!
     FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100;     //FCLK=400M  FIN=12000000

     val = rCLKDIVN;
     m = (val>>1)&3;
     p = val&1;   
     val = rCAMDIVN;
     s = val>>8;

     switch (m) {
     case 0:
          HCLK = FCLK;
          break;
     case 1:
          HCLK = FCLK>>1;
          break;
     case 2:
          if(s&2)
               HCLK = FCLK>>3;
          else
               HCLK = FCLK>>2;
          break;
     case 3:
          if(s&1)
               HCLK = FCLK/6;
          else
               HCLK = FCLK/3;
          break;
     }

     if(p)
          PCLK = HCLK>>1;
     else
          PCLK = HCLK;

     if(s&0x10)
          cpu_freq = HCLK;
     else
          cpu_freq = FCLK;

     val = rUPLLCON;
     m = (val>>12)&0xff;
     p = (val>>4)&0x3f;
     s = val&3;
     UPLL = ((m+8)*FIN)/((p+2)*(1<<s));
     UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;
}

U16 temp;
U8 DS18B20_ID[8] = {0};
extern unsigned int PCLK;

void usDelay(int time)
{
        U32 i,j;
        for (i = time; i > 0; i--)
                for (j = 1; j > 0; j--);
}

//========================================
//函数名称:  void DS18B20_Init(void)
//实现功能:  初始化18B20
//入口参数:   无
//出口返回值: 无
//========================================
void DS18B20_Init(void)
{       
        DQ_OUT;
        DQ_L;
        usDelay(700);
        DQ_H;
        usDelay(4);
        DQ_IN;
        usDelay(100);
/*        if(DQ_STAT!=0)        //测试复位是否成功
                Uart_Printf("There are no 18B20 at GPB5! 0x%x\n");
        else
                Uart_Printf("Init 18B20 succeed!\n");
*/       
        usDelay(250);
}
//========================================
//函数名称:  U8 DS18B20_ReadBit(void)
//实现功能:  读取18b20的一位数据
//入口参数:   无
//出口返回值: 读取的一位数据
//========================================
U8 DS18B20_ReadBit(void)   
{
        U8 dat;
        DQ_OUT;
        DQ_L;
        usDelay(2);
        DQ_IN;
        usDelay(10);
        if(DQ_STAT!=0)
                dat=1;
        else
                dat=0;
        usDelay(50);
        return (dat);
}
//========================================
//函数名称:  U8 DS18B20_ReadByte(void)
//实现功能:  读取一个字节的数据
//入口参数:   无
//出口返回值: 读取的一个字节数据
//========================================
U8 DS18B20_ReadByte(void)   
{
        U8 i,j,dat;
        dat=0;
        for(i=1;i<=8;i++)
        {
                j=DS18B20_ReadBit();
                dat=(j<<7)|(dat>>1);   //读出的数据最低位在最前面,这样刚好一个字节在DAT里
        }
        return(dat);
}

//========================================
//函数名称:  void DS18B20_WriteByte(U8 dat)
//实现功能:  向18B20写一个字节数据
//入口参数:   要写入的数据
//出口返回值: 无
//========================================
void DS18B20_WriteByte(U8 dat)
{
        U8 j;
        U8 testb;
        DQ_OUT;
        for(j=1;j<=8;j++)
        {
                testb=dat&0x01;
                dat=dat>>1;
                if(testb)     
                {
                        DQ_L;
                        usDelay(8);
                        DQ_H;
                        usDelay(50);
                }
                else
                {
                        DQ_L;
                        usDelay(90);
                        DQ_H;
                        usDelay(8);
                }
        }
}



//========================================
//函数名称:  void DS18B20_TmpChange(void)
//实现功能:  18B20开始温度转换
//入口参数:   无
//出口返回值: 无
//========================================
void DS18B20_TmpChange(void)
{
        DS18B20_Init();
        usDelay(2);/*delay(1);*/
        DS18B20_WriteByte(DS18B20_SkipROM);  // address all drivers on bus
        DS18B20_WriteByte(DS18B20_ConvertTemp);  //  initiates a single temperature conversion
}

//========================================
//函数名称:  U16 DS18B20_Temperature(void)
//实现功能:  得到18B20温度值
//入口参数:   无
//出口返回值: 温度值
//========================================
U16 DS18B20_Temperature(void)
{
        float tt;
        U8 a,b;
        DS18B20_Init();
        usDelay(4);/*delay(1);*/
        DS18B20_WriteByte(DS18B20_SkipROM);
        DS18B20_WriteByte(DS18B20_ReadSCR);
        a=DS18B20_ReadByte();
        b=DS18B20_ReadByte();
        temp=b;
        temp<<=8;             //two byte  compose a int variable
        temp=temp|a;
        tt=temp*0.0625;
        temp=tt*10+0.5;
        return temp;
}

//========================================
//函数名称:  void Test_DS18B20(void)
//实现功能:  18B20测试程序
//入口参数:   无
//出口返回值: 无
//========================================
void Main(void)
{
        U16 tmp;
    Set_Clk();
        Uart_Select(0);
    Uart_Init(0, 115200);

        Uart_Printf("\nDS18B20 TEST!\n");
        Uart_Printf("Now start temperature change!\n");
        while(Uart_GetKey() != ESC_KEY)
        {
                DS18B20_TmpChange();
                Delay(1000);
                tmp =  DS18B20_Temperature();
                Uart_Printf("Temperature is  [%d.%d `C]\n", tmp/10, tmp%10);       
        }
}

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号-2 )

GMT+8, 2024-6-26 20:15 , Processed in 1.296875 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表