Help with lpc17xx from 8051

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Help with lpc17xx from 8051

376 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ciernes on Sat Apr 05 11:35:56 MST 2014
Hello I want to introduce myself in the arm architecture
and I would like to start converting some codes made ​​in 8051 to arm
Could you help me please
thanks

 //crystal is 22-24MHz
//was made for Keil compiler

#include <reg51.h>

sbit Cclock=P1^1;
sbit Clatch=P1^0;
sbit Cdata=P3^7;
sbit Row5=P3^0;
sbit Row4=P3^1;
sbit Row3=P3^2;
sbit Row2=P3^3;
sbit Row1=P3^4;
unsigned int shift_delay;

unsigned char code font[96][5] =
{
    {0x00, 0x00, 0x00, 0x00, 0x00},  //
    {0x00, 0x00, 0x1d, 0x00, 0x00},  //
    {0x00, 0x18, 0x00, 0x18, 0x00},  //
    {0x0a, 0x1f, 0x0a, 0x1f, 0x0a},  //
    {0x09, 0x15, 0x1f, 0x15, 0x12},  //
    {0x11, 0x02, 0x04, 0x08, 0x11},  //
    {0x0a, 0x15, 0x15, 0x0f, 0x05},  //
    {0x00, 0x14, 0x18, 0x00, 0x00},  //
    {0x00, 0x00, 0x0e, 0x11, 0x00},  //
    {0x00, 0x11, 0x0e, 0x00, 0x00},  //
    {0x0a, 0x04, 0x1f, 0x04, 0x0a},  //
    {0x04, 0x04, 0x1f, 0x04, 0x04},  //
    {0x00, 0x05, 0x06, 0x00, 0x00},  //
    {0x04, 0x04, 0x04, 0x04, 0x04},  //
    {0x00, 0x03, 0x03, 0x00, 0x00},  //
    {0x01, 0x02, 0x04, 0x08, 0x10},  //
    {0x0e, 0x13, 0x15, 0x19, 0x0e},  //0
    {0x00, 0x09, 0x1f, 0x01, 0x00},  //1
    {0x13, 0x15, 0x15, 0x15, 0x09},  //2
    {0x11, 0x11, 0x15, 0x15, 0x0a},  //3
    {0x18, 0x04, 0x04, 0x04, 0x1f},  //4
    {0x1d, 0x15, 0x15, 0x15, 0x12},  //5
    {0x0e, 0x15, 0x15, 0x15, 0x12},  //6
    {0x10, 0x10, 0x10, 0x17, 0x18},  //7
    {0x0a, 0x15, 0x15, 0x15, 0x0a},  //8
    {0x08, 0x15, 0x15, 0x15, 0x0e},  //9
    {0x00, 0x1b, 0x1b, 0x00, 0x00},  //
    {0x00, 0x15, 0x16, 0x00, 0x00},  //
    {0x00, 0x04, 0x0a, 0x11, 0x00},  //
    {0x0a, 0x0a, 0x0a, 0x0a, 0x0a},  //
    {0x00, 0x11, 0x0a, 0x04, 0x00},  //
    {0x08, 0x10, 0x15, 0x14, 0x08},  //
    {0x0e, 0x11, 0x15, 0x12, 0x0e},  //
    {0x0f, 0x12, 0x12, 0x12, 0x0f},  //A
    {0x1f, 0x15, 0x15, 0x15, 0x0a},  //B
    {0x0e, 0x11, 0x11, 0x11, 0x11},  //C
    {0x1f, 0x11, 0x11, 0x11, 0x0e},  //D
    {0x1f, 0x15, 0x15, 0x15, 0x15},  //E
    {0x1f, 0x14, 0x14, 0x14, 0x10},  //F
    {0x0e, 0x11, 0x15, 0x15, 0x17},  //G
    {0x1f, 0x04, 0x04, 0x04, 0x1f},  //H
    {0x00, 0x11, 0x1f, 0x11, 0x00},  //I
    {0x02, 0x01, 0x11, 0x11, 0x1e},  //J
    {0x1f, 0x04, 0x0c, 0x14, 0x03},  //K
    {0x1f, 0x01, 0x01, 0x01, 0x01},  //L
    {0x1f, 0x08, 0x04, 0x08, 0x1f},  //M
    {0x1f, 0x10, 0x0e, 0x01, 0x1f},  //N
    {0x0e, 0x11, 0x11, 0x11, 0x0e},  //O
    {0x1f, 0x14, 0x14, 0x14, 0x08},  //P
   //{0x0e, 0x11, 0x11, 0x0f, 0x01},  //Q
    {0x0e, 0x11, 0x15, 0x12, 0x0d},  //Q   
    {0x1f, 0x14, 0x14, 0x16, 0x09},  //R
    {0x09, 0x15, 0x15, 0x15, 0x12},  //S
    {0x10, 0x10, 0x1f, 0x10, 0x10},  //T
    {0x1e, 0x01, 0x01, 0x01, 0x1e},  //U
    {0x18, 0x06, 0x01, 0x06, 0x18},  //V
    {0x1f, 0x02, 0x04, 0x02, 0x1f},  //W
    {0x11, 0x0a, 0x04, 0x0a, 0x11},  //X
    {0x18, 0x04, 0x07, 0x04, 0x18},  //Y
    {0x11, 0x13, 0x15, 0x19, 0x11},  //Z
    {0x00, 0x1f, 0x11, 0x11, 0x00},  //
    {0x10, 0x08, 0x04, 0x02, 0x01},  //
    {0x00, 0x11, 0x11, 0x1f, 0x00},  //
    {0x04, 0x08, 0x10, 0x08, 0x04},  //
    {0x01, 0x01, 0x01, 0x01, 0x01},  //
    {0x00, 0x00, 0x10, 0x08, 0x00},  //
    {0x12, 0x15, 0x15, 0x15, 0x0f},  //a
    {0x1f, 0x09, 0x09, 0x09, 0x06},  //b
    {0x0e, 0x11, 0x11, 0x11, 0x0a},  //c
    {0x06, 0x09, 0x09, 0x09, 0x1f},  //d
    {0x0e, 0x15, 0x15, 0x15, 0x0d},  //e
    {0x0f, 0x14, 0x14, 0x10, 0x10},  //f
    {0x09, 0x15, 0x15, 0x15, 0x0e},  //g
    {0x1f, 0x08, 0x08, 0x08, 0x07},  //h
    {0x00, 0x00, 0x17, 0x00, 0x00},  //i
    {0x01, 0x01, 0x01, 0x01, 0x1e},  //j
    {0x1f, 0x04, 0x04, 0x0a, 0x11},  //k
    {0x1e, 0x01, 0x01, 0x01, 0x01},  //l
    {0x0f, 0x10, 0x0f, 0x10, 0x0f},  //m
    {0x1f, 0x10, 0x10, 0x10, 0x0f},  //n
    {0x0e, 0x11, 0x11, 0x11, 0x0e},  //o
    {0x1f, 0x12, 0x12, 0x12, 0x0c},  //p
    {0x0c, 0x12, 0x12, 0x12, 0x1f},  //q
    {0x1f, 0x08, 0x10, 0x10, 0x08},  //r
    {0x09, 0x15, 0x15, 0x15, 0x12},  //s
    {0x1e, 0x09, 0x09, 0x01, 0x02},  //t
    {0x1e, 0x01, 0x01, 0x02, 0x1f},  //u
    {0x18, 0x06, 0x01, 0x06, 0x18},  //v
    {0x1e, 0x01, 0x1e, 0x01, 0x1e},  //w
    {0x1b, 0x04, 0x04, 0x04, 0x1b},  //x
    {0x19, 0x05, 0x05, 0x05, 0x1e},  //y
    {0x11, 0x13, 0x15, 0x19, 0x11},  //z
    {0x00, 0x04, 0x0e, 0x11, 0x00},  //
    {0x00, 0x00, 0x1f, 0x00, 0x00},  //
    {0x00, 0x11, 0x0e, 0x04, 0x00},  //
    {0x08, 0x10, 0x08, 0x04, 0x08},  //
    {0x00, 0x00, 0x00, 0x00, 0x00}   //
};
unsigned char column[33]=
{
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
}; //display memory, cleared before used.

void delayms(unsigned int ms) //just about 1ms
{
    unsigned int n;
    unsigned char i;
    for (n=0; n<ms; n++)
    {
        for (i=0; i<200; i++);
    }
}

void init_timer(void)
{
    TMOD=0x01;
    TH0=0xfb;
    TL0=0x00;
    TR0=1;
    ET0=1;
    EA=1;
}

void Timer0 (void) interrupt 1 //using 2
{
    unsigned char index;
    unsigned char i,tmp1;
    unsigned char code rowtable[]={0,1,2,4,8,16};
    //TH0=0xfb; //48fps
    //TL0=0x00;
    ET0=0;
    TH0=0xf8; //30fps
    TL0=0x00;
    Row5=1; Row4=1; Row3=1; Row2=1; Row1=1;
    index++;
    if (index>5) index=1;
    //column
    tmp1=rowtable[index];
    for (i=1; i<33; i++)
    {
        Cdata=!(column & tmp1);
        Cclock=1;
        Cclock=0;
    }
    //row
    Clatch=1;
    Clatch=0;
    switch (index)
    {
        case 1:
            Row1=0;
            break;
        case 2:
            Row2=0;
            break;
        case 3:
            Row3=0;
            break;
        case 4:
            Row4=0;
            break;
        case 5:
            Row5=0;
            break;
    }
    ET0=1;
}

void LED_put_byte(unsigned char inp)
{
    unsigned char i;
    for (i=1;i<33;i++) column=column[i+1];
    column[32]=inp;
}

void LED_puts(unsigned char *lcd_string)
{
    unsigned char i,tmp_chr;
    while (*lcd_string)
    {
        tmp_chr=*lcd_string;
        for (i=0;i<5;i++)
        {
            LED_put_byte(font[tmp_chr-32]);
            delayms(shift_delay);
        }
        LED_put_byte(0); //space between character
        delayms(shift_delay);
        lcd_string++;
    }
}


void main()
{
    init_timer();
    shift_delay=100; //bigger = slower shift
    while(1)
    {
        LED_puts("8x32 Matrix LED: AT89C2051, 74HC595, "
                 "HEM1588 8x8, LEDFCS9012        ");
    }
}
Labels (1)
0 Kudos
2 Replies

326 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ciernes on Mon Apr 07 03:53:16 MST 2014

Quote: MarcVonWindscooting
Seems like I'm not the only one who loses 'less signs' here. I wonder who collects them and what he does with those. :~

AT89C2051 - I remember that part! I programmed in assembler those days...

Back to the topic:
There are a few differences between 8051 and LPC.

First: on the LPC you typically use true push-pull outputs, rather than the NMOS+pullup of the 8051. Therefore you have to configure the outputs as such, because by default they're inputs with weak pull-ups enabled. This is done by setting the IOxDIR bit p to one, if you want Px.p as an output. Like this: IO0DIR |= 1 SHL p;

Next point: you don't have instructions for setting/resetting one single port pin. Instead you have to access all the 32bits of a port at once, preferably with the IOxSET or IOxCLR registers. You can set pin p of Port x by IOxSET = 1 SHL p; The clearing works by using IOxCLR.

Setting a bit and clearing in the next code line might be a bit fast on the LPC, not only because it has a higher clock, but because the clock is not divided by 12 in the first place.

I think your code can be ported relatively straightforward. But keep in mind, that porting almost never means: improving the code. And: you don't learn from porting, you learn from implementing it from scratch.

PS: replace 'SHL' by the C shift left operator (two less signs)



hello MarcVonWindscooting. I know the basics with arm, very basic. I would like to create this code to study it carefully.
I send you my attempt code  in arm
Might you help me build it? not want to bother you but would be a great help to me.
thank you very much in advance
0 Kudos

326 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MarcVonWindscooting on Sun Apr 06 16:35:25 MST 2014
Seems like I'm not the only one who loses 'less signs' here. I wonder who collects them and what he does with those. :~

AT89C2051 - I remember that part! I programmed in assembler those days...

Back to the topic:
There are a few differences between 8051 and LPC.

First: on the LPC you typically use true push-pull outputs, rather than the NMOS+pullup of the 8051. Therefore you have to configure the outputs as such, because by default they're inputs with weak pull-ups enabled. This is done by setting the IOxDIR bit p to one, if you want Px.p as an output. Like this: IO0DIR |= 1 SHL p;

Next point: you don't have instructions for setting/resetting one single port pin. Instead you have to access all the 32bits of a port at once, preferably with the IOxSET or IOxCLR registers. You can set pin p of Port x by IOxSET = 1 SHL p; The clearing works by using IOxCLR.

Setting a bit and clearing in the next code line might be a bit fast on the LPC, not only because it has a higher clock, but because the clock is not divided by 12 in the first place.

I think your code can be ported relatively straightforward. But keep in mind, that porting almost never means: improving the code. And: you don't learn from porting, you learn from implementing it from scratch.

PS: replace 'SHL' by the C shift left operator (two less signs)
0 Kudos