|
|
View previous topic :: View next topic |
Author |
Message |
albe01
Joined: 02 Jul 2010 Posts: 30 Location: italy
|
Help for #ASM in ccs compiler |
Posted: Mon Jul 05, 2010 4:52 am |
|
|
Hello to everyone,
I would like to know whether any of you knows the equivalent for this code 'ccs' but written in 'c' in 'asm' is wrong / not valid.. i use a pic 18F4525
Code: |
void fcsbit(byte tbyte){
#asm
BCF 03,0
RRF fcshi,F // rotates the entire 16 bits
RRF fcslo,F // to the right
#endasm
if (((STATUS & 0x01)^(tbyte)) == 0x01) {
crchi = cfshi^0x84;
crclo = fcslo^0x08;
}
} |
|
|
|
jbmiller
Joined: 07 Oct 2006 Posts: 73 Location: Greensville,Ontario
|
|
Posted: Mon Jul 05, 2010 5:36 am |
|
|
I find the easiest C code to asm convertor is to cut the correct C code, compile then look at the listing (.LST) file. It's fast,simple and easy....
Plus you can 'cut and paste' into other programs... |
|
|
albe01
Joined: 02 Jul 2010 Posts: 30 Location: italy
|
. |
Posted: Mon Jul 05, 2010 7:45 am |
|
|
this code not work on pic 18F, but only 16F i dont' know a solution to this problem... help! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon Jul 05, 2010 8:30 am |
|
|
In a PIC16, byte3, is the status register. Setting bit 1, is a bank select operation, addressing the second memory bank. On the PIC 18, bank control, is done via the BSR instaed, and this is at address 0xFE0.
In all honesty, there is almost nothing on the PIC, that can't now be done directly in C, rather than in assembler (the exception, is forcing a few things like using the RETFIE 1 instruction for an assembler return). Assembler, makes the code non portable between processor families (which is why it won't work, when you have moved to a PIC18....). Work out what the original code wanted to do (looks like a simple rotation on a 16bit register), and code it in C. It'll then translate to the PIC18 without problems...
Best Wishes |
|
|
albe01
Joined: 02 Jul 2010 Posts: 30 Location: italy
|
|
Posted: Mon Jul 05, 2010 8:48 am |
|
|
hello you know a similar function in ccs? i have found only this, is it similar?
Quote: |
rotate_left( )
Syntax:
rotate_left (address, bytes)
Parameters:
address is a pointer to memory, bytes is a count of the number of bytes to work with.
Returns:
undefined
Function:
Rotates a bit through an array or structure. The address may be an array identifier or an address to a byte or structure (such as &data). Bit 0 of the lowest BYTE in RAM is considered the LSB.
Availability:
All devices
Requires:
Nothing
Examples:
x = 0x86;
rotate_left( &x, 1);
// x is now 0x0d
Example Files:
None
Also See:
rotate_right(), shift_left(), shift_right() |
|
|
|
albe01
Joined: 02 Jul 2010 Posts: 30 Location: italy
|
. |
Posted: Mon Jul 05, 2010 8:52 am |
|
|
this is my complete code, but not work on pic18, only 16f.... you can help me? the modem connected is the old FX614...
Code: |
#define PTT PIN_A3
int port_E;
byte fcslo, fcshi,flag,fcsflag; int i,stuff;
byte SendData[27] = {0x86, 0xA2, 0x40, 0x40, 0x40, 0x40, 0x60, 0xAE, 0x64, 0x8C, 0xA6,0x40, 0x40, 0x68, 0xA4, 0x8A, 0x98, 0x82, 0xB2, 0x40, 0x61, 0x03,0xF0, 0x54, 0x65, 0x73, 0x74};
void flipout(void){ //flips the state of output pin a_1
stuff = 0; //since this is a 0, reset the stuff counter
if (!bit_test(port_E,1)){ output_high(pin_E0);} //if the state of the pin was low, make it high.
else{output_low(pin_E0);} //if the state of the pin was high make it low
}
void fcsbit(byte tbyte){
#asm
BCF 03,0
RRCF fcshi,1,0 // rotates the entire 16 bits
RRCF fcslo,1,0 // to the right
#endasm
if (((STATUS & 0x01)^(tbyte)) == 0x01) {
crchi = cfshi^0x84;
crclo = fcslo^0x08;
}
}
void SendByte(byte inbyte){
int k, bt;
for (k=0;k<8;k++){ //do the following for each of the 8 bits in the byte
bt = inbyte & 0x01; //strip off the rightmost bit of the byte to be sent (inbyte)
if ((fcsflag == FALSE) && (flag == false)) {fcsbit(bt);} //do FCS calc, but only if this
//is not a flag or fcs byte
if (bt == 0) {flipout();} // if this bit is a zero, flip the output state
else{ //otherwise if it is a 1, do the following:
stuff++; //increment the count of consequtive 1's
if ((flag == FALSE) & (stuff == 5)){ //stuff an extra 0, if 5 1's in a row
delay_us(850); //introduces a delay that creates 1200 baud
flipout(); //flip the output state to stuff a 0
}//end of if
}//end of else
inbyte = inbyte>>1; //go to the next bit in the byte
delay_us(850); //introduces a delay that creates 1200 baud
}//end of for
}//end of SendByte
void SendPacket(void){
fcslo=fcshi=0xFF; //The 2 FCS Bytes are initialized to FF
stuff = 0; //The variable stuff counts the number of 1's in a row. When it gets to 5
// it is time to stuff a 0.
output_high(PTT); //Turns on the microcontroller Pin that controlls the PTT line.
flag = TRUE; //The variable flag is true if you are transmitted flags (7E's) false otherwise.
fcsflag = FALSE; //The variable fcsflag is true if you are transmitting FCS bytes, false otherwise.
for (i=0;i<20;i++){SendByte(0x7E);} //Sends flag bytes. Adjust length for txdelay
//each flag takes approx 6.7 ms
flag = FALSE; //done sending flags
for(i=0;i<27;i++)
{SendByte(SendData[i]);} //send the packet bytes
fcsflag = TRUE; //about to send the FCS bytes
fcslo =fcslo^0xff; //must XOR them with FF before sending
fcshi = fcshi^0xff;
SendByte(fcslo); //send the low byte of fcs
SendByte(fcshi); //send the high byte of fcs
fcsflag = FALSE; //done sending FCS
flag = TRUE; //about to send flags
SendByte(0x7e); // Send a flag to end packet
output_low(PTT); //unkey PTT
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 05, 2010 11:52 am |
|
|
Quote: | #asm
BCF 03,0
RRCF fcshi,1,0 // rotates the entire 16 bits
RRCF fcslo,1,0 // to the right
#endasm
|
The 18F-series don't have the STATUS register at address 0x03. That's
for the 16F. If you write ASM code, you need to study the architecture,
instruction set, and register addresses in the PIC data sheet.
My advice is to do things in C code, if possible. Then it's usually portable
between different PICs. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Jul 05, 2010 5:49 pm |
|
|
The program as posted is what you get when an assembly programmer starts to write C-code. The program works but is an almost direct copy of assembly to C, not fully using the power of the C language.
Code: | BCF 03,0
RRCF fcshi,1,0 // rotates the entire 16 bits
RRCF fcslo,1,0 // to the right | This code is not actually rotating the 16 bits to the right, but shifting to the right with a zero being shifted in from the left (the BCF instruction is clearing the Carry flag which is then shifted in). For real rotation the bit shifted out at the right would have been inserted to the right again.
The bit shifted out on the right can be found in the Carry bit afterwards, that is what is tested here: Code: | if (((STATUS & 0x01)^(tbyte)) == 0x01) { |
To change the program to correct C, you have to:
1) Replace the fcshi and fcshi variables by a single int16 fcs variable
2) Same for crchi and crclo
3) Replace the function fcsbit by: Code: | void fcsbit(byte tbyte){
int8 lsb;
lsb = shift_right(&fcs, sizeof(fcs), 0);
if ((lsb ^ tbyte) == 0x01) {
crc = crc ^0x8408;
}
}
| 4) Sending the data then should be changed from: Code: | fcslo =fcslo^0xff; //must XOR them with FF before sending
fcshi = fcshi^0xff;
SendByte(fcslo); //send the low byte of fcs
SendByte(fcshi); //send the high byte of fcs | to: Code: | fcs ^= 0xFFFF; //must XOR them with FF before sending
SendByte( make8(fcs,0) ); //send the low byte of fcs
SendByte( make8(fcs,1) ); //send the high byte of fcs
|
|
|
|
albe01
Joined: 02 Jul 2010 Posts: 30 Location: italy
|
|
Posted: Tue Jul 06, 2010 8:37 am |
|
|
now work! thank to all
Last edited by albe01 on Tue Jul 06, 2010 11:05 am; edited 1 time in total |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Tue Jul 06, 2010 9:48 am |
|
|
Code: |
int port_E;
.
.
.
if (!bit_test(port_E,1))
{
output_high(pin_E0);
} //if the state of the pin was low, make it high.
else
{
output_low(pin_E0);
} //if the state of the pin was high make it low
|
The original code probably accessed the port directly. As you have declared port_E an int this won't work!
you need to set port_E to be at the address of the port using the #BYTE instruction, you may need to use FAST_IO mode on this port as well.
It would be easier to use
Code: |
void flipout(void)
{
stuff = 0;
output_toggle(pin_E0);
}
|
to do the same thing as this routine. |
|
|
albe01
Joined: 02 Jul 2010 Posts: 30 Location: italy
|
|
Posted: Tue Jul 06, 2010 11:07 am |
|
|
now i testing the rx rutines ;) thank to all |
|
|
|
|
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
|