|
|
View previous topic :: View next topic |
Author |
Message |
amdatlon
Joined: 07 Mar 2010 Posts: 10
|
INT_RDA -> Why is it? PIC18F6722 |
Posted: Sat Aug 27, 2011 6:56 am |
|
|
Hello, I try to start communication between PIC and PC via RS-232.
PIC-18F7622,
40 Mhz Clock = PLL + 10 Mhz Crystal.
Compiler - PCWHD 4.093
Send one byte of the PIC, and waiting PC to return 1 byte.
Example:
PIC send: "FE" ---> PC return: "E5"
Use Interrupt INT_RDA, to avoid wasting CPU time that is busy with other things.
Problem:
Send one byte ("FE") of the PIC, returns another byte computer ("E5"),
PIC reads the answer, but it is the same byte that is sent ("FE")?!?!
If you read the second time, then you get the correct byte ("E5")!
I.e. Should a preliminary reading from the PIC to get the desired response.
Why is that and how can I avoid it?
I tried and a single reading, and reading a buffer, but the result is the same - there is a parasitic byte!
State with such a buffer[32]:
Quote: | [FE] [E5] [FE] [E5]...........[ ] |
Code: |
#include <18F6722.h>
#device *=16
#device adc=10
#device HIGH_INTS=TRUE
#include <math.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or
#FUSES NOPUT
#FUSES H4
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(clock=40M )
#use rs232(baud=15625,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,Đ¢IMEOUT=860 ERRORS)
#define BUFFER_SIZE 32
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;
#int_rda
void serial_isr() {
int8 t;
buffer[next_in]=getc();
t=next_in;
next_in=(next_in+1)%BUFFER_SIZE;
if(next_in==next_out)
next_in=t; // Buffer full !!
}
#define bkbhit (next_in!=next_out)
int WaitComGetc( ) {
BYTE c;
while((!bkbhit) ) ;
c=buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}
.....
.....
....
.....
Void MAIN (){
.......
enable_interrupts(INT_RB);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
ext_int_edge(H_TO_L);
.....
.....
.....
While(true)
{
putc (0xFE ); // PC - send E5
tempBuff1=WaitComGetc( ); // read - FE
tempBuff2=WaitComGetc( ); // read -E5
displayInt8(1,22,0,tempBuff1, 1);
displayInt8(1,22,0,tempBuff2, 1);
.......
.......
.......
}
|
|
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Sat Aug 27, 2011 12:45 pm |
|
|
What type of interface are you using on the PC lets you use this weird baud rate? _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
amdatlon
Joined: 07 Mar 2010 Posts: 10
|
|
Posted: Sat Aug 27, 2011 2:40 pm |
|
|
use usb to rs232 by FT232RL, This is the computer.
The previous version program, worked on the 18F458 and there was no such problems, but I'm not used to interrupt for rs232 communication . |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sun Aug 28, 2011 2:12 am |
|
|
Some comments:
1) Get rid of '#device *=16'. This is _only_ applicable on chips like PIC 16's. On the PIC18, it is the default, and does nothing.
2) Are you using high priority interrupts anywhere?. There is no sign of it in the code. If not, get rid of '#device HIGH_INTS=TRUE'. It should _not_ be enabled, unless used.
3) Are you using #int_RB?. If not, don't enable it. If you are, show the handler. Enabling an interrupt without a handler, _will_ cause problems.
4) Are you using INT_EXT?. There is no sign of this in the code, except you set the EXT_INT_EDGE. This setting _only_ applies to INT_EXT.....
5) Simplify. You have large sections of dotted out code, being implied. If you are testing, and not using these, don't have them. Post a program that is simplified _and can be compiled_. No 'may be there' code. Same applies to definitions of tempbuff1, and 2. We can only guess if these are not show.
6) Get rid of timeout in the #use RS232. Timeout is only used if you are waiting for characters. With INT_RDA, an interrupt _only_ occurs when a character _has_ already been received. If you want a timeout, add it to your buffer handling code, so:
Code: |
int WaitComGetc( ) {
BYTE c;
int16 count=10000;
while((!bkbhit && count-->0) ) ;
if (count==0) {
return 0; //return null for a timeout
}
c=buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}
|
General comment, code posted, should if possible be a small program _that can be compiled_, and shows the problem.
Best Wishes |
|
|
amdatlon
Joined: 07 Mar 2010 Posts: 10
|
|
Posted: Sun Aug 28, 2011 5:09 am |
|
|
Many thanks for guidance
1. I agree, we will remove it.
2. use in other parts of the program from the CCP1 interrupt timer interruption And ..
3. Use the break and the external entrance to Port B (# int_RB) - occurrence of signal on Port B.
4. I thought that counts for the signal on port B. Interrupt from high to low
5. I agree:)
6. We will remove timeout
All code that is to use the 3000 lines will not be better if I put it all here:)
I played only part of the code which relates to RS232.
I will write a simple program for communication to the PC to find out exactly what was happening, but I'm sure the result will be the same.
I.e. first byte read that PIC is an echo of the query to the PC.
Sorry for bad English |
|
|
amdatlon
Joined: 07 Mar 2010 Posts: 10
|
|
Posted: Thu Sep 01, 2011 3:23 pm |
|
|
I made a simple program to test the connection to the computer.
The result is the same echo is received in reading the first byte of the PIC.
Here is the log file from the terminal connection.
Quote: |
000000001417.507085 0010.565 aListItem is nil Clear: 2011.09.02, 00:01:50:
000000001417.508962 0.001877 aListItem is nil LogCnt = 400:
000000001418.917178 0.639050 (N_1) Inp: 00 >>>
000000001421.924064 3.006886 (N_1) Inp: FE >>>
000000001430.657327 8.733263 (N_1) Out: E5 >>> ( I send manual this byte)
000000001430.659340 0.002013 (N_1) Inp: E5 >>>
000000001430.675394 0.016054 (N_1) Inp: FF >>>
000000001438.959616 8.284222 (N_1) Out: 0C >>> ( I send manual this byte)
000000001438.961619 0.002003 (N_1) Inp: 0C >>> |
If you use double reading of PIC, then the program is running successfully, otherwise it reads incorrect data
I can not understand why it receives an echo.
Before I used the 18F458 with the same hardware to connect around him, but I have not had similar problems?
Code: |
#include <18F6722.h>
#device PASS_STRINGS=IN_RAM
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOPUT
#FUSES H4
#FUSES NOXINST //Extended set extension and Indexed
#use delay(clock=32M )
#use rs232(baud=15625,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8 ,Errors)
#include "ks0108.c"
#include "graphics.c"
//*********************** DEFINE ***********************************/
//*******************************************************************/
#byte pA =0xF80 //port a //
#byte pB =0xF81 //b //
#byte pC =0xF82 //c //
#byte pD =0xF83 //d //
#byte pE =0xF84 //port e //
#byte pF =0xF85 //port e //
#byte pG =0xF86 //port e //
// *********************************
#Define SetConfigPortA 9//100011 //33 100001
#Define SetConfigPortB 240//255 11110010
#Define SetConfigPortC 196//1000100 196//196//bx 11000100
#Define SetConfigPortD 0
#Define SetConfigPortE 0
#Define SetConfigPortF 0
#Define SetConfigPortG 0
//**************************************************
#bit IngSwitch= pB.4
#bit UPButton= pB.5
#bit DOWNButton= pB.6
#bit MENUButton= pB.7
#bit Led= pE.6
#bit LCD_Power= pF.7
#ifndef Enable
#define Enable 1
#endif
#ifndef Disable
#define Disable 0
#endif
#ifndef ReadEP
#define ReadEP 0
#endif
#ifndef WriteEP
#define WriteEP 1
#endif
#define BUFFER_SIZE 32
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;
#define bkbhit (next_in!=next_out)
//***********************************
#int_rda
void serial_isr() {
int8 t;
buffer[next_in]=getc();
t=next_in;
if (++next_in ==BUFFER_SIZE){ next_in=0; }
if(next_in==next_out)
next_in=t; // Buffer full !!
}
//************************************
//***********************************
int WaitComGetc( ) {
BYTE c;
int16 count=10000;
while((!bkbhit ) ) ;
c=buffer[next_out];
if (++next_out ==BUFFER_SIZE)
{
next_out=0;
}
return(c);
}
//***********************************
//***********************************
void send_break(int16 time_ms)
{
// Disable the UART and send a Break
// for the specified time.
setup_uart(FALSE);
output_low(PIN_C6);
delay_ms(time_ms);
// Re-enable the UART.
setup_uart(TRUE);
set_uart_speed(15625);
}
//***********************************
//*********************************************************************
//Start initialization
void StartInit(void)
{
int tempBuff;
Delay_ms(70);
// Send 0x01 at 5 baud rate (5bps)
send_break(1800);
Delay_ms(200);
delay_ms(1000);
putc (0xFE );
tempBuff=WaitComGetc( ); // here tempBuff =0xFE -This is echoed
tempBuff=WaitComGetc( ); //here tempBuff =0xE5 - this is corect byte from PC
if (tempBuff==0xE5)
{
delay_ms(5 );
putc (0xFF );
WaitComGetc( ); // tempBuff =0xFF -This is echoed
if (WaitComGetc( )==0x0C) //here tempBuff =0x0C - this is corect byte from PC
{
ShowMessage("Connecton OK",1,1,1000,1);
}
else
{
ShowMessage("Wrong Reply",1,1,1000,1);
}
While((UPButton!=0) && (DOWNButton!=0) && (MENUButton!=0))
{ Delay_ms(10); }
}
}//**********************************************************
Void MAIN (){
char Message[21];
set_tris_b(SetConfigPortB);
set_tris_a(SetConfigPortA);
set_tris_d(SetConfigPortD);
set_tris_e(SetConfigPortE);
set_tris_f(SetConfigPortF);
set_tris_g(SetConfigPortG);
//LCD Init
LCD_Power=1;
delay_ms(20 );
Glcd_init(on);
delay_ms(20 );
glcd_fillScreen(off);
//LCD Init
delay_ms(500 );
enable_interrupts(INT_RDA); // turn on interrupts
enable_interrupts(GLOBAL);
While(true)
{
StartInit();
}
} //End******
|
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|