Gathering usefull ADC info
I don't seem to be approaching this in the right way, but I need to gather the 8 bits from my ADC and then convert that binary output into a usefull decimal value that I can use in my code later.
This is generally what most of my attempts have looked like...
The processor hangs and leaves Pin 14 high indefinately.......except when the counter wraps and the scope detects a small blip when this happens.
How do I go about gathering these 8 bits from the ADC, and how do I get it from binary to decimal.
Thank you.
This is generally what most of my attempts have looked like...
CON
'Set clock speed to 80 MHz
_clkmode = xtal1 + pll16x 'Sets the clock speed to 80 MHz using a times 16 multiplier
_xinfreq = 5_000_000 'Crystal speed: 5 MHz
VAR
Word ADCBITS
PUB start
Dira[noparse][[/noparse]27]~ 'Data Out
Dira[noparse][[/noparse]25]~~ 'CLK
Dira[noparse][[/noparse]26]~~ 'CS
Repeat
Outa[noparse][[/noparse]26]~~
Waitcnt(1000 + cnt)
Outa[noparse][[/noparse]26]~
Repeat 8
Outa[noparse][[/noparse]25]~~
Outa[noparse][[/noparse]25]~
ADCBITS := ADCBITS * 10
If Ina[noparse][[/noparse]27]==1
ADCBITS := ADCBITS + 1
Else
ADCBITS := ADCBITS + 0
Dira[noparse][[/noparse]14]~~
Outa[noparse][[/noparse]14]~~
Waitcnt(ADCBITS + cnt)
Outa[noparse][[/noparse]14]~
Waitcnt(ADCBITS + cnt)
The processor hangs and leaves Pin 14 high indefinately.......except when the counter wraps and the scope detects a small blip when this happens.
How do I go about gathering these 8 bits from the ADC, and how do I get it from binary to decimal.
Thank you.

Comments
A waitcnt with too small a value (you have about 10) certainly will wait for more than 50 seconds. That doesn't work in SPIN. Minimum ist something like 300? Forgot that number.
Also "converting to decimal" is ... um ... a quite strange wish.
Your CPU works with binaries so I'd feed it with binaries. And that's what you get from the ADC.
Also, using ADCBits for collecting data and for a waitcnt and multiplying it with 10 doesn't make any sense to me.
You have to shift the binary value from the ADC into ADCBits with "<<" or multiply by 2.
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
But when I wrote that I had hoped it would take the value of pin 27 (1 or 0) and add it to the variable ADCBITS. Then before it checks the next bit multiplies it by 10 to shift ADCBITS one zero to the right for the next bit (1 or 0). I hoped it would continue this 8 times until the variable ADCBITS would hopefully look something like this... 0010011 or similar depending on where the input voltage was and the output binary code that the ADC produced based on that voltage.
I however, do not know how to use something like 0010011, but I do know how to use something like 6225 or similar in my code. I need to get a value out of this ADC that I can use. When I use the command "Waitcnt" I write something like "320000" , not 0010011 or anything like that. That's why I need a decimal value instead of the binary value. I don't know what to do with the 1's and 0's in terms of actually using them. And I can't even gather anything usefull in terms of relative value by looking at them either other than 00000000 is less than 11111111.
I just need to read in an analog voltage and use the variance in that voltage to effect things in the code. I thought the ADC would do this. I had little trouble with it on the BS2PX, but with the prop things like this are a whole new ballgame it seems.
Any help is appreciated.
I have mixed feelings with requests like yours - you will understand that in a year or so after you have improved your programming skills... I have often been asked to not answer to such requests... But I see that you have run into problems, so help is indicated...
(a) You should generally debug your program, that is find a way to DISPLAY results and flag dubious situations. The Propeller is perfectly equipped for this: You can use Ariba's PropTerminal.
(b) As long as you do not tell us what ADC you use, there can be a host of bugs in the way you handle the strobing....
(c) Avoid overcomplex structures: Many persons here will NOT answer a request containing things as:
If Ina[noparse][[/noparse] 27 ]==1 ADCBITS := ADCBITS + 1 Else ADCBITS := ADCBITS + 0CAn you see that it is the same as
?
(d) Well, what you want to accomplish has been identified by Nick already.
It's:
rather than multiply it by 10. It however depends on the direction MSB or LSB first of the data from the ADC (see
(b))
Post Edited (deSilva) : 12/19/2007 3:35:51 PM GMT
I am sorry that I did not list the model of the ADC, it didn't even occur to me. It is National Semiconductor.
JR65RD
ADC0831CCN
And I had no idea how to increment the ADCBITS variable so that all of the bits would end up in-line, and the only thing that came to mind was to multiply by ten.
I would love to have a debug terminal so I could see what these variables were doing, but I am afraid that getting one up and running is also beyond my ability. I am simply low on the tools needed with the propeller. The stamp series takes care of many of these things for you, and I am now having to learn how to do them myself.
But, if I did get a variable named ADCBITS, and it did contain all 8 bits in-line... How do I use that? I appologize, but I honestly have no idea how to use that? My mind only seems to work in terms of numbers like 5, where when I add 1 to it I get 6. Can someone possibly point me to something where I can read about how the binary code works? I honestly couldn't even count using that at this point.
Does it make no sense to convert this value to a decimal value for use in my other code? Say, instead of getting a binary value in the range 00000000 - 11111111 I could instead get a value in the range 0 - 255? Is that not the way to do it? I honestly do not know. I had only hoped to be able to get a whole number out of this at some point, not binary code.
And thanks for any help. I know I am totally lost and ignorant to this right now.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Mosquito: An animal which buzzes in your ear and never stops. He may byte you, he may nibble you, but you will know you were bit.
·A good engineer borrows from others, a great engineer steals everything outright!!
Binary numbers are even much simpler. They only have "0" and "1".
You *HAVE* to read something about binary numbers, or you'll completely fail with tasks like these!
> Does it make no sense to convert this value to a decimal value for use in my other code?
No, not at all. The processor is working with binaries. When you write something like y:= 5 +10, the "5" and the "10" are converted to binaries before the propeller sees them.
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
I personally don't see anything wrong with the If-Else form and would argue it is actually clearer than the second in terms of describing what the requirement is although the second is better in achieving that functionality.
Any wrong only really arises because the Propeller Tool is not clever enough to convert both forms into identical object code. In that respect the if-else is far less efficient and wasteful.
If people will not answer questions simply because they don't like the way something is coded or the chosen 'house style' does not match their own then I think they are being ridiculously snobbish, but everyone has a right to be that way if they are so inclined.
Potatoehead had prepared a nice introduction where the first chapters contain just information about binary numbers and how to manipulate them, if I remember correctly: http://forums.parallax.com/showthread.php?p=668559
Have a look at this here obex.parallax.com/objects/209/ It will show you exactly what to do - 90% of this you have already accomplished yourself.
And: Do download Ariba's PropTerminal and use it! It is extremely simple, and will be of extreme help to you.
Never mind, I see that CharileII has been here longer than me.
Post Edited (Fred Hawkins) : 12/19/2007 6:33:13 PM GMT
I have looked but I cannot find the code by Ariba called PropTerminal for some reason. Is it in the "Propeller object exchange" ?
I think I will drop back here and figure out the hyperterminal first so that I can then wade my way through reading the ADC when I can view the variables in realtime. Not knowing what I'm getting on the variable is leaving me blind here.
Where can I get the "PropTerminal" code at? I would be very interested in getting started on setting it up because that would be a very powerful tool right now.
Thanks.
CharlieII, ariba's term is here: http://forums.parallax.com/showthread.php?p=649540
Post Edited (Fred Hawkins) : 12/19/2007 6:39:38 PM GMT
http://forums.parallax.com/showthread.php?p=649540
Start using the PC_Interface_Demo.spin
Note you have to configure the COM-Port... When in doubt which port, Press F7 in the PropellerTool.
What is supposed to happen? Or what have I done wrong because nothing happens at all, except that it is loaded into the propeller. Is this supposed to bring up a debug screen?
How does this work? I have yet to download anything, and I mean anything, that can be loaded to the propeller that will actually do something. It seems that these objects are meant to be pieces of a larger puzzle that I am unaware of possibly.
Very little of what has been mentioned here makes any sense to me whatsoever.
Why is it that if I load up one of the objects I cannot even compile it? The "PC_Interface_Demo" was the first one that has even compiled itself.
And I realize that I don't know up from down at this point, but I can't figure out which is which unless I ask someone who knows.
What a waste of precious lines!
ACDBITS += INA[noparse][[/noparse] 27 ] + 0 * (Dira[noparse][[/noparse]14]~~ + Outa[noparse][[/noparse]14]~~)
Nick, no APL
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
Which propeller product are you using (i.e. protoboard, demoboard, etc.)? Do you have the VGA or TV-out capability built-in? It might be a lot easier for you to debug using one of those methods right now rather than get the PropTerminal configured. If you pass some data to VGA_Text you can display it with the different formatters like dec, bin and hex. The demo programs like VGA_Text_Demo are a great starting point for this - read over the sample code and then re-write it to display what you want. I think that will go a long way towards alleviating some of your confusion about data and how it's stored / displayed.
Mike
congratulations that you could start the PC-Interface_Demo.
This SPIN code shows you many of the features you later can use:
Printing text or numbers in different formats, checking input from the PC keyboard, and even drawing some ver simple graphics on the PC screen.
This has many merrits over using TV or VGA, or PS/2 devices for debugging.
However you also need a program on the PC: This is PropTerminal.exe, also containes in the zip. Just start it!
It will try to contact the Propeller through the USB-Interface.
For this is has to know the COM port number which is easy to configure.
And - of course - it needs the PC_Interface_Demo, or your own program, using the PC_Interface.spin
Indeed it is not a matter of style (and was never addressed as such by me) but a matter of understanding of what is going on.
Nick gave an example of someone who understands what is going on, but he chose "bad style".
A common problem you encounter with requirements engineering is the missing awareness for appropriate "granularity". Many unexperienced "requirements engineers" overdo it by striving for "atomic requirements". Such a set of requirements is close to useless except for contractual disputes...
In this case you want to add the "value" of the ADC data, i.e.:
theWhole += theValue(theData)
It quickly turns out that "the value" is exactly the "theData", so no transformation is needed at all.
What you DO NOT WANT is to do something in one case and something else in the other case. A IF/THEN/ELSE construction might be needed to determine "theValue", but not from the point of "requirement" but from the point of "implementation" only.
Post Edited (deSilva) : 12/19/2007 9:53:23 PM GMT
> Nick gave an example of someone who understands what is going on, but he chose "bad style".
The subject is style, patterns, synonyms. It takes some time to learn them.
It only can be done by reading code of others and trying to understand it.
Yes, my example was really and intentionally bad. But even bad examples have something to learn from. Here: Write "dense" code, but don't obfuscate it.
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
I have attached a program for the ADC0831· or TLC0831.
This code was a straight translation of some excisting Basic STamp 1 code.
There are better way's to do it .. using Martin Hebel BS2. functions· object you can
use the shiftin and out fucntions..
Study the attached program and you get the drift of how essentially these shiftin
instructions operate..
We have also ported this exact same program to PropAsm ...
Also very esy to do .. but only if you need wicked conversion rates..
The program is commented hopefull well enough for you to study and understand it.
cheers··· Ron Nollet·· Melbourne Australia
What exactly is the above line doing to the variable "analog"?
And when the above line here is compiled, then executed, does it have this effect on the variable "analog"... 00000000 ? And how does the analog << 1 line effect that? If I knew how these memory spaces were filled up and from which end and such, I think I would have a better handle on this.
Does the << simply move over one bit to the left to "write" in the next bit? Is this the way to increment your way across the 8 bits I suppose?
Is it filling in the bits of analog from right to left then?
In the meantime, I got the "PC_Interface_Demo" to load up on the PropTerminal and I'm going to see if I can figure out a way to display a variable on that screen.
Thanks for the help so far.
Post Edited (CharlieII) : 12/20/2007 12:01:20 AM GMT
The PC_Interface_Demo from PropTerminal is a little bit complicated to begin.
Here is a simpler code that may help you, also to understand the binary and decimal relations:
{{ Single Step Demo }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ term : "PC_Interface" VAR long value PUB Main | k term.start(31,30) 'start the interface value := %00000101 'init value showval(value) 'and show in bin&dec repeat k := term.getkey 'wait for a keypress case k "l": value := value << 1 'l = shift left 1 bit "r": value := value >> 1 'r = shift right "s": value := value | 1 's = set Bit0 "a": value += 10 'add decimal 10 'add here your own commands showval(value) PRI showval(v) term.str(String("binary: ")) term.bin(v, 8) term.str(String(" = decimal: ")) term.dec(v) term.out(13) 'new lineJust copy this in the IDE, load it into the Propeller with F10. Then start PropTerminal and press a key. L, R,S and A are changes the value and shows the result.
Andy
I actually got the other demo working last night, and manipulated it to show only one variable in white in the center of the terminal screen.
From what I can gather, under the block "OBJ" you give some name to another program for reference, and you then place that program's file name in quotes like this...
Somename : "Filename"
Then whenever you want to run a chunk of code out of "Filename" you just say Somename.chunkofcode and it runs that routine out of "filename" .
I also noticed that I could add input variables to the routines that would also pass to the other program. Like, instead of running Somename.chunkofcode I could run Somename.chunckofcode(c) so that my new variable in my program could pass to the object and be manipulated there.
Only real problems I ran into were, it took an inordinate amount of time to execute the "object call?". I'm sure this has something to do with the fact that I was calling for a routine in one object (pc demo) that was then calling for another few out of yet another object (Pc interface).
Either way, I had an LED set to toggle on every cycle through the code reading the ADC, and at first it was only noticably blinking when you looked out of the corner of your eye (rods, not cones) and was running a pulsewidth of say 3 or 4 ms. Then after including the call to a routine within (Pc demo) that subsequently called for another routine within the object (Pc interface) it was taking two or three seconds to cycle and turn the light from on to off and another few seconds to turn it back on again. Painfully slow. What was my processor doing that whole time?
The second thing was that although I got the variable "analog" derived from the code thankfully offered to me by Ozstamp to output to the PropTerminal in both decimal and binary form, It was not dynamic. It seemed like it was running through the cycle correctly once, gathering the bits from the ADC and giving something like 10010011 or similar but then shortly thereafter it would change to 00000000 or 11111111 no matter where I turned the pot. And I did check out the pot for the 2 thousandth time, lol. It varies nicely from around .6 volts to 3.3ish volts. I had it set in the middle. And the ADC was referencing from 5v so I shouldn't ever see a 11111111 anyway.
Any ideas on that would be very much appreciated.
Also, I somehow managed to change my cursor in the propeller tool from the vertical line that is normally used to the old school horizontal blinking cursor. It is driving me insane, so if anyone knows what I did to toggle it to this thing I would really like to change it back
And thanks for the help.
CON _clkmode = xtal1 + pll16x '80MHZ quick runner.. _xinfreq = 5_000_000 '5 Mega HZ delay = 1_000_000 'longish delay sdlay = 5_000 'shorter delay CS = 26 'Chip select to ADC0831 chip CLK = 25 'Clock signal direct to ADC0831 chip DATA = 27 'Data from ADC0831 use series resistor 4.7K..10K OBJ Term : "Hyperterminal" VAR byte analog 'declared 1 global variable Byte New PUB a_dcon831 Dira[noparse][[/noparse]26]~~ Dira[noparse][[/noparse]25]~~ Dira[noparse][[/noparse]27]~ Dira[noparse][[/noparse]14]~~ outa[noparse][[/noparse]CS]~~ 'set output 0 ( CS signal) high waitcnt(8_000_000 + cnt) 'have a rest for 0.1 second New := %10010110 repeat 'pin26=CS pin25=clk ina27=data repeat 1 'run thru this first section just once analog := 0 'make sure analog byte is at zero outa[noparse][[/noparse]CS]~ 'set cs low waitcnt(sdlay + cnt) 'wait outa[noparse][[/noparse]CLK]~~ 'set (pulse) clk once waitcnt(cnt + delay) 'wait outa[noparse][[/noparse]CLK]~ 'reset clk to low repeat 8 'loop thru this second section 8 times analog := analog << 1 'shift data to the left 1 bit waitcnt(cnt + sdlay) 'wait outa[noparse][[/noparse]CLK]~~ 'set clock high waitcnt(cnt + sdlay) 'wait outa[noparse][[/noparse]CLK]~ 'reset clock to low analog := analog + ina[noparse][[/noparse]DATA] 'gather data into byte register analog waitcnt(cnt + sdlay) 'wait ! Outa[noparse][[/noparse]14] Term.Main(analog)CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 #0, WHITE,CYAN,RED,PINK,BLUE,GREEN,YELLOW,GRAY 'Standard colors OBJ term : "PC_Interface(Short)" VAR Byte Random PUB Main(c) | b Random := %10000000 'start the interface term.start(31,30) repeat while term.abs_x == 0 'wait for PropTerminal.exe started setpos(0,6) term.setcol(WHITE) term.bin(c,8) waitcnt(clkfreq/25 + cnt) 'Loop all 1/25 seconds PRI setpos(px, py) term.out(10) term.out(px) term.out(11) term.out(py)CON BAUDRATE = 115200 'customize if necessary SERINVERSE = 0 'RX+TX pins MSY_INVERS = 0 'Mouse Y direction STARTDELAY = 2 'seconds (0=off) VAR long cog, skey, kstat long col, row, color, flag long mousex, mousey long rx_head '9 contiguous longs for SerialDriver long rx_tail long tx_head long tx_tail long tx_pin long rx_pin long rx_mode long bit_ticks long buffer_ptr long oldx, oldy, oldz 'must be followed by parameters (10 contiguous longs) long par_x 'absolute x read-only (7 contiguous longs) long par_y 'absolute y read-only long par_z 'absolute z read-only long par_buttons 'button states read-only long par_present 'mouse present read-only byte rx_buffer[noparse][[/noparse]16] 'receive buffer (4 longs) byte tx_buffer[noparse][[/noparse]256] 'txbuffer (64 longs) PUB start(rxpin, txpin) : okay '' Start SerialDriver '' returns false if no cog available '' par_buttons := 0 flag := 0 stop if STARTDELAY waitcnt(clkfreq*STARTDELAY + cnt) longfill(@rx_head, 0, 4) tx_pin := txpin rx_pin := rxpin rx_mode := SERINVERSE bit_ticks := clkfreq / BAUDRATE buffer_ptr := @rx_buffer okay := cog := cognew(@entry, @rx_head) + 1 PUB stop '' Stop SerialDriver - frees a cog if cog cogstop(cog~ - 1) longfill(@rx_head, 0, 6) ' -- Mouse -- PUB present : type '' Check if interface present '' returns mouse type: 1 = two-button or three-button mouse '' type := 1 'two-button or three-button mouse PRI rxcheck : rxbyte ' Check if byte received (never waits) ' returns -1 if no byte received, $00..$FF if byte rxbyte-- if rx_tail <> rx_head rxbyte := rx_buffer[noparse][[/noparse]rx_tail] rx_tail := (rx_tail + 1) & $F ' -- Display -- PUB dec(value) | i '' Print a decimal number if value < 0 -value out("-") i := 1_000_000_000 repeat 10 if value => i out(value / i + "0") value //= i result~~ elseif result or i == 1 out("0") i /= 10 PUB bin(value, digits) '' Print a binary number value <<= 32 - digits repeat digits out((value <-= 1) & 1 + "0") PUB out(c) | i, k '' Output a character '' '' $00 = clear screen '' $01 = home '' $05 = Grafik (mode,x,y follows) '' $08 = backspace '' $09 = tab (8 spaces per) '' $0A = set X position (X follows) '' $0B = set Y position (Y follows) '' $0C = set color (color follows) '' $0D = return '' others = printable characters print(c) PRI print(c) '' Send byte (may wait for room in buffer) repeat until (tx_tail <> (tx_head + 1) & $0FF) tx_buffer[noparse][[/noparse]tx_head] := c tx_head := (tx_head + 1) & $0FF ' -- SimpleDraw -- PUB cls '' Clear screen (to black) print(0) PUB abs_x : x '' Get absolute-x x := par_x + (par_buttons>>5 & 1) PUB locate(gx, gy) '' set drawing position for characters '' will be quantized to 40x13 raster out(10) out(gx/8) out(11) out(gy/17) PUB setcol(c) '' set drawing color 0..7 print(12) print(c) DAT '*********************************** '* Assembly language serial driver * full duplex with mouse decoding '*********************************** org ' ' Entry ' entry mov t1,par 'get structure address add t1,#4 << 2 'skip past heads and tails rdlong t2,t1 'get tx_pin mov txmask,#1 shl txmask,t2 add t1,#4 rdlong t2,t1 'get rx_pin mov rxmask,#1 shl rxmask,t2 add t1,#4 'get rx_mode rdlong rxtxmode,t1 add t1,#4 'get bit_ticks rdlong bitticks,t1 add t1,#4 'get buffer_ptr rdlong rxbuff,t1 mov txbuff,rxbuff add txbuff,#16 add t1,#6 << 2 'set par_y pointer mov pz,t1 mov pb,t1 test rxtxmode,#%100 wz 'init tx pin according to mode test rxtxmode,#%010 wc if_z_ne_c or outa,txmask if_z or dira,txmask mov txcode,#transmit 'initialize ping-pong multitasking ' ' Receive ' receive jmpret rxcode,txcode 'run a chunk of transmit code, then return test rxtxmode,#%001 wz 'wait for start bit on rx pin test rxmask,ina wc if_z_eq_c jmp #receive mov rxbits,#9 'ready to receive byte mov rxcnt,bitticks shr rxcnt,#1 add rxcnt,cnt :bit add rxcnt,bitticks 'ready next bit period :wait jmpret rxcode,txcode 'run a chuck of transmit code, then return mov t1,rxcnt 'check if bit receive period done sub t1,cnt cmps t1,#0 wc if_nc jmp #:wait test rxmask,ina wc 'receive bit on rx pin rcr rxdata,#1 djnz rxbits,#:bit shr rxdata,#32-9 'justify and trim received byte and rxdata,#$FF test rxtxmode,#%001 wz 'if rx inverted, invert byte if_nz xor rxdata,#$FF cmp pb,pz wz 'mouse receiving? if_nz jmp #getMsPar cmp rxdata,#5 wz 'new mouse Event? if_nz jmp #toRxBuff 'no: write in buffer add pb,#1 << 2 'start receiving pointer to par_button jmp #receive getMsPar cmp pb,pz wz,wc if_a mov cmd,rxdata if_a and cmd,#$80 if_b shl rxdata,#1 'x,y *2 tjnz cmd,#nomouse wrlong rxdata,pb 'write par nomouse if_a sub pb,#4 << 2 'pointer from par_button to par_x add pb,#1 << 2 'pointer to next par until par_z jmp #receive toRxBuff rdlong t2,par 'save received byte and inc head add t2,rxbuff wrbyte rxdata,t2 sub t2,rxbuff add t2,#1 and t2,#$0F wrlong t2,par jmp #receive ' ' Transmit ' transmit jmpret txcode,rxcode 'run a chunk of receive code, then return mov t1,par 'check for head <> tail add t1,#2 << 2 rdlong t2,t1 add t1,#1 << 2 rdlong t3,t1 cmp t2,t3 wz if_z jmp #transmit add t3,txbuff 'get byte and inc tail rdbyte txdata,t3 sub t3,txbuff add t3,#1 and t3,#$0FF wrlong t3,t1 or txdata,#$100 'ready byte to transmit shl txdata,#2 or txdata,#1 mov txbits,#11 mov txcnt,cnt :bit test rxtxmode,#%100 wz 'output bit on tx pin according to mode test rxtxmode,#%010 wc if_z_and_c xor txdata,#1 shr txdata,#1 wc if_z muxc outa,txmask if_nz muxnc dira,txmask add txcnt,bitticks 'ready next cnt :wait jmpret txcode,rxcode 'run a chunk of receive code, then return mov t1,txcnt 'check if bit transmit period done sub t1,cnt cmps t1,#0 wc if_nc jmp #:wait djnz txbits,#:bit 'another bit to transmit? jmp #transmit 'byte done, transmit next byte ' ' Uninitialized data ' t1 res 1 t2 res 1 t3 res 1 pz res 1 pb res 1 rxtxmode res 1 bitticks res 1 rxmask res 1 rxbuff res 1 rxdata res 1 rxbits res 1 rxcnt res 1 rxcode res 1 cmd res 1 txmask res 1 txdata res 1 txbuff res 1 txbits res 1 txcnt res 1 txcode res 1