|
|
View previous topic :: View next topic |
Author |
Message |
stevenlkz
Joined: 05 Jun 2005 Posts: 5
|
Normal programming question |
Posted: Sat Jun 11, 2005 11:01 pm |
|
|
I got two questions about the programming of PIC16F877.
1. Normally, when we rotate 8 time with 8 bit data, we will get back the same data right? But if I rotate one time, then call a subroutine or goto other place, the carry flag already change. Then back to here and rotate again. This loop will go on for 8 time, is it finally still can get back the same data?
2. If I add 8 bit data with another 8 bit data and the result is is overload to 9 or 10 bit, then how a result will store? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jun 12, 2005 12:09 am |
|
|
Quote: | Normally, when we rotate 8 time with 8 bit data, we will get back the same data right ? But if I rotate one time, then call a subroutine or
goto other place, the carry flag already change |
If you use the CCS rotate functions instead of assembly language,
then you don't have to worry about this. If you make a test program,
compile it, and look at the .LST file, you will see the code created by
the compiler.
In the code below, you can see that CCS does the rotate operation
in two steps. First they rotate bit 7 of n into the Carry bit. They
don't care about the result, so they just stick it in the W register.
Their entire purpose is just to get bit 7 into the Carry bit.
Then in the next line, they do the actual rotation. They rotate n
to the left once, and the Carry bit is rotated into bit 0, and the
result is put back into n.
Code: |
.................... rotate_left (&n, 1);
0014: RLF n,W
0015: RLF n,F |
In other words, the basic answer to many of your questions is:
Don't use ASM. Instead, use a built-in function. They have
already solved the whole problem for you. Do this:
Code: |
int8 n;
rotate_left (&n, 1);
|
------------
Quote: | 2. If I add 8 bit data with another 8 bit data and the result is
overload to 9 or 10 bit, then how a result will store? |
You need to convert the 8-bit values to 16-bit before you do the addition.
This conversion is called "casting". Example:
Code: | int16 result;
int8 a, b;
result = (int16)a + (int16)b; |
|
|
|
stevenlkz
Joined: 05 Jun 2005 Posts: 5
|
|
Posted: Mon Jun 13, 2005 12:18 am |
|
|
Thanks for help! But I really need to write in MPlab compiler. Sad.
I have another 6 question with MPlab assembler programming.
1. Is the PIC can use to check the value whether it is a positive or negative value?
2. Is the IF/ELSE statement available in MPlab?
3. How to compare and get the smallest number between three number?
4. After I use the fixed point division of the application note, AN617 in microchip, but the output is in floating point, then how to read the result?
5. If the maximum number of floating point is 0.125 in decimal number, then how many bits should I use for math operation?
6. In application note, AN575 in microchip, it said that floating point 0X823C5198, but how to read it? What decimal value is it? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jun 13, 2005 12:31 am |
|
|
I think you should study the C language. |
|
|
Devin Electronics Guest
|
|
Posted: Fri Sep 16, 2005 1:25 pm |
|
|
I know C but lack knowledge on my Assembly so hofefully this is a simple question.
I have a 4 byte integer that I need to rotate out to the CARRY flag one bit at a time. I know I can use rotate_left(&msg_to_xmit, 4) easily enough but due to timing requirements, I only have one clock cycle at a time to do anything so I wrote the code to address that issue as shown in the example:
Code: | #inline
void transmit_0(void){
PHASE_B_PIN = 1; //Turn on Phase B pin for two
delay_cycles(1); // cycles total.
PHASE_B_PIN = 0; //Turn off Phase B pin.
PHASE_A_PIN = 1; //Turn on Phase A pin for two
delay_cycles(1); // cycles total.
PHASE_A_PIN = 0; //Turn off Phase A pin.
}
#inline
void transmit_0_shift_a(void) {
PHASE_B_PIN = 1; //This is the same as above
rotate_left(&msg_to_xmit+0,1); // except we use the NOPs
PHASE_B_PIN = 0; // to shift our next bit into
PHASE_A_PIN = 1; // position for our next
rotate_left(&msg_to_xmit+1,1); // transmission.
PHASE_A_PIN = 0; //
}
#inline
void transmit_0_shift_b(void) {
PHASE_B_PIN = 1; //This is the same as above
rotate_left(&msg_to_xmit+2,1); // except we use the NOPs
PHASE_B_PIN = 0; // to shift our next bit into
PHASE_A_PIN = 1; // position for our next
rotate_left(&msg_to_xmit+3,1); // transmission.
PHASE_A_PIN = 0; //
} |
Now I find out that the rotate_left command take TWO cycles instead of one cycle that I would get from the assembly RLF command. If I re-write the code in assembly as such
Code: | #inline
void transmit_1_shift_a(void) {
#asm
BSF PHASE_A_PIN //This is the same as above
RLF msg_to_xmit+0, F // except we use the NOPs
BCF PHASE_A_PIN // to shift our next bit into
BSF PHASE_B_PIN // position for our next
RLF msg_to_xmit+1, F // transmission.
BCF PHASE_B_PIN //
#endasm
}
|
it doesn't like my RLF msg_to_xmit+1,F line. Is using INDF/FSR the only option I have? And if so, is this the proper way to implimant it?
Code: | #inline
void transmit_1_shift_a(void) {
#asm
BSF PHASE_A_PIN //This is the same as above
RLF FSR+0, F // except we use the NOPs
BCF PHASE_A_PIN // to shift our next bit into
BSF PHASE_B_PIN // position for our next
RLF FSR+1, F // transmission.
BCF PHASE_B_PIN //
#endasm
}
void calling_routine(void) {
#asm
MOVLW msg_to_xmit
MOVWF FSR
CLRF INDF
#endasm
transmit_1_shift_a();
transmit_1_shift_b();
}
|
|
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Sep 16, 2005 1:58 pm |
|
|
This doesn't seem right
You aren't specifying the bit to set. |
|
|
Guest
|
|
Posted: Fri Sep 16, 2005 2:19 pm |
|
|
PHASE_A_PIN is defined as follows:
Code: | struct port_layout{
unsigned p0:1;
unsigned p1:1;
unsigned p2:1;
unsigned p3:1;
unsigned p4:1;
unsigned p5:1;
unsigned p6:1;
unsigned p7:1;
};
struct port_layout port_a;
#byte port_a = 5
#define PHASE_A_PIN port_a.p0 |
And complies as:
|
|
|
|
|
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
|