one-wire DS2431

17 篇文章 0 订阅
#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 );
        }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值