|
|
View previous topic :: View next topic |
Author |
Message |
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
PIC18F26K22 UART2 settings |
Posted: Sun May 22, 2016 9:28 pm |
|
|
Hi
Trying to make both UART's working with no success.
If UART2 enabled alone, works perfect and what can see in the LST file is:
Quote: | .................... //#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1,errors)
.................... #use rs232(baud=9600,parity=N,xmit=PIN_B6,rcv=PIN_B7,bits=8,stream=PORT2,errors)
*
000EE: BTFSS PIR3.RC2IF
000F0: BRA 00EE
000F2: MOVFF RCSTA2,rs232_errors
000F6: MOVFF RCREG2,01
000FA: BTFSS rs232_errors.1
000FC: BRA 0102
000FE: BCF RCSTA2.CREN
00100: BSF RCSTA2.CREN
00102: RETURN 0
*
00138: BTFSS PIR3.TX2IF
0013A: BRA 0138
0013C: MOVWF TXREG2
0013E: RETURN 0
.................... //-----------------------------------------------
.................... #define flashled PIN_B3 |
If both UART's are enabled:
Quote: | .................... #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1,errors)
*
000EE: BTFSS PIR1.RC1IF
000F0: BRA 00EE
000F2: MOVFF RCSTA1,rs232_errors
000F6: MOVFF RCREG1,01
000FA: BTFSS rs232_errors.1
000FC: BRA 0102
000FE: BCF RCSTA1.CREN
00100: BSF RCSTA1.CREN
00102: RETURN 0
*
00138: BTFSS PIR1.TX1IF
0013A: BRA 0138
0013C: MOVWF TXREG1
0013E: RETURN 0
.................... #use rs232(baud=9600,parity=N,xmit=PIN_B6,rcv=PIN_B7,bits=8,stream=PORT2,errors)
.................... //-----------------------------------------------
.................... #define flashled PIN_B3
|
Can see that nothing follows the UART2 declaration in the LST
While testing, if both UART's enabled and I try to send message through UART2 the controller is stuck. I can see it as the flashing led stops flashing.
Message via UART1 works fine.
My compiler: CCS PCH C Compiler, Version 5.056d, 1 MPLAB IDE v8.92
Code: | #include <18F26K22.h>
#device ADC=10
#FUSES NOPBADEN
#FUSES NOWDT
#FUSES BROWNOUT
#FUSES BORV29
#FUSES INTRC_IO
//#FUSES ECH_IO
#FUSES PLLEN
#FUSES NOIESO
#FUSES NOFCMEN
#FUSES NOHFOFST
//#use delay(clock=32M)
#use delay(internal=32MHz)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1,errors)
#use rs232(baud=9600,parity=N,xmit=PIN_B6,rcv=PIN_B7,bits=8,stream=PORT2,errors)
//-----------------------------------------------
#define flashled PIN_B3
short ms625flag=0;
int ms625cnt=0;
int txwords=0;
int txwchs=0;
int rxwords=0;
int rxdata0=0;
int rxdata1=0;
int rxdata2=0;
int tx2words=0;
int tx2wchs=0;
int rx2words=0;
int rx2data0=0;
int rx2data1=0;
int rx2data2=0;
//-----------------------------------------------
#INT_TIMER1
void TIMER1_isr(void)
{
set_timer1(3036);//62.5ms interrupt
ms625flag=1;
}
//-----------------------------------------------
#INT_RDA
void RDA_isr(void)
{
switch(rxwords)
{
case 0:
{
rxdata0=getc();
rxwords++;
}
break;
case 1:
{
rxdata1=getc();
rxwords++;
}
break;
case 2:
{
rxdata2=getc();
rxwords=0;
enable_interrupts(INT_TBE);
}
break;
}
}
//-----------------------------------------------
#INT_TBE
void TBE_isr(void)
{
switch(txwords)
{
case 0:
{
putc(0);
txwchs=0;
txwords++;
}
break;
case 1:
{
putc(0);
txwchs=0;
txwords++;
}
break;
case 2:
{
putc(txwchs);
txwords=0;
disable_interrupts(INT_TBE);
}
break;
}
}
//-----------------------------------------------
#INT_RDA2
void RDA2_isr(void)
{
switch(rx2words)
{
case 0:
{
rx2data0=getc();
rx2words++;
}
break;
case 1:
{
rx2data1=getc();
rx2words++;
}
break;
case 2:
{
rx2data2=getc();
rx2words=0;
enable_interrupts(INT_TBE2);
}
break;
}
}
//-----------------------------------------------
#INT_TBE2
void TBE2_isr(void)
{
switch(tx2words)
{
case 0:
{
putc(85);
tx2wchs=85;
tx2words++;
}
break;
case 1:
{
putc(170);
tx2wchs=255;
tx2words++;
}
break;
case 2:
{
putc(txwchs);
tx2words=0;
disable_interrupts(INT_TBE2);
}
break;
}
}
//-----------------------------------------------
void main()
{
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);//65.5 ms overflow
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_RDA);
disable_interrupts(INT_TBE);
enable_interrupts(INT_RDA2);
disable_interrupts(INT_TBE2);
enable_interrupts(GLOBAL);
while(TRUE)
{
restart_wdt();
if(ms625flag==1)
{
ms625flag=0;
ms625cnt++;
if(bit_test(ms625cnt,3))
{
output_high(flashled);
}
else
{
output_low(flashled);
}
}
if (ms625cnt>=32)
{
ms625cnt=0;
enable_interrupts(INT_TBE);
enable_interrupts(INT_TBE2);
}
}
}
|
I am sure I am doing something wrong as I read many topics in the subject and both UART's on this chip should work without problems
Will appreciate any help
Best wishes
Joe
Last edited by gjs_rsdi on Wed Jan 11, 2017 1:00 am; edited 3 times in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun May 22, 2016 11:45 pm |
|
|
If you use streams, you're supposed to use fgetc, fputc, fprintf, etc., and
specify the stream as one of the parameters. Example:
Look at the .LST file. You'll now see code generated for both #use rs232
statements:
Code: | #include <18F26K22.h>
#device ADC=10
#FUSES NOPBADEN
#FUSES NOWDT
#FUSES BROWNOUT
#FUSES BORV29
#FUSES INTRC_IO
#FUSES PLLEN
#FUSES NOIESO
#FUSES NOFCMEN
#FUSES NOHFOFST
#use delay(internal=32MHz)
#use rs232(baud=9600, UART1, stream=PORT1, errors)
#use rs232(baud=9600, UART2, stream=PORT2, errors)
//-----------------------------------------------
void main()
{
int8 temp;
fputc('1', PORT1);
fputc('2', PORT2);
temp = fgetc(PORT1);
temp = fgetc(PORT2);
while(TRUE);
} |
|
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Mon May 23, 2016 12:36 am |
|
|
Thank you PCM programmer
It works!!! I mean my code also, messages between 18F26F22, 16F1847 and the PC.
Best wishes
Joe
PS:
I don't know if to ask here or to open a new topic about the INTRC.
The LED's starting to blink together, after some 3 minutes they are shifted 500 ms from each other, after than get together, shifting again and so on.
Can be that the INTRC precision is much lower than the 1% written in the data sheet? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9253 Location: Greensville,Ontario
|
|
Posted: Mon May 23, 2016 5:30 am |
|
|
I looked at the datasheet and the table 27-2 (?) says +-2 to +-5% depending on temperature.
You need to understand that the internal RC oscillators are NOT precise(relative to externatl XTAL/2caps combination) and will vary from PIC to PIC . As such you can't use INTRC for say a 'real time clock',measuring 'pulse widths', etc.
Jay |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Mon May 23, 2016 5:01 pm |
|
|
Thanks temtronic
In the first page of the data sheet of 16F1847 is written:
Quote: | Factory calibrated to ± 1%, typical |
And then on page 349 as you wrote is +/- 2% at 25 degree.
The first page is misleading.
I was thinking I can work with it for an application that 2% is fine, but shift of 500 ms after 3 minutes it shows much bigger inaccuracy.
So as you said, can't eliminate the external clock or XTAL/2 caps.
Best wishes
Joe |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9253 Location: Greensville,Ontario
|
|
Posted: Mon May 23, 2016 6:08 pm |
|
|
I was using this..
#include <18F26K22.h>
from a post a couple up from here...
I'd have to check the 16F1847 datasheet to see what it's specs are.
You should always look at 'the details', NOT rely on the 'first page' of 'features'. Sometimes Microchip ( and others) 'copy and paste' from other sources......
Also not that temperature has a BIG bearing on frequency. Unless your PIC is staying in a nice warm house use the xtal/2 caps method.
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19562
|
|
Posted: Tue May 24, 2016 12:14 am |
|
|
gjs_rsdi wrote: | Thanks temtronic
In the first page of the data sheet of 16F1847 is written:
Quote: | Factory calibrated to ± 1%, typical |
And then on page 349 as you wrote is +/- 2% at 25 degree.
The first page is misleading.
I was thinking I can work with it for an application that 2% is fine, but shift of 500 ms after 3 minutes it shows much bigger inaccuracy.
So as you said, can't eliminate the external clock or XTAL/2 caps.
Best wishes
Joe |
Keyword. typical.
However, think about it. If one oscillator is drifting from another, you have _two_ oscillators involved. Two error sources not one. A discrepancy of 0.5 second in 180 seconds, is 1/360. Just under 0.3%. From two oscillators. Way under 1%. Could even be as low as 0.15% each, if the errors just happens to be in opposite directions!.....
As a comment, your page number is for an older data sheet. You should update if working with the chip. The Table 30-8 figure is the the 'design maximum' (though note even this is dependant on the supply decoupling, so you can make it worse than this!....). As a general rule, when designing, always work to 'worst case' figures, if you want kit to genuinely be reliable.
So your chips are probably performing well inside the 'typical' figure..... |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Tue May 24, 2016 6:04 am |
|
|
Thank you for the answer Ttelmah and temtronic
I was shocked to see such a drift so I stopped thinking
After calculating the error, it come out 24.33 hours per years, much less than the 1% required in the specific project, 3.6 days per year.
The device works in room temperature of 25 to 30 degree Celsius so the internal oscillator will do the job.
I will download the new data sheet. I was thinking that they are just making new ERATA and not modifying the data sheet.
I really appreciate all of you for your effort to help, I learned a lot in the last few months
Best wishes
Joe |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Wed Jan 11, 2017 12:48 am |
|
|
Opening again the topic as after not working on the program for a while, have again issues with the rs232.
CCS PCH C Compiler, Version 5.059, xxxxx
Here is the program:
Code: | #include <18F26K22.h>
#device ADC=10
#FUSES NOPBADEN
#FUSES NOWDT
#FUSES BROWNOUT
#FUSES BORV29
#FUSES INTRC_IO
#FUSES PLLEN
#FUSES NOIESO
#FUSES NOFCMEN
#FUSES NOHFOFST
#use delay(internal=32MHz)
#use rs232(baud=9600, UART1, stream=PORT1, errors)
#use rs232(baud=9600, UART2, stream=PORT2, errors)
//-----------------------------------------------
#define flashled PIN_C3
short ms625flag=0;
int tx2startcnt=0;
int txstartcnt=0;
int flashledcnt=0;
int txwords=0;
int txwchs=0;
int rx1words=0;
int rx1data0=0;
int rx1data1=0;
int rx1data2=0;
int tx2words=0;
int tx2wchs=0;
int rx2words=0;
int rx2data0=0;
int rx2data1=0;
int rx2data2=0;
//-----------------------------------------------
#INT_TIMER0
void TIMER0_isr(void)
{
delay_ms(1);
}
//-----------------------------------------------
#INT_TIMER1
void TIMER1_isr(void)
{
set_timer1(3036);//62.5ms interrupt
ms625flag=1;
}
//-----------------------------------------------
#INT_RDA
void RDA_isr(void)
{
switch(rx1words)
{
case 0:
{
rx1data0=fgetc(PORT1);
rx1words++;
}
break;
case 1:
{
rx1data1=fgetc(PORT1);
rx1words++;
}
break;
case 2:
{
rx1data2=fgetc(PORT1);
rx1words=0;
enable_interrupts(INT_TBE);
}
break;
}
}
//-----------------------------------------------
#INT_RDA2
void RDA2_isr(void)
{
switch(rx2words)
{
case 0:
{
rx2data0=fgetc(PORT2);
rx2words++;
}
break;
case 1:
{
rx2data1=fgetc(PORT2);
rx2words++;
}
break;
case 2:
{
rx2data2=fgetc(PORT2);
rx2words=0;
enable_interrupts(INT_TBE2);
}
break;
}
}
//-----------------------------------------------
#INT_TBE
void TBE_isr(void)
{
switch(txwords)
{
case 0:
{
fputc(85,PORT1);
txwchs=85;
txwords++;
}
break;
case 1:
{
fputc(170,PORT1);
txwchs=255;
txwords++;
}
break;
case 2:
{
fputc(txwchs,PORT1);
txwords=0;
disable_interrupts(INT_TBE);
}
break;
}
}
//-----------------------------------------------
#INT_TBE2
void TBE2_isr(void)
{
switch(tx2words)
{
case 0:
{
fputc(85,PORT2);
tx2wchs=85;
tx2words++;
}
break;
case 1:
{
fputc(170,PORT2);
tx2wchs=255;
tx2words++;
}
break;
case 2:
{
fputc(txwchs,PORT2);
tx2words=0;
disable_interrupts(INT_TBE2);
}
break;
}
}
//-----------------------------------------------
void main()
{
setup_timer_0(T0_INTERNAL|T0_DIV_32);//262.144 ms overflow
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);//65.536 ms overflow
disable_interrupts(INT_TIMER0);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_RDA);
disable_interrupts(INT_TBE);
enable_interrupts(INT_RDA2);
disable_interrupts(INT_TBE2);
enable_interrupts(GLOBAL);
while(TRUE)
{
if(ms625flag==1)
{
ms625flag=0;
flashledcnt++;
txstartcnt++;
tx2startcnt++;
}
if(flashledcnt>=8)//500ms
{
flashledcnt=0;
output_toggle(flashled);
}
if (txstartcnt>=32)//2000ms
{
txstartcnt=0;
enable_interrupts(INT_TBE);
}
if (tx2startcnt>=32)//2000ms
{
tx2startcnt=0;
enable_interrupts(INT_TBE2);
}
}
}
|
while watching the LST file, I found:
Quote: | .................... #use delay(internal=32MHz)
000EA: CLRF FSR0H
000EC: MOVLW ??65535
000EE: MOVWF FSR0L |
and
Quote: | .................... #INT_TIMER0
.................... void TIMER0_isr(void)
.................... {
.................... delay_ms(1);
*
00112: MOVLW 01
00114: MOVWF ??65535
00116: BRA 00EA
.................... } |
* The flash LED works correctly even that in the fuses:
Quote: | Configuration Fuses:
Word 1: 2800 INTRC_IO NOPLLEN PRIMARY NOFCMEN NOIESO |
* PORT1 answer if I send a message from the PC terminal
* PORT1 send messages every 2 seconds to the PC terminal
* PORT2 don't answer if I send a message from the PC terminal
* PORT2 don't send messages every 2 seconds to the PC terminal
Tried to find the reason but don't see nothing strange except the ??65535
EDIT:
Outcommented the Timer0 ISR and his interrupt enable, the ??65535 gone but the rs232 remain same
Don't understand also why the ??65535
Best wishes
Joe |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Jan 11, 2017 5:30 am |
|
|
Never put delay_ms or even delay_us in ISRs, and I mean never. A short delay_cycles (less than five I'd suggest) to give pulses suitable for specific hardware needs is okay. As it is, your timer 0 may try to interrupt while the ISR is still running as I think it will give you interrupts ever 1.02ms. Nothing will happen until the delay ends and the ISR exits, at which point it will simply be renetered to service the waiting interrupt. It will effectively never leave the timer 0 ISR: it's a Hotel California ISR - you can check out any time you like, but you can never leave. |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Wed Jan 11, 2017 5:04 pm |
|
|
Thank you for the post RF_Developer
The ??65535 disappeared when I change to:
Code: | #INT_TIMER0
void TIMER0_isr(void)
{
timer0overF=0;
} |
I am not using the interrupt right now and I was thinking it will not make problem just to write a delay there
The problem of rs232 PORT2 remain
Best wishes
Joe |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9253 Location: Greensville,Ontario
|
|
Posted: Wed Jan 11, 2017 5:42 pm |
|
|
time to go back to 'Step2'.
cut code for a simple SW loopback on #2 UART. Compile and test.....
Every character sent from the PC terminal program should be echoed back to the PC screen....
Does this work ?
post your swloopback program for us to see it.
Jay |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Wed Jan 11, 2017 6:31 pm |
|
|
Hi Jay
If you see the PORT1 and PORT2 RX/TX interrupt routines they are similar
The controller TX (both) is sending message every 2000 ms or activated by the RX (both)
PORT1 works, PORT2 not
Can see any difference in the LST file also
I am using the same cable for both and same treminal
By the way, this configuration worked a few months ago
I don't understand what you mean by:
"cut code for a simple SW loopback on #2 UART. Compile and test.....
Every character sent from the PC terminal program should be echoed back to the PC screen..."
Best wishes
Joe |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9253 Location: Greensville,Ontario
|
|
Posted: Wed Jan 11, 2017 7:34 pm |
|
|
SW loopback
A software loopback program, basic low level test program to easily confirm hardware is correct.
3-4 lines of code that is hsown in the CCS C manual
you get an incoming character then transmit it back to the PC terminal program, it's the software equal to a piece of wire between pins 2 and 3 of an RS232 connector.
You say this code worked months ago, so I suspect you might have a hardware problem. Since UART1 code works, UART2 ( a clone) should, so again...points to hardware.
Jay |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Wed Jan 11, 2017 8:13 pm |
|
|
Thanks Jay
I made a test program as you said:
Code: | #INT_RDA2
void RDA2_isr(void)
{
rx2data0=fgetc(PORT2);
enable_interrupts(INT_TBE2);
}
|
&
Code: | #INT_TBE2
void TBE2_isr(void)
{
fputc(rx2data0,PORT2);
disable_interrupts(INT_TBE2);
} |
I also added a 8MHz oscillator on socket, the previous board had one
The PORT2 still don't work
The fuses in the LST are correct now:
Quote: | Word 1: 3B00 ECM_IO PLLEN PRIMARY NOFCMEN NOIESO |
I will write later an email to CCS why the fuses seems not correct with internal and PLL enabled.
So as you said, should be hardware.
I am going to build a new board with the minimum necessary components and one old board and test again.
Best wishes
Joe |
|
|
|
|
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
|