bryan1
Well-Known Member
To convert a binary value from 0x001 to 0x270f to 0001 to 9999 decimal
By Transistorman
a simple count operation code
the code will totalize the output of AN0 and AN1
by ericgibbs
Simple conversion subroutines.
Useful for manipulating DS1307 RTC i/o values.
by EricGibbs
Demo using Oshonsoft Basic for sending bit serial data from PIC to PIC
'the receiving PIC could use, On PORTB.0 change interrupt to sense the clock
'and another PIC pin to to test the incoming data pin.
''
'Also useful for serial loading of external shift registers
from ericgibbs:
A point you should be aware of when using Timer interrupts is the
Define SIMULATION_WAITMS_VALUE = 1,
it will not automatically shorten the Timer interrupt period the same way that its does with WaitMs and WaitUs commands.
For example, say you set the Timer1 interrupt for 0.5 secs in the 'real' world , in simulation you could get a approx 15 sec to 20 sec period in Simulation.
I work around this using:
You can use this sim1 = 0/1 to perform other different tasks when in Simulation
or a PIC.
For a PIC ensure sim1=0 and then Compile the program with F9 key before programming the PIC
From ericgibbs. Demo for using the 16F628 Comparator.
'27Nov2010 for Oshonsoft IDE
'PIC 16F628/A COMPARATOR DEMO.
'Demo mode of comparator set for 4 analog channel inputs PA0.1.2.3
'displays the greater than/ less than Vref states of CMCON.7 and .6
''
'During tests, the comparision switch over is approx 5 to 10mV
From Mosiac.
ISIS Compatible OSHON Hybrid
Ok, based on the assistance of the forum I have come up with an OSHON compatible HD44780 LCD approach to simulating in ISIS. For full Oshon compatibility just replace the INIT & Cmd proc calls with the Oshon equivalent.
This approach permits the use of all Oshon instructions and allows the 4 data line & 2 control line single port LCD interface. I use PORTB.
I hope this sample Oshon Basic Compiler code helps others.
More to come as members post it in the 'Code Snippets Thread' in the main Oshonsoft Forum
Code:
Dim ascbfr3 As Byte 'used in convert routing
Dim ascbfr2 As Byte 'used in convert routing
Dim ascbfr1 As Byte 'used in convert routine
Dim ascbfr0 As Byte 'used in convert routine
binval = volts
Gosub bin2asc
bin2asc:
ascbfr3 = binval / 1000
temp3 = binval Mod 1000
ascbfr2 = temp3 / 100
temp3 = temp3 Mod 100
ascbfr1 = temp3 / 10
ascbfr0 = temp3 Mod 10
'results are BCD so
'convert to ASCII for LCD
ascbfr3 = ascbfr3 Or 0x30
ascbfr2 = ascbfr2 Or 0x30
ascbfr1 = ascbfr1 Or 0x30
ascbfr0 = ascbfr0 Or 0
' and to show on a lcd after it is set up
Lcdout "Volts:", ascbfr3, ascbfr2, ".", ascbfr1, ascbfr0
'this will put a decimal point in and the example shows a voltage reading to 2 decimal places
a simple count operation code
Code:
Define ADC_CLOCK = 3 'default value is 3
Define ADC_SAMPLEUS = 10 'default value is 20
Define LCD_BITS = 4 'allowed values are 4 and 8 - the number of data
Define LCD_DREG = PORTB
Define LCD_DBIT = 0 '0 or 4 for 4-bit interface, ignored for 8-bit
Define LCD_RSREG = PORTC
Define LCD_RSBIT = 1
Define LCD_EREG = PORTC
Define LCD_EBIT = 3
Define LCD_RWREG = PORTC 'set to 0 if not used, 0 is default
Define LCD_RWBIT = 2 'set to 0 if not used, 0 is default
Lcdinit
Dim adc1 As Word
Dim adc2 As Word
Dim total As Word
TRISB = %11110000
TRISA = %11111111
ADCON0 = 0xc0 'set A/D conversion clock to internal source
ADCON1 = 1 'set PORTA pins as analog inputs
High ADCON0.ADON 'turn on A/D converter module
loop:
Adcin 0, adc1
Adcin 1, adc2
total = adc1 + adc2
Lcdcmdout LcdClear
Lcdout #total
WaitMs 1
Goto loop
by ericgibbs
Simple conversion subroutines.
Useful for manipulating DS1307 RTC i/o values.
Code:
dim temp1 as byte
dim ascbfr0 as byte
dim ascbfr1 as byte
dim units as byte
dim tens as byte
'*******
'convert RTC packed bcd to a bin number for inc/dec usage
'enter with temp1 holding the packed BCD byte
'exit with temp1 holding the binary byte
bcd2bin:
units = temp1 And 0x0f
tens = temp1 And 0xf0
tens = ShiftRight(tens, 4)
tens = tens * 10
temp1 = tens + units
Return
'*******
'convert the bin number to packed bcd for RTC write
'enter with temp1 holding the binary byte
'exit with temp1 holding the packed BCD byte
'also ascbfr1,ascbfr0 hold the ASCII value
bin2bcd:
tens = temp1 / 10
units = temp1 Mod 10
ascbfr1 = tens Or 0x30
ascbfr0 = units Or 0x30
tens = ShiftLeft(tens, 4)
temp1 = tens Or units
Return
'*******
'convert packed bcd i/o to ascii for lcd
'enter with the packed BCD byte in temp1
'on exit ascbfr1 and ascbfr0 hold the ASCII numbers
bcd2asc:
ASM: movf temp1,w
ASM: andlw 0x0f
ASM: iorlw 0x30
ASM: movwf ascbfr0
ASM: movf temp1,w
ASM: swapf temp1,w
ASM: andlw 0x0f
ASM: iorlw 0x30
ASM: movwf ascbfr1
Return
Demo using Oshonsoft Basic for sending bit serial data from PIC to PIC
'the receiving PIC could use, On PORTB.0 change interrupt to sense the clock
'and another PIC pin to to test the incoming data pin.
''
'Also useful for serial loading of external shift registers
Code:
AllDigital
'select the PIC pins
Config PORTA.0 = Output 'set up port a.1 as an clock
Config PORTA.1 = Output 'set up port a.1 as an output
Symbol clk = PORTA.0
Symbol dta = PORTA.1
Dim bt As Byte
Dim mydata(4) As Word
mydata(0) = 0 'Dummy test data
mydata(1) = %0000000101010101 'Dummy test data
mydata(2) = %1010101011101111 'Dummy test data
mydata(3) = %0000001100110011 'Dummy test data
mydata(4) = %0000000011001100 'Dummy test data
'change the (x) to show different WORD patterns
'use the Sim Scope set for Display for Normal, use Zoom
'select PORT pins on scope to suit
mydata = mydata(2)
'or use a WORD value
''mydata = 0x80ff
Gosub xmitdata
End
xmitdata:
dta = mydata.15 '1st msb bit
WaitUs 1
clk = 1
clk = 0
For bt = 0 To 14 '15 bits to follow
mydata = ShiftLeft(mydata, 1)
dta = mydata.15
WaitUs 1
clk = 1
clk = 0
Next bt
dta = 0
Return
from ericgibbs:
A point you should be aware of when using Timer interrupts is the
Define SIMULATION_WAITMS_VALUE = 1,
it will not automatically shorten the Timer interrupt period the same way that its does with WaitMs and WaitUs commands.
For example, say you set the Timer1 interrupt for 0.5 secs in the 'real' world , in simulation you could get a approx 15 sec to 20 sec period in Simulation.
I work around this using:
Code:
Dim sim1 As Byte
'when in Sim set
sim1 = 1
'for real PIC
sim = 0
''when initialising
If sim1 = 1 Then
'set tmr1 count for shorter period in sim
TMR1H = 0xf8
TMR1L = 0x00
Else
'set tmr1 count for 0.5sec, count 60 for a 30 secs delay in PIC
TMR1H = 0x0b
TMR1L = 0xdc
Endif
and again, near the end of the interrupt subr.
If sim1 = 1 Then
'set tmr1 count for sim period
TMR1H = 0xf8
TMR1L = 0x00
Else
'set tmr1 count for 0.5sec, count 60 for a 30 secs delay
TMR1H = 0x0b
TMR1L = 0xdc
Endif
or a PIC.
For a PIC ensure sim1=0 and then Compile the program with F9 key before programming the PIC
From ericgibbs. Demo for using the 16F628 Comparator.
'27Nov2010 for Oshonsoft IDE
'PIC 16F628/A COMPARATOR DEMO.
'Demo mode of comparator set for 4 analog channel inputs PA0.1.2.3
'displays the greater than/ less than Vref states of CMCON.7 and .6
''
'During tests, the comparision switch over is approx 5 to 10mV
Code:
'for Sim only
Define SIMULATION_WAITMS_VALUE = 1
Dim temp1 As Word
Dim vref1 As Word
Dim vrhi As Word
Dim vrlo As Word
'LCD assignments
Define LCD_LINES = 4
Define LCD_CHARS = 16
Define LCD_BITS = 4
Define LCD_DREG = PORTB
Define LCD_DBIT = 4
Define LCD_RSREG = PORTB
Define LCD_RSBIT = 1
Define LCD_EREG = PORTB
Define LCD_EBIT = 2
'make AN0,,1,2,3 as Inputs
TRISA = %00001111
TRISB = %00000000 'outputs
'comparator settings
CMCON.C2OUT = 0
CMCON.C1OUT = 0
CMCON.C2INV = 1
CMCON.C1INV = 1
CMCON.CIS = 0 'comparator selection PA.0/1 to PA.3/2
CMCON.CM2 = 0 'mode set for internal Vref connected
CMCON.CM1 = 1
CMCON.CM0 = 0
'Vref settings
VRCON.VREN = 1
VRCON.VROE = 0
VRCON.VRR = 0 'select Vref low=1 or Vref high =0
VRCON.VR3 = 1 'Vref 2^3 bit
VRCON.VR2 = 1
VRCON.VR1 = 1
VRCON.VR0 = 1 'Vref 2^0 bit
Lcdinit
'this section converts the binary to decimal value of the Vref settings
'as selected by Vr3,2,1,0 , decimal 0 thru 15
If VRCON.VR3 = 1 Then
temp1 = 8
Endif
If VRCON.VR2 = 1 Then
temp1 = temp1 + 4
Endif
If VRCON.VR1 = 1 Then
temp1 = temp1 + 2
Endif
If VRCON.VR0 = 1 Then
temp1 = temp1 + 1
Endif
'* 1000 to allow for lack of decimal fractions
temp1 = temp1 * 1000
'test if in Low or High range of Vref options
If VRCON.VRR = 1 Then 'low range
temp1 = (temp1 / 24) * 5
vrhi = temp1 / 1000
vrlo = (temp1 - (vrhi * 1000)) / 10
Else 'high range
temp1 = 1250 + ((temp1 / 32) * 5)
vrhi = temp1 / 1000
vrlo = (temp1 - (vrhi * 1000)) / 10
Endif
'show on LCD line 1
Lcdout "Vref= ", #vrhi, "." #vrlo
'above Vref value displayed once only
main:
CMCON.CIS = 0
Lcdcmdout LcdLine3Home
'test for IF PORTA.0 is > or < than Vref, display result
If CMCON.6 = 1 Then
Lcdout "A.0>Vr"
Else
Lcdout "A.0<Vr"
Endif
Lcdcmdout LcdLine3Pos(10)
'test for IF PORTA.1 is > or < than Vref
If CMCON.7 = 1 Then
Lcdout "A.1>Vr"
Else
Lcdout "A.1<Vr"
Endif
'switch from PA.0 and PA.1 to PA.3 and PA.2 analog inputs
CMCON.CIS = 1
'repeat the Vref for PA.3 and PA.2 , display result
Lcdcmdout LcdLine4Home
If CMCON.7 = 1 Then
Lcdout "A.2>Vr"
Else
Lcdout "A.2<Vr"
Endif
Lcdcmdout LcdLine4Pos(10)
If CMCON.6 = 1 Then
Lcdout "A.3>Vr"
Else
Lcdout "A.3<Vr"
Endif
Goto main
End
From Mosiac.
ISIS Compatible OSHON Hybrid
Ok, based on the assistance of the forum I have come up with an OSHON compatible HD44780 LCD approach to simulating in ISIS. For full Oshon compatibility just replace the INIT & Cmd proc calls with the Oshon equivalent.
This approach permits the use of all Oshon instructions and allows the 4 data line & 2 control line single port LCD interface. I use PORTB.
I hope this sample Oshon Basic Compiler code helps others.
Code:
'General Device Configuration , 16f886 - Use of the procs below cause this to work in ISIS.
'Once the LCD init and all LCD cmds are handled by the PROCedures below , regular OSHON instructions function with ISIS sim (LM016L LCD)
Define CONF_WORD = 0x23c4
Define CONF_WORD_2 = 0x3eff
Define CLOCK_FREQUENCY = 8
OSCCON = 0x70 'define internal 8MHz clock
Define LCD_BITS = 4 'allowed values are 4 and 8 - the number of data interface lines
Define LCD_DREG = PORTB
Define LCD_DBIT = 0 '0 low port nybble or 4 hi port nybble for 4-bit interface, ignored for 8-bit interface
Define LCD_RSREG = PORTB 'note match this in lcd_cmd Proc below
Define LCD_RSBIT = 7
Define LCD_EREG = PORTB 'note match this in lcd_init Proc below
Define LCD_EBIT = 6
Define LCD_RWREG = 0 'set to 0 if not used, 0 is default
Define LCD_RWBIT = 0 '2 'set to 0 if not used, 0 is default
Define LCD_COMMANDUS = 5000 'delay after LCDCMDOUT, default value is 5000
Define LCD_DATAUS = 100 'delay after LCDOUT, default value is 100
Define LCD_INITMS = 100 'delay used by LCDINIT, default value is 100
'the last three Define directives set the values suitable for simulation; they can be omitted for a real device
Dim cnt As Byte
Dim an13 As Word '10bit adc.
AllDigital
TRISB = %00110000 'set rb5,rb4 portb pins as dig. inputs
ANSELH = %00100000 'an13,rb5 is analog input
ADCON1 = 0
Lcdinit 1 'initialize OSHON LCD module; cursor is blinking
Call lcd_init() 'ISIS lcd init.
loop:
Adcin 13, an13 'sample ADC
Call lcd_cmd(0x01) 'clear lcd
Call lcd_cmd(0x86) 'set cursor to start+6
Lcdout "Value:" 'text for line 1
For cnt = 1 To 100
Call lcd_cmd(0xc0) 'set cursor at the beginning of line 2
Lcdout #cnt 'formatted text for line 2
Lcdout " analog : " #an13 'output decimal adc.
WaitMs 10
Next cnt
Goto loop 'loop forever
End
Proc lcd_init() 'http://www.geocities.com/dinceraydin/lcd/commands.htm
PORTB.6 = 1 'set e line High, reqd for ISIS.
WaitMs 165
Call lcd_cmd(0x20)
Call lcd_cmd(0x28)
Call lcd_cmd(0x06)
Call lcd_cmd(0x0c) '0x0d => cursor.
Call lcd_cmd(0x01)
End Proc
Proc lcd_clk() 'clocks the data lines into the LCD controller, if RS line is 0 then data = an LCD command.
PORTB.6 = 1 'eline
WaitUs 20
PORTB.6 = 0
End Proc
Proc lcd_cmd(x As Byte) 'splits the command byte into two clocked nybbles.Send hi then low nybbles.
Dim y As Byte
y = ShiftRight(x, 4) 'shift hi nyb to low, as data lines are the low nybble of the port, not required for hi nybble data lines.
PORTB = y And 0x0f 'clear hi nyb, use f0 if data line were the hi nybble
PORTB.7 = 0 'clr rs line to take cmds
WaitUs 10
Call lcd_clk() 'edge trigger the 1st nybble of the command on the data lines
WaitMs 5
PORTB.7 = 0 'clr rs line to take cmds
'x = ShiftRight(x, 4) 'required if data lines were the hi nybble of the port.
PORTB = x And 0x0f 'clear hi nybble, use f0 if data line were the hi nybble
WaitUs 10
Call lcd_clk() 'clock the low nybble of the command.
WaitMs 5
End Proc
Last edited by a moderator: