单总线驱动复用
1、单总线抽象
1.1结构体,成员根据抽象对象的特征提取
struct onewire_dev
{
void (*output)(uint8_t state);//拉高、拉低
uint8_t(*input)(void);//读取
void(*delayus)(uint32_t time);
}
1.2对外接口,与硬件层分离,移植时几乎无需改动。
uint8_t onewire_reset(struct onewire_dev *onewire); //复位函数
int onewire_read(struct onewire_dev *onewire,void *buff,int size);//读函数
int onewire_write(struct onewire_dev *onewire,void *buff,int size);//写函数
入口参数“struct onewire_dev”为结构体指针,此部分就是硬件层相关,需要后期初始化的
1.3抽象接口实现
以DS18b20为例实现:
1.3.1复位函数
uint8_t onewire_reset(struct onewire_dev *onewire)
{
uint8_t ret = 0;
onewire->output(1);
onewire->delayus(50);
onewire->output(0);
onewire->delayus(500);
onewire->output(1);
onewire->delayus(40);
ret = onewire->input();
onewire->delayus(500);
onewire->output(1);
return ret;
}
1.3.2读函数
//读单字节
static char onewire_read_byte(struct onewire_dev *onewire)
{
char data = 0;
uint8_t i;
for(i=8;i>0;i--)
{
data <<= 1;
onewire->output(0);
onewire->delayus(5);
onewire->output(1);
onewire->delayus(5);
if(onewire->input())
data |= 0x80;
else
data &= 0x7f;
onewire->delayus(65);
onewire->output(1);
}
return data;
}
//读多字节
int onewire_read(struct onewire_dev *onewire,void *buff,int size)
{
int i;
char *p = (char*)buff;
for(i=0;isize;i++)
p[i++]=onewire_read_byte(onewire);
return i;
}
1.3.3写函数

//写单字节
static int onewire_write_byte(struct onewire_dev *onewire,char data)
{
uint8_t i;
for(i=8;i0;i--)
{
onewire->output(0);
onewire->delayus(5);
if(data&0x01)
onewire->output(1);
else
onewire->output(0);
onewire->delayus(65);
onewire->output(1);
onewire->delayus(2);
data >>= 1;
}
return 0;
}
//写多字节
int onewire_write(struct onewire_dev *onewire,void *buff,int size)
{
int i;
char *p = (char*)buff;
for(i=0;i<size;i++)
{
if(onewire_write_byte(onewire,p[i]) != 0)
break;
}
return i;
}
2、“struct onewire_dev” 实现,此部分与硬件相关
static void gpio_output(int8_t state)
{
if (state)
GPIO_SetBits(ONEWIRE1_PORT,ONEWIRE1_PIN);
else
GPIO_ResetBits(ONEWIRE1_PORT,ONEWIRE1_PIN);
}
static uint8_t gpio_input(void)
{
return (GPIO_ReadInputDataBit(ONEWIRE1_PORT,ONEWIRE1_PIN));
}
static void gpio_delayus(uint32_t us)
{
volatile int32_t i;
for (; us > 0; us--)
{
i = 30;
while(i--);
}
}
//定义结构体
struct onewire_dev onewire1_dev;
//单总线初始化
void stm32f1xx_onewire1_init(void)
{
/略去引脚配置/
//初始化结构体
onewire1_dev.input = gpio_input;
onewire1_dev.output = gpio_output;
onewire1_dev.delayus = gpio_delayus;
}
3、onewire使用
static uint8_t ds18b20_start(void)
{
char reg;
onewire_reset(&onewire1_dev);
reg = 0xcc; /* 跳过ROM /
onewire_write(&onewire1_dev,®,1);
reg = 0x44; / 温度转换指令 */
onewire_write(&onewire1_dev,®,1);
return 0;
}
//读取温度
float ds18b20_readtemp(void)
{
uint8_t tl,th,sign;
uint16_t reg_temp;
char reg;
float temp;
ds18b20_start();
onewire_reset(&onewire1_dev);
reg = 0xcc;
onewire_write(&onewire1_dev,®,1); /* 跳过ROM /
reg = 0xbe;
onewire_write(&onewire1_dev,®,1); / 读取RAM /
onewire_read(&onewire1_dev,&tl,1); / 低8位数据 /
onewire_read(&onewire1_dev,&th,1); / 高8位数据 /
if(th > 7)
{/ - /
th = ~th;
tl = ~tl + 1;
sign = 0;
}
else
{/ + */
sign = 1;
}
reg_temp = (th<<8) | tl;
temp = reg_temp * 0.0625f;
if(sign)
{
return temp;
}
else
{
return -temp;
}
}
//读唯一序列号
void ds18b20_readrom(char *rom)
{
uint8_t i;
char reg;
onewire_reset(&onewire1_dev);
reg = 0x33;
onewire_write(&onewire1_dev,®,1);
for (i = 0;i < 8;i++)
{
onewire_read(&onewire1_dev,&rom[i],1);
}
}