 |
Swordfish Structured BASIC for PICŪ Microcontrollers
|
| View previous topic :: View next topic |
| Author |
Message |
garryp4
Joined: 21 May 2007 Posts: 47 Location: Loveland, CO USA
|
Posted: Mon Mar 01, 2010 8:41 am Post subject: 7-bit ascii |
|
|
| Has anyone tried to do 7-bit ascii? I have a project to communicate with an old system that uses it. |
|
| Back to top |
|
 |
Raistlin
Joined: 01 Apr 2008 Posts: 61
|
Posted: Mon Mar 01, 2010 9:02 am Post subject: |
|
|
7 bit ASCII is easy enough , depends on what your aiming to do 7 bit ASCII is the same as 8bit only without the other codes Ie highest 7 bit ASCII is 01111111 _________________ If you can read this you are too close |
|
| Back to top |
|
 |
Jerry Messina
Joined: 30 Jan 2009 Posts: 99 Location: Frederick, MD
|
Posted: Mon Mar 01, 2010 10:29 am Post subject: |
|
|
I assume you're talking about the hardware uart and 7-bit mode. Since the uart in the pic only supports 8/9 bit operation (depending on the pic), you'll have to manually manipulate the eighth bit to match what the end system is expecting. You may have to use it for parity, a stop bit, etc...exactly what depends on what you're talking to. I did this with a system using 7O1, and it worked fine.
Jerry |
|
| Back to top |
|
 |
garryp4
Joined: 21 May 2007 Posts: 47 Location: Loveland, CO USA
|
Posted: Mon Mar 01, 2010 10:40 pm Post subject: |
|
|
Thanks for the quick reply. Its a standard called SDI-12. The communication is 7n1 at 1200 baud. Kind of dates the standard, but have a need none the less. I did look at the code for the usart and suart libraries but do not know assembly. That's why I use swordfish.
What changes did you have to make to talk 7O1?
Thanks. |
|
| Back to top |
|
 |
Jerry Messina
Joined: 30 Jan 2009 Posts: 99 Location: Frederick, MD
|
Posted: Tue Mar 02, 2010 10:18 am Post subject: |
|
|
To support 7O1 I had to make a number of changes to support dealing with the parity bit and inserting it into the eighth data bit.
For 7N1, things are a bit easier. Since there's no parity, the eighth bit is the stop bit (which is the same as an idle line), or a logic 1.
To transmit a byte, simple OR the ascii data with $80, and when receiving AND it with $7F.
When you transmit, you'll actually be sending a byte that looks like 7N2 since the uart will add a real stop bit, but the receiving system won't care.
When you receive, since the uart requires eight bits, you'll actually get the stop bit in bit 7 (which is why you AND out the msb).
There is one hiccup, and that's if the remote system is capable of sending back-to-back transmissions. For 7N1, a uart has 9 bits to deal with...
<start bit> <7 data bits> <stop bit>. The uart of the pic requires 10 bits...<start bit> <eight data bits> <stop bit>. For this to work, the remote
system must idle the line in between bytes for at least one bit time so that the pic's uart will see the idle line as a stop bit. If it doesn't do this,
then you can't use the hardware uart, and would have to resort to using a modified software uart that would deal with 7 bits.
Hopefully, it's an old, slow system and you'll have the extra bit time you need.
Jerry |
|
| Back to top |
|
 |
nigle
Joined: 12 Aug 2008 Posts: 36 Location: West London
|
Posted: Tue Mar 02, 2010 10:41 am Post subject: |
|
|
| garryp4 wrote: | | Its a standard called SDI-12. The communication is 7n1 at 1200 baud. | It isn't in the version of the standard that I downloaded:
| Code: | 4.1 Baud Rate and Byte Frame Format
The baud rate for SDI-12 is 1200. Table 2 shows the byte frame format for SDI-12.
1 start bit
7 data bits, least significant bit transmitted first
1 parity bit, even parity
1 stop bit |
The good news is that you can use the hardware UART, the bad is that you need to generate the parity bit. |
|
| Back to top |
|
 |
Jerry Messina
Joined: 30 Jan 2009 Posts: 99 Location: Frederick, MD
|
Posted: Tue Mar 02, 2010 11:10 am Post subject: |
|
|
Good catch nigle.
Here's some bits of code for dealing with transmitting 7E1...
| Code: |
//
// parity functions
// (these functions assume 7-bit data mode with parity in msb (8-bit)
//
public const
EVEN_PARITY = 0,
ODD_PARITY = 1
public const
PARITY_BIT = 7
' returns parity of b...
' 0 = even
' 1 = odd
public function parity(b as byte) as bit
' breakdown the following into a simpler expression...
' b = b xor ((b >> 4) or (b << 4))
asm
swapf b,W
end asm
b = b xor WREG
' magic parity calculation
b = b + $41
b = b or $7c
b = b + 2
' check if (b >= 128)
if (b.bits(7) = 1) then
result = ODD_PARITY
else
result = EVEN_PARITY
endif
end function
' 7-bit parity (parity bit in msb)
public function set_odd_parity(b as WREG) as byte
result = b
result.bits(PARITY_BIT) = 0
if (parity(result) = EVEN_PARITY) then
result.bits(PARITY_BIT) = 1
endif
end function
public function set_even_parity(b as WREG) as byte
result = b
result.bits(PARITY_BIT) = 0
if (parity(result) = ODD_PARITY) then
result.bits(PARITY_BIT) = 1
endif
end function
#define USART_PARITY = EVEN_PARITY
public sub WriteByte(b as byte)
// 7 data bits. parity is in msb of data char
#if (USART_PARITY = ODD_PARITY) // odd parity
b = set_odd_parity(b)
#elseif (USART_PARITY = EVEN_PARITY) // even parity
b = set_even_parity(b)
#endif
USART.WriteByte(b)
end sub
|
|
|
| Back to top |
|
 |
garryp4
Joined: 21 May 2007 Posts: 47 Location: Loveland, CO USA
|
Posted: Mon Mar 08, 2010 5:13 am Post subject: |
|
|
Thanks for the replies. And Nigle, you are correct. I want 7E1 not 7N1. Think I am so used to 8N1 and failed to check what I typed.
So, I came up with
| Code: | // device and clock...
Device = 18F4620
Clock = 40
// import modules...
Include "usart.bas"
Include "convert.bas"
Private Dim
an_sw As PORTD.4, ' High for RS port, low for Zigbee
red As PORTB.3, ' Red LED
green As PORTB.4 ' Green LED
Private Dim
b1 As Byte,
b2 As Byte,
lp1 as byte
ADCON0 = $00 ' Turn off internal A/D
ADCON1 = $0F
ADCON2 = $B2
USART.SetBaudrate(br57600) ' and baud rate
High(an_sw)
DelayMS(500)
USART.Write(0,10,13,"TEST PARITY! ",10,13)'
DelayMS(5)
'******************************************************************************
MAIN:
b2 = 0
USART.Write(10,13,"ENTER CHARACTER ",10,13)
b1 = USART.ReadByte
USART.Write(10,13,"CHARACTER = ",BinToStr(b1,8),10,13)
for lp1 = 0 to 7
if b1.bits(lp1) = 1 then
b2 = b2 + 1
endif
next
b1 = b1 << 1
USART.Write("SHIFTED CHARACTER = ",BinToStr(b1,8),10,13)
USART.Write("quantity of 1's = ",decToStr(b2),10,13)
if b2.bits(0) = 1 then ' 1 if odd number, 0 if even
B1 = b1 + 1
endif
USART.Write("7E1 CHARACTER = ",BinToStr(b1,8),10,13)
GoTo MAIN
|
It seems to work as I understand the SDI requirement. Now will have to connect and see how it works, of course without the extra messages. |
|
| Back to top |
|
 |
|
|
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
|