I take that by this you mean that the delays provided by the instructions execution themselves are never long enough. (including the time your finger takes).
The reference was very interesting but if I had to provide a 1/6 second delay to cover all cases, that did seem onerous.
Typically you can get by with delay of 10 mS to verify the press/release for clean debounce. Most setups I have seen will see a transition, delay 10 ms or so, recheck to see if the state is still the same and accept that a real transition has occured. Some will do this longer as a "did you really mean to press the switch?" test. And yet even longer checks as whe setting values once per press, slow count up/down for short hold press and fast count up/down for longer press and holds.
Onerous would be trying to chase down mystery behaviors due to poor/missing debounce methods either electronic or in sofgtware. Debounce the UI. Cost $0.00 in software. In hardware a few cents. Continued sanity, priceless.
[FONT=Arial, sans-serif]Here is a bit of code I developed to look at what was going on in the Propeller as I shifted the data left and right and reversed bits etc. As set up now, it lets to look at the data at three locations in the program. It can be expanded to whatever you like.[/FONT]
[FONT=Arial, sans-serif]The data appears on the PST.[/FONT]
[FONT=Arial, sans-serif]As set up,the code takes the data in the third byte of a long and reverses the bits. All other bits are erased. Then one erased bit is set. I need to reverse the bits because as my LCD was hooked up to the Propeller, the pins were in the reverse order to what was required.[/FONT]
[FONT=Arial, sans-serif]It is also useful for looking at what the MUX instructions do.[/FONT]
[FONT=Arial, sans-serif]H[/FONT]
[FONT=Lucida Console, monospace][SIZE=2]{{ Program 017 PASM minimum PAR.spin[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]This program is a minimal implementation for two variables and PAR.[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]There are two Cogs in this program, one in SPIN and one in PASM[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Cog 1 in SPIN displays the variables on the console[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Cog 2 in PASM sets the variables [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Finds the location of PAR and moves it to mem1[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Then mem2 is set to mem1 +4. [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]The two variables are transferred to mem1 and mem2[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]and become available to the SPIN environment[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Loop.[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]}} [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]CON[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]_clkmode = xtal1 + pll16x[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]_xinfreq = 5_000_000[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]VAR[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]long eightlongs[3],shared[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]OBJ[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds: "FullDuplexSerial"[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]PUB FirstCog 'displays values on console[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.start(31,30,0,115200) 'start console at 115200 for debug output[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]cognew(@SecondCog, @eightlongs) 'start the second Cog in PASM [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]waitcnt(clkfreq/4+cnt) 'wait 1/4 for everything to stabilize.[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]repeat 'loop [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($1) 'home to 0,0[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") 'display first value[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($0d) 'new line [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs[1] [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'fds.tx($1) 'home to 0,0[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") 'display first value[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($0d) 'new line[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs[2] [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'fds.tx($1) 'home to 0,0[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first value [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") 'display first value[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($d) 'new line[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'fds.dec(eightlongs[1]) 'display second value [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]waitcnt(clkfreq/60+cnt) 'flicker free wait[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'************************************************************************************************ [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]DAT[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]org 0 'start at 0 location in the cog [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]SecondCog 'start point identification[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov mem1, par[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov mem2, mem1 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]add mem2, #4[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov mem3, mem2 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]add mem3, #4[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]loop call #start[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]jmp #loop[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Start[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov dira, setdira [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov timer, onesec '40 000 000[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]:loop djnz timer, #:loop [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov outa, databyte [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]wrlong outa, mem1[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov timer, onesec '40 000 000[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]:loop1 djnz timer, #:loop1[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov outa, databyte[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shl outa, #16 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shr outa, #24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shl outa, #8 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]ror outa, #8[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]rev outa, #0[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]ror outa, #16 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]wrlong outa, mem2 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov timer, onesec '40 000 000[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]:loop2 djnz timer, #:loop2 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]or outa, enablebit [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]wrlong outa, mem3 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Start_ret ret [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]dataByte long %00000000_00000000_1001_1110_00000000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]setdira long %00000000_00000111_00000000_0000000[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]SelectBit long %00000000_00000100_00000010_00000000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]ReadBit long %00000000_00000010_00000000_00000000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]EnableBit long %00000000_00000001_00000000_00000000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]onesec long 80_000_00[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mem1 res 1 'first address storage space[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mem2 res 1 'second address storage space[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mem3 res 1[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]timer res 1[/SIZE][/FONT]
@Harprit: Your recent code postings have lost their useful formatting. Simply copying the code into the prop tool isn't working anymore (extra column on the left side). This is not helping people evaluating your stuff.
Also, your timing loops are confusing. Relative to clkfreq the variable onesec holds the clock count for 1/10th of a second, the comment (40M) suggests 1/2 a second and the actual loop delays for 4/10th of a second. What is it going to be?
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
DAT
...
mov timer, onesec '40 000 000
:loop2 djnz timer, #:loop2
...
onesec long 80_000_00
I managed to burn out one of the pins on my propeller as I developed PASM and had one heck of a time figuring out why things would not work. Finally got it replaced so hope to move on now
However here is the revised code for the program I posted last time with proper commenting and formatting as requested by kuroneko and stephan. These guys keep me honest!
[FONT=Lucida Console, monospace][SIZE=2]{{ Program 017 PASM minimum PAR.spin[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]This program allow you to look at data manipulations on PST.[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]There are two Cogs in this program, one in SPIN and one in PASM[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Cog 1 in SPIN displays the data on the console[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Cog 2 in PASM sets the data and manupulates it[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Finds the location of PAR and moves it to mem1[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Then mem2 is set to mem1 +4. mem3 is set to mem1+8[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]The data is transferred to mem1, mem2 and mem3 where selected by user[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]and become available to the SPIN environment for display[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Loop.[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]}}[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]CON[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]_clkmode = xtal1 + pll16x[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]_xinfreq = 5_000_000[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]VAR[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]long eightlongs[3],shared[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]OBJ[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds: "FullDuplexSerial"[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]PUB FirstCog 'displays values on console[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.start(31,30,0,115200) 'start console at 115200 for debug output[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]cognew(@SecondCog, @eightlongs) 'start the second Cog in PASM [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]waitcnt(clkfreq/4+cnt) 'wait 1/4 for everything to stabilize.[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'shared:=eightlongs[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]repeat 'loop [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($1) 'home to 0,0[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display first byte[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display second byte [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display third byte[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) 'display fourth byte[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($0d) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs[1] 'repeat for second long[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'fds.tx($1) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($0d)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared:=eightlongs[2] 'repeat for third long[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'fds.tx($1) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shared->=24[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx("_") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.bin(shared,8)[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx(" ") [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]fds.tx($d) [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]waitcnt(clkfreq/60+cnt) 'flicker free wait[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'************************************************************************************************ [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]DAT[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]org 0 'start at 0 location in the cog [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]SecondCog 'start point identification[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov mem1, par 'find par address[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov mem2, mem1 'store it in mem2[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]add mem2, #4 'add 4 to mem1 to get second address[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov mem3, mem1 'store mem1 in mem3[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]add mem3, #8 'add 8 to mem1 to get third address[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]:loop call #start 'repeating loop[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]jmp #:loop '[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Start mov dira, setdira 'set diretion of DIRA [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov outa, databyte 'read data into outa[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]wrlong outa, mem1 'write result into mem1[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mov outa, databyte 'read data into outa[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shl outa, #16 'manupulate outa, shift left 16 to clear bits[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shr outa, #24 'manupulate outa, shift right 24 to celar bits[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]shl outa, #8 'manupulate outa, move back to original position [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]ror outa, #8 'manupulate outa, rotate to rightmost bits[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]rev outa, #0 'manupulate outa, reverse bits[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]ror outa, #16 'manupulate outa, rotate back to original bits[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]wrlong outa, mem2 'write result into mem[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]or outa, enablebit 'manupulate outa[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]wrlong outa, mem3 'write result into mem[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]Start_ret ret [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]'various constants I was using in my particular experiments[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]dataByte long %00000110_00011000_10001100_00111000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]setdira long %00001111_00000111_00001111_00111110[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]SelectBit long %00000000_00000100_00000010_00000000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]ReadBit long %00000000_00000010_00000000_00000000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]EnableBit long %00000000_00000001_00000000_00000000 [/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mem1 res 1 'first address storage space[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mem2 res 1 'second address storage space[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]mem3 res 1 'third address storage space[/SIZE][/FONT]
[FONT=Lucida Console, monospace][SIZE=2]timer res 1 'for delays[/SIZE][/FONT]
I am not sure I understand the reason for using outa for the manipulations of the data as written. It would seem better (not to mention safer for the prop and any attached devices) to create a location in memory to carry out the manipulations. The comment text says that the values resulting from the manipulations will be output via the PST, so any non-spr memory location in the cog could be used to hold/manipulate the data.
Currently there are no delays or stored results between the manipulations that are taking place, and thus no way to actually see the results at each step; only the end result in the terminal. Consider breaking this into two exercises, one using an internal memory location, and terminal output with additional shared locations to hold/display the intermediate results (with additional text labels indicating the output is for___), and a second using outa, long delays, and perhaps a VERY slow system clock rate so that the results of each manipulation can be seen in the leds. With the caveat the user understands this is only for seeing the effects of the instructions in question as a learning exercise, and not a normal use of outa in practice.
I am not sure I understand the reason for using outa for the manipulations of the data as written. It would seem better (not to mention safer for the prop and any attached devices) to create a location in memory to carry out the manipulations.
Seconded. Especially with an active dira setup. otherwise it doesn't really matter.
@Harprit: Wouldn't the following sequence be easier to understand?
and outx, mask ' isolate required byte
rev outx, #{32 -}8 ' reverse data
...
mask long $FF << 8
As always, you guys are of course right
My problem is that I am not conversant or comfortable with binary manipulations
I need to write that chapter now
This was suggested to me earlier but I did not take the advise as I should have.
Same ole same ole.
Will spend time on binary chapter in the next week or so to see if I cant learn something.
Needs getting done.
In my beginner primer, there are the very basics of binary manipulations. Get the truth tables and work them on paper. Every one of the Propeller bit operation instructions can be easily written down and processed on paper, one digit at a time, using the truth table. When you've done that, do some addition and subtraction exactly the same way.
And, or, not, xor, rol, ror, shl, shr, mux (for the prop, and is a cool instruction), rev (again for the prop), are the core of assembly language.
All of these are not very complex. It's the use cases and short cuts they bring to the table that makes all the difference in the world. Of those the "and, or, shx" instructions see near constant use. They are the ones that break longs into chunks that one can work with and make decisions on.
[FONT=Arial, sans-serif]Read the material on binary math.[/FONT]
[FONT=Arial, sans-serif]Here is what I found specially as being specially relevant to a beginner.[/FONT]
[FONT=Arial, sans-serif]Binary mathematics are not particularly difficult. However, you have to pay exquisite detail to what you are doing, because beginners do not have a good feel for things that happen as we shift registers to the left and to the right and reverse bits to manipulate the I/O to get the results that we are seeking. It is best to lay it out on paper as you go along.[/FONT]
[FONT=Arial, sans-serif]At the level that I am working, I am not quite ready to add the shorthand notation that adds even more power to binary manipulations. That absolutely has to come later as the comfort level increases.[/FONT]
[FONT=Arial, sans-serif]Here is the code for activating a 2 x 16 character liquid crystal display with a standard Hitachi controller. The code is not particularly long, which surprised me, and is not particularly complicated once one figures out what needs to be done. How long it takes to figure out what needs to be done is a whole other matter complicated by that fact that the Hitachi controller manual has some difficult phraseology in it and some of the help material on the internet has mistakes in it.[/FONT]
[FONT=Arial, sans-serif]I am still not comfortable with the routine that reads the busy bit. Experts please examine and advise. Seems to me that I should not need a delay in this routine.[/FONT]
CheckBusyBit
mov dira, inputs
or outa, readbit 'hi
andn outa, selectbit 'low
[COLOR="red"]:loop andn ina, enablebit [/COLOR]
mov del_time, delay160us
call #delay
[COLOR="red"]andn ina, busymask wz[/COLOR] 'or ' outa, enablebit
if_nz jmp #:loop
mov dira, setdira
CheckBusyBit_ret ret
The first line should probably work on outa given that enablebit is a mask which is previously set for output (i.e. inputs & enablebit <> 0) and not be part of the loop. As for the second line, ina needs to in the source slot to be useful here. I'd suggest:
test bits1000_0000, ina wz
under the assumption that busy means not equal zero. Later you might want to get rid of the loop and simply use:
waitpne bits1000_0000, bits1000_0000 ' wait for high/low transition
I still am not happy with my check busybit routine in 435. Could some one please rewrite the routine for me. As it is, it works but it seems to me that it should not need the delay.
A book I always planned on writing but never got around to was a college text on propeller/asm/spin to an extent.
A good thing to look at is a typical college text, how the architecture is approached for a controller, then getting into ASM and internal peripherals.
Please do not expect a college text from me. I have neither the expertise of the desire to do a college text. I hope this will be an introduction for hobbyists, no more no less. I hope it will be an adequate one. So a detailed discussion of the architecture etc does not seem to be in the cards.
I got to thinking that maybe a delay is needed to allow the
The delay is required because your loop never loops and the delay artificially - I'm guessing here - covers the timeout (that's why it seems to work). This is all because in this context
andn ina, busymask wz
will always set the Z flag. You're using ina in the wrong slot (src vs dst). That's why I suggested this earlier:
[FONT=Arial, sans-serif]But I still need the delay and the delay cannot be less[/FONT]
[FONT=Arial, sans-serif]I still cannot get it right in my mind.[/FONT]
As a matter of fact the only thing that matters is the delay.
Everything else can be deleted. So the BUSY flag is not being read
I have come to the conclusion that I am not reading the busy bit right.
I need someone to explain it in detail to me.
What should be set to what when etc. or a code listing would help.
Everything works fine with a delay but tha's not the goal here.
The data sheet says that the condition of the BB can be read by making the register select line low and the read/write bit high. The BB is available when the enable bit is made low.
After that if I read ina into temp can I isolate the bit from that? I am having difficulty with that. Apparently I am doing something wrong.
I still am not happy with my check busybit routine in 435. Could some one please rewrite the routine for me. As it is, it works but it seems to me that it should not need the delay.
I haven't finished porting my [ working ] Spin LCD driver to PASM, but this is the port of the code that waits for the busy flag to clear -- perhaps it will help you.
Here's the working Spin routine:
pub waitbusy | addr
'' Reads busy flag and cursor address
'' -- returns cursor address when busy flag has cleared
dira[db7..db4] := %0000 ' make buss pins inputs
outa[rs] := 0 ' command mode
outa[rw] := 1 ' read
repeat
outa[e] := 1 ' request bf + high nib
addr := ina[db7..db4] << 4 ' bf + high nib of address
outa[e] := 0 ' finish nib read
outa[e] := 1 ' request low nibble
addr |= ina[db7..db4] ' low nib of address
outa[e] := 0
while (addr & %1000_0000) ' check busy flag
return addr
And here's my PASM conversion:
' waits for busy flag to clear
' -- leaves cursor address in "crsrpos"
wait_busy andn dira, bussmask ' make buss pins inputs
andn outa, rsmask ' low (command)
or outa, rwmask ' high (read)
:loop or outa, emask ' e pin high
mov delay, #1 ' 1us delay
call #us_delay
mov tmp1, ina ' get bf + high bits of address
and tmp1, bussmask ' mask off non-buss pins
shr tmp1, db4pin ' align lsb
shl tmp1, #4 ' move to high nib position
mov crsrpos, tmp1 ' copy to result
andn outa, emask ' e pin low
mov delay, #1 ' 1us delay
call #us_delay
or outa, emask ' e pin high
mov delay, #1 ' 1us delay
call #us_delay
mov tmp1, ina ' get low nib of address
and tmp1, bussmask
shr tmp1, db4pin
or crsrpos, tmp1 ' add low nib
andn outa, emask ' e pin low
mov delay, #1 ' 1us delay
call #us_delay
test crsrpos, BIT7 wc ' check busy flag
if_c jmp #:loop ' wait until busy clears
wait_busy_ret ret
When the object is finished and testing I'll post in ObEx.
The website is german but the manual is in english.
With this tool you can single-step through PASM-code and lookup the value of each long in the COG-RAM.
very helpful for analysing what is going on.
keep the questions coming
best regards
Stefan
if using chrome when you goto your link up top near the address bar, google asks you if you want to translate the page from German. Does a pretty good job. I use chrome to make sense of Chinese/Taiwan/Japan web pages..
I still consider myself something of a noob with the propeller, though I already had experience with assembly in other micros (SX28, 8051, PIC16) when I started, though that also gave me some preconceptions to deal with on the prop. The issues that I had the most trouble wrapping my mind around were working without interrupts, calling subroutines without having a stack to push or pop, literals being limited to less than the full value of the register--having to store a constant value in a variable if it exceeds nine bits, and figuring out how the prop handles indirect addressing through self-modifying code, and memory management between the hub and the cogs. The octothorpe # still manages to bite me on the butt occasionally.
Reading through this thread has also shown me a few tricks that I missed, so it's been a help for me already. One concern I have is your reliance on pre-compiled objects, specifically the FullDuplexSerial object. It's a wonderful object, no doubt, but I vastly prefer building my own objects so I know exactly how it works, and a UART is a really simple routine, good for a beginner, if you don't try to make it too fancy right away.
I go through the same basic routines whenever I pick up a new microcontroller; start be flashing a LED, flashing at a calculated frequency, building a binary LED counter, a ring counter, etc, just to get a feel for manipulating bits. Next I'll try reading pins, measuring a RC circuit and lighting LEDs depending on the time it takes to charge. After that it's usually a UART transmitter (having an o'scope admittedly does make this easier), and once the UART transmitter is displaying "A"s I'll create a string lookup routine to display messages, then a HEX to ASCII routine so I can display a counter, and a HEX to BCD to ASCII routine to see the counters in decimal. Then I get into stuff like a SPI driver for reading an ADC chip, I2C for reading and writing to the EEPROM, and parallel LCD drivers.
And on that note, here's the guts of a routine I managed to whip up yesterday, inspired by this thread. Hopefully the formatting doesn't get mangled again; it looks fine in preview.
{{Parallel LCD Driver
The LCD D4, D5, D6, D7 lines must be connected to sequential pins on prop in the same order
To execute an instruction (CLS, move cursor...):
load the instruction into LCD_Byte
jmpret Return_add,#LCD_Command
To display a character:
load the character into LCD_Byte
jmpret Return_add,#LCD_Text
}}
'-------------------------------------------------------------------------------
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
E_Pin = 19
RW_Pin = 18
RS_Pin = 17
D4_Pin = 20
D7_Pin = D4_Pin + 3
LCD_Offset = D4_Pin
'-------------------------------------------------------------------------------
PUB Main
cognew(@LCD_Init, 0)
'-------------------------------------------------------------------------------
DAT org
LCD_Init
or dira,LCD_mask
or dira,E_mask
or dira,RW_mask
or dira,RS_mask
mov LCD_Temp,#%0010 ' 4-bit mode
call #LCD_Send_Nibble
mov LCD_Byte,#%0010_1000 ' 4-bit mode, 2-line, 5x8 pixel characters
jmpret Return_add,#LCD_Command
mov LCD_Byte,#%0000_1100 ' Turn display on, no cursor
jmpret Return_add,#LCD_Command
mov LCD_Byte,#%0000_0001 ' Clear LCD
jmpret Return_add,#LCD_Command
'Display_Messages
mov LCD_Byte,#"H"
jmpret Return_add,#LCD_Text
mov LCD_Byte,#"i"
jmpret Return_add,#LCD_Text
mov LCD_Byte,#%1100_0000 ' Line 2 column 1
jmpret Return_add,#LCD_Command
mov LCD_Byte,#"W"
jmpret Return_add,#LCD_Text
mov LCD_Byte,#"o"
jmpret Return_add,#LCD_Text
mov LCD_Byte,#"l"
jmpret Return_add,#LCD_Text
mov LCD_Byte,#"d"
jmpret Return_add,#LCD_Text
mov LCD_Byte,#"!"
jmpret Return_add,#LCD_Text
jmp #$
'-------------------------------------------------------------------------------
LCD_Command
call #Check_Busy_Flag
' andn outa,RS_mask ' Send a command
jmp #LCD_Prepare_Byte
LCD_Text
call #Check_Busy_Flag
or outa,RS_mask ' Send text
LCD_Prepare_Byte
mov LCD_Temp,LCD_Byte ' Make a copy of the LCD_Byte
shr LCD_Temp,#4 ' Move high nibble into low nibble location
call #LCD_Send_Nibble ' Send fist nibble
mov LCD_Temp,LCD_Byte ' Reload LCD_Byte
call #LCD_Send_Nibble ' Send second nibble
jmp Return_add
LCD_Send_Nibble
and LCD_Temp,#$0F ' Preserve the low nibble
shl LCD_Temp,#LCD_offset ' Move the low nibble to the LCD pin locations
andn outa,LCD_mask ' Clear the LCD pins
or outa,LCD_Temp ' Update the LCD pins
call #Clock
LCD_Send_Nibble_ret ret
'-------------------------------------------------------------------------------
Check_Busy_Flag
andn dira,D7_mask ' Make D7 an input
andn outa,RS_mask ' Command mode
or outa,RW_mask ' Read mode
:Loop
call #Clock ' Clock the Enable line
test D7_mask,ina wz ' Read the busy flag
call #Clock ' Clock again for the low nibble
if_ne jmp #:Loop ' Loop until busy flag goes low
or dira,D7_mask ' Make D7 an output
andn outa,RW_mask ' Write mode
Check_Busy_Flag_ret ret
'-------------------------------------------------------------------------------
Clock
or outa,E_mask
mov Delay_cnt,#5 ' 250ns delay
djnz Delay_cnt,#$
andn outa,E_mask
Clock_ret ret
'-------------------------------------------------------------------------------
RS_mask long 1<<RS_pin
E_mask long 1<<E_pin
RW_mask long 1<<RW_pin
D7_mask long 1<<D7_pin
LCD_mask long $F<<LCD_Offset
LCD_Byte res 1
LCD_Temp res 1
Return_add res 1
Delay_cnt res 1
I had read your OBEX you sited above but could not convert it to PASM successfully. Of course I think I can now! Thanks.
Why do we need the delays you have inserted in the PASM routine?
We need to be able to look at things as we go along. I use the FDS object for its ease of use by a beginner. I stick with using FDS to keep it simple. As beginners we are not capable of creating something like the FDS or even a simpler version right now. May be later.
I could not agree more with you on the difficulties you had getting going with the PASM. I have had pretty much the same problems myself. Good to know that we share that! I am making a special effort to cover these areas in the book in that I am sure beginners will share our experiences.
Why do we need the delays you have inserted in the PASM routine?
According to the HD44780 data sheet (hint, hint), the minimum time before data is ready after the rising edge of the E pin is 160ns (0.16us). As my code has a delay routine that works in microseconds, I'm using the minimum delay; it's more than required which will not hurt anything.
I am sensitive and accepting of the the fact that the data sheets need to be read and understood.
I have/had the data sheet in front of me as I programmed the LCD. The way I read it, it clearly says that there is no wait required for reading the busy flag. And after that all instructions can be executed one after the other, as I understand it, and as worked just fine for my implementation of the LCD. The executions time delays apply only to the initialization sequence. But obviously I have it wrong. What am I not under standing right and where is the information I am skipping or misunderstanding. I feel that this is important to my proper understanding of reading the data sheets and so I ask for your further help.
Look in the timing diagrams. You will see that there is an offset between the low-to-high transition on E and having valid data on the buss. In the docs I'm using -- the original HD44780 data sheet on which most character LCDs are based -- Figure 28 (pdf page 59) shows buss read timing. The delta from E high to data ready is called Tddr; you can find the spec on pdf page 53 -- 160ns max.
Comments
http://www.ganssle.com/debouncing.htm
I take that by this you mean that the delays provided by the instructions execution themselves are never long enough. (including the time your finger takes).
The reference was very interesting but if I had to provide a 1/6 second delay to cover all cases, that did seem onerous.
H
Onerous would be trying to chase down mystery behaviors due to poor/missing debounce methods either electronic or in sofgtware. Debounce the UI. Cost $0.00 in software. In hardware a few cents. Continued sanity, priceless.
Frank
[FONT=Arial, sans-serif]The data appears on the PST.[/FONT]
[FONT=Arial, sans-serif]As set up,the code takes the data in the third byte of a long and reverses the bits. All other bits are erased. Then one erased bit is set. I need to reverse the bits because as my LCD was hooked up to the Propeller, the pins were in the reverse order to what was required.[/FONT]
[FONT=Arial, sans-serif]It is also useful for looking at what the MUX instructions do.[/FONT]
[FONT=Arial, sans-serif]H[/FONT]
Also, your timing loops are confusing. Relative to clkfreq the variable onesec holds the clock count for 1/10th of a second, the comment (40M) suggests 1/2 a second and the actual loop delays for 4/10th of a second. What is it going to be?
However here is the revised code for the program I posted last time with proper commenting and formatting as requested by kuroneko and stephan. These guys keep me honest!
Currently there are no delays or stored results between the manipulations that are taking place, and thus no way to actually see the results at each step; only the end result in the terminal. Consider breaking this into two exercises, one using an internal memory location, and terminal output with additional shared locations to hold/display the intermediate results (with additional text labels indicating the output is for___), and a second using outa, long delays, and perhaps a VERY slow system clock rate so that the results of each manipulation can be seen in the leds. With the caveat the user understands this is only for seeing the effects of the instructions in question as a learning exercise, and not a normal use of outa in practice.
Frank
@Harprit: Wouldn't the following sequence be easier to understand?
My problem is that I am not conversant or comfortable with binary manipulations
I need to write that chapter now
This was suggested to me earlier but I did not take the advise as I should have.
Same ole same ole.
Will spend time on binary chapter in the next week or so to see if I cant learn something.
Needs getting done.
Harprit
And, or, not, xor, rol, ror, shl, shr, mux (for the prop, and is a cool instruction), rev (again for the prop), are the core of assembly language.
All of these are not very complex. It's the use cases and short cuts they bring to the table that makes all the difference in the world. Of those the "and, or, shx" instructions see near constant use. They are the ones that break longs into chunks that one can work with and make decisions on.
http://www.math.grin.edu/~rebelsky/Courses/152/97F/Readings/student-binary
I would add to that, bit, nibble, byte, word, long, hex, octal, decimal notations and conversions.
[FONT=Arial, sans-serif]Here is what I found specially as being specially relevant to a beginner.[/FONT]
[FONT=Arial, sans-serif]Binary mathematics are not particularly difficult. However, you have to pay exquisite detail to what you are doing, because beginners do not have a good feel for things that happen as we shift registers to the left and to the right and reverse bits to manipulate the I/O to get the results that we are seeking. It is best to lay it out on paper as you go along.[/FONT]
[FONT=Arial, sans-serif]At the level that I am working, I am not quite ready to add the shorthand notation that adds even more power to binary manipulations. That absolutely has to come later as the comfort level increases.[/FONT]
[FONT=Arial, sans-serif]Here is the code for activating a 2 x 16 character liquid crystal display with a standard Hitachi controller. The code is not particularly long, which surprised me, and is not particularly complicated once one figures out what needs to be done. How long it takes to figure out what needs to be done is a whole other matter complicated by that fact that the Hitachi controller manual has some difficult phraseology in it and some of the help material on the internet has mistakes in it.[/FONT]
[FONT=Arial, sans-serif]I am still not comfortable with the routine that reads the busy bit. Experts please examine and advise. Seems to me that I should not need a delay in this routine.[/FONT]
[FONT=Arial, sans-serif]Here is the code[/FONT]
[FONT=Lucida Console, monospace]Harprit
[/FONT]
H
A good thing to look at is a typical college text, how the architecture is approached for a controller, then getting into ASM and internal peripherals.
I enjoy teaching the 8051 mainly because of the text - It's extremely important that the CPU & internal hardware is covered since ASM/Machine code ties in so closely to the internals. For the 8051 I use this text - check it out as to a sample approach.
http://www.amazon.com/8051-Microcontroller-Embedded-Systems-2nd/dp/013119402X/ref=sr_1_1?ie=UTF8&qid=1315882829&sr=8-1
-Martin
Please do not expect a college text from me. I have neither the expertise of the desire to do a college text. I hope this will be an introduction for hobbyists, no more no less. I hope it will be an adequate one. So a detailed discussion of the architecture etc does not seem to be in the cards.
Those interested will take it from there.
H
I got to thinking that maybe a delay is needed to allow the
loop andn ina, enablebit
instruction to complete. Am I right on this?
Still seems odd to me.
H
[FONT=Arial, sans-serif]I tried what you suggested but just could not get it to work.[/FONT]
[FONT=Arial, sans-serif]However this does work[/FONT] [FONT=Arial, sans-serif]But I still need the delay and the delay cannot be less[/FONT]
[FONT=Arial, sans-serif]I still cannot get it right in my mind.[/FONT]
As a matter of fact the only thing that matters is the delay.
Everything else can be deleted. So the BUSY flag is not being read
[FONT=Arial, sans-serif]HSS[/FONT]
I need someone to explain it in detail to me.
What should be set to what when etc. or a code listing would help.
Everything works fine with a delay but tha's not the goal here.
H
After that if I read ina into temp can I isolate the bit from that? I am having difficulty with that. Apparently I am doing something wrong.
H
I haven't finished porting my [ working ] Spin LCD driver to PASM, but this is the port of the code that waits for the busy flag to clear -- perhaps it will help you.
Here's the working Spin routine:
And here's my PASM conversion:
When the object is finished and testing I'll post in ObEx.
if using chrome when you goto your link up top near the address bar, google asks you if you want to translate the page from German. Does a pretty good job. I use chrome to make sense of Chinese/Taiwan/Japan web pages..
Reading through this thread has also shown me a few tricks that I missed, so it's been a help for me already. One concern I have is your reliance on pre-compiled objects, specifically the FullDuplexSerial object. It's a wonderful object, no doubt, but I vastly prefer building my own objects so I know exactly how it works, and a UART is a really simple routine, good for a beginner, if you don't try to make it too fancy right away.
I go through the same basic routines whenever I pick up a new microcontroller; start be flashing a LED, flashing at a calculated frequency, building a binary LED counter, a ring counter, etc, just to get a feel for manipulating bits. Next I'll try reading pins, measuring a RC circuit and lighting LEDs depending on the time it takes to charge. After that it's usually a UART transmitter (having an o'scope admittedly does make this easier), and once the UART transmitter is displaying "A"s I'll create a string lookup routine to display messages, then a HEX to ASCII routine so I can display a counter, and a HEX to BCD to ASCII routine to see the counters in decimal. Then I get into stuff like a SPI driver for reading an ADC chip, I2C for reading and writing to the EEPROM, and parallel LCD drivers.
And on that note, here's the guts of a routine I managed to whip up yesterday, inspired by this thread. Hopefully the formatting doesn't get mangled again; it looks fine in preview.
I had read your OBEX you sited above but could not convert it to PASM successfully. Of course I think I can now! Thanks.
Why do we need the delays you have inserted in the PASM routine?
H
We need to be able to look at things as we go along. I use the FDS object for its ease of use by a beginner. I stick with using FDS to keep it simple. As beginners we are not capable of creating something like the FDS or even a simpler version right now. May be later.
I could not agree more with you on the difficulties you had getting going with the PASM. I have had pretty much the same problems myself. Good to know that we share that! I am making a special effort to cover these areas in the book in that I am sure beginners will share our experiences.
I'll take a careful look at your code. Thanks
HSS.
According to the HD44780 data sheet (hint, hint), the minimum time before data is ready after the rising edge of the E pin is 160ns (0.16us). As my code has a delay routine that works in microseconds, I'm using the minimum delay; it's more than required which will not hurt anything.
Disregard, I see you're past that.
I am sensitive and accepting of the the fact that the data sheets need to be read and understood.
I have/had the data sheet in front of me as I programmed the LCD. The way I read it, it clearly says that there is no wait required for reading the busy flag. And after that all instructions can be executed one after the other, as I understand it, and as worked just fine for my implementation of the LCD. The executions time delays apply only to the initialization sequence. But obviously I have it wrong. What am I not under standing right and where is the information I am skipping or misunderstanding. I feel that this is important to my proper understanding of reading the data sheets and so I ask for your further help.
H