| 
	
	|  |  |  
	
		| 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: 19964
 
 
 
			    
 
 | 
			
				|  |  
				|  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: 19964
 
 
 
			    
 
 | 
			
				|  |  
				|  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
 
 |