View previous topic :: View next topic |
Author |
Message |
vtrx
Joined: 11 Oct 2017 Posts: 142
|
ASM delay control [Solved] |
Posted: Sun Sep 05, 2021 6:48 am |
|
|
I have a routine that uses a delay that needs to be written in ASM.
Using delay_ms(x) cannot be used because the routine gets out of sync.
The ideal delay routine for my routine is:
Code: |
char DELAY0,DELAY1,DELAY2;
#asm#
delay:
movlw 6
movwf DELAY0
movlw 100
movwf DELAY1
movwf DELAY2
delay_loop:
decfsz DELAY2
goto delay_loop
movwf DELAY2
decfsz DELAY1
goto delay_loop
movwf DELAY1
decfsz DELAY0
goto delay_loop
#endasm |
The problem is that I can't change the delay using a variable.
Code: |
char DELAY0,DELAY1,DELAY2,VAR;
VAR= 100;
#asm#
delay:
movlw 6
movwf DELAY0
movlw var//100
movwf DELAY1
movwf DELAY2
delay_loop:
decfsz DELAY2
goto delay_loop
movwf DELAY2
decfsz DELAY1
goto delay_loop
movwf DELAY1
decfsz DELAY0
goto delay_loop
#endasm |
This way it has no effect.
What would be the correct procedure? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9285 Location: Greensville,Ontario
|
|
Posted: Sun Sep 05, 2021 7:02 am |
|
|
you need to post your real code as whether you use 'delay_ms() 'or your ASM version, won't change your 'out of sync' problem. delay_ms() gets converted into ASM so same thing....
BTW, simply dump the listing and you'll see the delay_ms() code.
Remember that delays STOP the PIC from doing ANYTHING unti the delay is finished.
What is 'out of sync' ?
What are you trying to do ?
We need more info (code....) to see what's happening. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 482 Location: Montenegro
|
|
|
vtrx
Joined: 11 Oct 2017 Posts: 142
|
|
Posted: Sun Sep 05, 2021 1:45 pm |
|
|
temtronic wrote: | you need to post your real code as whether you use 'delay_ms() 'or your ASM version, won't change your 'out of sync' problem. delay_ms() gets converted into ASM so same thing....
BTW, simply dump the listing and you'll see the delay_ms() code.
Remember that delays STOP the PIC from doing ANYTHING unti the delay is finished.
What is 'out of sync' ?
What are you trying to do ?
We need more info (code....) to see what's happening. |
The code is an adaptation of an AVR/GCC code.
It's a little long to explain, but even the original code for AVR, the original delay is in ASM.
Code: | char DELAY0,DELAY1,DELAY2;
if(currentstart > (messagelength - MODULESNUMBER-1)){currentstart = 0;};
while(currentstart < (messagelength - MODULESNUMBER) && scroll_on ==1)
{
currentcolumn = 0;
while (currentcolumn < 8)
{
//-----------------------------------------------------------------------------
#asm#
delay:
movlw 6
movwf DELAY0
movlw 150
movwf DELAY1
movwf DELAY2
delay_loop:
decfsz DELAY2
goto delay_loop
movwf DELAY2
decfsz DELAY1
goto delay_loop
movwf DELAY1
decfsz DELAY0
goto delay_loop
#endasm
//-----------------------------------------------------------------------------
if(usb_kbhit(1))
{
usb_get_packet(1, in_data,USB_EP1_RX_SIZE);
if(in_data[0] =='7')
{
atraso = in_data[1];
}
if(in_data[0] =='8')
{
scroll_on = 0;
}
if(in_data[0] =='9')
{
scroll_on = 1;
}
}
//-----------------------------------------------------------------------------
for (letter=0; letter< MODULESNUMBER; letter++)
{
for(i=0; i<8; i++)
{
inputbuf[i] = fontdef[(int16)(messagebuf[currentstart + letter])*8 + i]; //font_2[(int16)(messagebuf[currentstart + letter])*8 + 8-x];
} // end of 'i' loop
for(i=8; i<16; i++)
{
inputbuf[i] = fontdef[(int16)(messagebuf[currentstart + letter + 1])*8 + (i-8)];//font_2[(int16)(messagebuf[currentstart + letter + 1])*8 + 8-x];
} // end of 'i' loop
for(unsigned int8 i = 0; i < 8; i++)
{
for(signed int8 j = 7; j > -1; j--)
{
outputbuf[i+(letter << 3)] = (outputbuf[i+(letter << 3)] << 1) | ((inputbuf[j + currentcolumn] >> (7 - i)) & 0x01);
} // end of 'j' loop
} // end of 'i'loop
} // end of 'letter' loop
for(i=0; i<8; i++)
{
for (j=0; j < MODULESNUMBER ; j++)
{
commands[(j*2)] = i+1;
commands[(j*2)+1] = outputbuf[i + ((MODULESNUMBER - j -1 ) << 3)]; //
} // end of 'j' loop
MAX7219_sendN(MODULESNUMBER, commands);
} // end of 'i' loop
currentcolumn++; // increase current column for scrolling
} // end of 'currentcolumn' WHILE LOOP for scrolling single character
currentstart++; // increase current position on text to scroll
}// end of LOOP for 'currentstart' for scrolling all the text |
I need to control the delay duration, programmed in ASM, externally.
Delay_ms(xx) probably uses 'call' and that could be the problem. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Sep 05, 2021 3:55 pm |
|
|
Quote: | Using delay_ms(x) cannot be used because the routine gets out of sync.
|
What does "out of sync" mean ? Gets out of sync with what ? |
|
|
vtrx
Joined: 11 Oct 2017 Posts: 142
|
|
Posted: Sun Sep 05, 2021 4:17 pm |
|
|
The above routine shifts characters in an array of LEDs, using delay_ms(xx), the characters jump out of order, using CCS/PIC or AVR/GCC. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Sep 05, 2021 4:45 pm |
|
|
Do you have an interrupt routine, and are you using delay_ms()
inside the routine ?
What compiler warning messages do you get ? |
|
|
vtrx
Joined: 11 Oct 2017 Posts: 142
|
|
Posted: Sun Sep 05, 2021 5:13 pm |
|
|
PCM programmer wrote: | Do you have an interrupt routine, and are you using delay_ms()
inside the routine ?
What compiler warning messages do you get ? |
No.
I found my mistake.
In the instruction 'movlw 150',the correct one is 'movf DLY,w'.
I don't know why in the two compilers just in ASM it works fine.
Code: | char DYL;
DLY = 150;
//-----------------------------------------------------------------------------
#asm#
delay:
movlw 120
movwf DELAY0
movf DLY,w
movwf DELAY1
movwf DELAY2
delay_loop:
decfsz DELAY2
goto delay_loop
movwf DELAY2
decfsz DELAY1
goto delay_loop
movwf DELAY1
decfsz DELAY0
goto delay_loop
#endasm
//-----------------------------------------------------------------------------
|
|
|
|
|