#include "stm32f10x_gpio.h"
#define DS2431_GPIO GPIOB
#define DS2431_GPIO_Pin GPIO_Pin_0
#define DS2431_Write_1() GPIO_SetBits( DS2431_GPIO, DS2431_GPIO_Pin ) //写1
#define DS2431_Write_0() GPIO_ResetBits( DS2431_GPIO, DS2431_GPIO_Pin ) //写0
#define DS2431_ReadBit() GPIO_ReadInputDataBit( DS2431_GPIO, DS2431_GPIO_Pin ) //读DS2431上的值
/**************操作指令码定义******************************/
/*DS2431 ROM功能命令*/
#define Rom_Read_Cmd 0x33 //Read ROM
#define Rom_Match_Cmd 0x55 //Match ROM
#define Rom_Skip_Cmd 0xCC //Skip ROM
#define Rom_Search_Cmd 0xF0 //Search ROM
/*DS2431 存储器功能命令*/
#define Memory_Read_Cmd 0xF0 //Read Memory
#define Scratchpad_Read_Cmd 0xAA //Read Scratchpad
#define Scratchpad_Write_Cmd 0x0F //Write Scratchpad
#define Scratchpad_Copy_Cmd 0x55 //Copy Scratchpad
/**********************************************************/
extern void Delay_Nus( u32 Nus );
extern void Delay_Nms( u16 Nms );
/******************************************
****************涉及DS2431部分*************
*******************************************/
/******************************************
函数名称:GPIO_DS2431_Out_Mode
功 能:设置DS2431引脚为开漏输出模式
参 数:无
返回值 :无
*******************************************/
static void GPIO_DS2431_Out_Mode( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DS2431_GPIO_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出
GPIO_Init( DS2431_GPIO, &GPIO_InitStructure );
}
/******************************************
函数名称:GPIO_DS2431_Input_Mode
功 能:设置DS2431引脚为浮空输入模式
参 数:无
返回值 :无
*******************************************/
static void GPIO_DS2431_Input_Mode( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DS2431_GPIO_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init( DS2431_GPIO, &GPIO_InitStructure );
}
/******************************************
1-Wire器件复位, 并检查应答;有应答返回0, 无应答返回1
*******************************************/
static unsigned char Reset( void )
{
GPIO_DS2431_Out_Mode();
DS2431_Write_1();
DS2431_Write_0();
Delay_Nus( 237 ); //复位低脉冲保持
DS2431_Write_1(); //释放总线后70us读应答
Delay_Nus( 35 );
GPIO_DS2431_Input_Mode();
if( 0 == DS2431_ReadBit() )
{
Delay_Nus( 200 );
return ( 0 );
}
else
{
return ( 1 );
}
}
/******************************************
写数据位1
*******************************************/
static void WriteBit_1( void )
{
GPIO_DS2431_Out_Mode();
DS2431_Write_1();
DS2431_Write_0(); //拉低总线保持6us
Delay_Nus( 2 );
DS2431_Write_1(); //释放总线延时65us
Delay_Nus( 30 );
}
/******************************************
写数据位0
*******************************************/
static void WriteBit_0( void )
{
GPIO_DS2431_Out_Mode();
DS2431_Write_1();
DS2431_Write_0(); //拉低总线保持65us
Delay_Nus( 30 );
DS2431_Write_1(); //释放总线延时6us
Delay_Nus( 2 );
}
/******************************************
读数据位
*******************************************/
static unsigned char Read_Bit( void )
{
unsigned char value;
GPIO_DS2431_Out_Mode();
DS2431_Write_1();
DS2431_Write_0(); //拉低总线保持6us
Delay_Nus( 2 );
DS2431_Write_1(); //释放总线延时9us
Delay_Nus( 3 );
GPIO_DS2431_Input_Mode();
value = DS2431_ReadBit(); //读取总线状态延时55us
Delay_Nus( 24 );
return value;
}
/******************************************
写字节
*******************************************/
static void Write_Byte( unsigned char value )
{
unsigned char i;
for( i = 0; i < 8; i++ )
{
if( value & 0x01 )
{
WriteBit_1();
}
else
{
WriteBit_0();
}
value = value >> 1;
}
}
/******************************************
读字节
*******************************************/
static unsigned char Read_Byte( void )
{
unsigned char i, value;
value = 0;
for( i = 0; i < 8; i++ )
{
value >>= 1;
if( Read_Bit() )
value |= 0x80;
}
return value;
}
/******************************************
功能:读8位家族码;48位序列号;8位CRC码;读取成功返回0
参数:*id--读取的数据存放地址
返回:0--操作成功;1--总线不可用;
*******************************************/
unsigned char DS2431_ReadRom( unsigned char *id )
{
unsigned char i;
if( Reset() != 0 )
return ( 1 );
Write_Byte( Rom_Read_Cmd ); //写命令
for( i = 0; i < 8; i++ )
{
*id++ = Read_Byte();
}
return ( 0 );
}
/******************************************
功能: 读EPROM
参数: tgaddr--目标地址;
len--要读取的字节数;
*buffer--存放地址
返回:0--操作成功;1--总线不可用;
*******************************************/
unsigned char DS2431_ReadMemory( unsigned char tgaddr, unsigned char len,
unsigned char * buffer )
{
unsigned char i;
if( Reset() != 0 )
return ( 1 );
Write_Byte( Rom_Skip_Cmd ); //写命令
Write_Byte( Memory_Read_Cmd ); //写命令
Write_Byte( tgaddr ); //写地址低字节
Write_Byte( 0 ); //写地址高字节
for( i = 0; i < len; i++ )
buffer[ i ] = Read_Byte();
Reset();
return ( 0 );
}
/******************************************
描述:DS2431的EEPROM 共为8 X 18个字节, 可以看作18个8字节块.
功能:写EPROM
参数:nblock--块号取值( 0--17 )16块为特殊功能寄存器17块为保留;
*buffer为要写入的8字节数据起始指针
返回: 0--操作成功;
1--总线不可用;
2--写暂存器失败;
3--写主存储器错误;
*******************************************/
unsigned char DS2431_WriteBlock( unsigned char nblock, unsigned char *buffer )
{
unsigned char sbuf[ 16 ];
unsigned char i;
if( nblock > 17 )
return ( 3 ); //地址超出范围
//构造要写入的命令和数据
sbuf[ 0 ] = Rom_Skip_Cmd;
sbuf[ 1 ] = Scratchpad_Write_Cmd;
sbuf[ 2 ] = nblock * 8; //写地址低字节
sbuf[ 3 ] = 0; //写地址高字节
for( i = 0; i < 8; i++ ) //8字节数据
sbuf[ i + 4 ] = buffer[ i ];
//器件复位
if( Reset() != 0 )
return ( 1 );
//写命令和数据
for( i = 0; i < 12; i++ )
Write_Byte( sbuf[ i ] );
Read_Byte();
Read_Byte();
//******************读暂存器比较写入的数据**************
if( Reset() != 0 )
return ( 1 );
Write_Byte( Rom_Skip_Cmd ); //写命令
Write_Byte( Scratchpad_Read_Cmd );
for( i = 1; i < 12; i++ )
sbuf[ i ] = Read_Byte();
if( sbuf[ 1 ] != ( nblock * 8 ) ) return ( 2 );
else if ( sbuf[ 2 ] != 0 ) return ( 2 );
else if ( sbuf[ 3 ] != 7 ) return ( 2 );
for( i = 0; i < 8; i++ )
if( sbuf[ i + 4 ] != buffer[ i ] ) return ( 2 );
//******************拷贝暂存器数据到主存储器**************
//构造要写入的命令和数据
sbuf[ 0 ] = Rom_Skip_Cmd;
sbuf[ 1 ] = Scratchpad_Copy_Cmd;
sbuf[ 2 ] = ( nblock * 8 ); //写地址低字节
sbuf[ 3 ] = 0; //写地址高字节
sbuf[ 4 ] = 7;
//器件复位
if( Reset() != 0 )
return ( 1 );
for( i = 0; i < 5; i++ )
Write_Byte( sbuf[ i ] );
Delay_Nms( 9 );
if( Read_Byte() == 0xaa )
{
Reset();
return ( 0 );
}
else
{
Reset();
return ( 3 );
}
}
#define DS2431_GPIO GPIOB
#define DS2431_GPIO_Pin GPIO_Pin_0
#define DS2431_Write_1() GPIO_SetBits( DS2431_GPIO, DS2431_GPIO_Pin ) //写1
#define DS2431_Write_0() GPIO_ResetBits( DS2431_GPIO, DS2431_GPIO_Pin ) //写0
#define DS2431_ReadBit() GPIO_ReadInputDataBit( DS2431_GPIO, DS2431_GPIO_Pin ) //读DS2431上的值
/**************操作指令码定义******************************/
/*DS2431 ROM功能命令*/
#define Rom_Read_Cmd 0x33 //Read ROM
#define Rom_Match_Cmd 0x55 //Match ROM
#define Rom_Skip_Cmd 0xCC //Skip ROM
#define Rom_Search_Cmd 0xF0 //Search ROM
/*DS2431 存储器功能命令*/
#define Memory_Read_Cmd 0xF0 //Read Memory
#define Scratchpad_Read_Cmd 0xAA //Read Scratchpad
#define Scratchpad_Write_Cmd 0x0F //Write Scratchpad
#define Scratchpad_Copy_Cmd 0x55 //Copy Scratchpad
/**********************************************************/
extern void Delay_Nus( u32 Nus );
extern void Delay_Nms( u16 Nms );
/******************************************
****************涉及DS2431部分*************
*******************************************/
/******************************************
函数名称:GPIO_DS2431_Out_Mode
功 能:设置DS2431引脚为开漏输出模式
参 数:无
返回值 :无
*******************************************/
static void GPIO_DS2431_Out_Mode( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DS2431_GPIO_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出
GPIO_Init( DS2431_GPIO, &GPIO_InitStructure );
}
/******************************************
函数名称:GPIO_DS2431_Input_Mode
功 能:设置DS2431引脚为浮空输入模式
参 数:无
返回值 :无
*******************************************/
static void GPIO_DS2431_Input_Mode( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DS2431_GPIO_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init( DS2431_GPIO, &GPIO_InitStructure );
}
/******************************************
1-Wire器件复位, 并检查应答;有应答返回0, 无应答返回1
*******************************************/
static unsigned char Reset( void )
{
GPIO_DS2431_Out_Mode();
DS2431_Write_1();
DS2431_Write_0();
Delay_Nus( 237 ); //复位低脉冲保持
DS2431_Write_1(); //释放总线后70us读应答
Delay_Nus( 35 );
GPIO_DS2431_Input_Mode();
if( 0 == DS2431_ReadBit() )
{
Delay_Nus( 200 );
return ( 0 );
}
else
{
return ( 1 );
}
}
/******************************************
写数据位1
*******************************************/
static void WriteBit_1( void )
{
GPIO_DS2431_Out_Mode();
DS2431_Write_1();
DS2431_Write_0(); //拉低总线保持6us
Delay_Nus( 2 );
DS2431_Write_1(); //释放总线延时65us
Delay_Nus( 30 );
}
/******************************************
写数据位0
*******************************************/
static void WriteBit_0( void )
{
GPIO_DS2431_Out_Mode();
DS2431_Write_1();
DS2431_Write_0(); //拉低总线保持65us
Delay_Nus( 30 );
DS2431_Write_1(); //释放总线延时6us
Delay_Nus( 2 );
}
/******************************************
读数据位
*******************************************/
static unsigned char Read_Bit( void )
{
unsigned char value;
GPIO_DS2431_Out_Mode();
DS2431_Write_1();
DS2431_Write_0(); //拉低总线保持6us
Delay_Nus( 2 );
DS2431_Write_1(); //释放总线延时9us
Delay_Nus( 3 );
GPIO_DS2431_Input_Mode();
value = DS2431_ReadBit(); //读取总线状态延时55us
Delay_Nus( 24 );
return value;
}
/******************************************
写字节
*******************************************/
static void Write_Byte( unsigned char value )
{
unsigned char i;
for( i = 0; i < 8; i++ )
{
if( value & 0x01 )
{
WriteBit_1();
}
else
{
WriteBit_0();
}
value = value >> 1;
}
}
/******************************************
读字节
*******************************************/
static unsigned char Read_Byte( void )
{
unsigned char i, value;
value = 0;
for( i = 0; i < 8; i++ )
{
value >>= 1;
if( Read_Bit() )
value |= 0x80;
}
return value;
}
/******************************************
功能:读8位家族码;48位序列号;8位CRC码;读取成功返回0
参数:*id--读取的数据存放地址
返回:0--操作成功;1--总线不可用;
*******************************************/
unsigned char DS2431_ReadRom( unsigned char *id )
{
unsigned char i;
if( Reset() != 0 )
return ( 1 );
Write_Byte( Rom_Read_Cmd ); //写命令
for( i = 0; i < 8; i++ )
{
*id++ = Read_Byte();
}
return ( 0 );
}
/******************************************
功能: 读EPROM
参数: tgaddr--目标地址;
len--要读取的字节数;
*buffer--存放地址
返回:0--操作成功;1--总线不可用;
*******************************************/
unsigned char DS2431_ReadMemory( unsigned char tgaddr, unsigned char len,
unsigned char * buffer )
{
unsigned char i;
if( Reset() != 0 )
return ( 1 );
Write_Byte( Rom_Skip_Cmd ); //写命令
Write_Byte( Memory_Read_Cmd ); //写命令
Write_Byte( tgaddr ); //写地址低字节
Write_Byte( 0 ); //写地址高字节
for( i = 0; i < len; i++ )
buffer[ i ] = Read_Byte();
Reset();
return ( 0 );
}
/******************************************
描述:DS2431的EEPROM 共为8 X 18个字节, 可以看作18个8字节块.
功能:写EPROM
参数:nblock--块号取值( 0--17 )16块为特殊功能寄存器17块为保留;
*buffer为要写入的8字节数据起始指针
返回: 0--操作成功;
1--总线不可用;
2--写暂存器失败;
3--写主存储器错误;
*******************************************/
unsigned char DS2431_WriteBlock( unsigned char nblock, unsigned char *buffer )
{
unsigned char sbuf[ 16 ];
unsigned char i;
if( nblock > 17 )
return ( 3 ); //地址超出范围
//构造要写入的命令和数据
sbuf[ 0 ] = Rom_Skip_Cmd;
sbuf[ 1 ] = Scratchpad_Write_Cmd;
sbuf[ 2 ] = nblock * 8; //写地址低字节
sbuf[ 3 ] = 0; //写地址高字节
for( i = 0; i < 8; i++ ) //8字节数据
sbuf[ i + 4 ] = buffer[ i ];
//器件复位
if( Reset() != 0 )
return ( 1 );
//写命令和数据
for( i = 0; i < 12; i++ )
Write_Byte( sbuf[ i ] );
Read_Byte();
Read_Byte();
//******************读暂存器比较写入的数据**************
if( Reset() != 0 )
return ( 1 );
Write_Byte( Rom_Skip_Cmd ); //写命令
Write_Byte( Scratchpad_Read_Cmd );
for( i = 1; i < 12; i++ )
sbuf[ i ] = Read_Byte();
if( sbuf[ 1 ] != ( nblock * 8 ) ) return ( 2 );
else if ( sbuf[ 2 ] != 0 ) return ( 2 );
else if ( sbuf[ 3 ] != 7 ) return ( 2 );
for( i = 0; i < 8; i++ )
if( sbuf[ i + 4 ] != buffer[ i ] ) return ( 2 );
//******************拷贝暂存器数据到主存储器**************
//构造要写入的命令和数据
sbuf[ 0 ] = Rom_Skip_Cmd;
sbuf[ 1 ] = Scratchpad_Copy_Cmd;
sbuf[ 2 ] = ( nblock * 8 ); //写地址低字节
sbuf[ 3 ] = 0; //写地址高字节
sbuf[ 4 ] = 7;
//器件复位
if( Reset() != 0 )
return ( 1 );
for( i = 0; i < 5; i++ )
Write_Byte( sbuf[ i ] );
Delay_Nms( 9 );
if( Read_Byte() == 0xaa )
{
Reset();
return ( 0 );
}
else
{
Reset();
return ( 3 );
}
}