s3c2440 ds18b20驱动编写

上一篇单总线时序分析:https://blog.csdn.net/qq_40215005/article/details/96435251
s3c2440 ds18b20驱动编写_第1张图片

这是ds18b20驱动大致结构

硬件初始化BYTE ds18b20_reset(void) 复位脉冲和应答脉冲函数
在这里插入图片描述

BYTE ds18b20_reset(void)
{
    s3c2410_gpio_cfgpin(S3C2410_GPG(0), S3C2410_GPIO_OUTPUT); //设置引脚GPG0为输出
    s3c2410_gpio_setpin(S3C2410_GPG(0), LOW);	//设置单总线信号为低电平
    udelay(480);//产生复位脉冲
    s3c2410_gpio_setpin(S3C2410_GPG(0), HIGH);	//设置单总线信号为高电平
    udelay(60);//从机等待

    s3c2410_gpio_cfgpin(S3C2410_GPG(0), S3C2410_GPIO_INPUT);//设置为输入,读取从机发送的信号
    if(s3c2410_gpio_getpin(S3C2410_GPG(0)))   //判断为低电平就应答成功
    {
        printk("ds18b20 reset failed.\r\n");
        return 1;
    }
    udelay(240);//保持60~240us时间
    return 0;
}

file opreation中定义了.read=s3c2440_ds18b20_read操作,就是从ds18b20获取温度。
s3c2440 ds18b20驱动编写_第2张图片
s3c2440_ds18b20_read

static ssize_t s3c2440_ds18b20_read(struct file *filp, char *buff, size_t len, loff_t *off)
{
        ds18b20_proc();

        buff[0] = data[0];
        buff[1] = data[1];

        return 1;
}

然后调用了ds18b20_proc();

void ds18b20_proc(void)//获取温度子函数
{
        while(ds18b20_reset()); //主从设备初始化
        udelay(120);
        ds18b20_write_byte(0xcc);
        ds18b20_write_byte(0x44);//发送获取温度转换命令
        udelay(5);

        while(ds18b20_reset());
        udelay(200);
        ds18b20_write_byte(0xcc);
        ds18b20_write_byte(0xbe);//读取暂存器值命令

        data[0] = ds18b20_read_byte();
        data[1] = ds18b20_read_byte();
}

s3c2440 ds18b20驱动编写_第3张图片
在这里插入图片描述
s3c2440 ds18b20驱动编写_第4张图片

BYTE ds18b20_write_byte(BYTE byte)

BYTE ds18b20_write_byte(BYTE byte)
{
    BYTE i;
    s3c2410_gpio_cfgpin(S3C2410_GPG(0), S3C2410_GPIO_OUTPUT);	//设置为输出
    for(i = 0; i < 8; i++) //八个位需要发送
    {   
        s3c2410_gpio_setpin(S3C2410_GPG(0), LOW);
        udelay(15);
        if(byte & HIGH)//写1时就拉高信号线
        {   
            s3c2410_gpio_setpin(S3C2410_GPG(0), HIGH);
        }   
        else//写0就拉低
        {   
            s3c2410_gpio_setpin(S3C2410_GPG(0), LOW);
        }   
        udelay(45);

        s3c2410_gpio_setpin(S3C2410_GPG(0), HIGH);
        udelay(1);
        byte >>= 1;//命令八个位依次右移
    }   
    s3c2410_gpio_setpin(S3C2410_GPG(0), HIGH);
    return 0;
}

比如发CCH命令 CC
11001100
00000001 &
与八次,总共发送一个字节的命令。

BYTE ds18b20_read_byte(BYTE byte);

BYTE ds18b20_read_byte(void)
{
    BYTE i = 0;
    BYTE byte = 0;

    for(i = 0; i < 8; i++)
    {
        s3c2410_gpio_cfgpin(S3C2410_GPG(0), S3C2410_GPIO_OUTPUT);
        s3c2410_gpio_setpin(S3C2410_GPG(0), LOW);
        udelay(1);
        byte >>= 1;
        s3c2410_gpio_setpin(S3C2410_GPG(0), HIGH);//上拉代表释放总线
        s3c2410_gpio_cfgpin(S3C2410_GPG(0), S3C2410_GPIO_INPUT);//采集信号
        if(s3c2410_gpio_getpin(S3C2410_GPG(0)))//为高电平则读1
            byte |= 0x80;//读一个字节
        udelay(50);
    }
    return byte;
}

ds18b20转化后得到的12位数据,存储在ds18B20的两个8比特的RAM中,二进制中的前面5位是符号位,如果测得的温度大于0, 这5位为0,只要将测到的数值乘于0.0625即可得到实际温度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际 温度。 例如+125℃的数字输出为07D0H,+25.0625℃的数字输出为0191H,-25.0625℃的数字输出为FE6FH,-55℃的数字输出为FC90H 。可以看做后四位为小数部分,精度为0.625,中间七位为整数部分。
  
所以测试程序中要对得到的两个字节做处理
测试程序

  1 #include 
  2 #include 
  3 #include 
  4 #include 
  5 #include 
  6 #include 
  7 #include 
  8 #include 
  9 
 10 int main (int argc, char **argv)
 11 {
 12     int fd;
 13     double result = 0;
 14     unsigned char buff[2];
 15     unsigned short temp = 0;
 16     int flag = 0;
 17 
 18     if ((fd=open("/dev/ds18b20",O_RDWR | O_NDELAY | O_NOCTTY)) < 0)
 19     {
 20         perror("open device ds18b20 failed.\r\n");
 21         exit(1);
 22     }
 23     while(1)
 24     {
 25         printf("open device ds18b20 success.\r\n");
 26         read(fd, buff, sizeof(buff));
 27         temp=((unsigned short)buff[1])<<8;
 28         temp|=(unsigned short)buff[0];
 29         if(temp & 0x0800)
 30         {
 31             temp &= 0xF000;
 32             result=0.0625*((double)(~temp+1));
 33         }
 34         else
 35             result=0.0625*((double)temp);
 36         printf("temperature is %4f \r\n", result);
 37         sleep(2);
 38     }
 39     close(fd);
 40 
 41     return 0;
 42 } /* ----- End of main() ----- */

你可能感兴趣的:(驱动学习,底层开发)