Delay PASM
Hello ,
I'm still working on my Lcd driver...
I noticed that my timers are " messed up "
lcd_reset has need almost 2 second to reach ret (??)
for example
http://pastebin.com/pQdy7mgN
any tips ?
Thanks
I'm still working on my Lcd driver...
I noticed that my timers are " messed up "
lcd_reset has need almost 2 second to reach ret (??)
for example
wait100us
rdlong delay100us, #5
mov t2, cnt ' setup
add t2, delay100us ' first add
waitcnt t2,delay100us
wait100us_ret ret
I know #5 is the 5th location as see
delay long 80_000_000 ' 1 second = 12.5ns*80KK loc 0
delay20ms long 1_600_000'............................... ' 1
delay10ms long 800_000'................................. ' 2
delay6ms long 480_000'................................. ' 3
delay200us long 16_000'.................................. ' 4
delay100us long 8_000'................................... ' 5
delay1us long 8'....................................... ' 6 ' or byte
so 8000*12.5ns@80Mhz = 100ushttp://pastebin.com/pQdy7mgN
any tips ?
Thanks

Comments
There are two values stored in the initialization area that might be of interest to your program:
a long at $0000 contains the initial master clock frequency, in Hertz
(e.g how many cnt you should wait for, to wait 1second)
I don't see any mention of a table in hub that you are referring to.
So I think you gone have to make your own table. (btw it's 80 cnt cycles in a micro second)
Your code already have a hardcoded one, so skip the rdlong #5 etc
And you could change it to:
waitcnt t2,#0
As delay is added to t2 after the wait, so unless you know what value t2
should have for next waitcnt, you just as might add 0 to it.
But it's good idea to not have a hardcoded table, so read hub location 0
Though dividing by 10 and 100 is not that easy in pasm, but by 4, 8 and 16 is
org 0 'Reset assembly pointer Toggle rdlong Delay, #0 'Get clock frequency shr Delay, #2 'Divide by 4 mov Time, cnt 'Get current time add Time, Delay 'Adjust by 1/4 second waitcnt Time, Delay 'Wait for 1/4 second
Personally I think you use CALL a little to much in your code.
When something can be done in 3 lines of code I would not use a subroutine.
mov cnt,delay100ms ' leftside cnt is a shadow and can be used as "regular memory".
add cnt,cnt
waitcnt cnt, #0
"rdlong delay100us, #5" reads the contents of HUB address 4 (rdlong ignores lower 2 bits).
Why don't you do this instead ?
wait100us mov t2, delay100us add t2, cnt ' better practice is to add here waitcnt t2,delay100us wait100us_ret ret
When you say rdlong ignores lower 2 bits , you mean that they are step by 4 ( so it is 32) bit) ?
I thought it was already "formatted" , I mean #0 ->0,1,2,3 #1->4,5,6,7 and so on...
thanks again,
start from scratch is not easy but I feel I am near to solution and I have some trouble to feedback my code. PASD doesnt keep the timing right (?) so I just add one led....
I am sure the trouble is the timing and the Register Select......
Thank to all
may I wrong, but I use call to keep code readable ( by my opinion) as write DelayUs (100); or Lcd_dat(0x80); and so on
the code is useless but it works and I learned some stuff .D
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 PUB Main cognew(@entry, 0) DAT org 0 entry mov dira,port Call #wait Call #lcd_reset Call #lcd_init :Main or outa,rs mov cmd,#104 'H Call #LcdDat mov cmd,#101 'E Call #LcdDat mov cmd,#108 'L Call #LcdDat mov cmd,#108 'L Call #LcdDat mov cmd,#111 'O Call #LcdDat :Loop jmp #:Loop lcd_reset '4 Bit mode andn outa,RS andn outa,CLR or outa,DB4 '0x3 or outa,DB5 Call #TogglE Call #wait6ms or outa,DB4 '0x3 or outa,DB5 Call #TogglE Call #wait200us or outa,DB4 '0x3 or outa,DB5 Call #TogglE ' Call #wait200us andn outa,DB4 '0x2 or outa,DB5 Call #TogglE Call #wait6ms ' Lcd_reset_ret ret Lcd_init andn outa,RS mov cmd,#$28 '4 bit,2linee,5x7 Call #LcdDat mov cmd,#$08 'Display OFF Call #LcdDat mov cmd,#$0C 'Display ON, cursor & blink off Call #LcdDat mov cmd,#$06 'Entry mode Call #LcdDat mov cmd,#$01 'Clear Screen Call #LcdDat mov cmd,#$06 'Entry mode Call #LcdDat mov cmd,#$02 'Cursor Home Call #LcdDat mov cmd,#$80 'Cursor prima riga Call #LcdDat Lcd_init_ret ret LcdDat 'MSB '----- mov t2,cmd or cmd,RS shr t2,#4 shl t2,#10 andn outa,CLR OR outa,t2 Call #TogglE 'LSB '----- mov t2,cmd or cmd,RS and t2,#$0F shl t2,#10 andn outa,CLR OR outa,t2 Call #TogglE Call #wait200us Call #wait200us LcdDat_ret ret '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' wait mov t2,delay add t2,cnt waitcnt t2,delay wait_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' wait20ms mov t2, delay20ms add t2, cnt waitcnt t2,delay20ms uswait20ms_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' wait6ms mov t2, delay6ms add t2, cnt waitcnt t2,delay6ms wait6ms_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' wait200us mov t2, delay200us add t2, cnt waitcnt t2,delay200us wait200us_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' wait1us mov t2, delay1us add t2, cnt waitcnt t2,delay1us wait1us_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' TogglE or outa,En Call #wait1us andn outa,En Call #wait1us TogglE_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'delay @80MHz delay long 80_000_000 ' 1 second = 12.5ns*80KK loc 0 delay20ms long 1_600_000'............................... ' 1 delay10ms long 800_000'................................. ' 2 delay6ms long 480_000'................................. ' 3 delay200us long 16_000'.................................. ' 4 delay100us long 8_000'................................... ' 5 delay1us long 8'....................................... ' 6 ' or byte RS long |< 15 RW long |< 14 EN long |< 24 DB4 long |< 10 DB5 long |< 11 DB6 long |< 12 DB7 long |< 13 Led23 long |< 23 Led22 long |< 22 Pin21 long |< 21 Pin20 long |< 20 'port long RS | RW | EN | DB7 | DB6 | DB5 | DB4 port long $100BC00 poweron long $FFFFFFFF DataMask long %1111000 CLR long %1111 << 10 cmd long 0 t1 res 1 t2 res 1 ' MSB LSB '7 6 5 4 3 2 1 0 SET '----------------------------------------------------------- '0 0 1 1 0 0 0 0 8 bit mode '0 0 1 0 0 0 0 0 4 bit '0 0 1 0 1 0 0 0 4-bits, 2-lines, 5x7 '0 0 0 0 1 0 0 0 display off, cursor off, blink off '0 0 0 0 1 1 0 0 display on '0 0 0 0 0 0 0 1 Clear display '0 0 0 0 0 1 1 0 increment, no display shift 'P32........P24..........P14 P13 P12 P11 P10 P0 ' En RS DB7 DB6 DB5 DB4 '0 0000000 X 000000000 X X X X X 0000000000 0 ' ' P10 DB4 ' P11 DB5 ' P12 DB6 ' P13 DB7 ' P14 RW ' P15 RS
Thsnks
Your code does have some "wrong" way of doing things and repeated code like mov dira, port
rdlong will only read from 4n values, reading from 5,6,7 is the same as reading from 4
rdlong and friends read data from a given HUB memory location. The only "formatting" you get is the "data type" width. rdlong get 32 bits, rdword gets 16 bits, rdbyte gets 8 bits. There is nothing automatic about the addresses that rdlong uses other than it will read on a 32 bit boundary.
rdlong value, #0 reads the content of HUB address 0 into value. this is usually the propeller startup clock frequency. If you want to read from HUB address 4, you would say rdlong value, #4, if you want to read from HUB address 12, you would say rdlong value, #12.
rdword value, #14 reads the content of HUB address 14. Address 14 is word 1 of address 12.
if you have this:
address long 0 rdlong value, address
It will read the content of hub address 0 into value.If you want to read contiguous longs, do something like this:
address long 0 rdlong value, address add address, #4 rdlong value, address add address, #4 rdlong value, address
If you want to read contiguous words, do something like this:
address long 0 rdword value, address add address, #2 rdword value, address add address, #2 rdword value, address
But where does address come from? Usually it is passed to the COG using a mailbox via the PAR register - that is the best practice. If you need to read the first 512 bytes and know what your doing, you can use the # syntax as described before.
You can set a breakpoint in PASD and run to the break. It will run real-time. If you're unlucky your break point will not get hit, and you'll have to reload the program.
I would not say that. The proper statement would be "The code is not needed now. But I made it work and learned from it." Now that is code with value.
Frank
I agree , I have to improve the code
Thanks for detailed answer . I have to improve my code or/and add new functions
I agree! You're right
It looks easy but
rdlong cmd,#4 Call #LcdDat Call #wait
wheredelay long 80_000_000 ' 1 second = 12.5ns*80KK loc 0 prova long 65 ' A ascii delay20ms long 1_600_000'............................... ' 1 delay10ms long 800_000'................................. ' 2 delay6ms long 480_000'................................. ' 3 delay200us long 16_000'.................................. ' 4 delay100us long 8_000'................................... ' 5 delay1us long 8'....................................... ' 6 ' or byte
It doesnt print char 'A' on LCDWhy would "rdlong cmd,#4" let you print 'A' on the LCD?
"mov cmd, prova" might work.
The longs in the dat section are not referenced by #4
try this in start:
cognew(@entry,@prova)
then use "rdlong cmd,par"
that should work if "mov cmd,prova" works.
you could try "rdlong cmd,prova" directly but I'm not sure if that would work or not.
I need to save one or more strings in order to show it on lcd
example :
message1 byte "message 1 test"
message2 byte "message 2 test"
The char 'A' is just an test
Yesterday I read the manual but I forgot to add "msg" to COGNEW
cognew(@entry, @msg) mov msg,par rdbyte cmd,par Call #LcdDat Call #wait msg byte "Hello"
PAR is a pointer ?I dont know like scan the whole string
pub start cognew(@entry, @msg) repeat ' the spin stops here dat ' separate dat section to show msg is independent msg byte "Hello",0 dat org 0 rdlong ndx,par ' read the address of msg to ndx :loop rdbyte cmd,ndx ' read the character from ndx tjz cmd, #done ' if the character is 0, exit the loop Call #LcdDat ' character is not 0, print it Call #wait add ndx, #1 ' get the next character address jmp #:loop ' repeat the loop done jmp #done ' nothing left to do, just jmp #done forever ndx long 0 ' use ndx as an index into the msg array
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 PUB Main cognew(@entry, @msg) repeat ' the spin stops here dat ' separate dat section to show msg is independent msg byte "Hello",0 dat org 0 entry mov dira,port Call #wait 'Wait for powerUp lcd Call #lcd_reset 'Reset LCD software Call #lcd_init 'Init or outa,rs ' mov cmd,#104 'Test Display Call #LcdDat rdlong ndx,par ' read the address of msg to ndx :loop rdbyte cmd,ndx ' read the character from ndx tjz cmd, #done ' if the character is 0, exit the loop Call #LcdDat ' character is not 0, print it Call #wait add ndx, #1 ' get the next character address jmp #:loop ' repeat the loop done jmp #done ' nothing left to do, just jmp #done forever {********************************************************************************} lcd_reset 'reset for 4 Bit mode mov cont,#3 mov cmd,#$03 '0x03 for 4bit mode, 0x30 for 8bit :Again Call #LcdDat Call #wait6ms djnz cont,#:Again mov cmd,#$02 Call #LcdDat Call #wait6ms Lcd_reset_ret ret Lcd_init andn outa,RS mov cmd,#$28 '4 bit,2linee,5x7 Call #LcdDat mov cmd,#$08 'Display OFF Call #LcdDat mov cmd,#$0C 'Display ON, cursor & blink off Call #LcdDat mov cmd,#$06 'Entry mode Call #LcdDat mov cmd,#$01 'Clear Screen Call #LcdDat mov cmd,#$06 'Entry mode Call #LcdDat mov cmd,#$02 'Cursor Home Call #LcdDat mov cmd,#$80 'Cursor prima riga Call #LcdDat Lcd_init_ret ret LcdDat 'Send MSB aftwerward LSB 'MSB '----- mov t2,cmd shr t2,#4 shl t2,#10 andn outa,CLR OR outa,t2 Call #TogglE 'LSB '----- mov t2,cmd and t2,#$0F shl t2,#10 andn outa,CLR OR outa,t2 Call #TogglE Call #wait200us 'There is no Busy Flag , wait an while.. Call #wait200us LcdDat_ret ret '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' wait mov t2,delay add t2,cnt waitcnt t2,delay wait_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' wait20ms mov t2, delay20ms add t2, cnt waitcnt t2,delay20ms uswait20ms_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' wait6ms mov t2, delay6ms add t2, cnt waitcnt t2,delay6ms wait6ms_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' wait200us mov t2, delay200us add t2, cnt waitcnt t2,delay200us wait200us_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' wait1us mov t2, delay1us add t2, cnt waitcnt t2,delay1us wait1us_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' TogglE or outa,En Call #wait1us andn outa,En Call #wait1us TogglE_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'delay @80MHz delay long 80_000_000 ' 1 second = 12.5ns*80KK loc 0 prova long 65 delay20ms long 1_600_000'............................... ' 4 delay10ms long 800_000'................................. ' 8 delay6ms long 480_000'................................. ' 12 delay200us long 16_000'.................................. ' 16 delay100us long 8_000'................................... ' 20 delay1us long 8'....................................... ' 24 RS long |< 15 RW long |< 14 EN long |< 24 DB4 long |< 10 DB5 long |< 11 DB6 long |< 12 DB7 long |< 13 Led23 long |< 23 Led22 long |< 22 Pin21 long |< 21 Pin20 long |< 20 port long $100BC00 poweron long $FFFFFFFF DataMask long %1111000 CLR long %1111 << 10 cmd long 0 cont long 0 ndx long 0 ' use ndx as an index into the msg array t1 res 1 t2 res 1
I am debbuging it
This should not be rdlong.
rdlong ndx,par ' read the address of msg to ndx
Use mov instead.mov ndx,par ' read the address of msg to ndx
Par is a pointer already and we want to dereference the pointer, not the contents.I forgot
dat ' separate dat section to show msg is independent long msg byte "Hello",0
Hello,
it works
but manage DAT section is a bit "dungerous"
for example I cant use _delayus here:
Delayus mov t2,_delayus ' because _delayus doesn't work( blank lcd) I have to use _delayms add t2,cnt 'Set the counter = counter +delayus :_Delay waitcnt t2,_delayus 'Waiting.. djnz _tmpDelay,#:_Delay 'every loop is about 1us ( our delay is 1us(micro)*_tmpDelay ) Delayus_ret ret
RS long |< 15 RW long |< 14 EN long |< 24 DB4 long |< 10 DB5 long |< 11 DB6 long |< 12 DB7 long |< 13 Led23 long |< 23 Led22 long |< 22 port long $100BC00 CLR long %1111 << 10 cmd long 0 ndx long 0 ' use ndx as an index into the msg array _tmp long 0 _delayms long 80_000 _delayus long 8 _tmpDelay long 0 t1 res 1 t2 res 1
If I change my section DAT in
_tmp long 0 _delayms long 80_000 _tmpDelay long 0 _delayus long 8
The code works at 90% :
it print "ello World" not "Hello world"
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 PUB Main cognew(@entry, @msg) repeat ' the spin stops here dat ' separate dat section to show msg is independent long msg byte "Hello " 'Test First message msg2 byte "World !",0 'Test second message dat org 0 entry mov dira,port 'Config Port I/O mov _tmpDelay,#500 Call #Delayms 'Wait for powerUp lcd about 0.5s Call #lcd_init 'Init Lcd or outa,rs ' mov ndx,par ' read the address of msg to ndx :loop rdbyte cmd,ndx ' read the character from ndx tjz cmd, #done ' if the character is 0, exit the loop Call #LcdDat ' character is not 0, print it mov _tmpDelay,#511 Call #Delayms add ndx, #1 ' get the next character address jmp #:loop ' repeat the loop done jmp #done ' nothing left to do, just jmp #done forever {********************************************************************************} Lcd_init 'reset for 4 Bit mode mov _tmp,#3 'Send 0x03 three times :Again mov cmd,#$03 '0x03 for 4bit mode, 0x30 for 8bit Call #LcdDat 'Send data mov _tmpDelay,#5 '5ms delay Call #Delayms djnz _tmp, #:Again 'need to Send 0x03 three times mov cmd,#$02 'last command Call #LcdDat mov _tmpDelay,#5 '5ms delay Call #Delayms 'Initialization sequence andn outa,RS mov cmd,#$28 '4 bit,2linee,5x7 Call #LcdDat mov cmd,#$08 'Display OFF Call #LcdDat mov cmd,#$0C 'Display ON, cursor & blink off Call #LcdDat mov cmd,#$06 'Entry mode Call #LcdDat mov cmd,#$01 'Clear Screen Call #LcdDat mov cmd,#$06 'Entry mode Call #LcdDat mov cmd,#$02 'Cursor Home Call #LcdDat mov cmd,#$80 'Cursor prima riga Call #LcdDat Lcd_init_ret ret LcdDat 'Send MSB aftwerward the LSB 'MSB '----- mov t2,cmd shr t2,#4 shl t2,#10 andn outa,CLR OR outa,t2 Call #TogglE 'LSB '----- mov t2,cmd and t2,#$0F shl t2,#10 andn outa,CLR OR outa,t2 Call #TogglE ' mov _tmpDelay,#1 ' Call #Delayms 'There is no Busy Flag , wait an while.. mov _tmpDelay,#400 Call #Delayus 'DELAYUS doesn't work , display is blank LcdDat_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Delayus mov t2,_delayms add t2,cnt 'Set the counter = counter +delayms :_Delay waitcnt t2,_delayms 'Waiting.. djnz _tmpDelay,#:_Delay 'every loop is about 1us ( our delay is 1us(micro)*_tmpDelay ) Delayus_ret ret '************************************************************************************* Delayms mov t2,_delayms ' becouse _delayus doesn't work I have to use _delayms add t2,cnt 'Set the counter = counter +delayms :_Delay waitcnt t2,_delayms 'Waiting.. djnz _tmpDelay,#:_Delay 'every loop is about 1ms ( our delay is 1ms(mili)*_tmpDelay ) Delayms_ret ret '*************************************************************************************** TogglE mov _tmpDelay,#1 or outa,En Call #Delayus andn outa,En TogglE_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' RS long |< 15 RW long |< 14 EN long |< 24 DB4 long |< 10 DB5 long |< 11 DB6 long |< 12 DB7 long |< 13 Led23 long |< 23 Led22 long |< 22 port long $100BC00 CLR long %1111 << 10 cmd long 0 ndx long 0 ' use ndx as an index into the msg array _tmp long 0 _delayms long 80_000 _delayus long 8 _tmpDelay long 0 t1 res 1 t2 res 1
delayms has no problem. It is not a problem timing related because 400us are enought
Some days ago I finished my lcd routine.It helped me to learn a bit of pasm ( delay,string,clr bit,uart,Dat section ecc....)
Im going to make one for Graphic lcd
I know it isn't so good but any feedback greatly appreciated
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 PUB Main cognew(@entry, @@0) repeat ' the spin stops here dat ' separate dat section to show msg is independent long Message_1 byte "Hello ",0 Message_2 byte "World!",0 Buffer byte " ",0 dat org 0 entry mov dira,port 'Config Port I/O or dira,Tx_Mask or outa,Tx_Mask 'INIT THE LCD mov _tmpDelay,#500 Call #Delayms 'Wait for powerUp lcd about 0.5s Call #lcd_init 'Init Lcd ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'DEMO 'READ STRING MSG FROM MEMORY AND PRINT IT mov _ndx,#@Message_1 add _ndx,par 'read the address of msg to ndx Call #LcdChar mov _ndx,#@Message_2 add _ndx,par 'read the address of msg to ndx Call #LcdChar ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' andn outa,rs 'Get ready for next string mov cmd,#$C0 'second line call #LcdDat 'Send command or outa,rs 'DATA enabled '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'DEMO 'TEST division & remainder and print on LCD mov __x,#66 mov __y,#10 Call #Divide 'ret __x mov _tmp,__x andn _tmp,clrW '_tmp = Integer value shr __x,#15 '__x = remainder mov _tmp2,__x mov number,_tmp Call #decToAscii mov _ndx,#@Buffer add _ndx,par 'read the address of msg to ndx Call #Lcdchar mov number,_tmp2 Call #decToAscii mov cmd,#"." Call #LcdDat mov _ndx,#@Buffer add _ndx,par 'read the address of msg to ndx Call #Lcdchar ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'DEMO 'Write custom char at first location and print it on LCD Call #LcdCgram 'Just test Cgram routine :uart mov _ndx,#@Message_1 Call #Send_Message mov _ndx,#$0D call #UART_Transmit JMP #:uart '&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 'DEMO UART Send_Message add _ndx,par ' Add the relative address of the message to the address :Get_Byte ' of String_Lookup to find the absolute address rdbyte cmd,_ndx wz if_z jmp Send_Message_ret call #UART_Transmit add _ndx,#1 jmp #:Get_Byte Send_Message_ret ret UART_Transmit or cmd,#$100 ' Add a stop bit shl cmd,#1 ' Add a start bit mov Bit_Counter,#10 mov cnt,Baud add cnt,#16 add cnt,cnt :Loop shr cmd,#1 wc ' Shift lsb out of Data into C muxc outa,Tx_Mask ' Set / clear the Tx_pin depending on C waitcnt cnt,Baud djnz Bit_Counter,#:Loop ' Loop until ten bits sent UART_Transmit_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' LcdChar or outa,RS :loop rdbyte cmd,_ndx WZ 'read the character from ndx IF_Z tjz cmd,:done 'if the character is 0, exit the loop Call #LcdDat 'character is not 0, print it mov _tmpDelay,#50 Call #Delayms add _ndx, #1 'get the next character address jmp #:loop 'repeat the loop :done LcdChar_ret ret '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'copy to memory and reverse it decToAscii mov _tmp,number ' :nDigit mov __x,_tmp 'x = number mov __y,#10 'y = 10 Call #Divide 'number = number / 10 add countTmp,#1 'Count digit andn __x,clrW 'Clear remainder ( High word) mov _tmp,__x 'copy to var number the new value ( number /=10) tjnz _tmp,#:nDigit mov _ndx,#@Buffer add _ndx,par 'read the address of msg to ndx add _ndx,countTmp 'start from last location to avoid reverse routine ( max 3 digit ( 3 + NULL) that is an long ) mov char,#0 wrbyte char,_ndx 'Add NULL Character.After reversed it , NULL will be at last position sub _ndx,#1 :loop Call #Modulus 'digit = number % 10 mov __x,number 'x = number mov __y,#10 'y = 10 Call #Divide 'number = number / 10 andn __x,clrW 'Clear remainder ( High word) mov number,__x 'copy to var number the new value ( number /=10) mov char,digit 'copy digit to char add char,#48 'Add '0' to char. The ascii-characters for numbers start at 48 (for 0) up to 57(for 9) wrbyte char,_ndx 'write to memory sub _ndx,#1 'next location (from 4 to 1) tjnz number,#:loop 'if number = 0 Exit mov countTmp,#0 decToAscii_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Lcd_init 'reset for 4 Bit mode mov _tmp,#3 'Send 0x03 three times :Again mov cmd,#$03 '0x03 for 4bit mode, 0x30 for 8bit Call #LcdDat 'Send data mov _tmpDelay,#5 '5ms delay Call #Delayms djnz _tmp, #:Again 'need to Send 0x03 three times mov cmd,#$02 'last command Call #LcdDat mov _tmpDelay,#5 '5ms delay Call #Delayms 'Initialization sequence andn outa,RS mov cmd,#$28 '4 bit,2linee,5x7 Call #LcdDat mov cmd,#$08 'Display OFF Call #LcdDat mov cmd,#$0C 'Display ON, cursor & blink off Call #LcdDat mov cmd,#$06 'Entry mode Call #LcdDat mov cmd,#$01 'Clear Screen Call #LcdDat mov cmd,#$06 'Entry mode Call #LcdDat mov cmd,#$02 'Cursor Home Call #LcdDat mov cmd,#$80 'Cursor prima riga Call #LcdDat Lcd_init_ret ret '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' LcdDat 'Send MSB aftwerward the LSB 'MSB '----- mov t2,cmd shr t2,#4 shl t2,#10 andn outa,CLR OR outa,t2 Call #TogglE 'LSB '----- mov t2,cmd and t2,#$0F shl t2,#10 andn outa,CLR OR outa,t2 Call #TogglE mov _tmpDelay,#400 Call #Delayus LcdDat_ret ret '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' LcdCgram 'TEST CGRAM andn outa,RS mov cmd,#64 'CGRAM Add first chr Call #LcdDat or outa,RS 'Draw the custom character mov cmd, #%10001 Call #LcdDat mov cmd, #%11111 Call #LcdDat mov cmd, #%10001 Call #LcdDat mov cmd, #%11111 Call #LcdDat mov cmd, #%00100 Call #LcdDat mov cmd, #%00000 Call #LcdDat mov cmd, #%00100 Call #LcdDat mov cmd, #%10001 Call #LcdDat ' andn outa,rs 'Get ready for next string mov cmd,#$C5 'second line call #LcdDat 'Send command or outa,rs mov cmd,#0 'DDRAM Add first chr Call #LcdDat LcdCgram_ret ret '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'DELAY US Delayus mov t2,_delayus ' add t2,cnt 'Set the counter = counter +delayus :_Delay waitcnt t2,_delayus 'Waiting.. djnz _tmpDelay,#:_Delay 'every loop is about 1us ( our delay is 1us(micro)*_tmpDelay ) Delayus_ret ret '************************************************************************************* 'DELAY MS Delayms mov t2,_delayms add t2,cnt 'Set the counter = counter +delayms :_Delay waitcnt t2,_delayms 'Waiting.. djnz _tmpDelay,#:_Delay 'every loop is about 1ms ( our delay is 1ms(mili)*_tmpDelay ) Delayms_ret ret '*************************************************************************************** TogglE mov _tmpDelay,#1 or outa,En Call #Delayus andn outa,En TogglE_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Modulus '---------------------------------------------------------- digit = number // 10 'digit = number - (10 * int(number/10)) 'Wikipedia mov __x,number 'x = number mov __y,#10 'y = 10 Call #Divide 'number = number / 10 andn __x,clrW 'Clear remainder ( High word) mov __x1,__x 'multiply __x * 10 mov __y1,#10 Call #multiply 'ret __y1 sub number,__y1 mov digit,number 'return result in digit Modulus_ret ret ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Divide x[31..0] by y[15..0] (y[16] must be 0) ' on exit, quotient is in x[15..0] and remainder is in x[31..16] ' Parallax ' Propeller Manual 1.1 divide shl __y,#15 'get divisor into y[30..15] mov __t,#16 'ready for 16 quotient bits :loop cmpsub __x,__y wc 'y =< x? Subtract it, quotient bit in c rcl __x,#1 'rotate c into quotient, shift dividend djnz __t,#:loop 'loop until done divide_ret ret 'quotient in x[15..0], 'remainder in x[31..16] '' Multiply x[15..0] by y[15..0] (y[31..16] must be 0) ' on exit, product in y[31..0] ' multiply shl __x1,#16 'get multiplicand into x[31..16] mov __t1,#16 'ready for 16 multiplier bits shr __y1,#1 wc 'get initial multiplier bit into c :loop if_c add __y1,__x1 wc 'if c set, add multiplicand to product rcr __y1,#1 wc 'put next multiplier in c, shift prod. djnz __t1,#:loop 'loop until done multiply_ret ret 'return with product in y[31..0] RS long |< 15 pwm long |< 14 EN long |< 24 DB4 long |< 10 DB5 long |< 11 DB6 long |< 12 DB7 long |< 13 Led23 long |< 23 Led22 long |< 22 port long $100BC00 CLR long %1111 << 10 clrW long $FFFF << 15 _delayms long 80_000 _delayus long 80 Tx_Mask long 1<<30 Baud long 694 ' 694 * 0.0125µs = 115,274 bps Temp res 1 Bit_Counter res 1 _tmpDelay res 1 _ndx res 1 ' use ndx as an index into the msg array _tmp res 1 _tmp2 res 1 t2 res 1 __x res 1 __y res 1 __t res 1 __x1 res 1 __y1 res 1 __t1 res 1 digit res 1 number res 1 cmd res 1 char res 1 countTmp res 1 fit 496