ds18b20/ds18b20.c
2019-06-07 21:27:29 +08:00

149 lines
3.3 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
unsigned int gpio_num = 223;
#define DQ_IN gpio_direction_input(gpio_num)
//#define DQ_OUT gpio_direction_output(gpio_num, gpio_get_value(gpio_num))
#define DQ_OUT gpio_direction_output(gpio_num, 1)
#define DQ_H gpio_set_value(gpio_num, 1)
#define DQ_L gpio_set_value(gpio_num, 0)
#define DQ_V gpio_get_value(gpio_num)
//spinlock_t lock;
//********************************
//功能:ds18b20复位
//********************************
int init_DS18B20(void)
{
unsigned int result;
DQ_OUT;
DQ_L;
udelay(480); //480~960
DQ_H;
udelay(60); //60-240
DQ_IN;
result = DQ_V;
udelay(420);
DQ_OUT;
printk("ds18b20 init result %d", result);
return result;
}
//*************************************
//功能:从ds18b20读一个字节的数据
//*************************************
// 读“1”时隙
// 若总线状态保持在低电平状态1微秒到15微秒之间
// 然后跳变到高电平状态且保持在15微秒到60微秒之间
// 就认为从DS18B20读到一个“1”信号
// 理想情况: 1微秒的低电平然后跳变再保持60微秒的高电平
//
// 读“0”时隙
// 若总线状态保持在低电平状态15微秒到30微秒之间
// 然后跳变到高电平状态且保持在15微秒到60微秒之间
// 就认为从DS18B20读到一个“0”信号
// 理想情况: 15微秒的低电平然后跳变再保持46微秒的高电平
unsigned char read_char(void)
{
unsigned int i = 0;
unsigned char dat = 0;
//spin_lock(&lock);
for(i=0; i<8; i++) {
DQ_OUT;
DQ_L;
udelay(2);
DQ_H;
udelay(8);
dat >>= 1;
DQ_IN;
if (DQ_V)
dat |= 0x80;
udelay(50);
}
DQ_OUT;
//spin_unlock(&lock);
return dat;
}
//*************************************
//功能:向ds18b20写一个字节的数据
//*************************************
// 写“1”时隙
// 保持总线在低电平1微秒到15微秒之间
// 然后再保持总线在高电平15微秒到60微秒之间
// 理想状态: 1微秒的低电平然后跳变再保持60微秒的高电平
//
// 写“0”时隙
// 保持总线在低电平15微秒到60微秒之间
// 然后再保持总线在高电平1微秒到15微秒之间
// 理想状态: 60微秒的低电平然后跳变再保持1微秒的高电平
void write_char(unsigned char dat)
{
unsigned int i = 0;
//spin_lock(&lock);
DQ_OUT;
for(i=0; i<8; i++)
{
DQ_L;
if (dat & 0x01)
DQ_H;
else
DQ_L;
udelay(60);
dat >>= 1;
}
//spin_unlock(&lock);
}
int initDs18b20(unsigned int gpioNum)
{
//spin_lock_init(&lock);
gpio_num = gpioNum;
if (init_DS18B20())
return 1;
return 0;
}
/*读取数据*/
void readDs18b20Data(unsigned char *value)
{
if (init_DS18B20())
{
return;
}
write_char(0xCC);
write_char(0x44);
mdelay(750);
if (init_DS18B20())
{
return;
}
write_char(0xCC);
write_char(0xBE);
if (sizeof(&value) > 1)
{
value[0] = read_char();
value[1] = read_char();
}
}
void freeDs18b20(void)
{
gpio_free(gpio_num);
}