Hi guys, it's been a long time since I've programmed microcontrollers, i'm back into it by the looks of things unfortunately a lot seems to have slipped my mind since last year
i'm having a bit of an amateurish problem, i've attempted to utilise an ft232rl serial<>usb converter on one of my boards and whilst it seems electrically ok (don't have a scope) it has been a right nightmare to get working.
Sending from pic (16f88) to pc seems to work fine, or at least I receive sentences okay in terminal, rewceiving on the other hand has been a bit of a pig.
I'm trying to handle the data as it comes in through an interrupt, the interrupt literally saves the byte to a buffer and sets a flag. That's it. The main program checks the flag, if set it adds it to a circular buffer then checks the sequence of bytes in that buffer to see if a command has been received (commands are 6 bytes long) if so then it goes and executes command x - flag gets reset and process should merely repeat.
I also drive an led activity light at the same time, and for testing reasons the program periodically transmits the contents of the circular buffer as well, so that I can see the received data.
I managed to get it so that when you send a byte, the byte is added to the buffer, and the contents are shifted one in the buffer array , so if we start with an empty buffer and send 0x01 we get:
0x00 0x00 0x00 0x00 0x00 0x01
and if we send 0x01 again we get
0x00 0x00 0x00 0x00 0x01 0x01 and so on.
Anyway the problem is, if you send a byte larger than 0xF7/F8 - let's say 0xFF for arguements sake - the pic freezes. It doesn't crash, it freezes - it's stuck and won't respond to anything...unless (and this is probably a big clue to the more experienced) you send a low value, like 0x00 which magically unfreezes the system and it then continues to run as if nothing happened. The buffer then does not contain 0xff, but rather 0xf1.
I've attached an untidy code listing, i'll try and clean it up if it's too complex
I'm quietly confident the hardware side of things is okay, i don't have a scope to see what's happening but I can see activity on the respective pins.
I've been a bit breif with details as I'm shooting out but if there's anything that's needed that I've missed let me know - if anyone has ideas it'd be much appreciated, it's probably some daft oversight of mine
Personally I think the biggest clue is with the program freezing when sent a byte near 0xff and unfreezing when 0x00 is sent, it's like the programs waiting for a stop bit and the 0x00 is seen as it or something. I have set the registers up manually aswell as using the compilers own function as you'll see further down in my code, so it's a weird one.
cheers
Kris
i'm having a bit of an amateurish problem, i've attempted to utilise an ft232rl serial<>usb converter on one of my boards and whilst it seems electrically ok (don't have a scope) it has been a right nightmare to get working.
Sending from pic (16f88) to pc seems to work fine, or at least I receive sentences okay in terminal, rewceiving on the other hand has been a bit of a pig.
I'm trying to handle the data as it comes in through an interrupt, the interrupt literally saves the byte to a buffer and sets a flag. That's it. The main program checks the flag, if set it adds it to a circular buffer then checks the sequence of bytes in that buffer to see if a command has been received (commands are 6 bytes long) if so then it goes and executes command x - flag gets reset and process should merely repeat.
I also drive an led activity light at the same time, and for testing reasons the program periodically transmits the contents of the circular buffer as well, so that I can see the received data.
I managed to get it so that when you send a byte, the byte is added to the buffer, and the contents are shifted one in the buffer array , so if we start with an empty buffer and send 0x01 we get:
0x00 0x00 0x00 0x00 0x00 0x01
and if we send 0x01 again we get
0x00 0x00 0x00 0x00 0x01 0x01 and so on.
Anyway the problem is, if you send a byte larger than 0xF7/F8 - let's say 0xFF for arguements sake - the pic freezes. It doesn't crash, it freezes - it's stuck and won't respond to anything...unless (and this is probably a big clue to the more experienced) you send a low value, like 0x00 which magically unfreezes the system and it then continues to run as if nothing happened. The buffer then does not contain 0xff, but rather 0xf1.
I've attached an untidy code listing, i'll try and clean it up if it's too complex
I'm quietly confident the hardware side of things is okay, i don't have a scope to see what's happening but I can see activity on the respective pins.
I've been a bit breif with details as I'm shooting out but if there's anything that's needed that I've missed let me know - if anyone has ideas it'd be much appreciated, it's probably some daft oversight of mine
Personally I think the biggest clue is with the program freezing when sent a byte near 0xff and unfreezing when 0x00 is sent, it's like the programs waiting for a stop bit and the 0x00 is seen as it or something. I have set the registers up manually aswell as using the compilers own function as you'll see further down in my code, so it's a weird one.
cheers
Kris
Code:
// test program
//variable declerations
unsigned char RX_Buffer[5]; //rx receive buffer
unsigned char RX_Temp_Buffer = 0; //temporary area for received bytes
unsigned char ByteReceivedFlag = 0; //this is set in the interrupt when a byte is received by uart
unsigned char CommandReceivedFlag = 0; //this is set when a sequence of received bytes match a command's profile
unsigned char ActivityLEDFlag = 0; //set this to a number to cause activity led to come on (higher means light on longer)
//functions
//interrupt handler
void interrupt() {
if (uart1_data_ready() == 1){ //if data is ready for reading
RX_Temp_Buffer = uart1_read(); //read byte
ByteReceivedFlag = 1; //set flag to identify to main program that new data wants adding to the command buffer
}
}
void ReceiveData(){ //function for taking received data and putting it into buffer, checking for command etc
ActivityLEDFlag = 2; //set activity light
RX_Buffer[0] = RX_Buffer[1];
RX_Buffer[1] = RX_Buffer[2];
RX_Buffer[2] = RX_Buffer[3];
RX_Buffer[3] = RX_Buffer[4];
RX_Buffer[4] = RX_Buffer[5];
RX_Buffer[5] = RX_Temp_Buffer;
ByteReceivedFlag = 0;
}
void main() {
//set up chip
trisa = 255;
trisb = 255; //everything inputs
//disable analogue for selected pins
ansel.b0 = 0;
ansel.b1 = 0;
ansel.b2 = 0;
ansel.b3 = 0;
ansel.b4 = 0;
ansel.b5 = 0;
ansel.b6 = 0;
//set up outputs
//led's
trisa.b1=0; //power
trisa.b0=0; //activity
trisb.b7=0; //notice?
//switch on power LED
porta.b1=1;
porta.b0=0;
portb.b7=0;
trisb.b0 = 0; //pwm out - use this later in development
trisb.b5 = 0; //tx output
//set up uart
uart1_init(9600);
rcsta.spen = 1;
rcsta.rx9 = 0;
rcsta.cren = 1;
txsta.tx9 = 0;
txsta.txen = 1;
txsta.sync = 0;
spbrg = 129;
txsta.brgh = 1;
//set up rx interrupt
intcon.b7 = 1; //int enabled
intcon.b6 = 1; //peripheral int enabled
pie1 = 0x00;
pie1.b5 = 1; //rx int enabled
//main loop
while (1){
//check if activity has occured recently and put light on if so (and decrement LED activity counter)
if (ActivityLEDFlag > 1) {
porta.b0 = 1; //led on
ActivityLEDFlag--;
} else {
ActivityLEDFlag = 0; //led off
porta.b0 = 0;
}
//check if byte is received - if so execute function to add byte to buffer
if (ByteReceivedFlag == 1) ReceiveData();
//main loop delay
delay_ms(2);
//write contents of buffer to pc
uart1_write(RX_Buffer[0]);
delay_ms(30);
uart1_write(RX_Buffer[1]);
delay_ms(30);
uart1_write(RX_Buffer[2]);
delay_ms(30);
uart1_write(RX_Buffer[3]);
delay_ms(30);
uart1_write(RX_Buffer[4]);
delay_ms(30);
uart1_write(RX_Buffer[5]);
delay_ms(30);
delay_ms(1000);
}//end main loop
}