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

Problems with serial communication

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..

0