This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem in PWM and UART (T89C51AC2)

#include <t89c51ac2.h>
//#include <math.h>

void serialInterrupt (void);
volatile char uart_data;

char duty;

void main(void)
{

        // Set up UART mode
        SCON = 0x50;                    // uart in mode 1 (8 bit), REN=1
        TMOD = TMOD | 0x20 ;    // Timer 1 in mode 2
        TH1 = 0xFB;                     // 9600 Bds at 18.432MHz
        TL1 = 0xFB;                     // 9600 Bds at 18.432MHz
        ES = 1;                                 // Enable serial interrupt
        EA = 1;                                 // Enable global interrupt      */
        TR1 = 1;

        // Set up PWM mode
        CMOD = 0x02;                    // Setup PCA timer
        CL = 0x00;
        CH = 0x00;
        CCAP0L = 0x40;                  // Set the initial value same as CCAP0H
        CCAP0H = 0x40;                  // 75% Duty Cycle
        CCAPM0 = 0x42;                  // Setup PCA module 0 in PWM mode.
        CR = 1;                                 // Start PCA Timer.*/



        // Init variable

        uart_data = 128;                        // 50% Duty Cycle


        //Program main routime, do forever
        while (1)
        {
                P2 = 0xFF;                      // turn off all lamps (for test)
                P2_2=0;                         // Turn on
                CCAP0H = (int) uart_data;

        }
}

void serialInterrupt (void) interrupt 4 using 1{
        if (RI)
        {                                                               // Byte received on UART.

                uart_data = SBUF;

                if (uart_data == '1')           // For Testing
                        P2_0 = 0;

                SBUF = uart_data;                       // Initiate transmit of the byte received.

                RI = 0;                                 // Clear interrupt flag.

        }
        else if (TI)
        {                               // Finished transmitting a byte.
                //P2_4 = 0;
                TI = 0;

        }
}

I try to control position of motor. So I need receive new position from computer through RS232 and control motor by PWM mode 1.

My PWM code (without UART) controlling a motor.
Result: SUCCESS!

My UART code (without PWM) echoing characters it receives.
Result: SUCCESS!

I have 2 questions:

1. Why in UART code, in serialInterrupt function I have to put this code:

if (uart_data == '1')           // For Testing
                        P2_0 = 0;


and in main loop :

P2 = 0xFF;                      // turn off all LED (for test)
                P2_2=0;                         // Turn on


If I use this code (first time I only think it only use for test) UART is well done, but when I close it, UART can not work correct.

2. If I combine UART and PWM projects, the new project (above code) only has PWM but can not send/receive.

One body said that: "If that indicates a PCA interrupt (I don't know because I'm not familiar with how uVision debugger presents the PCA subsystem) and you don't have an ISR for it, then that could cause a lot of problems."

But I don't understand much.

Did I miss somethings in my code?

Kind Regards,
Mr. Huy

  • What is connected to P2.0 and P2.2?

    "If I use this code (first time I only think it only use for test) UART is well done, but when I close it, UART can not work correct."

    Do you mean even without PWM, your UART code "doesn't work" without this?

    What, precisely, do you mean by "doesn't work"
    Does it receive?
    Does it transmit?

  • void serialInterrupt (void) interrupt 4 using 1
    {
       if (RI)
       {                           // Byte received on UART.
          uart_data = SBUF;
          if (uart_data == '1')    // For Testing
          {
             P2_0 = 0;
          }
          SBUF = uart_data;        // Initiate transmit of the byte received.
          RI = 0;                  // Clear interrupt flag.
       }
       else if (TI)
       {                           // Finished transmitting a byte.
          //P2_4 = 0;
          TI = 0;
       }
    }
    


    Why do you have an 'else' for checking TI?
    Both TI and RI could be set - remove the 'else':

    void serialInterrupt (void) interrupt 4 using 1
    {
       if (RI)
       {
          // Handle RI
       }
    
       if (TI)
       {
          // Handle TI
       }
    }
    

  • Why do you have an 'else' for checking TI?
    Both TI and RI could be set - remove the 'else'

    When I remove 'else'.

    1. It's still not working. Not working mean: PWM has, RS232: can not transfer/receive (I send data from computer and wait to receive: nothing).

    2. If I close PWM initiation code, still keep (P2 = 0xFF, P2.0 = 0; ..): RS232 can transmit/receive corect.

    3. If I close PWM code, remove (P2= OXFF,...)

    Send: '1' --> receive: '/r/r/r/r/r/r....'

    The receiving repeat until I press reset button.

  • What is connected to P2.0 and P2.2?

    Nothing connected to P2. In UART project, I use P1 to test like P2 in here. At that time, I connect P1 with LED. When 1 combine with PWM code, I can not use P1 because P1.3 is PWM mode 0. I remove it --> UART not working (can not send/receive) so I put P2 instead of P1.

    do you mean by "doesn't work"
    Does it receive?
    Does it transmit?

    I mean It can not transmit/receive without P2 put in main loop, and Interrupt function.

  • I see nothing blatantly wrong with your code (besides the 'else'), but vaguely remember that the T89Cxxx xhips were 'recalled' and replaced by AT89Cxxx 'equivalents.

    Now since these are Atmel chips, it is very likely that the errata is grossly incomplete, so my first try would be to assume that the PCA interrupt may be active when not enabled and insert a dummy PCA ISR in the code.

    If that does not help, try inplementing 'something else' that is not controlled by the serial in the PCA and see what happens.

    BTW, you know the existence of The PCA cookbook
    www.intel.com/.../270609.htm I hope

    Erik

  • "I mean It can not transmit/receive"

    So you don't know whether it's the receive or the transmit, or both that's not working, do you?

    You first step must be to determine precisely what is and what is not happening.

    You can't fix a problem before you know what the problem is!

    Do you have access to an oscilloscope?

  • So you don't know whether it's the receive or the transmit, or both that's not working, do you?

    I am sure that it can not transmit (because my software read it) but I not sure it can or can not receive.

    Do you have access to an oscilloscope?

    Yes, I have. I used it to test PWM signal. Ahh, so I think my Chip also can not receive because PWM duty didn't change.

    You first step must be to determine precisely what is and what is not happening.

    I don't understand why I need set P2 = 0xFF in main loop; and p2.0 =0 in interrupt function.

    Here, I have assembly code for RS232. It work quite good and no need put P2 like my code. But I not familiar with Assembly, I try to setup UART mode like this one but the Chip still not working (no transfer/receive).

    ;/***************************************/;
    ;/* Example Form For : CP-JR51AC2  V2.0 */;
    ;/* Controller       : T89C51AC2(ATMEL) */;
    ;/* Run X-TAL        : 18.432 MHz       */;
    ;/*                  : 12 Cycle Mode    */;
    ;/* Assembler        : SXA51.EXE        */;
    ;/* File Name        : RS232.ASM        */;
    ;/* Write By         : Eakachai Makarn  */;
    ;/* File Update      : 15-Nov-2002      */;
    ;/***************************************/;
    ;/* System IO Self Test For CP-JR51AC2  */;
    ;/* -> Test RS232/422                   */;
    ;/***************************************/;
    ;
    ;/* Clock Control Registers */;
    CKCON       EQU     08FH                ; Clock Control Register
    
                ORG     20H                 ; Start Internal RAM Buffer
    STACK:      DS      30                  ; Stack 30 Byte
    
                ORG     0000H                   ; Reset Vector of CPU
    MAIN:       MOV     SP,#STACK               ; Initial Stack
                ;ORL     CKCON,#00000001B        ; Select Clock = X2 Mode (6-Cycle)
                ANL     CKCON,#11111110B        ; Set Clock = Standard Mode (12 Clock)
                MOV     TMOD,#00100001B         ; Timer1(8Bit-Auto) & Timer0(16Bit)
                MOV     SCON,#01010000B         ; Serial Port Mode 1
                SETB    PS                      ; Serial Interupt High Piority
                CLR     ES                      ; Disable Serial Interupt
                CLR     ET0                     ; Disable Timer0 Interupt
                CLR     ET1                     ; Disable Timer1 Interupt
                MOV     A,#0FBH                 ; Set Baudrate 9600(18.432MHz/12Clock)
                MOV     TH1,A
                MOV     TL1,A
                SETB    TR0                     ; Start Timer0
                SETB    TR1                     ; Start Timer1
                SETB    EA                      ; Enable Global Interupt
                ;
                ;/*******************************/;
                ;/* Start Function Program Here */;
                ;/*******************************/;
                ;
                LCALL   PRINT_SER               ; Print Menu Function Test
                DB      0DH,0AH,0AH
                DB      'Demo Selftest For CP-JR51AC2 V1.0 & V2.0 (12-Clock Mode)'
                DB      0DH,0AH,00H
                ;
    TEST_232:   LCALL   PRINT_SER               ; Display Sign-on Logo
                DB      0DH,0AH,0AH
                DB      'RS232/RS422 Receive & Transmit Test'
                DB      0DH,0AH
                DB      'Press Any Key For Test.......'
                DB      0DH,0AH,00H
                ;
    LOOP_232:   LCALL   RX_BYTE                 ; Receive RS232
                CJNE    A,#0DH,ECHO_232
                LJMP    TEST_232                ; If Enter Restart
    ECHO_232:   LCALL   TX_BYTE                 ; Transmit RS232
                LJMP    LOOP_232
    
    ;/*************************/;
    ;/* Send 1-Byte to RS-232 */;
    ;/* Input   : ACC         */;
    ;/* Output  : Serial port */;
    ;/*************************/;
    ;
    TX_BYTE:    MOV     SBUF,A
                JNB     TI,$                    ; Wait TX Data Ready
                CLR     TI
                RET
    
    ;/****************************/;
    ;/* Receive Data From RS-232 */;
    ;/* Input   :  Serial Port   */;
    ;/* Output  :  ACC           */;
    ;/****************************/;
    ;
    RX_BYTE:    JNB     RI,RX_BYTE              ; Wait RX Data Ready
                CLR     RI
                MOV     A,SBUF                  ; Get RX Data
                RET
    
    ;/******************************/;
    ;/* Print Data to Serial Port  */;
    ;/* Usage    : LCALL PRINT_SER */;
    ;/*          : DB   'xxxx',00  */;
    ;/******************************/;
    ;
    PRINT_SER:  POP     DPH
                POP     DPL
    PRN_SER1:   CLR     A
                MOVC    A,@A+DPTR
                CJNE    A,#00H,PRN_SER2
                LJMP    PRN_SER3
    PRN_SER2:   LCALL   TX_BYTE
                INC     DPTR
                LJMP    PRN_SER1
    PRN_SER3:   PUSH    DPL
                PUSH    DPH
                RET
    
                END
    

  • remove (comment out?) ALL PWM code
    make a received byte toggle a bit on P1 or P2 verify that works. Then make it put the received byte on P1 or P2 - verify that works, then ...

    SIMPLIFY

    Debugging the whole kit and kaboodle will only make it more difficult

  • "I am sure that it can not transmit (because my software read it) but I not sure it can or can not receive."

    But the only time it attempts to transmit is to "echo" a received character, isn't it?

    So, if you don't receive the "echo", how can you tell whether that's because the receive didn't work (so there is nothing to echo), or the transmit doesn't work?!

  • Dear all,

    I will change to use PSoC chip with 2 UARTs, so want to say thank to all for your helps.

    Kind Regards,
    Huy

  • "I will change to use PSoC chip with 2 UARTs"

    Err... doesn't that belong in your other thread:
    http://www.keil.com/forum/docs/thread9116.asp

  • Yes, It is also my question.

    Thanks for all.