Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Code Snippets for the Oshonsoft Basic Compiler

Status
Not open for further replies.

bryan1

Well-Known Member
To convert a binary value from 0x001 to 0x270f to 0001 to 9999 decimal

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
By Transistorman

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
the code will totalize the output of AN0 and AN1

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
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

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
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
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
More to come as members post it in the 'Code Snippets Thread' in the main Oshonsoft Forum
 
Last edited by a moderator:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top