原创 带有EUI-48™ 节点标识符的2K UNI/O® 串行EEPROM 11AA02E48 的调试笔记

2012-12-10 17:14 2235 17 17 分类: MCU/ 嵌入式

如果想让网络控制板在广域网上飞,首先得解决MAC地址的问题。局域网无所谓,随机产生一个就是了,重名的可能性微乎其微。但在广域网那就得破费点了,美国人真能想招赚钱,数字也能卖钱。

      闲话少说,11AA02E48 是MICROCHIP中的一款带MAC地址的EEPROM.  里面预先设定全球唯一的48 位节点地址。  体积很小,SOT23封装,不仔细看就是一个贴片三极管。

2K的EEPROM, 猛一看以为是2K 字节,, 当然这是忽悠你的,实际是BITS,是256*8 ,只有256个字节。

MAC地址放在0XFA~0XFF的地址中,其余0~0XFA作为普通的EEPROM 使用。

占用的IO口很少,只有1根, 单I/O UNI/O® 串行接口总线。这个总线 11AA02E48数据手册的介绍的很少,我到现在也不知道时序,但是官网上提供了例程。

    例程中占用的资源是一个TIMER1和一个普通的IO口。   

   测试了一下,幸运的是第一遍就调通了。。。。。太幸运了。。

//UNIO.h

/********************************************************************/
/** I / O   P I N   D E F I N I T I O N S **************************/
#define SCIO        PORTCbits.RC2       // Serial clock, input/output pin, PORTB pin 4
#define SCIOTRIS    TRISCbits.TRISC2   // SCIO direction bit

 

/** C O N S T A N T   D E F I N I T I O N S ************************/
#define STARTHDR    0x55                // Define STARTHDR as 0x55
#define SAK         1                   // Define SAK as 1
#define NOSAK       0                   // Define NOSAK as 0
#define MAK         1                   // Define MAK as 1
#define NOMAK       0                   // Define NOMAK as 0
#define DEVICE_ADDR 0xA0                // Define DEVICE_ADDR as 0xA0
#define PAGESIZE    16                  // 16-byte page size for 11AA02E48   页写缓冲区最大为16字节

/** B U S   F R E Q U E N C Y   C A L C U L A T I O N **************/
#define BUSFREQ     75000               // Set desired bus frequency to 75 kHz
#define FCY         10000000            // Set instruction frequency to 10 MHz
#define HALF_PERIOD ((FCY/(2*BUSFREQ))-1)// Timer period calculation

/** C O M M A N D   D E F I N I T I O N S **************************/
#define WREN_E        0b10010110          // WREN command
#define WRDI        0b10010001          // WRDI command
#define WRITE       0b01101100          // WRITE command
#define READ        0b00000011          // READ command
#define WRSR        0b01101110          // WRSR command
#define RDSR        0b00000101          // RDSR command
#define ERAL        0b01101101          // ERAL command
#define SETAL       0b01100111          // SETAL command

/********************************************************/

 

 

  /********************************************************************
 * Function:        void WriteEnable(void)
 *
 * Description:     This function performs a Write Enable instruction
 *                  to set the WEL bit in the Status Register.
 *******************************************************************/
void WriteEnable(void)
{
    Delay100TCYx(1);                        // Observe Tss time
    _StartHeader();                 // Output Start Header
    dataOut._byte = DEVICE_ADDR;    // Load DEVICE_ADDR into dataOut
    _OutputByte();                  // Output byte
    dataOut._byte = WREN_E;           // Load WREN into dataOut
    flags.sendMAK = 0;              // Elect to send NoMAK
    _OutputByte();                  // Output byte
    _Standby();                     // Gracefully enter Standby
} // end of WriteEnable(void)


/********************************************************************
 * Function:        void WIP_Poll(void)
 *
 * Description:     This function performs WIP polling to determine
 *                  the end of the current write cycle. It does this
 *                  by continuously executing a Read Status Register
 *                  operation until the WIP bit (bit 0 of the Status
 *                  Register) is read low.
 *******************************************************************/
void WIP_Poll(void)
{
    Delay100TCYx(1);                        // Observe Tss time
    _StartHeader();                 // Output Start Header
    dataOut._byte = DEVICE_ADDR;    // Load DEVICE_ADDR into dataOut
    _OutputByte();                  // Output byte
    dataOut._byte = RDSR;           // Load RDSR into dataOut
    _OutputByte();                  // Output byte
    _InputByte();                   // Input byte
    while (dataIn.b0 == 1)
    {
        _AckSequence();             // Perform Acknowledge Sequence
        _InputByte();               // Input byte
    }
    flags.sendMAK = 0;              // Elect to send NoMAK
    _AckSequence();                 // Perform Acknowledge Sequence
    _Standby();                     // Gracefully enter Standby
} // end of WIP_Poll(void)


/********************************************************************
 * Function:        void ByteWrite(WORD address)
 *
 * Description:     This function writes the byte stored in the first
 *                  location of the pageBuffer array to the serial
 *                  EEPROM array location specified by address.
 *
 * Parameters:      address - Memory location at which to start
 * 输入参数: address ; pageBuffer[0](数据);
 * 输出参数:无
 
 
 
 *******************************************************************/
void ByteWrite(unsigned int  address,unsigned char dataa)
{
 union Ili9320 add;
 add.u16 = address; 
 
    WriteEnable();                  // Set Write Enable Latch
    Delay100TCYx(1);                         // Observe Tss time
    _StartHeader();                 // Output Start Header
    dataOut._byte = DEVICE_ADDR;    // Load DEVICE_ADDR into dataOut
    _OutputByte();                  // Output byte
    dataOut._byte = WRITE;          // Load WRITE into dataOut
    _OutputByte();                  // Output byte
    dataOut._byte = add.u8[1];   // Load address MSB into dataOut
    _OutputByte();                  // Output byte
    dataOut._byte = add.u8[0];   // Load address LSB into dataOut
    _OutputByte();                  // Output byte
    dataOut._byte = dataa;  // Load data into dataOut
    flags.sendMAK = 0;              // Elect to send NoMAK
    _OutputByte();                  // Output byte
    _Standby();                     // Gracefully enter Standby

    WIP_Poll();                     // Perform WIP Polling
} // end of ByteWrite(...)

 

/********************************************************************
 * Function:        void StandbyPulse(void)
 *
 * Description:     Hold SCIO high for Tstby time period to generate
 *                  standby pulse. This subroutine will delay for a
 *                  total of 600 us (6000 insts.) after setting SCIO
 *                  high.
 *******************************************************************/
void StandbyPulse(void)
{
    SCIO = 1;                       // Ensure SCIO is high
    SCIOTRIS = 0;                   // Ensure SCIO is driving

    Delay100TCYx(60);               // Delay for Tstby time
} // end of StandbyPulse(void)

/********************************************************************
 * Function:        void UNIO_INI (void)
 *
 * Description:     对UNIO初始化, 占用资源:TIMER1
 *
 * Parameters:     
 
 *******************************************************************/

void UNIO_ini(void)
{
SCIO = 0;                           // Set SCIO to drive low
SCIOTRIS = 0;                       // Configure SCIO to output
Nop();                              // Delay to ensure minimum pulse width of 200 ns
SCIO = 1;                           // Bring SCIO high to release from POR
 // Initialize Timer1
    T1CON = 0b10000000;                 // Configure Timer1, 1:1 prescalar, 16-bit
    ***R1H = 0x00;                      // Clear ***R1H
    ***R1L = HALF_PERIOD;               // Load HALF_PERIOD into ***R1L
    TMR1H = 0x00;                       // Clear TMR1H
    TMR1L = 0x00;                       // Clear TMR1L
    // Initialize ***1
    ***1CON = 0b00001011;               // Configure special event trigger保留
  // ***1CON = 0b00000010;
    StandbyPulse();                     // Generate Standby Pulse

}

 

 

/********************************************************************
 * Function:        void _OutputHalfBit(void)
 *
 * Description:     Waits until Timer 1 rolls over, then outputs the
 *                  next half of the current bit period. The value
 *                  used is specified by the MSb of dataOut.
 *******************************************************************/
void _OutputHalfBit(void)
{
    while (PIR1bits.***1IF == 0) {};// Wait until ***1IF flag is set

    SCIOTRIS = 0;                   // Ensure SCIO is outputting
    if (dataOut.b7 == 1)            // Check if dataOut MSb is 1
        SCIO = 0;                   // If 1, set SCIO low
    else
        SCIO = 1;                   // If 0, set SCIO high

    PIR1bits.***1IF = 0;            // Clear ***1IF flag
    dataOut._byte = ~dataOut._byte; // Invert dataOut for next half
} // end of _OutputHalfBit(void)

文章评论0条评论)

登录后参与讨论
我要评论
0
17
关闭 站长推荐上一条 /2 下一条