1822_eeprom

1822_eeprom
/*************************************************
EEPROM R/W testing by PIC12F1822
I2C LCD display and internal clock
By nobcha all right reserved
Ver 1.0 10/22/2011 for 24LC64
PIC12F1822 + LCD via I2C +24LC64
PIN Assign
#7 RA0:Monitor LED
#6 RA1:SDA I2C data
#5 RA2:SCL I2C clock
#4 RA3:Set select
#3 RA4:Down sw
#2:RA5:Up sw
OSC INT 8MHz
Development Circumstance
MPLAB IDE V8.73
HiTECH C V9.82
SWITCH
LATA3
LATA5
LATA4
input is
for MODE SET
for UP
for DOWN
24LC64 ADDRESS 0xA0
LCD ADDRESS 0x7C
**************************************************/
#define _XTAL_FREQ 8000000
#include
#include
#include
#include
#include
#include
#define
#define
#define
#define
<htc.h>
<pic.h>
<stdio.h>
<string.h>
"delay.h"
"lcd_i2c_mssp.h"
ROM24LC64 0xA0
Set_sw RA3
Down_sw RA4
Up_sw RA5
__CONFIG(
FOSC_INTOSC & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_OFF
& CPD_OFF & BOREN_OFF & CLKOUTEN_OFF & IESO_OFF & FCMEN_OFF
);
__CONFIG(
WRT_OFF & PLLEN_OFF & STVREN_ON &
);
LVP_OFF
unsigned char i ;
char data[8];
unsigned char set_pos;
char Msg1[16] = "i2c EEPROM TEST\0";
char Msg2[17] = "R_Byt #Addr #Dt \0";
char cmdline[4][6] = {{"W BYT\0"},{"R BYT\0"},{"W BLK\0"},{"R BLK\0"}};
char LCD_POS[3]={0x41,0x46,0x4C};
char EEPROM_MODE=0x00;
short EEPROM_ADDR=0x00;
char EEPROM_DATA=0x00;
//
//
//
//
R_Byt #xxxx #xx
EEPROM managemen mode
EEPROM management
EEPROM managemen data
/*******************************
* EEEPROMへデータ1バイト出力
*******************************/
void eep_write(unsigned short addr, unsigned char data){
unsigned char addr_data;
i2c_writeto(ROM24LC64);
// EEPROMアドレスをWRITE MODE で OPEN
addr_data=(unsigned char)((addr>>8)&0xFF);
i2c_write(addr_data);
// word high address
ページ(1)
}
addr_data=(unsigned char)(addr&0xFF);
i2c_write(addr_data);
i2c_write(data);
i2c_stop();
1822_eeprom
// word low address
// DATA バイトを送る
// stop コンディション
/*******************************
* EEEPROMからデータ1バイト取得
*******************************/
char eep_read(unsigned short addr){
char data1;
i2c_writeto(ROM24LC64);
// EEPROMアドレスをREAD MODE で OPEN
i2c_write((unsigned char)((addr>>8)&0xFF));
// word high address
i2c_write((unsigned char)(addr&0xFF));
// word low address
i2c_readfrom(ROM24LC64);
// RTCアドレスをREAD MODE で REOPEN
data1=i2c_read();
// DATA バイトを取得する
i2c_sendack(1);
// send NAK
i2c_stop();
// stop コンディション
return data1;
}
/*******************************
* EEEPROMへデータ8バイト書き込み
*******************************/
void eeprom_writestr(unsigned short addr, unsigned char data1){
unsigned char i ;
i2c_writeto(ROM24LC64);
// EEPROMアドレスをWRITE MODE で OPEN
i2c_write((unsigned char)((addr>>8)&0xFF));
// word high address
i2c_write((unsigned char)(addr&0xFF)); // word low address
for (i=0;i<8;i++){
// 32 bytes for 1 block
i2c_write(data1);
// DATA バイトを送る
}
i2c_stop();
// stop コンディション
}
/***********************************
* EEEPROMからデータ8バイト分をWORKへ取り込み
***********************************/
void eeprom_readstr(unsigned short addr, unsigned char *data ){
unsigned char i ;
i2c_writeto(ROM24LC64);
// EEPROMアドレスをWRITE MODE で OPEN
i2c_write((unsigned char)((addr>>8)&0xFF));
// word high address
i2c_write((unsigned char)(addr&0xFF));
// word low address
i2c_readfrom(ROM24LC64);
// EEPROMアドレスをREAD MODE で REOPEN
for (i=0;i<7;i++){
// 8 bytes for 1 block
data[i]=i2c_read();
// DATA バイトを読む
i2c_sendack(0);
// Send ACK for each Byte
}
data[7]=i2c_read();
// DATA バイトを読む
i2c_sendack(1);
// Send NACK for last Byte
i2c_stop();
// stop コンディション
}
/***************************************
/ HEX to Bynary
****************************************/
unsigned char hextob(unsigned char b2){
if(b2>0x3a){b2=b2+9;}
b2=b2&0x0F;
return (b2);
}
/***************************************
/ Bynary to HEX
****************************************/
unsigned char btohex(unsigned char b2){
b2=b2&0x0f;
if(b2>9){b2=b2+7;}
b2=b2 + 0x30 ;
return (b2);
}
// over 0x3A alphabet
// more than 9 0x30+7=0x40
/***************************************
/ data increment and MAX check
****************************************/
ページ(2)
1822_eeprom
void data_inc(unsigned char set_pos ){
switch(set_pos){
case 0:
// 0<MODE<4
EEPROM_MODE++;
if(EEPROM_MODE==4){EEPROM_MODE=0;}
break;
case 1: EEPROM_ADDR++;
// 0<ADDR<0x2000
if(EEPROM_ADDR>0x1FFF){EEPROM_ADDR=0;}
break;
case 2: EEPROM_DATA++;
// 0<DATA<0x100
break;
}
}
/***************************************
/ data decrement and 0 check
****************************************/
void data_dec(unsigned char set_pos){
switch(set_pos){
case 0:
if(EEPROM_MODE==0){EEPROM_MODE=0x4;}
EEPROM_MODE--;
break;
case 1: EEPROM_ADDR--;
if(EEPROM_ADDR<0){EEPROM_ADDR=0x1FFF;}
break;
case 2: EEPROM_DATA--;
break;
}
}
/***************************************
* cmd line data display
****************************************/
void disp_cmdline(void){
lcd_goto(40);
// goto 2nd line
lcd_str(cmdline[EEPROM_MODE]);
lcd_data(0x20);
lcd_data(0x23);
lcd_data(btohex((EEPROM_ADDR>>12)&0x0F));
lcd_data(btohex((EEPROM_ADDR>>8)&0x0F));
lcd_data(btohex((EEPROM_ADDR>>4)&0x0F));
lcd_data(btohex(EEPROM_ADDR&0x0F));
lcd_data(0x20);
lcd_data(0x23);
lcd_data(btohex((EEPROM_DATA>>4)&0x0F));
lcd_data(btohex(EEPROM_DATA&0x0F));
}
/***************************************
* MSSP initialize
****************************************/
void mssp_init(void){
/* SSP1CON1 REGISTERS */
SSPEN
= 1;
// Enables Serial Port Mode
SSPM3
= 1;
//
SSPM2
= 0;
// I2C Master Mode
SSPM1
= 0;
// clock= Fosc/(4*(SSP1ADD+1))
SSPM0
= 0;
//
/* SSPCON2
SSP1CON2
/* SSPCON3
SSP1CON3
REGISTERS */
= 0x00;
REGISTERS */
= 0x00;
/* SSP1STAT REGISTERS */
SMP
= 1;
CKE
= 0;
//SSP1ADD
//SSP1ADD
//SSP1ADD
SSP1ADD
= 0x19;
= 0x13;
= 0x07;
= 0x50;
// SPI MASTER MODE
// SMBus Specific Inputs Enabled
//~75kHz
//~100kHz
//~400kHz
ページ(3)
1822_eeprom
}
// Interrupt routine no mean
void interrupt clk1hz(void){
GIE=0;
}
void main(){
unsigned char i, j, zero_sup,disp_data ;
PORTA = 0b00000000;
ANSELA = 0b00000000;
//
TRISA = 0b00111110;
/*
^---------------led
^---------------SDA
^--------------SCL
^-------------SEL
^-------------Down
^-------------Up
// PORT clear
// all digital
*/
OSCCON = 0b01110000;
/*
^^^^------------IRCF:8MHz
^----------SCS:int */
OPTION_REG = 0b10110001;
/*
^------------Weak up disable
^----------TMR0CS:RA2/T0CKI
^---------TMR0SE:H->L of RA2/T0CKI
^--------PSA:assinged
^^^-----PS:1:4 */
//
0
INTCON=0;
T1CON = 0b11000000;
// INT off
// Timer1 CPS, T1CKPS:00, T1OSC DIS,T1SYNC, TMR1 off
T1GCON = 0b00000000;
PIR1 = 0b00000000;
// ADIF 0,RCIF 0,TXIF 0,SSPIF 0,CCP1IF 0,TMR2IF 0,TMR1IF
CM1CON0 = 0x00000111;
__delay_ms(200);
mssp_init();
__delay_ms(200);
__delay_ms(200);
//
lcd_init();
__delay_ms(200);
__delay_ms(200);
__delay_ms(200);
__delay_ms(200);
__delay_ms(200);
RA0=0;
while(1){
lcd_goto(0x00);
lcd_str(Msg1);
for(i=0;i<10;i++){lcd_data(0x20);}
// Compalator off
// LCD initialize
// select first line
//
// space padding
lcd_goto(0x40);
// select second line
lcd_str(Msg2);
//
set_pos=0;
// Set position CTRL 0:R/W,1;Addr,3:Data
while(Set_sw==1){}
if(Set_sw==0){
// if RA3==0 Set mode
__delay_ms(100);
if(Set_sw==0){
while(set_pos<4){
// set_pos>4
lcd_goto(LCD_POS[set_pos]);
__delay_ms(100);
while((PORTA&0x38)!=0x38){}
// Wait Switch on
__delay_ms(100);
// Wait a time
if(Up_sw==0){ data_inc(set_pos);}
if(Down_sw==0){ data_dec(set_pos);}
if(Set_sw==0){ set_pos++;}
disp_cmdline();
if(((EEPROM_MODE&0x1)==0x1 ) & (set_pos>1)){set_pos++;}
}
switch(EEPROM_MODE){
ページ(4)
1822_eeprom
case 0: eep_write(EEPROM_ADDR,EEPROM_DATA);
break;
case 1: lcd_goto(0x4D);
disp_data=eep_read(EEPROM_ADDR);
lcd_data(btohex((disp_data>>4)&0x0F));
lcd_data(btohex(disp_data&0x0F));
break;
case 2: eeprom_writestr(EEPROM_ADDR,EEPROM_DATA);
break;
case 3: eeprom_readstr(EEPROM_ADDR,data);
lcd_goto(0x0);
for(i=0;i<8;i++){
lcd_data(0x23);
// sepalator #
lcd_data(btohex((data[i]>>4)&0x0F));
lcd_data(btohex(data[i]&0x0F));
}
break;
}
lcd_data(0x24);
__delay_ms(200);
__delay_ms(200);
__delay_ms(200);
__delay_ms(200);
while (Set_sw==1){}
on
}
}
}
// Command complete mark $
// Display until set switch turn
}
RA0=1;
__delay_ms(200);
__delay_ms(200);
RA0=0;
// EXIO RA0
ページ(5)