I finally tried to tackle this problem myself and am having some
difficulties. I am simply attempting to shift in every bit from an
eight bit data stream off of a 9600 asynchronous serial line. I am
using an rs 232 to ttl convertor so the line going to the receive pin
(porta bit 0) will start of high. The program then polls for the pin to
go low, and then when it does that, it delays the inverse of 9600 plus
half of that so it may then read the bit in the middle of the next bit.
This would be 104+52=156us. I then shift the first bit in, decrement a
counter to tell me if I've gotten all of my bits, then go back to a
delay loop which runs for another 104us. the thing is......it doesn't
work. my code is below, and if someone could take a look at it that
would be wonderful. thanks
;should receive serial char in shiftreg at 9600 baud and output the 8
bit value to portb
;serial in pin is porta bit 0 with 4.00Mhz clock
porta equ 0x05
portb equ 0x06
count1 equ 0x0c
shftcnt equ 0x0d
shiftreg equ 0x0e
w equ 0
f equ 1
#define rx porta,0
start: movlw 0x00
tris portb ;portb outputs
tris porta ;porta inputs
dia: call rxin
movf shiftreg,w ;move char to w
movwf portb ;display on portb
rxin: clrf shftcnt
movlw .8 ;setup bit count registe
wait4sb: btfsc rx ;wait for start bit
movlw .16 ;setup for 56us delay
jon: decfsz count1,f
wait: movlw .32 ;setup for 104us delay
decreg: decfsz count1,f ;delay
shift: comf porta,f ;take complement because
line driver switches
rrf porta,w ;rotate into carry
rlf shiftreg,f ;rotate out of carry
decfsz shftcnt,f ;done?
goto wait ;nope
> shift: comf porta,f ;take complement becau
se line driver switches
> rrf porta,w ;rotate into carry
> rlf shiftreg,f ;rotate out of
Port A is all inputs, so "comf porta,f" will not do much for you.
If you want to negate the input, I guess you could do:
or something similar, instead of the instructions above. Alternatively,
simply comf the output once you've received all 8 bits.
Also, I think your main loop timing is off by a cycle, but at 9600 that
shouldn't affect you too much (remember that on the last iteration of a
decfsz loop, you don't execute the 2-cycle goto, but you do a 1-cycle
skip instead, so the loop actually consumes 3n-1 cycles).
Are you seeing any data at all? Garbled data? Inverted data?
|On Sat, 16 Jan 1999 18:28:34 -0800 MARK D NEWPORT
<worldnet.att.net> writes: jmnewp
>I finally tried to tackle this problem myself and am having some
It would be helpful to us to describe exactly what the problems seem to
be. Looking at your code briefly, I see one minor problem and 2 major
A "comf PORTA,f" will do nothing to change the input value. To invert
the data, I'd complement the shiftreg variable after all the bits are
shifted in. But, you don't want to complement the received data. If you
use an inverting line reciever, zero data bits will read as low on the
pin. So the routine is OK as it is, just delete the comf.
RS-232 data is transmitted LSB first. Thus you need rotate *right* into
the shift register, not left. After 8 shifts, the LSB (which was
received first) will be in its proper position. [A common optimization
is to initialize the shift register to 10000000, then test the flag after
each rotate to see if the 1 came out. When it does, 8 bits have been
received. This avoids the need for a bit counter variable.]
Your routine returns immediately after taking the sample at the center of
the last bit. If you call it again right away (which you do) and the
last bit transmitted was a zero, the routine will falsely detect the end
of the last bit as a start bit, then go on to improperly receive a byte
at the wrong time. If the line was idle, the byte received will be all
ones. One work-around is to ensure there is a delay of at least 1/2 to
3/4 bit time (preferably 1 bit time, but not any longer) between calls to
the receive routine to let the end of the last bit clear the line. A
probably better approach is to be sure the line is high (inactive, a stop
bit) at the top of the routine, then start looking for a start bit.
You don't need to buy Internet access to use free Internet e-mail.
Get completely free e-mail from Juno at http://www.juno.com/getjuno.html
or call Juno at (800) 654-JUNO [654-5866]
I suppose I looked over these simple errors, and have now gotten
everything working perfectly, thanks everyone.
Mike Keitz wrote:
Dr. Imre Bartfai
On Sat, 16 Jan 1999, Ben Stragnell wrote:
> > shift: comf porta,f ;take complement bec
ause line driver switches
> > polarity
> > rrf porta,w ;rotate into carry
> > rlf shiftreg,f ;rotate out of
rrf shiftreg,f ; belongs here!!!
Furthermore, there is another logical error. See comment above!
More... (looser matching)
- Last day of these posts
- In 1999
, 2000 only
- New search...