The following code samples data and then ouputs it , but i'm stuck big style
i am oversampling by 4 times the data rate ie 32Khz and what i want to do is
cut out bits i don't want , the theory is if i oversample by 4 times what would
normally be a 1 because its oversampled it would be 1111 and the same for 0 .
but how do i put this in my code and if there is a error condition like 1011
chances are its 1 one is there a efficiant way to do this ?
Please look at my code and if you can help me i'm new to pic programming and
would really appreciate your help .....
porta equ 5
clrf 0 ; Make sure RAM page bits are 0
movlw 10 ; Port A.0 as output
bcf porta,0 ; Output a 0
btfss porta,1 ; Look for the input on porta.1
bsf porta,0 ; Output a 1
btfsc porta,1 ; And wait for input to go low
Paul, your code started as following:
>porta equ 5
> clrf 0 ; Make sure RAM page bits are 0
> movlw 3
> movlw 10 ; Port A.0 as output
> tris porta
PortA,0 has to be tris'ed as output
PortA,1 has to be tris'Ed as input
Your problem probably is that you had an other number radix in mind at your
movlw-instructions than mpasm decodes. So better explicitely add the radix:
movlw d'3' ; decimal 3
movlw b'11111110' ; binary, bit0=output, other bits=input
Paul Bulmer wrote:
> The following code samples data and then ouputs it , but i'm stuck big style
> i am oversampling by 4 times the data rate ie 32Khz and what i want to do is
> cut out bits i don't want , the theory is if i oversample by 4 times what
> normally be a 1 because its oversampled it would be 1111 and the same for 0 .
> but how do i put this in my code and if there is a error condition like 1011
> chances are its 1 one is there a efficiant way to do this ?
--- I removed the code ---
I'm not sure exactly what you are trying to do...,
but it sounds like you want to use the PIC as a kind of filter. In other
words, you want to remove glitches from a signal. Assuming this is what
you want I have a few suggestions. If this is not what you want, well...
maybe someone will find this useful.
1) If you are using the PIC16C6X + family, move your input signal from PORTA<0>
to one of the other inputs with schmitt trigger input buffers (e.g. PORTA<5>).
However, from the context of your assembly program I assume your using the 5X
family (MicroChip recommends against the use of the "OPTION" instruction on all
but the 5x family). In which case, you can add an external buffer such as a
74HC14 or maybe someone has a creative solution using the RTCC input.
At any rate, the schmitt trigger is more immune to noise glitches.
2) Think for second about how a UART works. A UART divides a relatively high
frequency clock to typically 16 or 32 times the data baud rate. This clock
two state machines: the first is a filter that will remove glitches from the
input, the second is a phase locked loop that synchronizes itself to the edges
produced by the filter. There are obvious variations from UART to UART, and I'm
also glossing over most of UART's details. The point I'm trying to make is that
the UART might give us some insight on a good way to "clean up" a signal.
First, note that the divided down clock provides equally spaced samples. Equal
spacing means the filter's behavior will be consistant. Second, the oversampling
provides some flexibility on how to design the filter.
The code you posted does not have equally spaced samples. The "goto loop0" at
very bottom introduces two extra instruction cycles when the data changes from a
"1" to a "0". This is easily remedied with two "NOPS" just before the LOOP1
Secondly, as you noted there is ambiguity associated with glitches, i.e. your
does no filtering.
O.K. I hacked my debounce algorithm to fix these two problems. The "new" routine
called "de_glitch". Once called, it continuously loops and samples PORTA<0>,
it, outputs the filtered data PORTA<1>. "Filtered" means that the input remained
quiescent for two consecutive samples. The loop time is constant at 11
cycles (12 if you add the CLRWDT). Assuming you want four samples per data bit,
the relationship between the PIC clock rate and the data rate is
data rate <= Fosc /(4 * 11)
e.g. 9600 Baud data would require 44 * 9600 = 422kHz, not exactly a standard
filter_mem EQU 0x20
last EQU filter_mem
current_state EQU filter_mem+1
ORG 0 ;Reset Vector
ORG 4 ;Interrupt Vector
BSF STATUS,RP0 ;Point to BANK 1
BSF TRISA & 0x7f, 0 ;Bit 0 is an input
BCF TRISA & 0x7f, 1 ;Bit 1 is an output
BCF STATUS,RP0 ;Point to BANK 0
; The purpose of this routine is to continuously sample porta<0> and after
;filtering, write the sample to porta<1>. Filtering in this context means
;to ignore transitions that are of the duration of a single sample. In this
;sense, the filter is low-pass and tends to remove glitches from the input.
;Like any filter, there is an associated delay; one sample in this case.
;Here are some typical input/output relationships:
; IN 0000011111110000000011110100000001011111111101010101011111
; OUT x000001111111000000001111110000000001111111111111111111111
;The algorithm is:
; 1) sample the input. The input is sampled every 11 instruction cycles
; 2) If there is no difference between this sample and the last one then
; 2a) Set the output (current_value) equal to the current sample
; 2b) The output remains unchanged
; 3) Save the current sample as the "last" sample (for next time through)
; 4) Goto 1
; Memory used
; current_state, last
L1 BCF PORTA,1 ;Clear the current state
L2 MOVF PORTA,W ;Get the current sample (PORTA<0>)
XORWF last,W ;W = (last sample) ^ (current sample) = diff
; note that W contains the boolean difference
; between the last sample and this sample.
XORWF last,F ;last = last ^ current ^ last = current
;The "current" sample has been saved as the
;Note the boolean identity: A^B^A = B
;Update the current state according to the boolean equation
; current_state = (current_state & diff) | (current_sample & diff')
;In english, the current_state remains unchanged if "diff" is true.
;if diff is false then current_state becomes the same as the current_sample
;(which just so happens to be saved already as the last sample).
ANDWF current_state,F ;current_state &= diff
SUBLW 0xff ;W = diff' (SUBLW 0xff complements W)
ANDWF last,W ;W = last & diff' (note last == current sample)
IORWF current_state,F ;boolean equation has been implemented
goto L1 ;Need to clear the output
BSF PORTA,1 ;Current state is high
Hi scott your the only one to reply to my plea for help so far , the code
i am trying to decode it manchester encoded and the clock and data rate are
both the same i had thought of another way of doing it but how this would work
out in code is a bit beyond me at the moment but learning fast! What i could
do is time the length of the 1 and then 0 and have a routine that would output
valid data when the timeing of the 1 and 0's match ?? Also i thought it was
worth the mention i only have a 16c54 and 16c84 programmer at the moment but
Use John Morissons PIC ICE SYSTEM anyone else use it ??
Does anyone have any code examples of timeing a TTL input / ouput so i could
time the length of the 1 and 0 and output a de -manchesterised signal ???
What i'm doing to try and learn more is use the ICE system and on the output
of the Ice i use a scope to see the difference in 1 and 0 output against the
running code ....
Paul Bulmer wrote:
> Hi scott your the only one to reply to my plea for help so far , the code
> i am trying to decode it manchester encoded and the clock and data rate are
> both the same i had thought of another way of doing it but how this would work
> out in code is a bit beyond me at the moment but learning fast! What i could
> do is time the length of the 1 and then 0 and have a routine that would output
> valid data when the timeing of the 1 and 0's match ?? Also i thought it was
> worth the mention i only have a 16c54 and 16c84 programmer at the moment but
> Use John Morissons PIC ICE SYSTEM anyone else use it ??
> Does anyone have any code examples of timeing a TTL input / ouput so i could
> time the length of the 1 and 0 and output a de -manchesterised signal ???
> What i'm doing to try and learn more is use the ICE system and on the output
> of the Ice i use a scope to see the difference in 1 and 0 output against the
> running code ....
O.K., you want to decode Manchester encoded data. For everyone else's sake,
Manchester encoding combines the clock and data of (typically) synchronous
data into one serial data stream. The combination is simply an exclusive -
machester data = NRZ data ^ (NRZ clock)'
NRZ data == Non-Return to Zero data. A fancy way of saying there is no
encoding i.e. a logic 1 is +5 volts and a logic 0 is 0 volts.
NRZ clock == A clock whose rising edge occurs in the middle of each NRZ data
^ == exclusive or operator
( )' == The boolean complement operator
Now, back to your problem. You wish to "bit-bang" the serial
data stream and decode the Manchester data. Typically, a bit-banging
algorithm goes as follows.
1) Synchronize to the input data stream by hunting for an edge. For NRZ
data, you would hunt for the falling edge of the start bit. For Manchester
data, you will continuously have edges. This could be either good or bad
2) Wait for one half bit time. Presumably, the data is "cleanest" in the
middle of a bit.
3) Wait for one whole bit time.
4) Sample the input data. Note that this sample will occur in the middle
of a bit.
5) Decode the data bit, i.e. convert from Manchester to NRZ.
6) go to step 3.
The "continuous edges" of Manchester-encoded data dilemmma/panacea depends
on your computing resources. If you have to use the PIC16C54 with a 32kHz
crystal, your capabilities are extremely limited. Instruction cycles are
around 125 usec. However, you need at least two cycles to acquire one sample.
Yet a moderate data rate of 9600 baud (NRZ) has a bit time of about 100 usec.
I think you see the picture.
On the other hand, if you can increase the frequency, then it is possible to
continuously re-synchronize to the data. This will allow you to accurately
sample the middle of the data bits, and perhaps saving you the burden of
having to filter the data.
I'm sure (almost that is) that this message will excite someone to post
their "bit-banging" code, or at least point you to a Microchip ap-note. I would
post mine, but I ain't got none (for the PIC that is).
> The "continuous edges" of Manchester-encoded data dilemmma/panacea depends
> on your computing resources. If you have to use the PIC16C54 with a 32kHz
> crystal, your capabilities are extremely limited. Instruction cycles are
> around 125 usec. However, you need at least two cycles to acquire one sample.
> Yet a moderate data rate of 9600 baud (NRZ) has a bit time of about 100 usec.
> I think you see the picture.
Actually, it does pose some interesting handicaps and possibilities depending
upon what other things are going on in the system. For example, if you are
writing a "spin-loop"-based system (check for data; if no data, run a polling
cycle; repeat) your system can run just fine with a main loop that takes up
to 1/2 bit time (if the bit rate is not known) or just under 1 full bit time
(if the bit rate is known). You simply call the main loop routine after each
edge, knowing that you won't need to poll the line until the next edge (if
the communications line is dead, you should probably time out and just call
the main loop periodically, but hopefully there should be a few "idle" bits
sent before any data is needed).
Scotts posts on manchester decodeing are most helpful and i would like to thank
him for his time and effort although it didn't spark anything from you pic
experts i'm sure it wil be of great reference for those who save ideas...