ONE WIRE总线是一种对硬件设计很友好,对软件设计不友好的总线,一根线可以完成供电、时钟、和双向数据的功能,时序要求非常严格,写驱动的时候最好配合示波器,通信速度并不快,但距离较远,传输百米以上没有问题。
驱动如下:
/******************************************************************************
* 文 件 名 称:BspOneWire.c
* 文件功能概述:实现1-WIRE通信驱动接口
* 文 件 作 者:xxx
* 版 本:V1.0.0.0
* 修 订 记 录:2017-6-30创建
******************************************************************************/
#include "BspOneWire.h"
/*-------------------------- start implemention -----------------------------*/
/*
* 1-WIRE总线设置
*/
S_GpioCtrl sOWCtrlScl[E_OW_Max] =
{
{RCC_AHB1Periph_GPIOI, GPIOI, GPIO_Pin_11},
{RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_0},
{RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_0},
{RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_3},
{RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_3}
};
/*******************************************************************************
* 函 数 名:static void OneWireDelayUs(uint16 Us)
* 参 数:uint16 Us : 延时单位
* 返 回:无
* 创 建 人:xxx
* 创建时间:2017-6-30
* 详 述:OneWire使用的延时函数
* 修改记录:2017-6-30创建
*******************************************************************************/
//static void OneWireDelayUs(uint16 Us)
//{
// uint32 i = 0, j = 0;
//
// for (j = 0; j < Us; j++)
// {
// for(i = 0; i < 17; i++)
// {
// ;
// }
// }
//
//}
/*******************************************************************************
* 函 数 名:static sint8 OneWireSetDirOut(E_OWx eOWx)
* 参 数:无
* 返 回:0
* 创 建 人:xxx
* 创建时间:2017-6-30
* 详 述:设置总线为数据输出方向
* 修改记录:2017-6-30创建
*******************************************************************************/
static sint8 OneWireSetDirOut(E_OWx eOWx)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = sOWCtrlScl[eOWx].GPIOxPinx;
GPIO_Init(sOWCtrlScl[eOWx].GPIOx, &GPIO_InitStructure);
return 0;
}
/*******************************************************************************
* 函 数 名:static sint8 OneWireSetDirIn(E_OWx eOWx)
* 参 数:无
* 返 回:0
* 创 建 人:xxx
* 创建时间:2017-6-30
* 详 述:设置总线为数据输入方向
* 修改记录:2017-6-30创建
*******************************************************************************/
static sint8 OneWireSetDirIn(E_OWx eOWx)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = sOWCtrlScl[eOWx].GPIOxPinx;
GPIO_Init(sOWCtrlScl[eOWx].GPIOx, &GPIO_InitStructure);
return 0;
}
/*******************************************************************************
* 函 数 名:static void OneWireOutputData(E_OWx eOWx,uint8 value)
* 参 数:uint8 value : 0 :输出低电平 非0 :输出高电平
* 返 回:无
* 创 建 人:xxx
* 创建时间:2017-6-30
* 详 述:输出高电平或低电平
* 修改记录:2017-6-30创建
*******************************************************************************/
static void OneWireOutputData(E_OWx eOWx,uint8 value)
{
if(value == 0)
{
GPIOxWriteBit(sOWCtrlScl[eOWx].GPIOx, sOWCtrlScl[eOWx].GPIOxPinx , 0);
}
else
{
GPIOxWriteBit(sOWCtrlScl[eOWx].GPIOx, sOWCtrlScl[eOWx].GPIOxPinx , 1);
}
}
/*******************************************************************************
* 函 数 名:static uint8 OneWireGetBit(E_OWx eOWx)
* 参 数:无
* 返 回:0 :低电平 非0 :高电平
* 创 建 人:xxx
* 创建时间:2017-6-30
* 详 述:读取总线上当前的电平状态
* 修改记录:2017-6-30创建
*******************************************************************************/
static uint8 OneWireGetBit(E_OWx eOWx)
{
uint8 data = 0;
data = GPIO_ReadInputDataBit(sOWCtrlScl[eOWx].GPIOx, sOWCtrlScl[eOWx].GPIOxPinx);
return data;
}
void OneWireTakeBus(E_OWx eOWx)
{
OneWireSetDirOut(eOWx);
OneWireOutputData(eOWx,0);
}
void OneWireRealseBus(E_OWx eOWx)
{
OneWireSetDirOut(eOWx);
OneWireOutputData(eOWx,1);
}
/*******************************************************************************
* 函 数 名:sint8 OneWireInit(void)
* 参 数:无
* 返 回:-1 : 发生错误 0 : 正常返回
* 创 建 人:xxx
* 创建时间:2017-6-30
* 详 述:初始化1-wire总线上端口
* 修改记录:2017-6-30创建
*******************************************************************************/
sint8 OneWireInit(E_OWx eOWx)
{
if(E_OW_Max <= eOWx)
{
return -1;
}
else
{
/* do nothing */
}
/*配置DQ引脚*/
RCC_AHB1PeriphClockCmd(sOWCtrlScl[eOWx].GPIOxSource, ENABLE);
OneWireSetDirOut(eOWx);
OneWireOutputData(eOWx,0);
OneWireDelayUs(500);
OneWireOutputData(eOWx,1);
OneWireDelayUs(80);
OneWireSetDirIn(eOWx);
if(OneWireGetBit(eOWx) == 0)
{
OneWireDelayUs(100);
return 0;
}
return -1;
}
/*******************************************************************************
* 函 数 名:sint8 OneWireReset(void)
* 参 数:无
* 返 回:-1 : 发生错误 0 : 正常返回
* 创 建 人:xxx
* 创建时间:2017-6-30
* 详 述:复位1-wire总线上端口
* 修改记录:2017-6-30创建
*******************************************************************************/
sint8 OneWireReset(E_OWx eOWx)
{
OneWireSetDirOut(eOWx);
OneWireOutputData(eOWx,0);
OneWireDelayUs(1000);
OneWireOutputData(eOWx,1);
OneWireDelayUs(80);
OneWireSetDirIn(eOWx);
if(OneWireGetBit(eOWx) == 0)
{
OneWireDelayUs(100);
return 0;
}
return -1;
}
/*---------------------------- end implemention -----------------------------*/
/*******************************************************************************
* 函 数 名:static sint8 OneWireWriteBit(uint8 data)
* 参 数:uint8 data : 0/1 发送的bit位
* 返 回:0 : 正常返回
* 创 建 人:xxx
* 创建时间:2017-6-30
* 详 述:在1-wire总线上发送一位数据
* 修改记录:2017-6-30创建
*******************************************************************************/
sint8 OneWireWriteBit(E_OWx eOWx,uint8 data)
{
OneWireSetDirOut(eOWx);
OneWireOutputData(eOWx,0);
OneWireDelayUs(2);
if(data&0x01)
{
OneWireOutputData(eOWx,1);
OneWireDelayUs(70);
}
else
{
OneWireDelayUs(70);
OneWireOutputData(eOWx,1);
}
OneWireOutputData(eOWx,1);
OneWireDelayUs(1);
return 0;
}
/*******************************************************************************
* 函 数 名:static uint8 OneWireReadBit(void)
* 参 数:无
* 返 回:0 或 1
* 创 建 人:xxx
* 创建时间:2017-6-30
* 详 述:从1-wire总线上读取一位数据
* 修改记录:2017-6-30创建
*******************************************************************************/
uint8 OneWireReadBit(E_OWx eOWx)
{
uint8 data = 0;
OneWireSetDirOut(eOWx);
OneWireOutputData(eOWx,0);
OneWireDelayUs(5);
OneWireOutputData(eOWx,1);
OneWireSetDirIn(eOWx);
OneWireDelayUs(10);
data = OneWireGetBit(eOWx);
OneWireDelayUs(48);
return data;
}
/*******************************************************************************
* 函 数 名:sint8 OneWireWriteByte(uint8 data)
* 参 数:uint8 data : 发送的数据
* 返 回:0
* 创 建 人:xxx
* 创建时间:2017-6-30
* 详 述:在1-wire总线上发送一个字节数据
* 修改记录:2017-6-30创建
*******************************************************************************/
sint8 OneWireWriteByte(E_OWx eOWx,uint8 data)
{
uint8 temp=0;
if(E_OW_Max <= eOWx)
{
return -1;
}
else
{
/* do nothing */
}
OneWireSetDirOut(eOWx);
temp = 0;
while(temp < 8)
{
if(data&0x01)
{
OneWireWriteBit(eOWx,1);
}
else
{
OneWireWriteBit(eOWx,0);
}
data = data >> 1;
temp ++;
}
return 0;
}
/*******************************************************************************
* 函 数 名:sint8 OneWireReadByte(void)
* 参 数:无
* 返 回:uint8 data :读取的字节
* 创 建 人:xxx
* 创建时间:2017-6-30
* 详 述:在1-wire总线上读取一个字节数据
* 修改记录:2017-6-30创建
*******************************************************************************/
sint8 OneWireReadByte(E_OWx eOWx)
{
uint8 temp=0;
uint8 data=0;
if(E_OW_Max <= eOWx)
{
return -1;
}
else
{
/* do nothing */
}
temp = 0;
while(temp < 8)
{
data = data>>1;
if(OneWireReadBit(eOWx) == 1)
{
data |= 0x80;
}
temp++;
}
return data;
}
头文件如下:
/******************************************************************************
* 文 件 名 称:BspOneWire.h
* 文件功能概述:实现1-Wire通信接口声明
* 文 件 作 者:
* 版 本:V1.0.0.0
* 修 订 记 录:2017-6-30创建
******************************************************************************/
#ifndef __BSP_ONEWIRE_H__
#define __BSP_ONEWIRE_H__
/*----------------------------------------------*
* 包含头文件 *
*----------------------------------------------*/
#include "BspConfig.h"
#include "BspGpio.h"
#include "BspConfig.h"
#include "BspDelay.h"
/*----------------------------------------------*
* 宏定义 *
*----------------------------------------------*/
#define OneWireDelayUs(x) DelayUs(x)
/*----------------------------------------------*
* 常量定义 *
*----------------------------------------------*/
typedef enum
{
E_OW_1 = 0, /*通信板自己的MAX31826*/
E_OW_DYDY, /*低压电源板的MAX31826*/
E_OW_GYDY, /*高压电源板的MAX31826*/
E_OW_MB, /*母板的MAX31826*/
E_OW_BB, /*背板的MAX31826*/
E_OW_Max,
E_OW_Invalid
}E_OWx;
/*----------------------------------------------*
* 外部变量说明 *
*----------------------------------------------*/
/*----------------------------------------------*
* 全局变量 *
*----------------------------------------------*/
/*----------------------------------------------*
* 模块级变量 *
*----------------------------------------------*/
/*----------------------------------------------*
* 外部函数原型说明 *
*----------------------------------------------*/
/*----------------------------------------------*
* 内部函数原型说明 *
*----------------------------------------------*/
void OneWireTakeBus(E_OWx eOWx);
void OneWireRealseBus(E_OWx eOWx);
sint8 OneWireInit(E_OWx eOWx);
sint8 OneWireReset(E_OWx eOWx);
sint8 OneWireWriteByte(E_OWx eOWx,uint8 data);
sint8 OneWireReadByte(E_OWx eOWx);
extern sint8 OneWireWriteBit(E_OWx eOWx,uint8 data);
extern uint8 OneWireReadBit(E_OWx eOWx);
#endif /* __BSP_ONEWIRE_H__ */
/*******************************************************************************
* 函 数 名:void DelayUs(uint16 us)
* 参 数:uint16 us : 延时时间长度
* 返 回:无
* 创建时间:2017-6-30
* 详 述:实现us级的延时
* 修改记录:2017-6-30创建
*******************************************************************************/
void DelayUs(uint16 us)
{
uint16 i=0,j=0;
for(j=0; j<us; j++)
{
for(i=0; i<32; i++)
{
__NOP();
}
}
}