unsigned char Send_SPI(unsigned char x){ unsigned char y = 0; int z; int error = 0; SPICN = 3; /* MSTSM, SPIEN */ z = 0; while ((SPICN_bit.STBY) && (++z < SPI_TIMEOUT)); if (z == SPI_TIMEOUT) error = 1; SPICN_bit.SPIC = 0; /* Clear transfer complete flag */ SPIB = x; z = 0; while ((!SPICN_bit.SPIC) && (++z < SPI_TIMEOUT)); if (z == SPI_TIMEOUT) error = 1; y = SPIB; SPICN_bit.SPIC = 0; dly_us(100); if (error) return 0; return y;}
图6. Send_SPI原代码long Read_AFE(enum METER_REGISTER_RECORD reg, uint16 reg_addr){ extern unsigned char record[8]; unsigned long x = 0; unsigned char i, regadd, command_code = 0; for(i=0; i<8; i++) record[i] = 0; switch(register_lookup_table[reg].register_length) { case 2: command_code |= 0x10; break; case 4: command_code |= 0x20; break; case 8: command_code |= 0x30; break; } command_code |= reg_addr >> 8; regadd = reg_addr & 0xff; /* Disable SPI to reset it */ SPICN_bit.SPIEN = 0; for(x=0; x<300; x++); SPICN_bit.SPIEN = 1; SPI_SELECT_0; i = 0; while((Send_SPI(command_code)!= 0xC1)&&(++i < SPI_COMMAND_RETRIES)) spi_comm_timeout(); x = 0xffffffff; if (i == SPI_COMMAND_RETRIES) goto spierror; Send_SPI(regadd); i = 0; while((Send_SPI(0) != 'A') && (++i < SPI_RETRIES)); if (i == SPI_RETRIES) goto spierror; x = 0; for(i=0; i<register_lookup_table[reg].register_length; i++) { record[i] = Send_SPI(0); x |= ((uint32)record[i]) << (i * 8); }spierror: SPI_DESELECT_0; return (int32)x;}
图7. ReadAFE (SPI_Read)子程序代码void Write_AFE(enum METER_REGISTER_RECORD reg, uint16 reg_addr, uint32 data){ uint8 i, regadd, command_code = 0x80; int x; switch(register_lookup_table[reg].register_length) { case 2: command_code |= 0x10; break; case 4: command_code |= 0x20; break; case 8: command_code |= 0x30; break; } command_code |= reg_addr >> 8; regadd = reg_addr & 0xff; /* Disable SPI hardware to reset it */ SPICN_bit.SPIEN = 0; for(x=0; x<300; x++); SPICN_bit.SPIEN = 1; SPI_SELECT_0; i = 0; while((Send_SPI(command_code)!=0xC1)&&(++i < SPI_COMMAND_RETRIES)) spi_comm_timeout(); if (i == SPI_COMMAND_RETRIES) goto spierror; Send_SPI(regadd); for(i=0; i<register_lookup_table[reg].register_length; i++) Send_SPI((data >> (i * 8)) & 0xff); i = 0; while((Send_SPI(0) != 'A') && (++i < SPI_RETRIES));spierror: SPI_DESELECT_0;}
图8. Write_AFE (SPI_Write)子程序代码