??? 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 |