如果想让网络控制板在广域网上飞,首先得解决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条评论)
登录后参与讨论