十年專注單片機方案開發的方案公司英銳恩,分享用HI-TECH C寫的使用PIC12C508讀寫93LC46。英銳恩現提供服務產品涉及主控芯片:8位單片機、16位單片機、32位單片機及各類運算放大器等。
用HI-TECH C寫的使用PIC12C508讀寫93LC46
/************************************************************ * Processer : Microchip PIC12C508 * * Compiler : Hi-TECH PICC 8.00 PL2 * * Writer : Jason Kuo * * Description : It can read/write 93LC46 (64 x 16-bit organization) * *************************************************************/ static volatile unsigned char RTCC @ 0x01; static volatile unsigned char TMR0 @ 0x01; static volatile unsigned char PCL @ 0x02; static volatile unsigned char STATUS @ 0x03; static unsigned char FSR @ 0x04; static volatile unsigned char OSCCAL @ 0x05; static volatile unsigned char GPIO @ 0x06;
static unsigned char control OPTION @ 0x00; static volatile unsigned char control TRIS @ 0x06;
/* STATUS bits */ static bit GPWUF @ (unsigned)&STATUS*8+7; static bit PA0 @ (unsigned)&STATUS*8+5; static bit TO @ (unsigned)&STATUS*8+4; static bit PD @ (unsigned)&STATUS*8+3; static bit ZERO @ (unsigned)&STATUS*8+2; static bit DC @ (unsigned)&STATUS*8+1; static bit CARRY @ (unsigned)&STATUS*8+0;
/* OPTION bits */ #define GPWU (1<<7) #define GPPU (1<<6) #define T0CS (1<<5) #define T0SE (1<<4) #define PSA (1<<3) #define PS2 (1<<2) #define PS1 (1<<1) #define PS0 (1<<0)
/* OSCCAL bits */ static volatile bit CAL3 @ (unsigned)&OSCCAL*8+7; static volatile bit CAL2 @ (unsigned)&OSCCAL*8+6; static volatile bit CAL1 @ (unsigned)&OSCCAL*8+5; static volatile bit CAL0 @ (unsigned)&OSCCAL*8+4;
static volatile bit GP5 @ (unsigned)&GPIO*8+5; static volatile bit GP4 @ (unsigned)&GPIO*8+4; static volatile bit GP3 @ (unsigned)&GPIO*8+3; static volatile bit GP2 @ (unsigned)&GPIO*8+2; static volatile bit GP1 @ (unsigned)&GPIO*8+1; static volatile bit GP0 @ (unsigned)&GPIO*8+0;
#define CONFIG_ADDR 0xFFF
/* code protection */ #define MCLREN 0xFFFF // memory clear enable #define MCLRDIS 0xFFEF // memory clear disable
/*watchdog*/ #define WDTEN 0xFFFF // watchdog timer enable #define WDTDIS 0xFFFB // watchdog timer disable
/* code protection */ #define PROTECT 0xFFF7 // protect the program code #define UNPROTECT 0xFFFF // do not protect the program code
/*osc configurations*/ #define EXTRC 0xFFFF // external resistor/capacitor #define INTRC 0xFFFE // internal #define XT 0xFFFD // crystal/resonator #define LP 0xFFFC // low power crystal/resonator
/* 93LC46 I/O pin define */ #define CS GP0 //Chip Select #define CLK GP1 //Serial Data Clock #define DI GP2 //Serial Data Input #define DO GP4 //Serial Data Output
void Delay(unsigned int counter); void Pulse(void); void StartBit(void); void EWEN(void); void EWDS(void); extern void Write93LC46(unsigned char Offset_Addr, unsigned int tx_data); extern unsigned int Read93LC46(unsigned char Offset_Addr); void InitPIC(void);
#define CLRWDT() asm(" clrwdt") #define SLEEP() asm(" sleep")
#define ___mkstr1(x) #x #define ___mkstr(x) ___mkstr1(x) #define __CONFIG(x) asm("\tpsect config,class=CONFIG,delta=2"); asm("\tglobal\tconfig_word"); asm("config_word"); asm("\tdw "___mkstr(x))
#define __IDLOC(w) asm("\tpsect idloc,class=IDLOC,delta=2"); asm("\tglobal\tidloc_word"); asm("idloc_word"); asm("\tirpc\t__arg," ___mkstr(w)); asm("\tdw 0&__arg&h"); asm("\tendm")
__CONFIG(MCLRDIS & WDTDIS & EXTRC & PROTECT);
/*---------------------------------------------------- Function : Delay Input : unsigned int (counter) Output : None Description : Delay routine if counter=1 delay 35us , if counter=10 delay 134us, if counter=100 delay 1.12ms, These delay is base on internal 4MHz ------------------------------------------------------*/ void Delay(unsigned int counter) { while(counter>0) counter--; }
/*---------------------------------------------------- Function : Pulse Input : None Output : None Description : Send a pulse (10) to Serial Data Clock(CLK) ------------------------------------------------------*/ void Pulse(void) { CLK = 1; Delay(25); CLK = 0; }
/*---------------------------------------------------- Function : StartBit Input : None Output : None Description : 1. Set Chip Select(CS) = 1 (high) 2. Set a Start Bit(1) to Serial Data Input(DI) ------------------------------------------------------*/ void StartBit(void) { CS = 1; DI = 1; Pulse(); }
/*---------------------------------------------------- Function : EWEN Input : None Output : None Description : ERASE/WRITE Enable ------------------------------------------------------*/ void EWEN(void) { unsigned char i,temp;
StartBit(); /* 1 */
temp = 0x80; /* 0011xxxx ,(opcode:00, Address:11xxxx) */ for(i=0; i<8; i++) { if(0x30 & temp) DI = 1; else DI = 0; Pulse(); temp >>= 1; }
CS = 0; }
/*---------------------------------------------------- Function : EWDS Input : None Output : None Description : ERASE/WRITE Disable ------------------------------------------------------*/ void EWDS(void) { unsigned char i;
StartBit(); /* 1 */
DI = 0; /* 0000xxxx, (opcode:00, Address:00xxxx) */ for(i=0; i<8; i++) Pulse();
CS = 0; }
/*---------------------------------------------------- Function : Write93LC46 Input : unsigned char Offset Address, unsigned int tx_data Output : None Description : Write 16bits data in to 93LC46 Offset Address ------------------------------------------------------*/ void Write93LC46(unsigned char Offset_Addr, unsigned int tx_data) { unsigned char Addr, i; unsigned int temp;
EWEN();
StartBit(); /* 1 */ Offset_Addr=Offset_Addr&0x3F; /* 6bits address */ Addr = Offset_Addr + 0x40; /* 01AAAAAA ,(opcode:01, address:AAAAAA) */ temp = 0x0080; for(i=0; i<8; i++) { if(Addr & temp) DI = 1; else DI = 0; Pulse(); temp >>= 1; }
temp = 0x8000; /* DDDDDDDDDDDDDDDD(16bits data)*/ for(i=0; i<16; i++) { if(tx_data & temp) DI = 1; else DI = 0; Pulse(); temp >>= 1; } CS = 0;
EWDS(); }
/*---------------------------------------------------- Function : Read93LC46 Input : unsigned char Offset Address Output : unsigned int Description : Read 16bits data from 93LC46 offset address ------------------------------------------------------*/ unsigned int Read93LC46(unsigned char Offset_Addr) { unsigned char Addr, i, temp; unsigned int rx_data;
StartBit(); /* 1 */ Offset_Addr = Offset_Addr&0x3F; /* 6bits address */ Addr = Offset_Addr + 0x80; /* 10AAAAAA ,(opcode:10, address:AAAAAA) */ temp = 0x80; for(i=0; i<8; i++) { if(Addr & temp) DI = 1; else DI = 0; Pulse(); temp >>= 1; }
rx_data = 0x0000; /* DDDDDDDDDDDDDDDD(16bits data)*/ for(i=0; i<16; i++) { Pulse(); if(DO) rx_data |= 0x0001; if(i < 15) rx_data <<= 1; } CS = 0;
return(rx_data); }
void InitPIC(void) { OPTION = (GPWU | GPPU | PS2 | PS1 | PS0); TRIS = 0x10; CS = 0; CLK = 0; DI = 0; }
/* Main routine */ void main(void) { unsigned char addr; unsigned int rx_buf; InitPIC(); /* Read a word then +1 and write back to 93LC46 */ for (addr = 0; addr < 10; addr++) { rx_buf = Read93LC46(addr); rx_buf = rx_buf+1; Write93LC46(addr, rx_buf); }
}