|
|
View previous topic :: View next topic |
Author |
Message |
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
rs232 - Hardware or software SOLVED |
Posted: Fri May 06, 2016 11:54 pm |
|
|
I am getting more and more confused regarding how to know that I am using hardware or software rs232.
The examples are with 16F648A, working software, EEPROM read, write/read, time counting, push buttons, LED's and and AC motor controller by PWM.
I tested with two #use rs232, both works with no any mistakes, tested 100's times each:
Code: | #use delay(internal=4M,RESTART_WDT) |
Code: | #use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8,restart_wdt) |
The LST file shows:
Quote: | .................... #use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8,restart_wdt)
------------------------------
At interrupts:
.................... #int_TBE
.................... void TBE_isr(void)
.................... {
.................... switch(scomtxwords)
*
0055: MOVF scomtxwords,W
0056: ADDLW F5
0057: BTFSC STATUS.C
0058: GOTO 0BE
0059: ADDLW 0B
005A: GOTO @goto44841
-----------------------
.................... putc(85);
005B: MOVLW 55
005C: CLRWDT
005D: BTFSS PIR1.TXIF
005E: GOTO 05C
005F: MOVWF TXREG
....................
---------------------------
.................... #int_RDA
.................... void RDA_isr(void)
.................... {
.................... switch(scomrxwords)
*
00D0: MOVF scomrxwords,W
00D1: ADDLW F8
00D2: BTFSC STATUS.C
00D3: GOTO 137
00D4: ADDLW 08
00D5: GOTO @goto44939
-------------------------
.................... scomrxw0=getc();
00D6: CLRWDT
00D7: BTFSS PIR1.RCIF
00D8: GOTO 0D6
00D9: MOVF RCREG,W
00DA: MOVWF scomrxw0 |
With the setting learned on the forum:
Code: | #use rs232(baud=9600,parity=N,UART1,bits=8,BRGH1OK,restart_wdt,errors) |
The LST shows:
Quote: | .................... #use rs232(baud=9600,parity=N,UART1,bits=8,BRGH1OK,restart_wdt,errors)
*
00D0: CLRWDT
00D1: BTFSS PIR1.RCIF
00D2: GOTO 0D0
00D3: MOVF RCSTA,W
00D4: MOVWF rs232_errors
00D5: MOVF RCREG,W
00D6: MOVWF @78
00D7: BTFSS rs232_errors.1
00D8: GOTO 0DB
00D9: BCF RCSTA.CREN
00DA: BSF RCSTA.CREN
00DB: RETURN
-----------------------
.................... #int_TBE
.................... void TBE_isr(void)
.................... {
.................... switch(scomtxwords)
*
0055: MOVF scomtxwords,W
0056: ADDLW F5
0057: BTFSC STATUS.C
0058: GOTO 0BE
0059: ADDLW 0B
005A: GOTO @goto1834
---------------------------
005B: MOVLW 55
005C: CLRWDT
005D: BTFSS PIR1.TXIF
005E: GOTO 05C
005F: MOVWF TXREG
-------------------------
.................... #int_RDA
.................... void RDA_isr(void)
.................... {
.................... switch(scomrxwords)
*
00DC: MOVF scomrxwords,W
00DD: ADDLW F8
00DE: BTFSC STATUS.C
00DF: GOTO 134
00E0: ADDLW 08
00E1: GOTO @goto1916
-------------------------
00E2: CALL @GETCH_BIU_1
00E3: MOVF @78,W
00E4: MOVWF scomrxw0 |
I am using the first #use rs232 sentence from the time I started to use the CCS compiler 10 years ago, thinking it is a hardware rs232. After the latest things I learned on the forum, I don't know if it is hardware or software.
The difference between the two except GOTO is at LST #use rs232
Can someone explain me how to to assess the LST above to understand if it is software/hardware rs232?
Best wishes
Joe
Last edited by gjs_rsdi on Wed May 18, 2016 9:25 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sat May 07, 2016 1:04 am |
|
|
A lot of this is in the manual....
However parts, implications, and reasons are not, and some of the manual entries have disappeared over the years.
So.
Old manual specifically told you that:
#USE RS232 will use the hardware USART, if XMIT and RCV select the hardware pins.
This is not in the current manual, but is mentioned in a couple of the examples. This disappeared at about the time that stream identifiers appeared, and a lot of the new abilities were attached to the function (direction control etc..).
However it is implied in the 'FORCE_SW' manual entry which tells you that this will use a software UART, even if you select the hardware pins.
I had to go back to the mid 1990's to find a manual that did say this!....
Ugh....
Now, as a comment (ignoring RS232), understand that people who use the RESTART_WDT abilities of delay, and RS232, should be publicly flogged!. This is _not_ how to use a watchdog, and is basically pointless. It really disables the functionality of the watchdog, unless the processor gets into a 'hung' state, which is almost unbelievably rare. For any programming situation, where a watchdog is actually _required_ by the certification process (medical, some military applications etc.), having this would result in the code being refused immediately. Beware.
Now your first approach, is basically fine, except that since it lacks 'ERRORS', the UART can become hung. Generally unlikely when using #INT_RDA, unless there is something that disables this for a significant time. However always better to have ERRORS.
The advantage of the second approach, really starts to appear, first on chips with relocatable peripherals (many of the modern PIC's), where you have to 'SELECT' the pins to be used. The best way on these is to #PIN SELECT the pins, then use the UARTx name, _which ensures the hardware UART will be used_. Then in general it reduces the risk of typing errors, and makes sure you _are_ using the hardware. Gets rid of any doubt.
BRGH1OK allows the compiler to use the BRGH bit. A lot of the early PIC's had a hardware problem with this bit. However now almost no chips do. This gives more accurate baud rates, especially at lower CPU clocks.
The difference in your list file, is because the first code was compiled with the default #NOLIST, which is in the processor include file. This means that the code for things like RS232 is hidden. The 'idea' is to make it _your_ code that is shown, to simplify debugging this.
The #INT_RDA, and INT_TBE, just won't work at all, unless the hardware is actually used. |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Sat May 07, 2016 5:08 am |
|
|
Thanks for the answers PCM programmer and Ttelmah
The answers are making things clear.
I have a 2006 manual, version 4, it says that 'FORCE_SW' will force a software rs232, but not the other things.
Just to conclude if I understand correct:
* always use errors in hardware rs232
* don't use restart_wdt
* if the LST of the rs232 is short, it is a hardware rs232
Started to test the same with 16F1847 but I have problems
If I am out-commenting all the setup_ccp1(CCP_PWM); the rs232 works OK. If not out-commented works, but not always with:
Code: | #use rs232(baud=9600,parity=N,UART1,bits=8,BRGH1OK,restart_wdt,errors) |
with
Code: | #use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8,restart_wdt) |
not working at all
Can be difference on how CCS implementing the PWM in the new chip?
I am testing the subject, will update when I have results
Best wishes
Joe |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat May 07, 2016 9:48 am |
|
|
Look at the Device Overview section in the 16F1847 data sheet. Look
at the pin descriptions. What does it say about TX and RX and the SPI
pins ? It tells you what you need to do to fix the problem. It's important
to do this when you're designing your circuit and choosing what pins to
use on the PIC. |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Sat May 07, 2016 2:39 pm |
|
|
Hi PCM programmer
Thank you for your answer
I have done as you wrote because I want the 16F1847 as replacement for 16F648A on an existing project and for some future projects.
I done it again right now, printed out the pins description of both controllers and checked again.
They are 100% compatible pins wise, the 16F1847 have a lot of options on the different pins and analog inputs.
The program works perfect on the 1847 except the rs232 at 4MHz and 8Mhz. All the pins are doing the same on both controllers.
The rs232 works perfect with 1847 on 16MHz and 32MHz.
Just bothering me why the 648A works perfect at the low frequencies and the 1847 not.
I am checking again all the data sheet to try to find a clue
Best wishes
Joe |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat May 07, 2016 4:06 pm |
|
|
Disregard my comment. I was not fully awake when I posted it. Sorry.
Your most recent post is a continuation of this previous thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=55114
But with a new problem. It fails sometimes if pwm is enabled.
To get help on this, you need to:
1. Post a test program.
2. Post a link to your circuit schematic.
3. Describe your test procedure.
4. Tell us what you expect to see from your testing, and tell us
how it fails, in detail.
If you do all those things, I can probably duplicate your hardware and
software, and maybe duplicate your failures. Then I can probably fix it.
Example:
In the following thread, a person had 10% average error rate when
transmitting bytes between PICs with SPI. I built a test board with
two PICs on it, duplicated the problem, and then tracked it down to
floating input pins. This is a 2-page thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=45371
In the previous thread, Ttelmah pointed out this issue to you. That's why
we need to see your test program, to see if you implemented the
suggested corrections. |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Sat May 07, 2016 4:43 pm |
|
|
Thank you for the proposal PCM programmer
The test program will take me some time as I am flying abroad for a week but I will make it.
Can I attache a PDF file with the schematic?
Best wishes
Joe |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat May 07, 2016 4:54 pm |
|
|
The CCS forum doesn't host downloads. You can't upload anything
to the CCS forum. You can post a link to a file hosted on some
other website. Then post a link to it in this thread. |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Wed May 18, 2016 9:24 pm |
|
|
First I would like to thank PCM programmer and Ttelmah for their advice and help and to state that I learned a lot from this topic and many others I had read on the forum.
I started to write a test program per PCM programmer advice. Wrote it for the PIC16F1847, originally with 8MHz internal oscillator.
Each step I went forward worked without any errors so I went on until finished the all new program. The used memory is 28%, the previous was 33%.
Made adaptations for the internal 32MHz, external clock of 8MHz and 32MHz using the PLL.
Adapted it also to the PIC16F648A, the previous program memory size was 62%, now 52% at 8MHz, even at 4MHz internal oscillator works perfect.
Tested 100’ts times, not any error.
No disable_interrupts(GLOBAL);/ enable_interrupts(GLOBAL); and no setup_ccp1(CCP_OFF);/ setup_ccp1(CCP_PWM); before/after write_eeprom(0xXX,0xXX);
Below the settings I used, CCS PCM C Compiler, Version 5.056d, 1; MPLAB v8.92 in Release:
Code: | #include <16F648A.h>
#FUSES WDT
#FUSES EC_IO
#FUSES BROWNOUT
#FUSES PROTECT
#FUSES NOCPD
#FUSES MCLR,NOLVP,PUT
#use delay(clock=8M)
#use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8,stream=PORT1,errors)
#include <16F1847.h>
#device ADC=10
#FUSES WDT
#FUSES INTRC_IO
#FUSES PLL_SW
#FUSES NOIESO
#FUSES BORV25
#FUSES PROTECT
#FUSES NOCPD
#FUSES MCLR,NOLVP,PUT
#FUSES NOFCMEN
#FUSES STVREN
#use delay(internal=8M)
#use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8,stream=PORT1,errors)
|
Thank you again and best wishes.
Joe |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Mon May 30, 2016 2:39 am |
|
|
One more question in the rs232 subject:
Can I use just TX or just RX of the rs232 an the other pin for regular I/O?
In a project I am working using just rs232 TX and would like to use the RX pin as general I/O.
Best wishes
Joe |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Mon May 30, 2016 6:34 am |
|
|
If you look through the data sheet, the PIC will have a receive status and a transmit status (or some similar names) register. In order to enable the receiver, a certain bit will need to be enabled. Same goes for transmit. If the corresponding bit is NOT set, then that pin can be used for I/O.
I have no idea what you'd have to put into the #use rs232() argument list to achieve that. I usually set those bits myself. |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Mon May 30, 2016 8:44 pm |
|
|
Thank you for the answer newguy
As I see in the LST, CCS compiler doing the enable/disable bits.
Worked in assembler until 2006 (still my C format is like assembler) but working rarely so to do the bits manually will take me a lot of time.
I have a ready board with PIC16F1847 so I spent some time for testing.
Here are the results:
Code: | #use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=none,bits=8,stream=PORT1,errors) |
given by the CCS Wizard gives error on compiling
With:
Code: | #use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8,stream=PORT1,errors) |
If no TBE interrupt used, RB2 works as input, as output always '1', rx works OK as serial in
If no RDE interrupt used, RB1 works as input and output, tx works OK as serial out
If using one of:
Code: | //#use rs232(baud=9600,parity=N,xmit=PIN_B2,bits=8,stream=PORT1,errors)
//#use rs232(baud=9600,parity=N,rcv=PIN_B1,bits=8,stream=PORT1,errors)
//#use rs232(baud=9600,parity=N,rcv=PIN_B1,bits=8) |
the LST shows software TX or RX
My serial communication routines don't work with software rs232.
My test program below if someone interested:
Code: | #include <16F1847.h>
#device ADC=10
#FUSES WDT //Watch Dog Timer
#FUSES PUT //Power Up Timer
#FUSES MCLR //Master Clear pin enabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOCPD //No EE protection
#FUSES BROWNOUT //Reset when brownout detected
#FUSES PLL
#FUSES NOCLKOUT //I/O function on OSC2
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOWRT //Program memory not write protected
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES BORV25 //Brownout reset at 2.5V
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(internal=32M)
#use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8,stream=PORT1,errors)
//#use rs232(baud=9600,parity=N,xmit=PIN_B2,bits=8,stream=PORT1,errors)
//#use rs232(baud=9600,parity=N,rcv=PIN_B1,bits=8,stream=PORT1,errors)
//#use rs232(baud=9600,parity=N,rcv=PIN_B1,bits=8)
#define flashled PIN_A6
//#define switchin PIN_A7
//#define switchin PIN_B2//WORKS AS INPUT***************************************************************
//#define switchin PIN_B1//WORKS AS INPUT***************************************************************
//#define flashled PIN_A7
#define rxled PIN_B0
#define switchled PIN_B2//DON'T WORK AS OUTPUT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//#define switchled PIN_B1//WORKS AS OUTPUT*************************************************************
#define switchin PIN_A7
//#define switchin PIN_B5
short ms625flag=0;
int ms625cnt=0;
int txwords=0;
int txwchs=0;
int data=0;
int rxwords=0;
int rxdata0=0;
int rxdata1=0;
int rxdata2=0;
#INT_TIMER1
void TIMER1_isr(void)
{
set_timer1(3036);//62.5ms interrupt
ms625flag=1;
}
//-----------------------------------------------
/*
#INT_TBE
void TBE_isr(void)
{
switch(txwords)
{
case 0:
{
putc(0x55);
txwchs=85;
txwords++;
}
break;
case 1:
{
putc(0xAA);
txwchs=255;
txwords++;
}
break;
case 2:
{
putc(data);
txwchs=txwchs+data;
txwords=0;
disable_interrupts(INT_TBE);
}
break;
}
}
*/
//-----------------------------------------------
#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;
output_toggle(rxled);
}
}
}
//-----------------------------------------------
void main()
{
setup_wdt(WDT_128MS); //~128 ms reset
port_a_pullups(0xFF);
output_low(rxled);
output_low(switchled);
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(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);
}
if(input(switchin))
{
output_high(switchled);
data=1;
}
else
{
output_low(switchled);
data=0;
}
}
}
|
Best wishes
Joe |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Tue May 31, 2016 2:21 am |
|
|
Just for your information. Have a look at this thread:
<http://www.ccsinfo.com/forum/viewtopic.php?t=49307&highlight=txen>
There are many others covering this.
There are quite a few situations, where (for instance), you need the hardware receive, but do not need transmit, or perhaps want to use another pin, and then the solution is to disable the TXEN as shown.
You can generate a software UART, with 'receive only', or 'transmit only' whenever required. |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Tue May 31, 2016 4:08 pm |
|
|
Thank you for the answer and the link Ttelmah.
I try to use hardware rs232 and not the software one.
The only think I don't understand why if I want to use the tx line as output it is always high (as digital input is OK) even when I am driving it low by software.
Code: | if(input(switchin))
{
output_high(switchled);
data=1;
}
else
{
output_low(switchled);
data=0;
} |
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
|