Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
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


List of 8 messages in thread
TopicAuthorDate
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      

Back to Subject List