1. 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.
    Dismiss Notice

Code Snippets for the Oshonsoft Basic Compiler

Discussion in 'Oshonsoft' started by bryan1, Oct 26, 2010.

Thread Status:
Not open for further replies.
  1. bryan1

    bryan1 Well-Known Member

    Joined:
    Aug 4, 2004
    Messages:
    1,678
    Likes:
    46
    Location:
    Adelaide Hills Sth Oz
    To convert a binary value from 0x001 to 0x270f to 0001 to 9999 decimal

    Code (text):

    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 (text):

    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 (text):

    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 (text):
    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 (text):

    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 (text):
    '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 (text):
    '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: Jun 17, 2012
Thread Status:
Not open for further replies.

Share This Page