| ??? 04/25/07 12:33 Read: times |
#137920 - start with assembler code generated from C Responding to: ???'s previous message |
Iam trying it for a while and unable to implement the exact logic. As the algorithm seems to be the problem here (not the 1 second intervall) I'd start with some higher level code and then hand-optimize the assembler code generated from C. The C-code below uses 3 different methods to address your problem. Pass this snippet through sdcc with "sdcc -c output.c"
#include <at89x52.h>
void my_irq_dontcareabout_p1_high_nibble(void) __interrupt
{
unsigned char __code table[] = {0x0e, 0x0d, 0x0c, 0x0b, /**/};
static unsigned char counter;
P1 = table[counter];
counter++;
counter %= sizeof table;
}
unsigned char P1_mirror = 0xa0;
void my_irq_beniceto_p1_high_nibble(void) __interrupt
{
unsigned char __code table[] = {0x0e, 0x0d, 0x0c, 0x0b /**/};
static unsigned char counter;
P1_mirror &= 0xf0;
P1_mirror |= table[counter];
P1 = P1_mirror;
counter++;
counter %= sizeof table;
}
void my_irq_bitwise(void) __interrupt
{
unsigned char __code table[] = {0x0e, 0x0d, 0x0c, 0x0b /**/};
static unsigned char counter;
P1_0 = (0x01 & table[counter]);
P1_1 = (0x02 & table[counter]);
P1_2 = (0x04 & table[counter]);
P1_3 = (0x08 & table[counter]);
counter++;
counter %= sizeof table;
}
and you get these as a starting point:
_my_irq_dontcareabout_p1_high_nibble:
push acc
push dpl
push dph
push psw
mov psw,#0x00
; output.c:8: P1 = table[counter];
mov a,_my_irq_dontcareabout_p1_high_nibble_counter_1_1
mov dptr,#_my_irq_dontcareabout_p1_high_nibble_table_1_1
movc a,@a+dptr
mov _P1,a
; output.c:9: counter++;
inc _my_irq_dontcareabout_p1_high_nibble_counter_1_1
; output.c:10: counter %= sizeof table;
anl _my_irq_dontcareabout_p1_high_nibble_counter_1_1,#0x03
pop psw
pop dph
pop dpl
pop acc
reti
_my_irq_beniceto_p1_high_nibble:
push acc
push dpl
push dph
push ar2
push psw
mov psw,#0x00
; output.c:21: P1_mirror &= 0xf0;
anl _P1_mirror,#0xF0
; output.c:22: P1_mirror |= table[counter];
mov a,_my_irq_beniceto_p1_high_nibble_counter_1_1
mov dptr,#_my_irq_beniceto_p1_high_nibble_table_1_1
movc a,@a+dptr
orl _P1_mirror,a
; output.c:23: P1 = P1_mirror;
mov _P1,_P1_mirror
; output.c:24: counter++;
inc _my_irq_beniceto_p1_high_nibble_counter_1_1
; output.c:25: counter %= sizeof table;
anl _my_irq_beniceto_p1_high_nibble_counter_1_1,#0x03
pop psw
pop ar2
pop dph
pop dpl
pop acc
reti
_my_irq_bitwise:
push acc
push dpl
push dph
push ar2
push psw
mov psw,#0x00
; output.c:33: P1_0 = (0x01 & table[counter]);
mov a,_my_irq_bitwise_counter_1_1
mov dptr,#_my_irq_bitwise_table_1_1
movc a,@a+dptr
mov r2,a
rrc a
mov _P1_0,c
; output.c:34: P1_1 = (0x02 & table[counter]);
mov a,r2
mov c,acc.1
mov _P1_1,c
; output.c:35: P1_2 = (0x04 & table[counter]);
mov a,r2
mov c,acc.2
mov _P1_2,c
; output.c:36: P1_3 = (0x08 & table[counter]);
mov a,r2
mov c,acc.3
mov _P1_3,c
; output.c:38: counter++;
inc _my_irq_bitwise_counter_1_1
; output.c:39: counter %= sizeof table;
anl _my_irq_bitwise_counter_1_1,#0x03
pop psw
pop ar2
pop dph
pop dpl
pop acc
reti
The first algorithm is straightforward but spoils the high nibble, the second algorithm preserves the high nibble of P1 at the cost of some overhead, the third algorithm does bitwise access and thus is even more friendly to the high nibble of P1. But it switches P0_0..P0_3 with a little delay (and thus exhibits "unwanted bit combinations" for some cpu cycles during the switching (note, that this problem also exists for some tens of nanoseconds with algorithm 1 and 2)). Know what you want!^) Greetings, Frieder |
| Topic | Author | Date |
| timing sequence generation using AT89S52 | 01/01/70 00:00 | |
| Can you count? | 01/01/70 00:00 | |
| I used 1 sec delay | 01/01/70 00:00 | |
| This is a typical PCA job | 01/01/70 00:00 | |
PCA? | 01/01/70 00:00 | |
| start with assembler code generated from C | 01/01/70 00:00 | |
| or rather try this highly pathological C code :^) | 01/01/70 00:00 | |
| Use the Timer | 01/01/70 00:00 |



