View Full Version : PIC C, salvare dati nella eeprom
Salve a tutti, avrei bisogno di un aiutino con il PIC C (il C per i microcontrollori PIC, per chi non lo sapesse, ma se qualcuno non lo sa non può comunque aiutarmi, quindi era una precisazione inutile :D ).
Devo inserire dei dati nella eeprom del pic, sia a livello di programmazione sia a livello di esecuzione (in pratica, inserisco dei valori e lui deve salvarli sulla sua eeprom), ma non so come si fa... Che comandi si usano? Come funziona poi la lettura?
Fenomeno85
10-07-2005, 20:51
se non erro dipende dall'assembly che pic usi? io usavo il pic 16f84 e sulla guida mi sembra che c'era (guida del compilatore che non ricordo come se ciamava)
~§~ Sempre E Solo Lei ~§~
se non erro dipende dall'assembly che pic usi? io usavo il pic 16f84 e sulla guida mi sembra che c'era (guida del compilatore che non ricordo come se ciamava)
~§~ Sempre E Solo Lei ~§~
Programmo in C, non in assembler... l'ho fatto una volta ed è molto bello, però in termini di tempo è infinitamente più comodo il C con tutte le sue librerie belle pronte, tu pensa solo che per mandare su lcd basta fare un printf, pensa cosa sarebbe farlo in assembler.
Comunque ho guardato sul manuale del compilatore e ho visto che ci sono i comandi, però vogliono gli indirizzi della memoria della eeprom, ma non so dove comincia e non l'ho trovata questa informazione. Se qualcuno lo sa... per il 16f84...
Fenomeno85
10-07-2005, 21:02
mmm penso che parti da 0 quando ti riferisci alla eprom
~§~ Sempre E Solo Lei ~§~
mmm penso che parti da 0 quando ti riferisci alla eprom
~§~ Sempre E Solo Lei ~§~
No, c'è un esempio dove parte da un numero molto alto, ma non so a che pic sia riferito.
Fenomeno85
10-07-2005, 21:07
ho visto dei miei compagni che ci lavoravano sullo schermo lcd era anche divertente :D
// Program 24_256_1.C (CCS Info PCM Compiler - PIC16F84)
//
// Illustrates how to write a byte to an address and read a byte from an
// an address.
//
// May be used for the following EEPROMs;
//
// 2432 (max adr 0x0fff)
// 2465 (max adr 0x1fff)
// 24128 (max adr 0x3fff)
// 24256 (max adr 0x7fff)
//
// Program writes the 16 values 0xff, 0xfe, etc to locations beginning
// at memory adr 0x0700. Reads them back and displays on serial LCD.
//
// PIC16F84 24LC256
//
// RB1 (term 7) ------------------- SCL (term 6) ----- To Other
// RB2 (term 8) ------------------- SDA (term 5) ----- I2C Devices
//
// Note that the slave address is determined by A2 (term 3), A1
// (term 2) and A0 (term 1) on the 24LC256. The above SCL and SDA leads
// may be multipled to eight group "1010" devices, each strapped for a
// unique A2 A1 A0 setting.
//
// 10K pullup resistors to +5VDC are required on both signal leads.
//
// Serial LCD is connected to RA0. Serial data is 9600 baud, inverted.
//
//
// copyright, Peter H. Anderson, Scotland Co, NC, Mar, '99
#case
#include <16f84.h>
#include <string.h>
#include <defs_f84.h> // See Notes
// routines used for 24LC256
void random_write(byte dev_adr, long mem_adr, byte dat);
byte random_read(byte dev_adr, long mem_adr);
// common i2c routines
byte i2c_in_byte(void);
void i2c_out_byte(byte o_byte);
void i2c_nack(void);
void i2c_ack(void);
void i2c_start(void);
void i2c_stop(void);
void i2c_high_sda(void);
void i2c_low_sda(void);
void i2c_high_scl(void);
void i2c_low_scl(void);
// LCD routines
void delay_ms(long t);
void delay_10us(int t);
void lcd_init(void);
void out_RAM_str(int *s);
void lcd_hex_byte(int val);
void lcd_dec_byte(int val, int digits);
int num_to_char(int val);
void lcd_char(int ch);
void lcd_new_line(void);
#define TxData 0 // RA.0 for serial LCD
#define SDA_PIN rb2 // RB.2
#define SCL_PIN rb1 // RB.1
#define SDA_DIR trisb2
#define SCL_DIR trisb1
void main(void)
{
long mem_adr;
byte dat, n;
while(1)
{
mem_adr=0x0700;
for(n=0; n<16; n++)
{
dat = 0xff-n;
random_write(0x00, mem_adr, dat);
++mem_adr;
}
// now, read the data back and display
lcd_init();
mem_adr=0x0700;
for(n=0; n<16; n++)
{
if ((n!=0) && ((n%4) == 0))
{
lcd_new_line();
}
dat = random_read(0x00, mem_adr);
lcd_hex_byte(dat);
lcd_char(' ');
++mem_adr;
}
delay_ms(500);
} // end of while
}
void random_write(byte dev_adr, long mem_adr, byte dat)
{
i2c_start();
i2c_out_byte(0xa0 | (dev_adr << 1));
i2c_nack();
i2c_out_byte((mem_adr >> 8) & 0xff); // high byte of memory address
i2c_nack();
i2c_out_byte(mem_adr & 0xff); // low byte of mem address
i2c_nack();
i2c_out_byte(dat); // and finally the data
i2c_nack();
i2c_stop();
delay_ms(25); // allow for the programming of the eeprom
}
byte random_read(byte dev_adr, long mem_adr)
{
byte y;
i2c_start();
i2c_out_byte(0xa0 | (dev_adr << 1));
i2c_nack();
i2c_out_byte((mem_adr >> 8) & 0xff);
i2c_nack();
i2c_out_byte(mem_adr & 0xff);
i2c_nack();
i2c_start(); // no intermediate stop
i2c_out_byte(0xa1 | (dev_adr << 1)); // read operation
i2c_nack();
y=i2c_in_byte();
i2c_stop();
return(y);
}
// Common I2C Routines
byte i2c_in_byte(void)
{
byte i_byte, n;
i2c_high_sda();
for (n=0; n<8; n++)
{
i2c_high_scl();
if (SDA_PIN)
{
i_byte = (i_byte << 1) | 0x01; // msbit first
}
else
{
i_byte = i_byte << 1;
}
i2c_low_scl();
}
return(i_byte);
}
void i2c_out_byte(byte o_byte)
{
byte n;
for(n=0; n<8; n++)
{
if(o_byte&0x80)
{
i2c_high_sda();
}
else
{
i2c_low_sda();
}
i2c_high_scl();
i2c_low_scl();
o_byte = o_byte << 1;
}
i2c_high_sda();
}
void i2c_nack(void)
{
i2c_high_sda(); // data at one
i2c_high_scl(); // clock pulse
i2c_low_scl();
}
void i2c_ack(void)
{
i2c_low_sda(); // bring data low and clock
i2c_high_scl();
i2c_low_scl();
i2c_high_sda();
}
void i2c_start(void)
{
i2c_low_scl();
i2c_high_sda();
i2c_high_scl(); // bring SDA low while SCL is high
i2c_low_sda();
i2c_low_scl();
}
void i2c_stop(void)
{
i2c_low_scl();
i2c_low_sda();
i2c_high_scl();
i2c_high_sda(); // bring SDA high while SCL is high
// idle is SDA high and SCL high
}
void i2c_high_sda(void)
{
// bring SDA to high impedance
SDA_DIR = 1;
delay_10us(5);
}
void i2c_low_sda(void)
{
SDA_PIN = 0;
SDA_DIR = 0; // output a hard logic zero
delay_10us(5);
}
void i2c_high_scl(void)
{
SCL_DIR = 1; // high impedance
delay_10us(5);
}
void i2c_low_scl(void)
{
SCL_PIN = 0;
SCL_DIR = 0;
delay_10us(5);
}
// LCD routines
void delay_10us(int t)
{
#asm
BCF STATUS, RP0
DELAY_10US_1:
CLRWDT
NOP
NOP
NOP
NOP
NOP
NOP
DECFSZ t, F
GOTO DELAY_10US_1
#endasm
}
void delay_ms(long t) // delays t millisecs
{
do
{
delay_10us(100);
} while(--t);
}
int num_to_char(int val) // converts val to hex character
{
int ch;
if (val < 10)
{
ch=val+'0';
}
else
{
val=val-10;
ch=val + 'A';
}
return(ch);
}
void lcd_char(int ch) // serial output to PIC-n-LCD, 9600 baud
{
int n, dly;
// start bit + 8 data bits
#asm
BCF STATUS, RP0
MOVLW 9
MOVWF n
BCF STATUS, C
LCD_CHAR_1:
BTFSS STATUS, C
BSF PORTA, TxData
BTFSC STATUS, C
BCF PORTA, TxData
MOVLW 32
MOVWF dly
LCD_CHAR_2:
DECFSZ dly, F
GOTO LCD_CHAR_2
RRF ch, F
DECFSZ n, F
GOTO LCD_CHAR_1
BCF PORTA, TxData
CLRWDT
MOVLW 96
MOVWF dly
LCD_CHAR_3:
DECFSZ dly, F
GOTO LCD_CHAR_3
CLRWDT
#endasm
}
// LCD routines
void lcd_init(void) // sets TxData in idle state and resets PIC-n-LCD
{
#asm
BCF STATUS, RP0
BCF PORTA, TxData
BSF STATUS, RP0
BCF TRISA, TxData
BCF STATUS, RP0
#endasm
lcd_char(0x0c);
delay_ms(250);
}
void lcd_new_line(void) // outputs 0x0d, 0x0a
{
lcd_char(0x0d);
delay_ms(10); // give the PIC-n-LCD time to perform the
lcd_char(0x0a); // new line function
delay_ms(10);
}
void out_RAM_str(int *s)
{
while(*s)
{
lcd_char(*s);
++s;
}
}
void lcd_hex_byte(int val) // displays val in hex format
{
int ch;
ch = num_to_char((val>>4) & 0x0f);
lcd_char(ch);
ch = num_to_char(val&0x0f);
lcd_char(ch);
}
void lcd_dec_byte(int val, int digits)
// displays byte in decimal as either 1, 2 or 3 digits
{
int d;
int ch;
if (digits == 3)
{
d=val/100;
ch=num_to_char(d);
lcd_char(ch);
}
if (digits >1) // take the two lowest digits
{
val=val%100;
d=val/10;
ch=num_to_char(d);
lcd_char(ch);
}
if (digits == 1) // take the least significant digit
{
val = val%100;
}
d=val % 10;
ch=num_to_char(d);
lcd_char(ch);
}
~§~ Sempre E Solo Lei ~§~
Fenomeno85
10-07-2005, 21:08
No, c'è un esempio dove parte da un numero molto alto, ma non so a che pic sia riferito.
spero che funzioni ;)
~§~ Sempre E Solo Lei ~§~
Adesso me lo guardo e ti so dire... grazie intanto :smack: :D
Azz, queste però è fatto per le eeprom esterne, quella della serie 24xxx, io voglio usare quella interna del pic, tanto devo scriverci quattro numeri... comunque adesso provo a cercare altri esempi su internet.
Fenomeno85
10-07-2005, 21:16
Azz, queste però è fatto per le eeprom esterne, quella della serie 24xxx, io voglio usare quella interna del pic, tanto devo scriverci quattro numeri... comunque adesso provo a cercare altri esempi su internet.
visto ha 64byte di memoria per i dati ... quindi adesso devo capire dove è posizionata nel 1k
~§~ Sempre E Solo Lei ~§~
Fenomeno85
10-07-2005, 21:42
che versione hai esattamente il pic16f84 o 16f84a che ho visto che nel secondo ha 68byte cmq dovrebbero essere gli ultimi almeno credo
~§~ Sempre E Solo Lei ~§~
che versione hai esattamente il pic16f84 o 16f84a che ho visto che nel secondo ha 68byte cmq dovrebbero essere gli ultimi almeno credo
~§~ Sempre E Solo Lei ~§~
Il 16f84a. Credevo differissero solo per la massima velocità, 20Mhz per l'"a" contro 4Mhz per quello "liscio". Comunque se aggiunge quattro byte non mi cambia niente, a me interessa l'indirizzo di partenza.
Fenomeno85
11-07-2005, 10:24
Il 16f84a. Credevo differissero solo per la massima velocità, 20Mhz per l'"a" contro 4Mhz per quello "liscio". Comunque se aggiunge quattro byte non mi cambia niente, a me interessa l'indirizzo di partenza.
te hai detto che avevi un esempio che partiva da un indi alto ... prova a vedere se non è appunto dal 956 byte
~§~ Sempre E Solo Lei ~§~
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.