Hello,
I have two AT89C52 in a simplex connection, I'm having problems with my receiver. I've tried like 5 different ways of receiving data but it looks like I'm getting the wrong data in SBUF and it receives like 20% packets that are actually sent. I used an osciloscope to see if the packets are sent, and it looks fine. no noises and such.
I tried putting the 2 processors on a matrice to check them with a simple program and it works, so I guess it has something to do with the bigger program.
This is a LED Matrice project (with scanning) so the extra stuff is related to it. It would be very helpful if someone could comment and maybe find what I'm doing wrong
#include <reg52.h> #include <intrins.h> // prototypes char set_font(unsigned int row, unsigned int letter); ///char pow(char num, char pow); //bit is_effect(char DATA); sbit CLK_COL = P3^1; sbit ROW0 = P1^0; sbit ROW1 = P1^1; sbit ROW2 = P1^2; sbit ROW3 = P1^3; sbit OE_ROW = P1^4; sbit OE_COL = P1^5; sbit OE_COL_D = P3^4; sbit LE = P1^6; sbit SER = P1^7; // global variables //xdata char my_string[] = {6,4,14,17,6,4,36,17,20,1,8,13,36,14,22,13,25,36,24,14,20,17,36,0,18,18,36,36,36,36}; //xdata char str_len=30; xdata char output[7][48] = {{0}}; xdata unsigned char my_string[] = {22,4,11,2,14,12,4,36,36,36,36}; xdata unsigned char str_len=11,border; xdata char timer0_c=0; xdata unsigned char tmp_sbuf=0; bit shift_flag=0,data_ready=0,clean_flag=0; char set_font(unsigned int row, unsigned int letter) // returns wanted code for font according to wanted row { .... } void SER_ISR() interrupt 4 { if(RI) { RI = 0; my_string[str_len++] = SBUF; } } void INT0_ISR() interrupt 0 { SCON = 0x50; // Mode 1, No Parity, Receive Enable TMOD &= 0x0F; TMOD |= 0x20; // T1 Mode 2 (auto reload - baud gen). TH1 = -52; // 1200 baud rate TR1 = 1; IE &= 0xef; IE |= 0x10; // Enable SER ISR str_len = 0; data_ready = 1; } void timer0_ISR() interrupt 1 { TH0 = ~(50000/256); TL0 = -(50000%256); if(timer0_c<=2) { timer0_c++; } else { timer0_c = 0; shift_flag = 1; } } void main(void) { xdata char carry[48]={0}; xdata char i=0,j,cor_order,tmp,cur_row=5; border = (str_len>=4) ? str_len : 4; IE = 0x83; // Timer 0 (rotation). INT0 (serial transmission) IT0 = 1; // Using FF SCON = 0x50; // Mode 1, No Parity, Receive Enable TMOD = 0x21; // T0 Mode 1 (rotate counter). T1 Mode 2 (baud rate generator) TH1 = -52; // 1200 baud rate TR1 = 1; T2CON = 0x01; // T2 Capture Mode TH0 = ~(50000/256); TL0 = -(50000%256); TR0 = 1; // populate output(array) with font data for(i=0; i<7; i++) for(j=str_len-1,cor_order=0; j>=0; j--,cor_order++) output[cor_order] = set_font(i,my_string[j]); while(1) { if(data_ready) { data_ready = 0; if(my_string[str_len--] == 0xaa) { str_len-=2; // Fill font array with new data for(i=0; i<7; i++) for(j=str_len-1,cor_order=0; j>=0; j--,cor_order++) output[cor_order] = set_font(i,my_string[j]); border = (str_len>=4) ? str_len : 4; // Set new borders //IE &= 0xef; // Disable SER ISR clean_flag = 0; } } // RESET BEFORE SHOW LE = 0; OE_COL_D = 0; OE_COL = 1; OE_ROW = 1; ROW0=cur_row%2; ROW1=(cur_row>>1)%2; ROW2=(cur_row>>2)%2; ROW3=(cur_row>>3)%2; // shift data left when needed if(shift_flag) { // i = index, j = row for(j=0; j<7; j++) { // save msb for(i=0; i<border; i++) carry = _crol_ (output[j]&0x80,1); // shift for(i=0; i<border; i++) output[j] = output[j]<<1; // get msb(new lsb) from next cell for(i=0; i<border; i++) { if(i==0) output[j][0] += carry[border-1]; else output[j] += carry[i-1]; } } shift_flag = 0; } // output fonts to SER for(j=0; j<4; j++) { tmp = ~output[cur_row-5][j]; for(i=0; i<8; i++) { SER = tmp%2; tmp=tmp>>1; CLK_COL = 1; CLK_COL = 0; } } LE = 1; OE_COL_D = 1; OE_COL = 0; OE_ROW = 0; if(cur_row==11) cur_row=5; else cur_row++; TH2 = ~(500/256); TL2 = -(500%256); TR2=1; while(!TF2); TR2=0; TF2=0; } }
It should work in the following way: 1) I receive an INT0 when a new batch of packets is coming (text) 2) in the INT0 ISR I set all necessary registers for serial commmunication 3) I receive data using SER ISR 4) When finished receiving data I process it (in the main program)
Thanks in advance..
Why not have the receive interrupt enabled all the time?
If you have too slow interrupt response times, you will not have time to enable the UART before you have lost the first byte of the packet.
There are really no reason to turn on/off the UART. It doesn't consume any processing power when no data is sent. And it doesn't affect the power consumption, since you are not developing a tiny battery-driven device that has to survive on a button cell.
You are just complicating your life.
I guess you're right.
It doesn't help when I leave it enabled all the time too, so I guess it's not really the problem.