热度 17
2012-12-10 17:14
2238 次阅读|
0 个评论
如果想让网络控制板在广域网上飞,首先得解决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 (数据); * 输出参数:无 *******************************************************************/ 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 ; // Load address MSB into dataOut _OutputByte(); // Output byte dataOut._byte = add.u8 ; // 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)