驱动加载无问题、 就是读不出来温度,全是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);
}
}
|