用户0680
发布于

单总线驱动复用

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写函数 ![](https://weidongshan.oss-cn-shenzhen.aliyuncs.com/images/2025/03/13/b3d1147823c2d688dfe201dff2b1bdf7.png) //写单字节 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,&reg,1);
 reg = 0x44; /
 温度转换指令 */
 onewire_write(&onewire1_dev,&reg,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,&reg,1); /* 跳过ROM /
 reg = 0xbe;
 onewire_write(&onewire1_dev,&reg,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,&reg,1);
 for (i = 0;i < 8;i++)
 {
  onewire_read(&onewire1_dev,&rom[i],1);  
 } 
}

浏览 (73)
点赞
收藏
评论
暂无数据