PIC16F887 Serial Reception

Thread Starter

josephgebran

Joined Jun 5, 2011
10
Dear All, I am working on a project that consists of a RC CAR controlled over the internet by WiFi. I am using PIC16F887 and the Control Interface on the PC is VB.NET . I take data into the PIC through Serial RS232. when i Use ISIS professional to simulate the PIC with a simple LED and i link ISIS and VB.NET , the PIC receives Data but nothing happens and the LED doesn't turn on, so i thought there is something wrong in my code .( i am not very smart in microcontroller programming , here is a part of the code, please help)

void main()
{
again:
init();
Reception_loop:
if(OERR==1)
{RCSTA=0b10000000;
goto again;
}
if(RCIF==1)
{x1=RCREG-30;
x2=RCREG-30;
}
else
goto Reception_loop;

The x1= rcreg-30 and x2=rcreg-30 i thought i had to write -30 because VB sends String type . and the PIC receives 2 characters one after the other, so i save them in x1 and then x2.
In the init() function i wrote:

RCSTA=0b10010000;
TXSTA=0b00100100;
BAUDCTL=0b00001000;
SPBRG=832;

please try to help me
 

DumboFixer

Joined Feb 10, 2009
217
Firstly, welcome to the Forum.
Secondly, please put your code inside "Code" tags (#)

You haven't included all the code - there mar/are be important bits missing.

Did you really mean to call
Rich (BB code):
init()
every iteration of the loop - I suspect not.

A programming tip - get rid of those Goto statements, a little bit of redesign work and you should be able to do it (try drawing a flowchart of what you want to happen).
 

Thread Starter

josephgebran

Joined Jun 5, 2011
10
Yes i call init() everytime, but you are right maybe it's dumb, but i read that if OERR is set, i mean if i haven't read RCREG and a third character comes, it will be lost, and error will be generated, and i won't be able to read characters again until i clear the OERR and this OERR is cleared when we clear CREN or SPEN , but i want them set not clear !! so how should i make a condition to read coming information without having the OERR problem ? i will post the full code in a few minutes
 

Thread Starter

josephgebran

Joined Jun 5, 2011
10
Rich (BB code):
#define _XTAL_FREQ 8000000
#define  TMR2_PRESCALER 4

__CONFIG(0x3CC4);    // config word 1
__CONFIG(0x3eff);    // config word 2 (in sequence)


#define byte unsigned char
#define word unsigned int
#define dword unsigned long
#define  SENSOR1 5
#define Numsteps 4

char step[]= {5,9,10,6};
char index=0;
char pos=10;

typedef union _word_VAL
{
    word Val;
    struct { byte LB; byte HB; } byte1;
} word_VAL;

int x1,x2,x3,speed;
byte ccpr1l_copy,ccpr2l_copy;
void PWM1_Init(word x),PWM1_Set_Duty(byte x),PWM1_Start(),PWM1_Stop();
void PWM2_Init(word x),PWM2_Set_Duty(byte x),PWM2_Start(),PWM2_Stop();
void init();
void Connection_done();
void Reset();
void fault();
void Move_Forward(int speed);
void Move_Backward();
void Clutch();
void Change_FlashLight();
void Horn();
void Reset_Horn();
void Change_Cam_Status();
void Rotate_Right();
void Rotate_Left();
void No_Rotate();
void Rotate_Cam_Left();
void Rotate_Cam_Right();
void No_Cam_Rotate();
void inc_index();
void dec_index();
void PulseMotor();
byte adc_read8(byte channel);
word adc_read10(byte channel);

void main()
{
	again:
	init();
 Reception_loop:
                if(OERR==1)
					{RCSTA=0b10000000;
					goto again;
					}
				if(RCIF==1)
                  {x1=RCREG-30;
					x2=RCREG-30;
                   }
                else
                  goto Reception_loop;

x3 = x1 & 224 ;  //  to specify the speed of the robot ( XXX0 0000 )
switch(x3)
 { case 32:
         speed = 1 ;
         break;
   case 64:
         speed = 2 ;
         break;
   case 128:
         speed = 3 ;
         break;
   default:
         speed = 0 ;}
 

x3 = x1 & 24 ;   // to specify the direction of rotation ( 000X X000 )
switch(x3)
 { case 8:
         Rotate_Left();
         break;
   case 16:
         Rotate_Right();
         break;
   case 24: // in case both buttons left and right are pressed at same time
         break; // do nothing
   default:
         No_Rotate();
         break; }
 

 x3 = x1 & 7 ;   // to specify the direction of rotation ( 0000 0XXX )
switch(x3)
 { case 0:
         Reset();
         break;
   case 1:
         Move_Forward(speed);
         break;
   case 2:
         Move_Backward(speed);
         break;
   default:
         Clutch();
         break;}
 

 x3 = x2 & 1 ;
   if ( x3 == 1 ) Change_FlashLight();

 x3 = x2 & 2 ;
   if ( x3 == 2 ) Horn();
   else Reset_Horn();

 x3 = x2 & 4 ;
   if ( x3 == 4 ) Change_Cam_Status();

 x3 = x2 & 24 ;
switch( x3 )
 { case 8:
         Rotate_Cam_Left();
         break;
   case 16:
            Rotate_Cam_Right();
            break;
   default:
            No_Cam_Rotate();
            break;}
 
goto Reception_loop;

}             // End main program

void init()
{
OSCCON=0b01110000;   //frequency = 8M
ANSEL=0b1110000;     //Enable PortA Analog Input,AN4,AN5,AN6
ANSELH=0;            //Disable PortB Analog Input
C1ON=0;              //turn off
C2ON=0;              //comparators
TRISA=0b11110000;	 //RA0,RA1,RA2,RA3 Digital Outputs for stepper motor of Camera,AN4 Analog Input for Light Sensor
TRISB=0b11101011;    //RB2,RB4 Digital Outputs for Horn and Flashlight
TRISC=0b11110000;    //RC0,RC3 Digital Outputs for DC motor, CCP1,CCP2 for PWM Output
TRISD=0b11000000;    //RD0,RD1,RD2,RD3 Digital Outputs for stepper motor of Robot ,RD4 Digital Output for Camera,RD5 Digital Output for Clutch
T2CON=0b00000001;    // prescaler=4
CCP1CON=0b00001100;
CCP2CON=0b00001100;
CCPR1H=CCPR1L=CCPR2H=CCPR2L=0;
ccpr1l_copy=ccpr2l_copy=0;
PWM1_Init(5000);   //Initialize PWM modules at
PWM2_Init(5000);   //5KHz frequency
RCSTA=0b10010000;
TXSTA=0b00100100;
BAUDCTL=0b00001000;
SPBRG=832;
}

void Connection_done()
{ Transmission_loop:
        if ( TXIF == 0 )
                goto Transmission_loop;
        else
        TXREG = 2; }

void fault()
{ Fault_loop:
        if ( TXIF == 0 )
                goto Fault_loop;
        else
        TXREG = 5; }

void Reset()
{ RD5=0;
  RC0=0;
  RC3=0;
  PWM1_Stop();
  PWM2_Stop();
  }


void Move_Forward(int speed)
{ byte current_duty;
        switch(speed)
        { case 1:
            current_duty = 51;
            break;
          case 2:
            current_duty = 127;
            break;
          case 3:
            current_duty = 203;
            break;
          case 0:
            RC0=0;
            PWM1_Stop();
            break; }
   if (current_duty!=0)      
   
	{PWM1_Set_Duty ( current_duty );
   PWM1_Start();
   RC0=1; }
} 

 void Move_Backward()
 { byte current_duty1=127;
         PWM2_Set_Duty( current_duty1 );
         PWM2_Start();
         RC3=1; }
  

 void Clutch()
 { RD5=1;
   RC0=0;
   RC3=0;
   PWM1_Stop();
   PWM2_Stop();
   }
 

 void Change_FlashLight()
 { if (RB4==1 )
         RB4=0;
   else
     RB4=1;
 }

 void Horn()
 { RB2=1; }

 void Reset_Horn()
 { RB2=0; }

 void Change_Cam_Status()
 { if( RD4==1 )
         RD4=0;
   else
     RD4=1;
 }

void inc_index(void){
	index++;
    if(index == Numsteps)
      index = 0;
    pos++;
      }

void dec_index(void){
//   index = (index++) % Numsteps;
	if(index == 0)
   			 index = Numsteps-1;
	else index--;
	pos--;}

void PulseMotor(){
byte tmp;
	tmp= PORTD & 0xF0;
	tmp += step[index];
	PORTD=tmp;
 	 __delay_ms(50);}
 

void Rotate_Right()
{
 //RD0:Coil 1
 //RD1:Coil 2
 //RD2:Coil 3
 //RD3:Coil 4
      while (pos==10){
      inc_index();
	   PulseMotor();}
}

void Rotate_Left()
{
 //RD0:Coil 1
 //RD1:Coil 2
 //RD2:Coil 3
 //RD3:Coil 4
     while (pos==10){
     dec_index();
     PulseMotor(); }
}

void No_Rotate()
{
   if(pos>10) while(pos !=10) Rotate_Left();
   else if(pos<10)  while(pos !=10) Rotate_Right();
};

void Rotate_Cam_Left(){};
void Rotate_Cam_Right(){};
void No_Cam_Rotate(){};

word adc_read10(byte channel)
{
byte tmp;
word_VAL rslt;

   ADFM=1;
   tmp=ADCON0;
   tmp &= 0b11000111;   // ADCS1,ADCS0,  CHS2,CHS1,CHS0,GO,ON
   tmp |= (channel << 3);
   ADCON0 = tmp;
   __delay_us(20);
   GODONE=1;
   while(GODONE);	// wait for conversion complete
   rslt.byte1.LB=ADRESL;
   rslt.byte1.HB=ADRESH;
   return rslt.Val;
}

byte adc_read8(byte channel)
{
byte tmp;

   ADFM=0;
   tmp=ADCON0;
   tmp &= 0b11000111;   //VCFG,-,CHS2,CHS1,CHS0,GO,ON
   tmp |= (channel << 3);
   ADCON0 = tmp;
   __delay_us(20);
   GODONE=1;
	while(GODONE);	// wait for conversion complete
   return ADRESH;
}

void PWM1_Init(word x)
{
PR2=((_XTAL_FREQ/(4*TMR2_PRESCALER))/x)-1;
}

void PWM1_Set_Duty(byte x)
{
ccpr1l_copy=x*(PR2+1)/100;
}


void PWM1_Start()
{   
CCPR1L=ccpr1l_copy; 
}
   
void PWM1_Stop()
{
CCPR1L=0;  
}
   
void PWM2_Init(word x)
{
PR2=(500000/x)-1;   
}

void PWM2_Set_Duty(byte x)
{
ccpr2l_copy=x*(PR2+1)/100;
}


void PWM2_Start()
{
CCPR2L=ccpr2l_copy; 
}
   
void PWM2_Stop()
{
CCPR2L=0;     
}
Btw,thank you for welcoming me :D
 
Top