View previous topic :: View next topic |
Author |
Message |
lisek_lichu
Joined: 27 Aug 2012 Posts: 23
|
access to a RAM array in a loop |
Posted: Thu Aug 08, 2013 12:45 pm |
|
|
Hello,
I am looking for some solution to my program. I am trying to write a LCD routine to display some text from specified RAM memory in a loop.
I want to allocate some array 2x16 [32] bytes in RAM memory for example at 0x20 in PIC16F628 to 0x3F and put there some values to display on LCD. Program should read every byte starting from 0x20 to 0x3F and display each on LCD in a loop. So if nothing changes in RAM memory LCD will still read and display the same text on display till some changes appears in RAM memory.
Then if I change text in RAM so in next loop LCD will read something new it will display it on screen.
for example:
Code: | int8 LCDtext[32];
#locate LCDtext = 0x20
LCDtext = "test of LCD display to check it!";
lcd_init();
for(i=1; i<=16; i++)
{
lcd_gotoxy(1,i);
lcd_putc(LCDtext[i-1]);
lcd_gotoxy(2,i);
lcd_putc(LCDtext[16+i-1]);
} |
and for now that works but it uses LCDtext array and I need to do something like this:
Code: | for(i=1; i<=16; i++)
{
lcd_gotoxy(1,i);
lcd_putc(get_value(0x20 + (i-1)));
lcd_gotoxy(2,i);
lcd_putc(get_value(0x20 + (i-1)));
} |
and also some functionality like put_value(address, value)
I found that post http://kanaweb.wmrp.com/forum/viewtopic.php?p=35212 but this is not what i need. I am looking for some function like:
get_value(RAM_address)
put_value(RAM_address, value)
without declaring #byte for every byte in RAM memory to get it address.
Can it be done like that? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Thu Aug 08, 2013 2:13 pm |
|
|
In C, just use *. It is built into the language.
lcd_putc(*(int8 *)(0x20+i));
Reads a byte at address 0x20+i.
(*(int8 *)(0x20+i))=val_you_want;
Writes a byte to address 0x20+i.
* says 'treat the following number as an address, and access this address in RAM memory'.
Best Wishes |
|
|
lisek_lichu
Joined: 27 Aug 2012 Posts: 23
|
|
Posted: Thu Aug 08, 2013 2:15 pm |
|
|
Thanks a lot, I will try it in a moment |
|
|
lisek_lichu
Joined: 27 Aug 2012 Posts: 23
|
|
Posted: Thu Aug 08, 2013 3:01 pm |
|
|
Ok something I am doing wrong:
Code: |
#define LCD_data_address 0x20
char LCDtext[32];
#locate LCDtext = LCD_data_address
int get_value(*(int8 *)(LCD_data_address + int offset))
{
return 0;
}
int set_value(*(int8 *)(LCD_data_address + int offset))
{
return 0;
}
|
i get errors like:
Expecting an identifier
Expecting a declaration
Identifier is already used in this scope
More info: First Declaration of offset |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Fri Aug 09, 2013 12:35 am |
|
|
Your code needs to be in a different line from the statement declaration. This is standard C. You are trying to do all the work in the declaration line, and then not returning anything.....
Your declaration is rather how you would code for a #define, but written as a function...
You don't really need a function at all:
Code: |
#define get_byte(offset) (*(int8 *)(offset+LCD_data_address))
#define write_byte(offset,val) *(int8 *)(offset+LCD_data_address)=val
//Then use like
#define LCD_data_address 0x20
char LCDtext[32];
#locate LCDtext = LCD_data_address
int8 val;
int8 offset=0x10;
val=get_byte(offset); //reads the byte from address 0x30
write_byte(offset+1,0xAA); //Writes 0xAA to 0x31
|
To do it as a function you'd need:
Code: |
int8 get_value(int8 offset)
{
return *((int8 *)(LCD_data_address + offset));
}
|
Get a C textbook, and study how functions are declared. |
|
|
lisek_lichu
Joined: 27 Aug 2012 Posts: 23
|
|
Posted: Sun Aug 11, 2013 1:53 pm |
|
|
Ok i created two functions and tested them on device, they works
thanks for help
LCD array of 32 signs is located in RAM memory starting from 0x20
Code: |
#define LCD_data_address 0x20
char LCDtext[32];
#locate LCDtext = LCD_data_address
///////////////////////////////////////////////////
//
// function get one char from LCD buffer
//
///////////////////////////////////////////////////
char get_LCD_value(unsigned int offset)
{
if(offset <= 32 && offset >=1)
{
return *((char *)(LCD_data_address + offset - 1));
}
else
{
return 0;
}
}
///////////////////////////////////////////////////
//
// function set one char to LCD buffer
//
///////////////////////////////////////////////////
void set_LCD_value(unsigned int offset, char value)
{
if(offset <= 32 && offset >=1)
{
*((unsigned int *)(LCD_data_address + offset - 1)) = value;
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Sun Aug 11, 2013 2:50 pm |
|
|
The added bounds testing for this, is _very sensible indeed_.
Best Wishes |
|
|
lisek_lichu
Joined: 27 Aug 2012 Posts: 23
|
|
Posted: Sun Aug 11, 2013 3:27 pm |
|
|
are these bound ok or You are laughing at me beacuse they are unnecessary for some reason? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Mon Aug 12, 2013 12:22 am |
|
|
No.
Smiling, not laughing. So few people realise that when using pointers (or arrays), that it is terribly 'easy' to go beyond the area they are meant to be using, and end up walking 'over' other memory....
Best Wishes |
|
|
|