View previous topic :: View next topic |
Author |
Message |
mshearer
Joined: 12 Jan 2009 Posts: 33
|
replacing putc with write to TXREG |
Posted: Thu Mar 05, 2009 5:08 am |
|
|
I'm having a bit of a problem with using the TXREG.
I'm trying to output a chain of hex values
Code: | 00 A1 F2 C4 40 00 00 00 00 00 F0 00 01 01 00 00 |
when i use putc(); i get the correct 16bytes out.
However if i use writes to TXREG, with the USART setup all done manually i get
Code: |
while(!bit_TXIF)
continue;
reg_TXREG = byte_out;
|
Code: | 00 A1 F2 C4 00 40 00 00 00 00 00 F0 00 00 01 00 01 00 00 |
i try narrow down the code and post it up, just wondering if anyone else has come across this.
any help would be great
matt[/code] |
|
|
mshearer
Joined: 12 Jan 2009 Posts: 33
|
|
Posted: Thu Mar 05, 2009 6:00 am |
|
|
example source
Im working on a PICDEM baord with a 10MHZ crystal. Aiming to work at 9600baud, odd parity
Code: |
#include <18F4520.h>
#fuses H4
#fuses NOWDT
#fuses WDT128
#fuses NOPROTECT
#fuses NOBROWNOUT
#fuses NOPUT
#fuses STVREN
#fuses DEBUG
#fuses NOLVP
#fuses NOWRTB
#fuses NOWRTC
#fuses NOCPD
#fuses NOCPB
#fuses NOEBTR
#fuses NOEBTRB
#define ZERO 0x00
#define ONE 0x01
#define TWO 0x02
#define ONE_BYTE 0x08
#define TWO_BYTES 0x10
#define THREE_BYTES 0x18
typedef unsigned char uchar_t;
typedef unsigned int uint8_t;
typedef unsigned long uint16_t;
#byte reg_TXREG = 0xFAD
#byte reg_RCREG = 0xFAE
#byte reg_SPBRG = 0xFAF
#byte reg_TXSTA = 0xFAC
#bit bit_CSRC = reg_TXSTA.7
#bit bit_TX9 = reg_TXSTA.6
#bit bit_TXEN = reg_TXSTA.5
#bit bit_SYNC = reg_TXSTA.4
#bit bit_SENDB = reg_TXSTA.3
#bit bit_BRGH = reg_TXSTA.2
#bit bit_TRMT = reg_TXSTA.1
#bit bit_TX9D = reg_TXSTA.0
#byte reg_RCSTA = 0xFAB
#bit bit_SPEN = reg_RCSTA.7
#bit bit_RX9 = reg_RCSTA.6
#bit bit_SREN = reg_RCSTA.5
#bit bit_CREN = reg_RCSTA.4
#bit bit_ADDEN = reg_RCSTA.3
#bit bit_FERR = reg_RCSTA.2
#bit bit_OERR = reg_RCSTA.1
#bit bit_RX9D = reg_RCSTA.0
#byte reg_PIR1 = 0xF9E
#bit bit_RCIF = reg_PIR1.5
#bit bit_TXIF = reg_PIR1.4
#byte reg_BAUDCON = 0xFB8
#bit bit_BRG16 = reg_BAUDCON.3
#bit bit_WUE = reg_BAUDCON.1
#bit bit_ABDEN = reg_BAUDCON.0
void send_byte(char);
void parity_errorGeneration(uint8_t cms_tx_message);
void main(void)
{
int i;
char in = 0x00;
char a[] = {0x00,0xA1,0xF2,0xC4,0x40,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x01,0x01,0x00,0x00};
bit_TX9 = TRUE;
bit_TXEN = TRUE;
bit_SYNC = FALSE;
bit_SENDB = FALSE;
bit_BRGH = FALSE;
bit_SPEN = TRUE;
bit_RX9 = TRUE;
bit_SREN = FALSE;
bit_CREN = TRUE;
bit_ADDEN = FALSE;
bit_BRG16 = 0;
bit_WUE = 0;
bit_ABDEN = 0;
reg_SPBRG = 0x40;
while(1)
{
if(bit_RCIF == TRUE)
{
in = reg_RCREG;
for(i=0;i<16;i++)
send_byte(a[i]);
}
}
}
void send_byte(char c)
{
parity_errorGeneration(c);
while(!bit_TXIF)
continue;
reg_TXREG = c;
}
void parity_errorGeneration(uint8_t cms_tx_message)
{
uint8_t tx_bit_count = ZERO;
uint8_t tx_loop_count = ZERO;
for(tx_loop_count = ZERO; tx_loop_count < ONE_BYTE; tx_loop_count++)
{
if((cms_tx_message & ONE) == TRUE)
{
tx_bit_count++;
}
cms_tx_message >>= 1;
}
if((tx_bit_count & ONE) == FALSE)
{
bit_TX9D = TRUE;
}
else
{
bit_TX9D = FALSE;
}
} |
Last edited by mshearer on Thu Mar 05, 2009 7:52 am; edited 1 time in total |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Mar 05, 2009 6:55 am |
|
|
Your homebrewed putc() should work, although an exact equivalent would be two ASM instructions shorter
Code: | while(!bit_TXIF);
reg_TXREG = c; |
Why aren't you using putc(), may be an inline variant?
But it's possibly incorrect to set TX9D during transmission of the previous character, as you do. I thought, odd parity would be provided by the UART itself, did I miss something? |
|
|
mshearer
Joined: 12 Jan 2009 Posts: 33
|
|
Posted: Thu Mar 05, 2009 7:21 am |
|
|
I have concerns that using compiler functions might be called up by a safety board at a later date. Any experience of this with the likes of putc() ?
The USART takes care of parity if you use
but not when your doing it manualy, i think.
Ah so you think that the TX9D bit might be changing while previous bytes are still in the buffer?[/code] |
|
|
mshearer
Joined: 12 Jan 2009 Posts: 33
|
|
Posted: Thu Mar 05, 2009 7:58 am |
|
|
changing the position of the parity generation seems to have done it.
Code: |
void send_byte(char c)
{
while(!bit_TXIF)
continue;
parity_errorGeneration(c);
reg_TXREG = c;
}
|
thank you very much |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Mar 05, 2009 8:08 am |
|
|
I see, that PIC18 actually has no hardware parity generator as most uP have. I wasn't yet aware of. The CCS C built-in parity code should be supposed more effective. I don't see a particular reason not to use built-in functions. They may be faulty, but compiler implementation of simple C expressions can be as well. |
|
|
andreluizeng
Joined: 04 Apr 2006 Posts: 117 Location: Brasil
|
|
Posted: Thu Mar 05, 2009 1:51 pm |
|
|
you may also try this code:
Code: |
void SendByte (char Data)
{
char Aux;
// wait for xmit shifter
while (! TRMT);
// wait txif
while (! TXIF);
TXREG = Data; // load TXREG with data
while (! TXIF); // wait until transmission ends
return;
} |
it works fine here.
regards _________________ Andre |
|
|
|