1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

Keil compiler & 8051 simulator

Discussion in 'Embedded' started by Roman Mashak, May 11, 2004.

  1. Roman Mashak

    Roman Mashak Guest

    Hello, All!

    I'm studying the 8051 microcontroller and exploring now sample code I've
    found. I'm using:
    - Keil C compiler v6.21
    - assembler compiler v6.20c
    - simulation DLL v2.20b

    There sre some items I can't understand. Anyway, the code I included to
    this message, is doing the following:

    1) initialize Timer 2
    2) calculate the number of timer increments
    3) define 16-bit reload value
    4) split reload 16-bit value onto two 8-bit values....
    etc.

    .........
    #define TICK_MS 30
    #define OSC_FREQ (12000000UL)
    #define OSC_PER_INST (12)

    void Init_Timer2(const tByte TICK_MS)
    {
    tLong Inc, Reload_long;
    tWord Reload_16;
    tByte Reload_08H, Reload_08L;

    // Timer 2 is configured as a 16-bit timer,
    // which is automatically reloaded when it overflows
    T2CON = 0x04; // Load Timer 2 control register

    // Number of timer increments required (max 65536)
    Inc = ((tLong)TICK_MS * (OSC_FREQ/1000)) / (tLong)OSC_PER_INST;

    // 16-bit reload value
    Reload_16 = (tWord) (65536UL - Inc);
    // Reload_long = (tLong) (65536UL - Inc);

    // 8-bit reload values (High & Low)
    Reload_08H = (tByte)(Reload_16 / 256);
    Reload_08L = (tByte)(Reload_16 % 256);

    // Used for manually checking timing (in simulator)
    //P2 = Reload_08H;
    //P3 = Reload_08L;

    TH2 = Reload_08H; // Load Timer 2 high byte
    RCAP2H = Reload_08H; // Load Timer 2 reload capt. reg. high byte
    TL2 = Reload_08L; // Load Timer 2 low byte
    RCAP2L = Reload_08L; // Load Timer 2 reload capt. reg. low byte

    // Timer 2 interrupt is enabled, and ISR will be called
    // whenever the timer overflows.
    ET2 = 1;

    // Start Timer 2 running
    TR2 = 1;

    EA = 1; // Globally enable interrupts
    }

    When I'm doing tracing of the code, I find that the value of Reload_16
    is set to 0x00D0 (in hex), but it should be:

    Inc = ( 30 * (12000000/1000) ) / 12 = 30000, that's OK, clear...
    Reload_16 = 65536-30000 = 35536, 0x8AD0 in hex

    But how?

    And then Reload_08H and Reload_08L appeared to be: 0xD0 and 0xD0, so I
    still don't understand....

    I'm sorry if my question is too silly, so please direct me onto some
    useful resource. Thanks in advance!

    With best regards, Roman Mashak. E-mail:
     
    Roman Mashak, May 11, 2004
    #1
    1. Advertising

  2. Roman Mashak

    Phil W Guest

    Because 65536 = 0x010000 = to big for an int. So effectively you are
    subtracting from zero.

    Try 65535.

    Phil W


    "Roman Mashak" <> wrote in message
    news:c7pdht$17ja$...
    > Hello, All!
    >
    > I'm studying the 8051 microcontroller and exploring now sample code

    I've
    > found. I'm using:
    > - Keil C compiler v6.21
    > - assembler compiler v6.20c
    > - simulation DLL v2.20b
    >
    > There sre some items I can't understand. Anyway, the code I included

    to
    > this message, is doing the following:
    >
    > 1) initialize Timer 2
    > 2) calculate the number of timer increments
    > 3) define 16-bit reload value
    > 4) split reload 16-bit value onto two 8-bit values....
    > etc.
    >
    > ........
    > #define TICK_MS 30
    > #define OSC_FREQ (12000000UL)
    > #define OSC_PER_INST (12)
    >
    > void Init_Timer2(const tByte TICK_MS)
    > {
    > tLong Inc, Reload_long;
    > tWord Reload_16;
    > tByte Reload_08H, Reload_08L;
    >
    > // Timer 2 is configured as a 16-bit timer,
    > // which is automatically reloaded when it overflows
    > T2CON = 0x04; // Load Timer 2 control register
    >
    > // Number of timer increments required (max 65536)
    > Inc = ((tLong)TICK_MS * (OSC_FREQ/1000)) / (tLong)OSC_PER_INST;
    >
    > // 16-bit reload value
    > Reload_16 = (tWord) (65536UL - Inc);
    > // Reload_long = (tLong) (65536UL - Inc);
    >
    > // 8-bit reload values (High & Low)
    > Reload_08H = (tByte)(Reload_16 / 256);
    > Reload_08L = (tByte)(Reload_16 % 256);
    >
    > // Used for manually checking timing (in simulator)
    > //P2 = Reload_08H;
    > //P3 = Reload_08L;
    >
    > TH2 = Reload_08H; // Load Timer 2 high byte
    > RCAP2H = Reload_08H; // Load Timer 2 reload capt. reg. high byte
    > TL2 = Reload_08L; // Load Timer 2 low byte
    > RCAP2L = Reload_08L; // Load Timer 2 reload capt. reg. low byte
    >
    > // Timer 2 interrupt is enabled, and ISR will be called
    > // whenever the timer overflows.
    > ET2 = 1;
    >
    > // Start Timer 2 running
    > TR2 = 1;
    >
    > EA = 1; // Globally enable interrupts
    > }
    >
    > When I'm doing tracing of the code, I find that the value of

    Reload_16
    > is set to 0x00D0 (in hex), but it should be:
    >
    > Inc = ( 30 * (12000000/1000) ) / 12 = 30000, that's OK, clear...
    > Reload_16 = 65536-30000 = 35536, 0x8AD0 in hex
    >
    > But how?
    >
    > And then Reload_08H and Reload_08L appeared to be: 0xD0 and 0xD0, so

    I
    > still don't understand....
    >
    > I'm sorry if my question is too silly, so please direct me onto some
    > useful resource. Thanks in advance!
    >
    > With best regards, Roman Mashak. E-mail:
    >
    >
     
    Phil W, May 11, 2004
    #2
    1. Advertising

  3. Roman Mashak

    Thad Smith Guest

    Roman Mashak wrote:

    > Hello, All!
    >
    > I'm studying the 8051 microcontroller and exploring now sample code I've
    > found. I'm using:
    > - Keil C compiler v6.21
    > - assembler compiler v6.20c
    > - simulation DLL v2.20b
    >
    > There sre some items I can't understand. Anyway, the code I included to
    > this message, is doing the following:
    >
    > 1) initialize Timer 2
    > 2) calculate the number of timer increments
    > 3) define 16-bit reload value
    > 4) split reload 16-bit value onto two 8-bit values....
    > etc.
    >
    > ........
    > #define TICK_MS 30
    > #define OSC_FREQ (12000000UL)
    > #define OSC_PER_INST (12)
    >
    > void Init_Timer2(const tByte TICK_MS)
    > {
    > tLong Inc, Reload_long;
    > tWord Reload_16;
    > tByte Reload_08H, Reload_08L;
    >
    > // Timer 2 is configured as a 16-bit timer,
    > // which is automatically reloaded when it overflows
    > T2CON = 0x04; // Load Timer 2 control register
    >
    > // Number of timer increments required (max 65536)
    > Inc = ((tLong)TICK_MS * (OSC_FREQ/1000)) / (tLong)OSC_PER_INST;
    >
    > // 16-bit reload value
    > Reload_16 = (tWord) (65536UL - Inc);
    > // Reload_long = (tLong) (65536UL - Inc);


    How is tWord defined? If it is unsigned char, you would get rhe results
    you specify. Otherwise, watch the execution in the simulator and find
    out.

    Thad
     
    Thad Smith, May 11, 2004
    #3
  4. Roman Mashak

    Roman Mashak Guest

    Hello, Phil!
    You wrote on Tue, 11 May 2004 15:21:51 +1000:

    PW> Try 65535.

    I tried... In this case Reload_16=0x00CF, that's 207. So, it's not the
    reason, I guess.

    PW> Phil W

    PW> "Roman Mashak" <> wrote in message
    PW> news:c7pdht$17ja$...
    ??>> Hello, All!
    ??>>
    ??>> I'm studying the 8051 microcontroller and exploring now sample
    ??>> code
    PW> I've
    ??>> found. I'm using:

    With best regards, Roman Mashak. E-mail:
     
    Roman Mashak, May 11, 2004
    #4
  5. Roman Mashak

    Roman Mashak Guest

    Hello, Thad!
    You wrote on Mon, 10 May 2004 23:41:19 -0600:

    ??>> Timer 2 control register // Number of timer increments required
    ??>> (max 65536) Inc = ((tLong)TICK_MS * (OSC_FREQ/1000)) /
    ??>> (tLong)OSC_PER_INST; // 16-bit reload value Reload_16 = (tWord)
    ??>> (65536UL - Inc); // Reload_long = (tLong) (65536UL - Inc);

    TS> How is tWord defined? If it is unsigned char, you would get rhe
    TS> results you specify. Otherwise, watch the execution in the simulator
    TS> and find out.
    tWord is defined as 'unsigned int'.

    With best regards, Roman Mashak. E-mail:
     
    Roman Mashak, May 11, 2004
    #5
  6. Roman Mashak

    nospam Guest

    "Roman Mashak" <> wrote:

    >#define TICK_MS 30


    >void Init_Timer2(const tByte TICK_MS)


    This should not even compile

    > When I'm doing tracing of the code, I find that the value of Reload_16
    >is set to 0x00D0 (in hex), but it should be:
    >
    > Inc = ( 30 * (12000000/1000) ) / 12 = 30000, that's OK, clear...
    > Reload_16 = 65536-30000 = 35536, 0x8AD0 in hex
    >
    > But how?
    >
    > And then Reload_08H and Reload_08L appeared to be: 0xD0 and 0xD0, so I
    >still don't understand....


    I would suspect what the simulator is showing you did you actually inspect
    T2H and T2L ? The variables you are looking at are likely to be assigned to
    registers and/or optimised away completely. Try turning off all compiler
    optimisation.
     
    nospam, May 11, 2004
    #6
  7. Roman Mashak wrote:
    > Hello, All!
    >
    > I'm studying the 8051 microcontroller and exploring now sample
    > code I've found. I'm using:
    > - Keil C compiler v6.21
    > - assembler compiler v6.20c
    > - simulation DLL v2.20b
    >
    > There sre some items I can't understand. Anyway, the code I
    > included to this message, is doing the following:
    >
    > 1) initialize Timer 2
    > 2) calculate the number of timer increments
    > 3) define 16-bit reload value
    > 4) split reload 16-bit value onto two 8-bit values....
    > etc.
    >
    > ........
    > #define TICK_MS 30
    > #define OSC_FREQ (12000000UL)
    > #define OSC_PER_INST (12)
    >
    > void Init_Timer2(const tByte TICK_MS)
    > {
    > tLong Inc, Reload_long;
    > tWord Reload_16;
    > tByte Reload_08H, Reload_08L;
    >
    > // Timer 2 is configured as a 16-bit timer,
    > // which is automatically reloaded when it overflows
    > T2CON = 0x04; // Load Timer 2 control register
    >
    > // Number of timer increments required (max 65536)
    > Inc = ((tLong)TICK_MS * (OSC_FREQ/1000)) / (tLong)OSC_PER_INST;
    >
    > // 16-bit reload value
    > Reload_16 = (tWord) (65536UL - Inc);
    > // Reload_long = (tLong) (65536UL - Inc);
    >
    > // 8-bit reload values (High & Low)
    > Reload_08H = (tByte)(Reload_16 / 256);
    > Reload_08L = (tByte)(Reload_16 % 256);
    >
    > // Used for manually checking timing (in simulator)
    > //P2 = Reload_08H;
    > //P3 = Reload_08L;
    >
    > TH2 = Reload_08H; // Load Timer 2 high byte
    > RCAP2H = Reload_08H; // Load Timer 2 reload capt. reg. high byte
    > TL2 = Reload_08L; // Load Timer 2 low byte
    > RCAP2L = Reload_08L; // Load Timer 2 reload capt. reg. low byte
    >
    > // Timer 2 interrupt is enabled, and ISR will be called
    > // whenever the timer overflows.
    > ET2 = 1;
    >
    > // Start Timer 2 running
    > TR2 = 1;
    >
    > EA = 1; // Globally enable interrupts
    > }
    >
    > When I'm doing tracing of the code, I find that the value of
    > Reload_16 is set to 0x00D0 (in hex), but it should be:
    >
    > Inc = ( 30 * (12000000/1000) ) / 12 = 30000, that's OK, clear...
    > Reload_16 = 65536-30000 = 35536, 0x8AD0 in hex
    >
    > But how?
    >
    > And then Reload_08H and Reload_08L appeared to be: 0xD0 and 0xD0,
    > so I still don't understand....
    >
    > I'm sorry if my question is too silly, so please direct me onto
    > some useful resource. Thanks in advance!
    >
    > With best regards, Roman Mashak. E-mail:


    Try this change. It may not be the "correct" solution, but it seems to
    work:

    void Init_Timer2( const tByte tick)
    {
    static tLong Inc, Reload_long;
    static tWord Reload_16;
    tByte Reload_08H, Reload_08L;


    // Timer 2 is configured as a 16-bit timer,
    // which is automatically reloaded when it overflows
    T2CON = 0x04; // Load Timer 2 control register

    // Number of timer increments required (max 65536)
    Inc = ((tLong)TICK_MS * (OSC_FREQ/1000)) / (tLong)OSC_PER_INST;

    // 16-bit reload value
    Reload_long = (tLong) (65536UL - Inc);
    Reload_16 = (tWord) Reload_long;

    // 8-bit reload values (High & Low)
    Reload_08H = (tByte)(Reload_16 / 256);
    Reload_08L = (tByte)(Reload_16 % 256);
     
    Not Really Me, May 11, 2004
    #7
  8. "Roman Mashak" <> wrote in news:c7pdht$17ja$:

    > Hello, All!
    >
    > I'm studying the 8051 microcontroller and exploring now sample code
    > I've
    > found. I'm using:
    > - Keil C compiler v6.21
    > - assembler compiler v6.20c
    > - simulation DLL v2.20b
    >
    > There sre some items I can't understand. Anyway, the code I included
    > to
    > this message, is doing the following:
    >
    > 1) initialize Timer 2
    > 2) calculate the number of timer increments
    > 3) define 16-bit reload value
    > 4) split reload 16-bit value onto two 8-bit values....
    > etc.


    This is how I remember doing it. First, let the pre-processor do the math,
    not the CPU. E.g.

    /* 1000 T2 ticks is my example timer interval, the minus sign
    ** makes it all work for incrementing timers.
    */
    #define NUM_TICKS -1000
    #define T2_RELOAD_HI (NUM_TICKS >> 8)
    #define T2_RELOAD_LO (NUM_TICKS & 0xFF00)

    ....

    /* Be sure T2 is stopped. Load T2 up to run at NUM_TICKS
    ** interval.
    */
    RCAP2H = T2_RELOAD_HI; // Useless comment removed
    RCAP2L = T2_RELOAD_LO; // Useless comment removed
    T2H = T2_RELOAD_HI; // Useless comment removed
    T2L = T2_RELOAD_LO; // Useless comment removed

    /* Start T2
    */

    I seem to remember something about need to write to TL2 first or last,
    maybe I'm thinking of something else.
     
    Mark A. Odell, May 11, 2004
    #8
  9. Roman Mashak

    Roman Mashak Guest

    Hello, Not!
    You wrote on Tue, 11 May 2004 10:00:44 -0600:

    NRM> Try this change. It may not be the "correct" solution, but it seems
    NRM> to work:

    NRM> void Init_Timer2( const tByte tick)
    NRM> {
    NRM> static tLong Inc, Reload_long;
    NRM> static tWord Reload_16;
    NRM> tByte Reload_08H, Reload_08L;

    NRM> // Timer 2 is configured as a 16-bit timer,
    NRM> // which is automatically reloaded when it overflows
    NRM> T2CON = 0x04; // Load Timer 2 control register

    NRM> // Number of timer increments required (max 65536)
    NRM> Inc = ((tLong)TICK_MS * (OSC_FREQ/1000)) / (tLong)OSC_PER_INST;

    NRM> // 16-bit reload value
    NRM> Reload_long = (tLong) (65536UL - Inc);
    NRM> Reload_16 = (tWord) Reload_long;

    Thank you very much! It's really worked out.
    It seems compiler cannot make type casting correctly and assign 'tLong'
    value to 'tWord' variable ?

    With best regards, Roman Mashak. E-mail:
     
    Roman Mashak, May 12, 2004
    #9
  10. Roman Mashak

    Roman Mashak Guest

    Hello, nospam!
    You wrote on Tue, 11 May 2004 14:22:18 +0100:

    ??>> void Init_Timer2(const tByte TICK_MS)

    n> This should not even compile
    Nevertheless it did...
    ??>> When I'm doing tracing of the code, I find that the value of
    ??>> Reload_16 is set to 0x00D0 (in hex), but it should be: Inc = ( 30 *
    ??>> (12000000/1000) ) / 12 = 30000, that's OK, clear... Reload_16 =
    ??>> 65536-30000 = 35536, 0x8AD0 in hex But how? And then
    ??>> Reload_08H and Reload_08L appeared to be: 0xD0 and 0xD0, so I still
    ??>> don't understand....

    Now I changed code a little using the advice from this conference. I
    assigned variables Inc and Reload_16 as 'static':

    static tLong Inc, Reload_long;
    static tWord Reload_16;
    staic tByte Reload_08H, Reload_08L;

    And I changed to 65536 to 65535 -> Reload_16 = (tWord) (65535UL -
    Inc);

    Reload_08H = (tByte)(Reload_16 / 256);
    Reload_08L = (tByte)(Reload_16 % 256);

    In this case I got the following:

    'Inc' is calculated correctly, 'Reload_16' also....
    Reload_08H got 0x8A (OK), Reload_08L is 0xCF - why? If we make '%'
    operation (35535 % 256) - it should take division remainder, i.e. 80.

    And now is the most intersting: TH2 and TL2. TH2 is assigned correctly,
    i.e. 0x8A, but TL2 is 0xD1 now, so it was increased with 2, why?

    Thank you for any help!

    With best regards, Roman Mashak. E-mail:
     
    Roman Mashak, May 12, 2004
    #10
  11. Roman Mashak

    Gary Kato Guest

    One of the things you should do is look at the atual instructions that the
    compiler generates to see why it does certain things. You have a simulator so
    you should be able to single step and see exactly what is going on. You don't
    seem to be doing that and just guessing at what the compiler has done.
     
    Gary Kato, May 12, 2004
    #11
  12. On Wednesday, in article <c7robl$1tmc$>
    "Roman Mashak" wrote:
    >Hello, Not!
    >You wrote on Tue, 11 May 2004 10:00:44 -0600:
    >
    > NRM> Try this change. It may not be the "correct" solution, but it seems
    > NRM> to work:
    >
    > NRM> void Init_Timer2( const tByte tick)
    > NRM> {
    > NRM> static tLong Inc, Reload_long;
    > NRM> static tWord Reload_16;
    > NRM> tByte Reload_08H, Reload_08L;
    >
    > NRM> // Timer 2 is configured as a 16-bit timer,
    > NRM> // which is automatically reloaded when it overflows
    > NRM> T2CON = 0x04; // Load Timer 2 control register
    >
    > NRM> // Number of timer increments required (max 65536)
    > NRM> Inc = ((tLong)TICK_MS * (OSC_FREQ/1000)) / (tLong)OSC_PER_INST;
    >
    > NRM> // 16-bit reload value
    > NRM> Reload_long = (tLong) (65536UL - Inc);
    > NRM> Reload_16 = (tWord) Reload_long;
    >
    > Thank you very much! It's really worked out.
    > It seems compiler cannot make type casting correctly and assign 'tLong'
    >value to 'tWord' variable ?


    Have you checked whether you have something set in the compiler to say
    an 'int' is 32 bit?

    Try using tWord defined as an unsigned short?

    After that check the assembly code and what registers are actually being
    changed at each instruction. That is what the simulator is for debugging
    the code.

    --
    Paul Carpenter |
    <http://www.pcserv.demon.co.uk/> Main Site
    <http://www.gnuh8.org.uk/> GNU H8 & mailing list info.
    <http://www.badweb.org.uk/> For those web sites you hate.
     
    Paul Carpenter, May 12, 2004
    #12
  13. On Wednesday, in article <c7rrjr$22u7$>
    "Roman Mashak" wrote:

    >Hello, nospam!
    >You wrote on Tue, 11 May 2004 14:22:18 +0100:
    >
    > ??>> void Init_Timer2(const tByte TICK_MS)
    >
    > n> This should not even compile
    > Nevertheless it did...
    > ??>> When I'm doing tracing of the code, I find that the value of
    > ??>> Reload_16 is set to 0x00D0 (in hex), but it should be: Inc = ( 30 *
    > ??>> (12000000/1000) ) / 12 = 30000, that's OK, clear... Reload_16 =
    > ??>> 65536-30000 = 35536, 0x8AD0 in hex But how? And then
    > ??>> Reload_08H and Reload_08L appeared to be: 0xD0 and 0xD0, so I still
    > ??>> don't understand....
    >
    > Now I changed code a little using the advice from this conference. I
    >assigned variables Inc and Reload_16 as 'static':
    >

    .....
    > Reload_08H = (tByte)(Reload_16 / 256);
    > Reload_08L = (tByte)(Reload_16 % 256);
    >
    > In this case I got the following:
    >
    > 'Inc' is calculated correctly, 'Reload_16' also....
    > Reload_08H got 0x8A (OK), Reload_08L is 0xCF - why? If we make '%'
    >operation (35535 % 256) - it should take division remainder, i.e. 80.


    Why are you not just simply getting the low byte by anding with 0xFF ?

    It may just by that the modulus function is not correctly linked in.
    Use a simpler method as modulus '%' is nearly always some form of
    library function, which can need all sorts of extra code loaded.

    --
    Paul Carpenter |
    <http://www.pcserv.demon.co.uk/> Main Site
    <http://www.gnuh8.org.uk/> GNU H8 & mailing list info.
    <http://www.badweb.org.uk/> For those web sites you hate.
     
    Paul Carpenter, May 12, 2004
    #13
  14. Roman Mashak

    Roman Mashak Guest

    Hello, Paul!
    You wrote on Wed, 12 May 2004 06:49:08 +0000 (UTC):

    ??>> Thank you very much! It's really worked out.
    ??>> It seems compiler cannot make type casting correctly and assign
    ??>> 'tLong' value to 'tWord' variable ?

    PC> Have you checked whether you have something set in the compiler to say
    PC> an 'int' is 32 bit?
    It's all fine...
    PC> Try using tWord defined as an unsigned short?

    Yes, I tried, but nothing changed.... They all have the same width - 32
    bits.

    PC> After that check the assembly code and what registers are actually
    PC> being changed at each instruction. That is what the simulator is for
    PC> debugging the code.

    I was fighting with assembler debugger for some time :) and what I've
    found. All code is correctly processed, except this part :

    TH2 = Reload_08H; -> MOV TH2(0xCD), 0x12
    RCAP2H = Reload_08H; -> MOV RCAP2H(0xCB), 0x12
    TL2 = Reload_08L; -> MOV TL2(0xCC), 0x13
    RCAP2L = Reload_08L; -> MOV RCAP2L(0xCA), 0x13

    So, TH2 is correctly setup (0x8A), RCAP2H also, BUT TL2 is incorrectly setup
    (0xD1 instead of 0xCF), while RCAP2L is fine! It seems to me that timer is
    getting increasing, but it's not turned on at this time, because line TR2 is
    beneath.....

    Moreover, the memory window is showing absolutely correct values calculated
    during the program.

    What else can you recommend?

    With best regards, Roman Mashak. E-mail:
     
    Roman Mashak, May 12, 2004
    #14
  15. Roman Mashak

    Roman Mashak Guest

    Hello, Paul!
    You wrote on Wed, 12 May 2004 06:49:09 +0000 (UTC):

    ??>> 'Inc' is calculated correctly, 'Reload_16' also....
    ??>> Reload_08H got 0x8A (OK), Reload_08L is 0xCF - why? If we make '%'
    ??>> operation (35535 % 256) - it should take division remainder, i.e. 80.

    PC> Why are you not just simply getting the low byte by anding with 0xFF ?

    PC> It may just by that the modulus function is not correctly linked in.
    PC> Use a simpler method as modulus '%' is nearly always some form of
    PC> library function, which can need all sorts of extra code loaded.

    As I said before, I'm studying this microcontroller, so I would like to
    understand this code, and find the error!
    By the way, this source code was provided in the book by Michael J. Pont
    "Embedded C".

    With best regards, Roman Mashak. E-mail:
     
    Roman Mashak, May 12, 2004
    #15
  16. Roman Mashak <> wrote:

    > PC> Try using tWord defined as an unsigned short?


    > Yes, I tried, but nothing changed.... They all have the same width - 32
    > bits.


    Most certainly not. On an 8051 compiler, both int and short will
    almost invariably be 16-bit data types. You don't want to use 32 bit
    types any more than you absolutely have to, on such a small CPU.

    > So, TH2 is correctly setup (0x8A), RCAP2H also, BUT TL2 is incorrectly setup
    > (0xD1 instead of 0xCF), while RCAP2L is fine!


    I'm still not convinced. Show actual assembly output from the listing
    file please.

    --
    Hans-Bernhard Broeker (-aachen.de)
    Even if all the snow were burnt, ashes would remain.
     
    Hans-Bernhard Broeker, May 12, 2004
    #16
  17. Roman Mashak

    nospam Guest

    "Roman Mashak" <> wrote:

    >
    > Reload_08H = (tByte)(Reload_16 / 256);
    > Reload_08L = (tByte)(Reload_16 % 256);
    >
    > In this case I got the following:
    >
    > 'Inc' is calculated correctly, 'Reload_16' also....
    > Reload_08H got 0x8A (OK), Reload_08L is 0xCF - why? If we make '%'
    >operation (35535 % 256) - it should take division remainder, i.e. 80.


    35535 is 0x8ACF so the 0xCF is correct

    > And now is the most intersting: TH2 and TL2. TH2 is assigned correctly,
    >i.e. 0x8A, but TL2 is 0xD1 now, so it was increased with 2, why?


    Without checking the timer documentation and modes I am not sure but make
    sure the timer is stopped before you configure it and configured in the
    right mode before you start it. It is the function of the timer in some
    modes to increment TL2 so the value you load may be incremented by the
    timer hardware before you inspect it.
     
    nospam, May 12, 2004
    #17
  18. Roman Mashak

    Chris Hills Guest

    In article <>, Paul Carpenter
    <paul$@pcserv.demon.co.uk> writes
    >On Wednesday, in article <c7robl$1tmc$>
    > "Roman Mashak" wrote:
    >>Hello, Not!
    >>You wrote on Tue, 11 May 2004 10:00:44 -0600:
    >>
    >> NRM> Try this change. It may not be the "correct" solution, but it seems
    >> NRM> to work:
    >>
    >> NRM> void Init_Timer2( const tByte tick)
    >> NRM> {
    >> NRM> static tLong Inc, Reload_long;
    >> NRM> static tWord Reload_16;
    >> NRM> tByte Reload_08H, Reload_08L;
    >>
    >> NRM> // Timer 2 is configured as a 16-bit timer,
    >> NRM> // which is automatically reloaded when it overflows
    >> NRM> T2CON = 0x04; // Load Timer 2 control register
    >>
    >> NRM> // Number of timer increments required (max 65536)
    >> NRM> Inc = ((tLong)TICK_MS * (OSC_FREQ/1000)) / (tLong)OSC_PER_INST;
    >>
    >> NRM> // 16-bit reload value
    >> NRM> Reload_long = (tLong) (65536UL - Inc);
    >> NRM> Reload_16 = (tWord) Reload_long;
    >>
    >> Thank you very much! It's really worked out.
    >> It seems compiler cannot make type casting correctly and assign 'tLong'
    >>value to 'tWord' variable ?

    >
    >Have you checked whether you have something set in the compiler to say
    >an 'int' is 32 bit?
    >
    >Try using tWord defined as an unsigned short?


    int and short are both 16 bit on this compiler.

    /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
    \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/\
    /\/\/ www.phaedsys.org \/\/
    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
     
    Chris Hills, May 12, 2004
    #18
  19. On Wednesday, in article
    <>
    "Chris Hills" wrote:

    >In article <>, Paul Carpenter
    ><paul$@pcserv.demon.co.uk> writes
    >>On Wednesday, in article <c7robl$1tmc$>
    >> "Roman Mashak" wrote:
    >>>Hello, Not!
    >>>You wrote on Tue, 11 May 2004 10:00:44 -0600:
    >>>
    >>> NRM> Try this change. It may not be the "correct" solution, but it seems
    >>> NRM> to work:
    >>>
    >>> NRM> void Init_Timer2( const tByte tick)
    >>> NRM> {
    >>> NRM> static tLong Inc, Reload_long;
    >>> NRM> static tWord Reload_16;
    >>> NRM> tByte Reload_08H, Reload_08L;
    >>>
    >>> NRM> // Timer 2 is configured as a 16-bit timer,
    >>> NRM> // which is automatically reloaded when it overflows
    >>> NRM> T2CON = 0x04; // Load Timer 2 control register
    >>>
    >>> NRM> // Number of timer increments required (max 65536)
    >>> NRM> Inc = ((tLong)TICK_MS * (OSC_FREQ/1000)) / (tLong)OSC_PER_INST;
    >>>
    >>> NRM> // 16-bit reload value
    >>> NRM> Reload_long = (tLong) (65536UL - Inc);
    >>> NRM> Reload_16 = (tWord) Reload_long;
    >>>
    >>> Thank you very much! It's really worked out.
    >>> It seems compiler cannot make type casting correctly and assign 'tLong'
    >>>value to 'tWord' variable ?

    >>
    >>Have you checked whether you have something set in the compiler to say
    >>an 'int' is 32 bit?
    >>
    >>Try using tWord defined as an unsigned short?

    >
    >int and short are both 16 bit on this compiler.


    They are on quite a few, but it is possible on some like GCC
    to force ALL ints to 32bit, which may be his problem, or how
    the link to the simulator is doing it.

    --
    Paul Carpenter |
    <http://www.pcserv.demon.co.uk/> Main Site
    <http://www.gnuh8.org.uk/> GNU H8 & mailing list info.
    <http://www.badweb.org.uk/> For those web sites you hate.
     
    Paul Carpenter, May 12, 2004
    #19
  20. Roman Mashak

    Roman Mashak Guest

    Hello, Hans-Bernhard!
    You wrote on 12 May 2004 13:10:38 GMT:

    ??>> Yes, I tried, but nothing changed.... They all have the same width
    ??>> - 32 bits.

    HBB> Most certainly not. On an 8051 compiler, both int and short will
    HBB> almost invariably be 16-bit data types. You don't want to use 32 bit
    HBB> types any more than you absolutely have to, on such a small CPU.
    Yes, you absolutely right. My mistake, I misprinted....
    ??>> So, TH2 is correctly setup (0x8A), RCAP2H also, BUT TL2 is incorrectly
    ??>> setup (0xD1 instead of 0xCF), while RCAP2L is fine!

    HBB> I'm still not convinced. Show actual assembly output from the listing
    HBB> file please.
    Here is a full assembler output of function I got after compilation:

    0000 75C804 MOV T2CON,#04H
    0003 E4 CLR A
    0004 FC MOV R4,A
    0005 FD MOV R5,A
    0006 FE MOV R6,A
    0007 7BE0 MOV R3,#0E0H
    0009 7A2E MOV R2,#02EH
    000B F9 MOV R1,A
    000C F8 MOV R0,A
    000D 120000 E LCALL ?C?LMUL
    0010 E4 CLR A
    0011 7B0C MOV R3,#0CH
    0013 FA MOV R2,A
    0014 F9 MOV R1,A
    0015 F8 MOV R0,A
    0016 120000 E LCALL ?C?ULDIV
    0019 8F00 R MOV Inc+03H,R7
    001B 8E00 R MOV Inc+02H,R6
    001D 8D00 R MOV Inc+01H,R5
    001F 8C00 R MOV Inc,R4
    ; SOURCE LINE # 82
    0021 C3 CLR C
    0022 74FF MOV A,#0FFH
    0024 9F SUBB A,R7
    0025 F500 R MOV Reload_16+01H,A
    0027 74FF MOV A,#0FFH
    0029 9E SUBB A,R6
    002A F500 R MOV Reload_16,A
    ; SOURCE LINE # 87
    002C F500 R MOV Reload_08H,A
    ; SOURCE LINE # 88
    002E 850000 R MOV Reload_08L,Reload_16+01H
    ; SOURCE LINE # 89
    0031 750000 R MOV Reload_16,#00H
    ; SOURCE LINE # 95
    0034 8500CD R MOV TH2,Reload_08H
    ; SOURCE LINE # 96
    0037 8500CB R MOV RCAP2H,Reload_08H
    ; SOURCE LINE # 97
    003A 8500CC R MOV TL2,Reload_08L
    ; SOURCE LINE # 98
    003D 8500CA R MOV RCAP2L,Reload_08L
    ; SOURCE LINE # 102
    0040 D2AD SETB ET2
    ; SOURCE LINE # 105
    0042 D2CA SETB TR2
    ; SOURCE LINE # 107
    0044 D2AF SETB EA
    ; SOURCE LINE # 108
    0046 22 RET


    With best regards, Roman Mashak. E-mail:
     
    Roman Mashak, May 13, 2004
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. X.O.R. Gates
    Replies:
    1
    Views:
    911
    Tom Woodrow
    Aug 21, 2003
  2. Thomas Hoppe

    Keil compiler or FX2 ?

    Thomas Hoppe, May 7, 2004, in forum: Embedded
    Replies:
    4
    Views:
    557
    Hans-Bernhard Broeker
    May 8, 2004
  3. Replies:
    3
    Views:
    367
    Hans-Bernhard Broeker
    Nov 8, 2004
  4. Replies:
    4
    Views:
    456
    Murray R. Van Luyn
    Nov 26, 2004
  5. ishita

    keil compiler

    ishita, May 31, 2006, in forum: Embedded
    Replies:
    9
    Views:
    2,383
Loading...

Share This Page