|
|
View previous topic :: View next topic |
Author |
Message |
leevise
Joined: 05 Aug 2010 Posts: 89
|
internal EEPROM of PIC16F877A #rom |
Posted: Mon Feb 04, 2013 7:17 am |
|
|
hello guys
I use the internal eeprom for saving "min,sec"value ,it is a RTC project.
my code is as follow"
Code: |
#include <16f877a.h>
#fuses XT,NOWDT,PUT,NOPROTECT
#use delay(CLOCK=4000000)
#define RA 0x5
#define RB 0x6
#define RC 0x7
#define RD 0X8
.......
#ROM 0x2100={0x00,0x01}
..........
main()
{
..........
min=30;//initial value
sec=00; //initial value
write_eeprom(0x00,min);
write_eeprom(0x01,sec);
...........
..........
min=read_eeprom(0x00);
sec=read_eeprom(0x01);
...........
}
|
when the code run, i got the "min=30,sec=1" via segment led.
why occur the sec wrong vlaue? the "sec" value should "0" not is "1"
Thanks a lot
Last edited by leevise on Mon Feb 04, 2013 8:17 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon Feb 04, 2013 8:13 am |
|
|
I'm surprised it runs at all:
Code: |
#fuses XT,NOWDT,PUT,NOPROTECT
#use delay(CLOCK=14000000)
|
What is the maximum clock rate supported by XT?.
Best Wishes |
|
|
leevise
Joined: 05 Aug 2010 Posts: 89
|
|
Posted: Mon Feb 04, 2013 8:18 am |
|
|
Ttelmah wrote: | I'm surprised it runs at all:
Code: |
#fuses XT,NOWDT,PUT,NOPROTECT
#use delay(CLOCK=14000000)
|
What is the maximum clock rate supported by XT?.
Best Wishes |
I wrote it wrong, it should be 4Mhz. |
|
|
ronaldoklais
Joined: 18 Dec 2012 Posts: 13
|
|
Posted: Mon Feb 04, 2013 9:07 am |
|
|
int8 byte_address = 0;
int8 value = 123;
write_eeprom(0x2100 + byte_address, value);
then to read:
read_eeprom(0x2100 + byte_address); |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 04, 2013 3:43 pm |
|
|
Quote: | write_eeprom(0x2100 + byte_address, value);
then to read:
read_eeprom(0x2100 + byte_address);
|
This is wrong. You do not add the hardware address of the data eeprom
to the basic address.
Example of how to use #rom, read_eeprom() and write_eeprom():
http://www.ccsinfo.com/forum/viewtopic.php?t=32722 |
|
|
leevise
Joined: 05 Aug 2010 Posts: 89
|
|
Posted: Mon Feb 04, 2013 6:51 pm |
|
|
PCM programmer wrote: | Quote: | write_eeprom(0x2100 + byte_address, value);
then to read:
read_eeprom(0x2100 + byte_address);
|
This is wrong. You do not add the hardware address of the data eeprom
to the basic address.
Example of how to use #rom, read_eeprom() and write_eeprom():
http://www.ccsinfo.com/forum/viewtopic.php?t=32722 |
@PCM
I also don't understand about the #ROM define. Do you think where my code is wrong?
My value isn't float variable, but they are int variable.
Thank you |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 04, 2013 6:55 pm |
|
|
Post a small but complete test program that shows all the variable
declarations, and that compiles OK. Also post your compiler version. |
|
|
leevise
Joined: 05 Aug 2010 Posts: 89
|
|
Posted: Mon Feb 04, 2013 7:36 pm |
|
|
PCM programmer wrote: | Post a small but complete test program that shows all the variable
declarations, and that compiles OK. Also post your compiler version. |
my code is as follow:
Code: |
#include <16f877a.h>
#fuses HS,NOWDT,PUT,NOPROTECT
#use delay(CLOCK=4000000) //
#define RA 0x5
#define RB 0x6
#define RC 0x7
#define RD 0X8
#define uchar unsigned char
#define uint unsigned int
/*--------------------------------------------
//****** HD7279A instructions ******
//Hd7279A is a Segment LED driver chip, its' function is similar with MAX7219
--------------------------------------------*/
#define CMD_RESET 0xa4 //reset
#define DECODE0 0x80 //decodeing mode 0
#define ACTCTL 0x98 //blanketing
//================================//
#bit M1=RD.5
#bit M2=RD.4
//=========HD7279A interface communicate with 16F==========//
#bit cs=RA.0
#bit clk=RA.1
#bit dat=RA.2
//===========input signals =============//
#bit start=RB.1 //start/stop
#bit reset=RB.2 //reset
#bit counter=RB.4 //counter
#bit time=RB.5 //adjust min value
//================================//
uchar digit[6];
uchar count_10ms,i;
uchar min=30,sec=00,number=00;
//void long_delay(void); // 50us
//void short_delay(void); // 8us
//void delay10ms(void); // 10mS
void write7279(unsigned char, unsigned char);//write into HD7279
void send_byte(unsigned char); //send a byte
#zero_ram //
#ROM 0x2100 = {0x00,0x01} //eeprom
/*--------------------------------------------*/
//send a bye to HD7279
void send_byte( unsigned char out_byte)
{
uchar i;
cs=0;
delay_us(50);//long_delay();
for (i=0;i<8;i++)
{
if (out_byte&0x80)
{ dat=1;
}
else
{ dat=0;
}
clk=1;
delay_us(8);//short_delay();
clk=0;
delay_us(8);//short_delay();
out_byte=out_byte<<1;
}
dat=0;
}
/*=========write HD7279A===*/
void write7279(unsigned char cmd, unsigned char dta)
{
send_byte (cmd);
send_byte (dta);
}
//=================================//
/****************/
void conv1(uchar in1,uchar in2)//min,sec,number
{
digit[0]=in1/10; // min
digit[1]=in1%10; // min
digit[2]=in2/10; // sec
digit[3]=in2%10; // sec
}
void conv2(uchar in3)
{
digit[4]=in3/10; // number
digit[5]=in3%10; // number
}
/********display function********/
void display1()
{
conv1(min,sec); //write the initail value :min=30.sec=00.
write7279(DECODE1+0, digit[0]);
write7279(DECODE1+1, digit[1]);
write7279(DECODE1+2, digit[2]);
write7279(DECODE1+3, digit[3]);
write7279(DECODE1+4, digit[4]);
write7279(DECODE1+5, digit[5]);
}
void display2()
{
conv2(number); //write the initail value :number=00
write7279(DECODE1+4, digit[4]);
write7279(DECODE1+5, digit[5]);
}
/********timer ******/
#int_timer1
void timer1_init()
{
set_timer1(0x0bdb);
count_10ms++; //
M1=M2=1;
if(count_10ms >= 2)
{
count_10ms = 0; //
sec++; //
M1=M2=0;
if(sec == 60)
{
sec = 00;
min--; //
if(min ==00)
{
min = 30;sec=00;
}
}
}
}
/********counter******/
#int_rb
void count()
{
//int state;
if(counter==1)
{
//delayms(50);// I write a wrong ,this sentence is no used
if(counter==1)
{
while(!counter);
number++;
write_eeprom(0, number);
if(number>99)
{
number=0;
}
}
}
}
/*========*/
void main()
{
output_d(0x00);
set_tris_a(0x00);
set_tris_b(0xff);
port_b_pullups(true);
send_byte(0xa4);//
set_tris_d(0x00);
delay_ms(250);
number = read_eeprom(0);
min = read_eeprom(0x01);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
set_timer1(0x0bdb);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
while(true)
{
if(start==1)
{
disable_interrupts(INT_TIMER1);
display1();
//display2();
if(reset==1)
{
reset_cpu();
send_byte(0xa4);//
delay_ms(10);
}
else if(time==1)
{
delay_ms(100);
if(time==1)
{
while(!time);
min++;
write_eeprom(0x01,min);
if(min==80)
{
min=30;
}
}
}
}
else
{
enable_interrupts(INT_TIMER1);
display1();
display2();
}
}
}
|
the complier version is 4.110
Last edited by leevise on Mon Feb 04, 2013 9:13 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 04, 2013 8:38 pm |
|
|
Your #int_rb function doesn't clear the mismatch condition that causes
the Interrupt-on-Change interrupt. To do this, you must read PortB
in the interrupt routine. Add the lines shown in bold below:
Quote: |
#int_rb
void count()
{
int8 temp;
temp = input_b();
//int state;
if(counter==1)
{
delayms(50);
if(counter==1)
{
while(!counter);
number++;
write_eeprom(0, number);
if(number>99)
{
number=0;
}
}
}
} |
Also, I don't know if this is real code because this is not a
CCS function name:
It's delay_ms() |
|
|
leevise
Joined: 05 Aug 2010 Posts: 89
|
|
Posted: Mon Feb 04, 2013 9:16 pm |
|
|
PCM programmer wrote: | Your #int_rb function doesn't clear the mismatch condition that causes
the Interrupt-on-Change interrupt. To do this, you must read PortB
in the interrupt routine. Add the lines shown in bold below:
Quote: |
#int_rb
void count()
{
int8 temp;
temp = input_b();
//int state;
if(counter==1)
{
delayms(50);
if(counter==1)
{
while(!counter);
number++;
write_eeprom(0, number);
if(number>99)
{
number=0;
}
}
}
} |
Also, I don't know if this is real code because this is not a
CCS function name:
It's delay_ms() |
Yes, this sentence is no used. I forget cancel it, sorry. I modified code. pls check it.
About the #ROM define is right?
and i set the write_eeprom/read_eeprom is also right ?
I only get a right value from read the 0x00 address, when read the 0x01 address, get wrong value. |
|
|
andrewg
Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia
|
|
Posted: Tue Feb 05, 2013 7:23 am |
|
|
Try this: Code: | #rom int8 getenv("EEPROM_ADDRESS") = {0x00, 0x01}; |
Using getenv saves you having to remember which address to use for different model PICs. See the CCS manual for details on what int8 does. _________________ Andrew |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Tue Feb 05, 2013 7:57 am |
|
|
As a comment, worth saying that a lot depends on what you have been trying to do.....
The EEPROM has a limited write life (how many times you can write to a cell in it). On the chip involved here, only 'guaranteed' at 10000 cycles. If you wrote to the cell in a loop, you can kill a cell in the EEPROM in just 40 seconds. Given the reference to 'seconds', if you wrote once per second, you can kill the cell in under three hours.
I'd suspect you are trying to write a 'time' to the EEPROM. If so, don't....
The way this is done in normal kit, is either to use a small area of battery backed RAM (which doesn't have this limitation), or to detect when power goes 'off', and have enough supply capacitance, to only write to the chip during the few mSec _after_ power goes off. This way things like 'seconds', can be kept in RAM during normal operation, and the EEPROM only uses a life when the chip is turned off.
EEPROM is not designed for anything that changes at all frequently.
Best Wishes |
|
|
leevise
Joined: 05 Aug 2010 Posts: 89
|
|
Posted: Mon Feb 18, 2013 8:19 am |
|
|
I use the Debug mode, when watch the
Code: | min = read_eeprom(0x01);
|
I got the error code ERROR #117:Improper use of a function identifier, the lED display the min=1, it should get 00.
Why ? |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|