|
|
View previous topic :: View next topic |
Author |
Message |
vtrx
Joined: 11 Oct 2017 Posts: 142
|
How to load a content of a variable to port in ASM ? |
Posted: Thu Oct 04, 2018 6:35 am |
|
|
I'm trying to optimize a code to give exit in PORTB:
Code: | void Saida()
{
int8 count;
#asm
movlw 121
movwf count
SAIDA:
// movlw 5//Buf_VGA[count] ERROR
movwf PORTB
decfsz count
goto SAIDA
FIM:
#endasm
} |
GLOBAL
int8 Buf_VGA[244]={...
How can I do it? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Thu Oct 04, 2018 7:46 am |
|
|
You need to tell us the chip.
You are going to have to use indirect addressing, where you have a 'pointer' that says 'where' the value is going to come 'from', and increment this for each byte. Indirect addressing uses very different instructions on different PIC's...
Funnily enough, there is a thread just running about CRC's which shows a fairly generic fetch for most PIC's. So using this:
Code: |
// Setup Index Register locations (FSR and INDF)
#if defined(__PCM__) // For example (and tested on) PIC16F74, PIC16F887
#byte FSR = GETENV("SFR:FSR")
#byte INDF = GETENV("SFR:INDF")
#elif defined(__PCH__) // For example (and tested on) PIC18F458
#word FSR = GETENV("SFR:FSR0L")
#byte POSTINC0 = GETENV("SFR:POSTINC0")
#else
#Error You need to setup the above for your PIC chip
#endif
void Saida(byte * data)
{
int8 count=121; //Why? you say the array is 244 bytes?
#asm
Loop: //must not be the same name as the function
#if defined(__PCM__)
movf INDF, W // load W with next databyte
incf FSR // do a 8-bit increment - increment indirection register to point to next databyte - for the next time
#elif defined(__PCH__)
movf POSTINC0, W // load w with next databyte and increment indirection register to point to next databyte - for the next time
#else
#Error You need to setup the above for your PIC Chip
#endif
movwf PORTB
decfsz count, F
goto loop // loop for next byte
#endasm
}
|
Except for the oddity of having a 244 byte array, and a count of only 121, this should output the bytes basically as fast as possible. |
|
|
vtrx
Joined: 11 Oct 2017 Posts: 142
|
|
Posted: Thu Oct 04, 2018 8:53 am |
|
|
Thank you for helping me.
The PIC is 18F2550.
I am trying to program a VGA output but for the CCS compiler.
Using :
Code: | for(x=0; x<120 ; x++){ output_b(out_vga[x]);} | is very slow and desynchronizes the routine that is in the timer.
I'm using this for one line:
Code: | void saida_vga(void)
{
output_b(out_vga[0]);
output_b(out_vga[1]);
output_b(out_vga[2]);
output_b(out_vga[3]);
output_b(out_vga[4]);
output_b(out_vga[5]);
output_b(out_vga[6]);
output_b(out_vga[7]);
output_b(out_vga[8]);
output_b(out_vga[9]);
output_b(out_vga[10]);
output_b(out_vga[11]);
output_b(out_vga[12]);
output_b(out_vga[13]);
output_b(out_vga[14]);
output_b(out_vga[15]);
output_b(out_vga[16]);
output_b(out_vga[17]);
output_b(out_vga[18]);
output_b(out_vga[19]);
output_b(out_vga[20]);
output_b(out_vga[21]);
output_b(out_vga[22]);
output_b(out_vga[23]);
output_b(out_vga[24]);
output_b(out_vga[25]);
output_b(out_vga[26]);
output_b(out_vga[27]);
output_b(out_vga[28]);
output_b(out_vga[29]);
output_b(out_vga[30]);
output_b(out_vga[31]);
output_b(out_vga[32]);
output_b(out_vga[33]);
output_b(out_vga[34]);
output_b(out_vga[35]);
output_b(out_vga[36]);
output_b(out_vga[37]);
output_b(out_vga[38]);
output_b(out_vga[39]);
output_b(out_vga[40]);
output_b(out_vga[41]);
output_b(out_vga[42]);
output_b(out_vga[43]);
output_b(out_vga[44]);
output_b(out_vga[45]);
output_b(out_vga[46]);
output_b(out_vga[47]);
output_b(out_vga[48]);
output_b(out_vga[49]);
output_b(out_vga[50]);
output_b(out_vga[51]);
output_b(out_vga[52]);
output_b(out_vga[53]);
output_b(out_vga[54]);
output_b(out_vga[55]);
output_b(out_vga[56]);
output_b(out_vga[57]);
output_b(out_vga[58]);
output_b(out_vga[59]);
output_b(out_vga[60]);
output_b(out_vga[61]);
output_b(out_vga[62]);
output_b(out_vga[63]);
output_b(out_vga[64]);
output_b(out_vga[65]);
output_b(out_vga[66]);
output_b(out_vga[67]);
output_b(out_vga[68]);
output_b(out_vga[69]);
output_b(out_vga[70]);
output_b(out_vga[71]);
output_b(out_vga[72]);
output_b(out_vga[73]);
output_b(out_vga[74]);
output_b(out_vga[75]);
output_b(out_vga[76]);
output_b(out_vga[77]);
output_b(out_vga[78]);
output_b(out_vga[79]);
output_b(out_vga[80]);
output_b(out_vga[81]);
output_b(out_vga[82]);
output_b(out_vga[83]);
output_b(out_vga[84]);
output_b(out_vga[85]);
output_b(out_vga[86]);
output_b(out_vga[87]);
output_b(out_vga[88]);
output_b(out_vga[89]);
output_b(out_vga[90]);
output_b(out_vga[91]);
output_b(out_vga[92]);
output_b(out_vga[93]);
output_b(out_vga[94]);
output_b(out_vga[95]);
output_b(out_vga[96]);
output_b(out_vga[97]);
output_b(out_vga[98]);
output_b(out_vga[99]);
output_b(out_vga[100]);
output_b(out_vga[101]);
output_b(out_vga[102]);
output_b(out_vga[103]);
output_b(out_vga[104]);
output_b(out_vga[105]);
output_b(out_vga[106]);
output_b(out_vga[107]);
output_b(out_vga[108]);
output_b(out_vga[109]);
output_b(out_vga[110]);
output_b(out_vga[111]);
output_b(out_vga[112]);
output_b(out_vga[113]);
output_b(out_vga[114]);
output_b(out_vga[115]);
output_b(out_vga[116]);
output_b(out_vga[117]);
output_b(out_vga[118]);
output_b(out_vga[119]);
output_b(out_vga[120]);
output_b(out_vga[121]);
output_b(0);
} |
I need to change the index for each line. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Thu Oct 04, 2018 10:13 am |
|
|
That is what the code I've posted does. On the PIC18, there is a special instcuction which post increments a RAM pointer when you use it. What is missing, is the address setup:
Code: |
void Saida(byte * data)
{
int8 count=121; //Why? you say the array is 244 bytes?
#asm
#if defined(__PCM__)
movf data, W // copy pointer to w reg..
movwf FSR // ..to pointer register
#elif defined(__PCH__)
movff data, FSR0L // copy low byte of pointer to low byte of pointer register 0..
movff &p_data+1, FSR0H // copy high byte of pointer to high byte of pointer register 0..
#else
#Error You need to setup the above for your PIC Chip
#endif
Loop: //must not be the same name as the function
#if defined(__PCM__)
movf INDF, W // load W with next databyte
incf FSR // do a 8-bit increment - increment indirection register to point to next databyte - for the next time
#elif defined(__PCH__)
movf POSTINC0, W // load w with next databyte and increment indirection register to point to next databyte - for the next time
#else
#Error You need to setup the above for your PIC Chip
#endif
movwf PORTB
decfsz count, F
goto loop // loop for next byte
#endasm
}
|
This needs to be called with the address of the data, so:
Saida(Buf_VGA);
It should code as 4 instruction times per byte (a loop takes two instruction times). |
|
|
vtrx
Joined: 11 Oct 2017 Posts: 142
|
|
Posted: Thu Oct 04, 2018 10:28 am |
|
|
Compiler show a error:
*** Error 28 "main.c" Line 412(10,15): Expecting an identifier
on:
movff data, FSR0L |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Thu Oct 04, 2018 10:51 am |
|
|
You need the setup stuff loaded before it is used. The:
Code: |
// Setup Index Register locations (FSR and INDF)
#if defined(__PCM__) // For example (and tested on) PIC16F74, PIC16F887
#byte FSR = GETENV("SFR:FSR")
#byte INDF = GETENV("SFR:INDF")
#elif defined(__PCH__) // For example (and tested on) PIC18F458
#word FSR = GETENV("SFR:FSR0L")
#byte POSTINC0 = GETENV("SFR:POSTINC0")
#else
#Error You need to setup the above for your PIC chip
#endif
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Thu Oct 04, 2018 10:54 am |
|
|
hmm.... FSROL should be FSR0L
Is that a captial 'O' ?
It should be the number '0' ( zero).
very hard to tell with the font, but if you look at Mr. T.'s post you can just see a slight differenec in an 'O' versus a '0'.
in this msg the 0 (zero) is thinner.
Jay |
|
|
vtrx
Joined: 11 Oct 2017 Posts: 142
|
|
Posted: Thu Oct 04, 2018 10:59 am |
|
|
This way?
Code: | // Setup Index Register locations (FSR and INDF)
#if defined(__PCM__) // For example (and tested on) PIC16F74, PIC16F887
#byte FSR = GETENV("SFR:FSR")
#byte INDF = GETENV("SFR:INDF")
#elif defined(__PCH__) // For example (and tested on) PIC18F458
#word FSR = GETENV("SFR:FSR0L")
#byte POSTINC0 = GETENV("SFR:POSTINC0")
#else
#Error You need to setup the above for your PIC chip
#endif
void Saida(byte * data)
{
int8 count=121; //Why? you say the array is 244 bytes?
#asm
Loop: //must not be the same name as the function
#if defined(__PCM__)
movf INDF, W // load W with next databyte
incf FSR // do a 8-bit increment - increment indirection register to point to next databyte - for the next time
#elif defined(__PCH__)
movf POSTINC0, W // load w with next databyte and increment indirection register to point to next databyte - for the next time
#else
#Error You need to setup the above for your PIC Chip
#endif
movwf PORTB
decfsz count, F
goto loop // loop for next byte
#endasm
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Thu Oct 04, 2018 11:01 am |
|
|
No that is missing the stuff that actually programs the FSR. That's why I posted the modified version of the function. |
|
|
vtrx
Joined: 11 Oct 2017 Posts: 142
|
|
Posted: Thu Oct 04, 2018 11:03 am |
|
|
Can't compile this code:
Code: | // Setup Index Register locations (FSR and INDF)
#if defined(__PCM__) // For example (and tested on) PIC16F74, PIC16F887
#byte FSR = GETENV("SFR:FSR")
#byte INDF = GETENV("SFR:INDF")
#elif defined(__PCH__) // For example (and tested on) PIC18F458
#word FSR = GETENV("SFR:FSR0L")
#byte POSTINC0 = GETENV("SFR:POSTINC0")
#else
#Error You need to setup the above for your PIC chip
#endif
void Saida(byte * data)
{
int8 count=121; //Why? you say the array is 244 bytes?
#asm
#if defined(__PCM__)
movf data, W // copy pointer to w reg..
movwf FSR // ..to pointer register
#elif defined(__PCH__)
movff data, FSR0L // copy low byte of pointer to low byte of pointer register 0..
movff &p_data+1, FSR0H // copy high byte of pointer to high byte of pointer register 0..
#else
#Error You need to setup the above for your PIC Chip
#endif
Loop: //must not be the same name as the function
#if defined(__PCM__)
movf INDF, W // load W with next databyte
incf FSR // do a 8-bit increment - increment indirection register to point to next databyte - for the next time
#elif defined(__PCH__)
movf POSTINC0, W // load w with next databyte and increment indirection register to point to next databyte - for the next time
#else
#Error You need to setup the above for your PIC Chip
#endif
movwf PORTB
decfsz count, F
goto loop // loop for next byte
#endasm |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Thu Oct 04, 2018 11:51 am |
|
|
OK. I've tweaked a couple of things and put it together with a basic demo:
Code: |
#include <18F4550.h>
#fuses NOWDT, NOXINST
#use delay(internal=8MHz)
//Minimum processor setup
#byte PORTB=getenv("SFR:LATB")
// Setup Index Register locations (FSR and INDF)
#if defined(__PCM__) // For example (and tested on) PIC16F74, PIC16F887
#byte FSR = GETENV("SFR:FSR")
#byte INDF = GETENV("SFR:INDF")
#elif defined(__PCH__) // For example (and tested on) PIC18F458
#word FSR = GETENV("SFR:FSR0L")
#byte POSTINC0 = GETENV("SFR:POSTINC0")
#else
#Error You need to setup the above for your PIC chip
#endif
void Saida(byte * data)
{
int8 count=121; //Why? you say the array is 244 bytes?
FSR=data; //simplest way to load the FSR
#asm
Loop: //must not be the same name as the function
#if defined(__PCM__)
movf INDF, W // load W with next databyte
incf FSR // do a 8-bit increment - increment indirection register to point to next databyte - for the next time
#elif defined(__PCH__)
movf POSTINC0, W // load w with next databyte and increment indirection register to point to next databyte - for the next time
#else
#Error You need to setup the above for your PIC Chip
#endif
movwf PORTB
decfsz count, F
goto loop // loop for next byte
#endasm
}
void main(void)
{
unsigned int8 data_array[244] = {0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1,2,3,4,5,6,7,8,9,10,
0,1 };
set_tris_b(0);
Saida(data_array);
while (TRUE)
;
}
|
|
|
|
vtrx
Joined: 11 Oct 2017 Posts: 142
|
|
Posted: Thu Oct 04, 2018 12:40 pm |
|
|
I'll be home at night.
I'll post the results. Thank you very much. |
|
|
|
|
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
|