#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.
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?
I am sure that it can not transmit (because my software read it) but I not sure it can or can not receive.
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.
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.