Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Asynchronous receive problem for PIC , urgent

Status
Not open for further replies.

redsuns

New Member
i get only 2q only and then a OERR but the code can't continue and means i just got 2 input of data only but i need to get it like in the picture

**broken link removed**

Code:
#include <pic18f2620.h>

#define LCD_data PORTB
#define LCD_D7   PORTBbits.RB1
#define LCD_rs   PORTAbits.RA0
#define LCD_rw   PORTAbits.RA1
#define LCD_en   PORTAbits.RA2	

void LCD_busy(void);
void LCD_init(void);
void LCD_command(unsigned char var);
void LCD_senddata(unsigned char var);
void LCD_sendstring(unsigned char *var);
void camera_tx (unsigned char);
void camera_cmd (unsigned char , unsigned char , unsigned char, unsigned char , unsigned char  , unsigned char );
void camera_rx (void);
unsigned char rx_buffer[12];

void main(void)
{
	int x,y;
	ADCON1 = 0x0F;
	TRISA = 0x00;
	TRISB = 0x00;
	RCSTAbits.SPEN = 1;
	TRISCbits.TRISC6 = 0;
	TRISCbits.TRISC7 = 1;
	TXSTAbits.TXEN = 1;
	TXSTAbits.SYNC = 0;
	TXSTAbits.BRGH = 1;
	TXSTAbits.TX9 = 0;
	RCSTAbits.RX9 = 0;
	RCSTAbits.CREN = 1;
	BAUDCONbits.BRG16 = 0;
	SPBRG = 21;
	
	LCD_init();
    LCD_sendstring("camera sync");
    LCD_command(0x01); //LCD clear screen before printing new word 
	for(x=0;x<=60;x++) //max 60 times to send sync command to establish camera connection
	{
		LCD_sendstring("a");
		//LCD_command(0x01); //LCD clear screen before printing new word 
		camera_cmd(0xAA , 0x0D , 0x00 , 0x00 , 0x00 , 0x00); //sync command
		LCD_busy();
		if(PIR1bits.RCIF==1)
		{
			LCD_command(0x01);
			LCD_sendstring("ack coming");
			LCD_command(0x01); //LCD clear screen before printing new word 
			rx_buffer[0]=RCREG;
			for(y=1;y<12;y++)
			{
			//	while(!PIR1bits.RCIF);
				LCD_sendstring("q");
				while(!PIR1bits.RCIF)
				{	
					if(RCSTAbits.OERR ==1)
						{
							LCD_sendstring("OERR");
							RCSTAbits.CREN = 0;
							RCSTAbits.CREN = 1;
						}
					}
				rx_buffer[y]=RCREG;
			}		
			if(rx_buffer[0]== 0xAA && rx_buffer[1]== 0x0E /*&& rx_buffer[6]==0xAA && rx_buffer[7] == 0x0D && rx_buffer[2] == 0x0D*/) //ACK
			{
				LCD_command(0x01);
				LCD_sendstring("com ok");
				break;
			}
				
			 
		}
		if(rx_buffer[0]== 0xAA && rx_buffer[1]== 0x0E && rx_buffer[6]==0xAA /*&& rx_buffer[7] == 0x0D && rx_buffer[2] == 0x0D*/) //ACK
			{	
				LCD_command(0x01);
				LCD_sendstring("com2 ok");
				break;
			}
	}
	if(x==60)
	{
	LCD_command(0x01);
	LCD_sendstring("fail");
	}
	LCD_busy();
	LCD_sendstring("sync bac");
	if(RCSTAbits.OERR ==1)
	{
		LCD_sendstring("OERR");
		RCSTAbits.CREN = 0;
		RCSTAbits.CREN = 1;
	}
/* 	if(PIR1bits.RCIF==1)
		{			
			LCD_sendstring("sync coming");
			LCD_command(0x01); //LCD clear screen before printing new word 
			rx_buffer[0]=RCREG;
			for(y=1;y<6;y++)
			{
				LCD_sendstring("w");
				rx_buffer[y]=RCREG;
			}

		}
	if(rx_buffer[6]!= 0xAA && rx_buffer[7]!= 0x0D && rx_buffer[8] != 0x00)
	{
		LCD_command(0x01);
		LCD_sendstring("fail2");
//		while(1);
	}
	else if(rx_buffer[6]== 0xAA && rx_buffer[7]== 0x0D && rx_buffer[8] == 0x00)
	{
	camera_cmd(0xAA , 0x0E , 0x0D , 0x00 , 0x00 , 0x00); //ACK command to finalize connection
	LCD_command(0x01);
	LCD_sendstring("sync complete");
	}*/
}



void LCD_init()
{
     LCD_data = 0x38;     //Function set: 2 Line, 8-bit, 5x7 dots
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in data register
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();          //Wait for LCD to process the command
     LCD_data = 0x0F;     //Display on, Curson blinking command
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in data register
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();          //Wait for LCD to process the command
     LCD_data = 0x01;     //Clear LCD
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in data register
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();          //Wait for LCD to process the command
     LCD_data = 0x06;     //Entry mode, auto increment with no shift
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in data register
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();
     LCD_data = 0x80;     //cursor position at first row
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in data register
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();
}

void LCD_busy()
{
	int i,j;
	for(i=0;i<50;i++)
		for(j=0;j<255;j++);
}

void LCD_command(unsigned char  var)
{
     LCD_data = var;      //Function set: 2 Line, 8-bit, 5x7 dots
     LCD_rs   = 0;        //Selected command register
     LCD_rw   = 0;        //We are writing in instruction register
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();          //Wait for LCD to process the command
}

void LCD_senddata(unsigned char  var)
{
     LCD_data = var;      //Function set: 2 Line, 8-bit, 5x7 dots
     LCD_rs   = 1;        //Selected data register
     LCD_rw   = 0;        //We are writing
     LCD_en   = 1;        //Enable H->L
     LCD_en   = 0;
     LCD_busy();          //Wait for LCD to process the command
}

void LCD_sendstring(unsigned char *var)
{

	while(*var)              //till string ends
       LCD_senddata(*var++);  //send characters one by one
}

void camera_tx (unsigned char var)
{
	while(!PIR1bits.TXIF); //check TXREG full, load TXREG if not full
	TXREG = var;
}
	
// camera_command
void camera_cmd (unsigned char cmd1 , unsigned char cmd2 , unsigned char cmd3 , unsigned char cmd4 , unsigned char cmd5 , unsigned char cmd6)
{
	camera_tx(cmd1);
	camera_tx(cmd2);
	camera_tx(cmd3);
	camera_tx(cmd4);
	camera_tx(cmd5);
	camera_tx(cmd6);
	while(!TXSTAbits.TRMT); //check until data finish send out from TXREG
}

void camera_rx(void)
{
	unsigned char x;

	for(x=0 ; x<6 ; x++)
	{
		LCD_sendstring("before");
		while(!PIR1bits.RCIF);
		LCD_sendstring("after");
		rx_buffer[x]=RCREG;
	}
}
 
Last edited:
First of all, why are you sending the SYNC 60 times? Surely you only need to send one, Secondly, you are receiving 0xAA 0x0D, you are checking 0xAA and 0x0E, which is the start of an ACK response.

And why do you have so many RCIF checks?

If this is for a camera controller I would suggest a state machine.

You can use either polling or interrupts for your receive routine, I would suggest a interrupt for a "professional" approach.
 
Last edited:
First of all, why are you sending the SYNC 60 times? Surely you only need to send one

This is usually called out in the device spec, that the device will be ready within X number of SYNC's. It's not guaranteed to be ready in 1. My MMC/SD card initialize routine allows for 255 initialize command requests and breaks out of the loop when correct response is received.
 
when i put the enable interrupt code which is
PIE1bits.RCIF = 1; the code can't proceed to the first line of the code which is initialize of the LCD
 
The reason you're getting overrun errors is because you are writing stuff to the LCD between receiving data. Your LCD routines are very slow due to the delay in LCD_busy. Change your code so that it does all the sending and receiving before you write to the LCD or, as suggested, switch to interrups and implement a fifo buffer.

Here's how I implement a fifo buffer on interrupt,
Code:
unsigned char FifoBuffer[16];
unsigned char *FifoStart;
unsigned char *FifoEnd;

void high_isr();                    
void InitFifo(void);
void PutFifo(unsigned char chr);
unsigned char GetFifo(void);
unsigned char FifoCount(void);

#pragma code high_vector=0x08               //setup the ISR vector
void high_interrupt (){
  _asm GOTO high_isr _endasm                //jump to interrupt handler
}
#pragma code

#pragma interruptlow high_isr               //the actual ISR
void low_isr(){
    if(PIR1bits.RCIF){
        PutFifo(RCREG);
    }
}
#pragma code


void InitFifo(void){
    FifoStart=FifoBuffer;
    FifoEnd=FifoBuffer;
}

void PutFifo(unsigned char chr){
    *FifoEnd++=chr;
    if(FifoEnd==FifoBuffer+16)      //reached end
        FifoEnd=FifoBuffer;         //yes so wrap
    if(FifoStart==FifoEnd){         //is head eating tail?
        //fifo full so deal with it!!
    }
}

unsigned char GetFifo(void){
unsigned char chr;
    while(FifoStart==FifoEnd);      //if fifo empty then wait
    chr=*FifoStart++;
    if(FifoStart==FifoBuffer+16)    //wrapped?
        FifoStart=FifoBuffer;       //yes
    return(chr);
}

unsigned char FifoCount(void){
    return((FifoEnd-FifoStart)&15);
}

In your main code you use GetFifo to read the data. You may need to make the buffer bigger.

Edit, to enable interrupts you do PIE1bits.RCIE=1; not PIE1bits.RCIF=1;

HTH

Mike.
 
Last edited:
sorry typo error, now the above routine is settle already but i got another problem here
i need to do something like this
**broken link removed**

it just can read until the packages -1 only
but the Number of packages = Image size / (Package size – 6)
and one more is less than the package size which will give to a floating number
does i make a mistake anywhere
and my code is like this
Code:
LCD_sendstring("get picture");
	camera_cmd(0xAA , 0x04 , 0x01 , 0x00 , 0x00 , 0x00);//get picture
	for(y=0;y<12;y++)
	{
		while(!PIR1bits.RCIF);
		rx_buffer[y]=RCREG;
	}
	while(rx_buffer[0] != 0xAA && rx_buffer[1] != 0x0E && rx_buffer[6] != 0xAA && rx_buffer[8] != 0x01);
		LCD_command(0x01);
		LCD_sendstring("get picture ok");
		b1=rx_buffer[9];
		b2=rx_buffer[10];
		b3=rx_buffer[11];
	LCD_command(0x01);
	LCD_sendstring("cal packet");
	temp=b3;
	temp=temp*256;
	temp+=b2;
	temp=temp*256;
	temp+=b1;
	temppack=temp/506;
	packages = (unsigned long) temppack;
	ultoa(packages,pac_show,10);
	LCD_sendstring(pac_show);
	for(fb=0;fb<255;fb++)
		{
		for(sb=0;sb<255;sb++)
			{
			LCD_command(0x01);
			size=fb;
			size<<=8;
			size+=sb;
			uitoa(size,img_show,16);
			LCD_sendstring(img_show);
			camera_cmd(0xAA,0x0E,0x00,0x00,sb,fb);
			image();
//			size=image_data[3];
//			size=size*256;
//			size+=image_data[2];
//			uitoa(size,img_show,10);
//			LCD_command(0x01);
//			LCD_sendstring("pac size");
//			LCD_sendstring(img_show);
			count=fb;
			count<<=8;
			count+=sb;

			if(count==packages)//break from routine after package size is achieve
			{
				LCD_sendstring("finish");
				camera_cmd(0xAA,0x0E,0x00,0x00,0xF0,0xF0);//indicate finish
				break;
			}
		}
	}
}

void image(void)
{
	unsigned int x;
	for(x=0 ; x<512 ; x++)
	{
		while(!PIR1bits.RCIF);
		image_data[x]=RCREG;
	}
}
 
Last edited:
I can't see anything that stands out as wrong. There are however a few confusing bits.

Assuming temp=the length of the data then shouldn't temppack=temp/512 not temp/506?

The break statement will only terminate the inner for loop and so I suggest changing it to,
Code:
    LCD_sendstring(pac_show);
    [COLOR="red"]count=0;
    fb=0;
    while(count!=packages)[/COLOR]
    {
        for(sb=0;sb<255;sb++)
        {
            LCD_command(0x01);
            size=fb;
            size<<=8;
            size+=sb;
            uitoa(size,img_show,16);
            LCD_sendstring(img_show);
            camera_cmd(0xAA,0x0E,0x00,0x00,sb,fb);
            image();
            count=fb;
            count<<=8;
            count+=sb;
            if(count==packages)//break from routine after package size is achieve
            {
                LCD_sendstring("finish");
                camera_cmd(0xAA,0x0E,0x00,0x00,0xF0,0xF0);//indicate finish
                break;
            }
        }
        [COLOR="red"]fb++;[/COLOR]
    }
Scroll down to see other changes.

Mike.
 
it is divide by 506 instead of 512 because
**broken link removed**

i tried to change according to your code but still can't receive all data package and stop at the last incoming
like if got 5 packages, the receiving for the 5 package can't complete it process
and the datasheet of my module didn't state that the last package will be send by stuff bits for a whole 512 bytes package or just the last size
 
Have you checked what packages contains?

Have you tried removing the write to LCD in case the camera is timing out?

You may still be getting overrun errors.

Edit, do you have a link to the data sheet?

Mike.
 
Last edited:
The data sheet states that raw images are not packetised but sent as a constant stream.

Mike.
 
i supposed to save the data image inside a sd card so thats y i use the jpeg to break into packages so it would allowed me to store to the SD card between each ACK and DATA command , and i am also still trying to get my SD card done because i am unfamiliar with how to put it into FAT16 tables
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top