View previous topic :: View next topic |
Author |
Message |
paolope
Joined: 29 May 2009 Posts: 7
|
software rs232 |
Posted: Thu Feb 16, 2012 3:46 am |
|
|
hello,
I chose pic18f26k80 for its 2xUART, but the second shares the pins with ICDU64 so I think to use a sw rs232.
The question is
running it at say 9600, is it interruptable?
paolo |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
Re: sotware rs232 |
Posted: Thu Feb 16, 2012 4:45 am |
|
|
paolope wrote: | hello,
I chose pic18f26k80 for its 2xUART, but the second shares the pins with ICDU64 so I think to use a sw rs232.
The question is
running it at say 9600, is it interruptable?
paolo |
The standard CCS software UART using bit timing. Interrupts will corrupt the bit timing however if you clock speed is very high (40MHz) and if interrupts are very infrequent and the interrupt handler processing time is very very very short then it should be possible.
Naturally a far better solution is to use the second hardware UART then, failing that, use a timer based interrupt driven software UART. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19509
|
|
Posted: Thu Feb 16, 2012 5:08 am |
|
|
Also remember the software UART is half duplex only, and that you must poll (with kbhit) the incoming data line at least something over 20000* per second if you are not going to miss arriving data....
Best Wishes |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu Feb 16, 2012 9:51 am |
|
|
use the debugger between your ears
if you are already using the primary serial port-
that ALONE is sure to eventually corrupt any SW RS232 you may attempt .
only pain awaits you if you go that way.
the 2nd RS232 hardware port is WAY more valuable for its intended use
ICD is for the easily confused anyway - |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Feb 16, 2012 2:53 pm |
|
|
Quote: | sw rs232.
The question is running it at say 9600, is it interruptable?
|
Download the compiler manual and put it on your desktop.
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
Look in the #use rs232() section. You will find a parameter which disables
interrupts temporarily while transmitting or receiving a byte when using
a software UART. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19509
|
|
Posted: Thu Feb 16, 2012 4:08 pm |
|
|
As a separate comment, you are presumably aware that MicroChip makes a version of the 26K80 for debugging, which has extra pins, and a 'carrier', so you can use the ICD, and the hardware UART....
Best Wishes |
|
|
paolope
Joined: 29 May 2009 Posts: 7
|
|
Posted: Fri Feb 17, 2012 2:21 am |
|
|
Unfortunately I had the "nice" idea to migrate from a 18f2523 to a 18f26k80 on an existing PCB, with "just a couple of wires".
So, as usual, I got extra sw and extra hassle.
paolo |
|
|
n-squared
Joined: 03 Oct 2006 Posts: 99
|
|
Posted: Fri Feb 17, 2012 3:55 am |
|
|
Hi
I pulled out a piece of code from a project I did a few years ago, that implements an interrupt driven software UART.
Feel free to use.
Code: |
//==========================================================
// description: complete software UART using 1 external
// interrupt and a single timer.
// Both TX and RX are interrupt driven, freeing
// application to execute other tasks.
// FIFO sizes for both TX and RX can be modified
// written by: Noam Naaman
// functions: COM2_init() initializes TX and RX
// COM2_send_chr() adds a character to outgoing FIFO
// COM2_get_chr() retrieves oldest character from incoming FIFO
// COM2_chr_ready() returns TRUE if incoming FIFO contains a character
//==========================================================
//======- type definitions =================================
#define UINT int16
#define UCHAR int8
#define ICHAR signed int8
#define bit int1
#define ULONG int32
//======- COM2 definitions =================================
#bit COM2_OUT = PORTH.1
#bit COM2_IN = PORTB.3
#define COM2_POLARITY 1 // inverse output
#define COM2_RX_LEN 16
#define COM2_TX_LEN 16
bit COM2_tx; // transmitting a byte
UINT COM2_tword; // transmit buffer for start, 8 data, stop bits
UCHAR COM2_tbits; // transmit bit counter
UCHAR COM2_tbuf[COM2_TX_LEN]; // transmit data buffer
UCHAR COM2_tcnt; // bytes to transmit
UCHAR COM2_txi, COM2_txo; // buffer input/output pointers
UCHAR COM2_rx; // receive bit count
UCHAR COM2_rbits; // receive bits
UCHAR COM2_rbuf[COM2_RX_LEN]; // receive data buffer
UCHAR COM2_rcnt; // received bytes
UCHAR COM2_rxi, COM2_rxo; // buffer input/output pointers
//======- COM2 software UART ===============================================
#ignore_warnings 225
#int_EXT3 high
void RX_start_bit(void) // UART input on RB3
{
/* TMR2 = 0;
PR2 = 150; // set timer to middle of first data bit
TMR2IF = 0; // clear interrupt flag
TMR2ON = 1; // enable interrupt*/
setup_timer_2(T2_DIV_BY_4,51 ,2); // 75uS interrupt for middle of bit 0 at 32MHz for 19200 Baud
set_timer2(0);
COM2_tx = 0; // disable transmission
COM2_rx = 0; // initialize bit counter
disable_interrupts(int_EXT3);
clear_interrupt(int_timer2); // start bit collection interrupt
enable_interrupts(int_timer2);
}
//==============================================================
#int_TIMER2 high
void COM2_isr(void) // software UART @19200bps
{
if (COM2_tx) // transmitting?
{
COM2_OUT = (make8(COM2_tword, 0) & 1);
COM2_tword >>= 1;
if (!--COM2_tbits)
{
if (!COM2_tcnt) // no more chars to send?
{
COM2_OUT = 1;
COM2_tx = 0;
disable_interrupts(int_TIMER2);
delay_us(10);
clear_interrupt(int_ext3); // no more chars to send, switch to receive mode
enable_interrupts(int_EXT3); // prepare for next char
}
else // more chars to send
{
COM2_tword = (0xff00 | COM2_tbuf[COM2_txo]) << 1; // add start and stop bits
COM2_tbits = 10;
if (++COM2_txo >= COM2_TX_LEN)
COM2_txo = 0;
COM2_tcnt--;
}
}
}
else // in receive mode
{
if (!COM2_rx)
setup_timer_2(T2_DIV_BY_4,47,2); // 52uS interrupt at 32MHz for 19200 Baud
set_timer2(5);
COM2_rbits >>= 1;
if (input(PIN_B3))
COM2_rbits |= 0x80;
if (++COM2_rx >= 8)
{
COM2_rcnt++;
COM2_rbuf[COM2_rxi] = COM2_rbits;
if (++COM2_rxi >= 16)
COM2_rxi = 0;
disable_interrupts(int_TIMER2);
clear_interrupt(int_ext3);
enable_interrupts(int_EXT3); // prepare for next char
TMR2ON = 0; // disable interrupt
}
}
}
//==================================================================-
void COM2_send_chr(UCHAR chr)
{
while (COM2_tcnt >= COM2_TX_LEN); // wait for space in transmit buffer
if (!COM2_tx)
{
COM2_tword = (0xff00 | chr) << 1; // add start and stop bits
COM2_tbits = 10;
COM2_tx = 1;
clear_interrupt(int_TIMER2);
enable_interrupts(int_TIMER2); // start transmission
}
else
{
COM2_tbuf[COM2_txi] = chr;
if (++COM2_txi >= COM2_TX_LEN)
COM2_txi = 0;
COM2_tcnt++;
}
}
//=============================================================================
UCHAR COM2_get_chr(void)
{
UCHAR x;
x = COM2_rbuf[COM2_rxo];
if (++COM2_rxo >= COM2_RX_LEN)
COM2_rxo = 0;
if (COM2_rcnt)
COM2_rcnt--;
return x;
}
//=============================================================================
bit COM2_chr_ready(void)
{
return COM2_rcnt;
}
//=============================================================================
void COM2_init(void)
{
COM2_OUT = 1;
COM2_rxi = COM2_rxo = COM2_rcnt = 0;
COM2_txi = COM2_txo = COM2_tcnt = 0;
COM2_tx = 0;
ext_int_edge(3, H_TO_L);
setup_timer_2(T2_DIV_BY_4,51,2); // 52uS interrupt at 32MHz for 19200 Baud
clear_interrupt(int_EXT3);
enable_interrupts(int_EXT3); // enable RX
}
|
BR
NN _________________ Every solution has a problem. |
|
|
|