MELabs programs |
06 Jan '09 |
You are advised to download all programs from the MeLabs web site so that you will
get the latest versions. This consolidated list is best for searching for
keywords in one file so you can see how they were used by MeLabs |
EncoderGeek / EncoderGeek |
' PicBasic Pro program to read pots on 16F877 ADC ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DefineLOADER_USED1 ' Define LCD pins Define LCD_DREG PORTD Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 ' Allocate variables x var byte y var byte z var byte ADCON1 = 4 ' Set PortA 0, 1, 3 to analog inputs Low PORTE.2 ' LCD R/W line low (W) Pause 100 ' Wait for LCD to start Goto mainloop ' Skip subroutines ' Subroutine to read a/d convertor getad: Pauseus 50 ' Wait for channel to setup ADCON0.2 = 1 ' Start conversion Pauseus 50 ' Wait for conversion Return ' Subroutine to get pot x value getx: ADCON0 = $41 ' Set A/D to Fosc/8, Channel 0, On Gosub getad x = ADRESH Return ' Subroutine to get pot y value gety: ADCON0 = $49 ' Set A/D to Fosc/8, Channel 1, On Gosub getad y = ADRESH Return ' Subroutine to get pot z value getz: ADCON0 = $59 ' Set A/D to Fosc/8, Channel 3, On Gosub getad z = ADRESH Return mainloop: Gosub getx ' Get x value Gosub gety ' Get y value Gosub getz ' Get z value Lcdout $fe, 1, "x=", #x, " y=", #y, " z=", #z ' Send values to LCD Pause 100 ' Do it about 10 times a second Goto mainloop ' Do it forever End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to display result of ' 8-bit A/D conversion on LCD ' ' Connect analog inputs to channels 0, 1, 3 (RA0, 1, 3) ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DefineLOADER_USED1 ' Define LCD registers and bits Define LCD_DREG PORTD Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 ' Define ADCIN parameters Define ADC_BITS 8 ' Set number of bits in result Define ADC_CLOCK 3 ' Set clock source (3=rc) Define ADC_SAMPLEUS 50 ' Set sampling time in uS advalvarbyte' Create adval to store result TRISA = %11111111' Set PORTA to all input ADCON1 = %00000100' Set PORTA analog Pause 500 ' Wait .5 second mainloop: Lcdout$fe, 1' Clear the LCD Adcin0, adval' Read the first ADC channel Lcdout"0=", #adval' Send it to the LCD Adcin1, adval' Read the second ADC channel Lcdout" 1=", #adval' Send it to the LCD Adcin3, adval' Read the third ADC channel Lcdout" 3=", #adval' Send it to the LCD Pause 200 ' Delay for time to read the display Goto mainloop ' Do it forever End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to blink all the LEDs connected to PORTD ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DefineLOADER_USED1 i var byte ' Define loop variable LEDS var PORTD ' Alias PORTD to LEDS TRISD = %00000000 ' Set PORTD to all output loop: LEDS = 1 ' First LED on Pause 500 ' Delay for .5 seconds For i = 1 to 7 ' Go through For..Next loop 7 times LEDS = LEDS << 1 ' Shift on LED one to left Pause 500 ' Delay for .5 seconds Next i Goto loop ' Go back to loop and blink LED forever End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to blink an LED connected to PORTD.0 about once a second ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DefineLOADER_USED1 LED var PORTD.0 ' Alias PORTD.0 to LED loop: High LED ' Turn on LED connected to PORTD.0 Pause 500 ' Delay for .5 seconds Low LED ' Turn off LED connected to PORTD.0 Pause 500 ' Delay for .5 seconds Goto loop ' Go back to loop and blink LED forever End 0000000000000000000000000000000000000000000000000000000000 ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DefineLOADER_USED1 ' Define LCD registers and bits Define LCD_DREG PORTD Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 char var byte ' Storage for serial character mode var byte ' Storage for serial mode rcv var PORTC.7 ' Serial receive pin baud var PORTA.0 ' Baud rate pin - 0 = 2400, 1 = 9600 state var PORTA.1 ' Inverted or true serial data - 1 = true ADCON1 = 7 ' Set PORTA and PORTE to digital Low PORTE.2 ' LCD R/W line low (W) Pause 500' Wait for LCD to startup mode = 0 ' Set mode If (baud == 1) Then mode = 2 ' Set baud rate Endif If (state == 0) Then mode = mode + 4 ' Set inverted or true Endif Lcdout $fe, 1 ' Initialize and clear display loop: Serin rcv, mode, char ' Get a char from serial input Lcdout char ' Send char to display Goto loop ' Do it all over again End 0000000000000000000000000000000000000000000000000000000000 ' LCD clock program using On Interrupt ' Uses TMR0 and prescaler. Watchdog Timer should be ' set to off at program time and Nap and Sleep should not be used. ' Buttons may be used to set hours and minutes Define LCD_DREG PORTD ' Define LCD connections Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 hour var byte ' Define hour variable dhour var byte ' Define display hour variable minute var byte ' Define minute variable second var byte ' Define second variable ticks var byte ' Define pieces of seconds variable update var byte ' Define variable to indicate update of LCD i var byte ' Debounce loop variable ADCON1 = 7 ' PORTA and E digital Low PORTE.2 ' LCD R/W low = write Pause 100 ' Wait for LCD to startup hour = 0 ' Set initial time to 00:00:00 minute = 0 second = 0 ticks = 0 update = 1 ' Force first display ' Set TMR0 to interrupt every 16.384 milliseconds OPTION_REG = $55 ' Set TMR0 configuration and enable PORTB pullups INTCON = $a0 ' Enable TMR0 interrupts On Interrupt Goto tickint ' Main program loop - in this case, it only updates the LCD with the time mainloop: PORTB = 0 ' PORTB lines low to read buttons TRISB = $f0 ' Enable all buttons ' Check any button pressed to set time If PORTB.7 = 0 Then decmin If PORTB.6 = 0 Then incmin ' Last 2 buttons set minute If PORTB.5 = 0 Then dechr If PORTB.4 = 0 Then inchr ' First 2 buttons set hour ' Check for time to update screen chkup: If update = 1 Then Lcdout $fe, 1 ' Clear screen ' Display time as hh:mm:ss dhour = hour ' Change hour 0 to 12 If (hour // 12) = 0 Then dhour = dhour + 12 Endif ' Check for AM or PM If hour < 12 Then Lcdout dec2 dhour, ":", dec2 minute, ":", dec2 second, " AM" Else Lcdout dec2 (dhour - 12), ":", dec2 minute, ":", dec2 second, " PM" Endif update = 0 ' Screen updated Endif Goto mainloop ' Do it all forever ' Increment minutes incmin: minute = minute + 1 If minute >= 60 Then minute = 0 Endif Goto debounce ' Increment hours inchr: hour = hour + 1 If hour >= 24 Then hour = 0 Endif Goto debounce ' Decrement minutes decmin: minute = minute - 1 If minute >= 60 Then minute = 59 Endif Goto debounce ' Decrement hours dechr: hour = hour - 1 If hour >= 24 Then hour = 23 Endif ' Debounce and delay for 250ms debounce: For i = 1 to 25 Pause 10 ' 10ms at a time so no interrupts are lost Next i update = 1 ' Set to update screen Goto chkup ' Interrupt routine to handle each timer tick disable ' Disable interrupts during interrupt handler tickint: ticks = ticks + 1 ' Count pieces of seconds If ticks < 61 Then tiexit ' 61 ticks per second (16.384ms per tick) ' One second elasped - update time ticks = 0 second = second + 1 If second >= 60 Then second = 0 minute = minute + 1 If minute >= 60 Then minute = 0 hour = hour + 1 If hour >= 24 Then hour = 0 Endif Endif Endif update = 1 ' Set to update LCD tiexit: INTCON.2 = 0 ' Reset timer interrupt flag Resume End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to demonstrate the page-write ' capability of the 24LC256 serial memory. This program ' will transfer 64 bytes of data to the memory before ' a pause is needed to complete the write. ' Set receive register to receiver enabled DEFINE HSER_RCSTA 90h ' Set transmit register to transmitter enabled DEFINE HSER_TXSTA 24h ' Set baud rate DEFINE HSER_BAUD 9600 scl VAR PORTC.3 ' Clock pin sda VAR PORTC.4 ' Data pin addr VAR WORD ' Memory Address data_array VAR BYTE[64] ' Data array with location for checksum i VAR BYTE ' Loop counter ADCON1 = 7 ' Set PORTA and PORTE to digital HSerout ["Programming", 10,13] For i = 0 to 63' Load the array with test data data_array[i] = i Next i 'From the Microchip memory databook: '"Page write operations are limited to writing 'bytes within a single physical page, 'regardless of the number of bytes actually 'being written. Physical page boundaries 'start at addresses that are integer 'multiples of the page buffer size (or 'page 'size') and end at addresses that are 'integer multiples of [page size - 1]. If a 'Page Write command attempts to write 'across a physical page boundary, the 'result is that the data wraps around to the 'beginning of the current page (overwriting 'data previously stored there), instead of 'being written to the next page, as might be 'expected. It is, therefore, necessary for the 'application software to prevent page write 'operations that would attempt to cross a 'page boundary." For addr = 0 To 32767 Step 64 ' Store $00 to all locations (for testing) I2CWrite sda,scl,$A0,addr,[STR data_array\64] ' Send a 64-byte page HSerout ["."]' Indicate progress Pause 10' Pause 10mS to let the write complete Next addr ' Spot-check the data on the terminal screen i = 0 Hserout [10,13, 10,13, "checking", 10,13] For addr = 0 to 32767 Step 257' read every 257th address i = i + 1 I2CRead sda, scl, $A0, addr, [data_array[0]]' Read a single byte from memory Hserout [HEX2 data_array[0], " "]' To terminal with hex value If (i & $0007) = 0 Then' Break it into organized lines Hserout [10,13]' 8 locations to a line Endif Next addr' Go get the next test End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to demonstrate the page-write ' capability of the 24LC256 serial memory. This program ' will transfer 64 bytes of data to the memory before ' a pause is needed to complete the write. ' Set receive register to receiver enabled DEFINE HSER_RCSTA 90h ' Set transmit register to transmitter enabled DEFINE HSER_TXSTA 24h ' Set baud rate DEFINE HSER_BAUD 9600 scl VAR PORTC.3 ' Clock pin sda VAR PORTC.4 ' Data pin addr VAR WORD ' Memory Address data_array VAR BYTE[64] ' Data array with location for checksum i VAR BYTE ' Loop counter ADCON1 = 7 ' Set PORTA and PORTE to digital HSerout ["Programming", 10,13] For i = 0 to 63' Load the array with test data data_array[i] = i Next i 'From the Microchip memory databook: '"Page write operations are limited to writing 'bytes within a single physical page, 'regardless of the number of bytes actually 'being written. Physical page boundaries 'start at addresses that are integer 'multiples of the page buffer size (or 'page 'size') and end at addresses that are 'integer multiples of [page size - 1]. If a 'Page Write command attempts to write 'across a physical page boundary, the 'result is that the data wraps around to the 'beginning of the current page (overwriting 'data previously stored there), instead of 'being written to the next page, as might be 'expected. It is, therefore, necessary for the 'application software to prevent page write 'operations that would attempt to cross a 'page boundary." For addr = 0 To 32767 Step 64 ' Store $00 to all locations (for testing) I2CWrite sda,scl,$A0,addr,[STR data_array\64] ' Send a 64-byte page HSerout ["."]' Indicate progress Pause 10' Pause 10mS to let the write complete Next addr ' Spot-check the data on the terminal screen i = 0 Hserout [10,13, 10,13, "checking", 10,13] For addr = 0 to 32767 Step 257' read every 257th address i = i + 1 I2CRead sda, scl, $A0, addr, [data_array[0]]' Read a single byte from memory Hserout [HEX2 data_array[0], " "]' To terminal with hex value If (i & $0007) = 0 Then' Break it into organized lines Hserout [10,13]' 8 locations to a line Endif Next addr' Go get the next test End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to send and receive from the hardware serial port ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DefineLOADER_USED1 ' Define LCD registers and bits Define LCD_DREG PORTD Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 char var byte ' Storage for serial character col var byte ' Keypad column row var byte ' Keypad row key var byte ' Key value lastkey var byte ' Last key storage ADCON1 = 7 ' Set PORTA and PORTE to digital Low PORTE.2 ' LCD R/W line low (W) Pause 500' Wait for LCD to startup OPTION_REG.7 = 0 ' Enable PORTB pullups key = 0 ' Initialize vars lastkey = 0 Lcdout $fe, 1 ' Initialize and clear display loop: Hserin 1, tlabel, [char] ' Get a char from serial port Lcdout char ' Send char to display tlabel: Gosub getkey ' Get a keypress if any If (key != 0) and (key != lastkey) Then Hserout [key] ' Send key out serial port Endif lastkey = key ' Save last key value Goto loop ' Do it all over again ' Subroutine to get a key from keypad getkey: key = 0 ' Preset to no key For col = 0 to 3 ' 4 columns in keypad PORTB = 0 ' All output pins low TRISB = (dcd col) ^ $ff ' Set one column pin to output row = PORTB >> 4 ' Read row If row != $f Then gotkey ' If any keydown, exit Next col Return ' No key pressed gotkey: ' Change row and column to ASCII key number key = (col * 4) + (ncd (row ^ $f)) + "0" Return ' Subroutine over End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to read and write to I2C SEEPROMs ' ' Write to the first 16 locations of an external serial EEPROM ' Read first 16 locations back and send to LCD repeatedly ' Note: for SEEPROMs with byte-sized address ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DefineLOADER_USED1 ' Define LCD registers and bits Define LCD_DREG PORTD Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 SCL var PORTC.3 ' Clock pin SDA var PORTC.4 ' Data pin B0 var byte ' Address B1 var byte ' Data 1 B2 var byte ' Data 2 ADCON1 = 7 ' Set PORTA and PORTE to digital Low PORTE.2 ' LCD R/W line low (W) Pause 100 ' Wait for LCD to start up For B0 = 0 To 15 ' Loop 16 times B1 = B0 + 100 ' B1 is data for SEEPROM I2CWRITE SDA,SCL,$A0,B0,[B1] ' Write each location Pause 10 ' Delay 10ms after each write Next B0 loop: For B0 = 0 To 15 Step 2 ' Loop 8 times I2CREAD SDA,SCL,$A0,B0,[B1,B2] ' Read 2 locations in a row Lcdout $fe,1,#B0,": ",#B1," ",#B2," " ' Display 2 locations Pause 1000 Next B0 Goto loop End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to read and write to I2C SEEPROMs ' that require a word-sized address ' ' Write to the first 16 locations of an external serial EEPROM ' Read first 16 locations back and send to LCD repeatedly ' ' Define LCD registers and bits DEFINE LCD_DREG PORTD DEFINE LCD_DBIT 4 DEFINE LCD_RSREG PORTE DEFINE LCD_RSBIT 0 DEFINE LCD_EREG PORTE DEFINE LCD_EBIT 1 SCL VAR PORTC.3 ' Clock pin SDA VAR PORTC.4 ' Data pin address VAR WORD ' Address B1 VAR BYTE ' Data 1 B2 VAR BYTE ' Data 2 ADCON1 = 7 ' Set PORTA and PORTE to digital Low PORTE.2 ' LCD R/W line low (W) Pause 100 ' Wait for LCD to start up For address = 0 TO 15 ' Loop 16 times B1 = address + 100 ' B1 is data for SEEPROM I2CWrite SDA,SCL,$A0,address,[B1] ' Write each location Pause 10 ' Delay 10ms after each write Next address loop: For address = 0 TO 15 STEP 2 ' Loop 8 times I2CRead SDA,SCL,$A0,address,[B1,B2] ' Read 2 locations in a row LCDOut $fe,1,#address,": ",#B1," ",#B2," " ' Display 2 locations Pause 1000 Next address GoTo loop End 0000000000000000000000000000000000000000000000000000000000 ' LCD clock program using JRC6355 RTC ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DefineLOADER_USED1 Include "MODEDEFS.BAS" ' Include Shiftin/out modes Define LCD_DREG PORTD ' Define LCD connections Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 ' Alias pins CE var PORTA.2 CLK var PORTC.1 SDATA var PORTC.3 IO var PORTC.5 ' Allocate variables rtcyear var byte rtcmonth var byte rtcdate var byte rtcday var byte rtchr var byte rtcmin var byte rtcsec var byte Low CE ' Disable RTC Low CLK High IO ADCON1 = 7 ' PORTA and E digital Low PORTE.2 ' LCD R/W low = write Pause 100 ' Wait for LCD to startup ' Set initial time to 8:00:00AM 07/16/99 rtcyear = $99 rtcmonth = $07 rtcdate = $16 rtcday = 6 rtchr = $08 rtcmin = 0 rtcsec = 0 Gosub settime ' Set the time Goto mainloop ' Skip subroutines ' Subroutine to write time to RTC settime: IO = 1 ' Set RTC to input CE = 1 ' Enable transfer ' Write all 7 RTC registers Shiftout SDATA, CLK, LSBFIRST, [rtcyear, rtcmonth, rtcdate, rtcday\4, rtchr, rtcmin] CE = 0 ' Disable RTC Return ' Subroutine to read time from RTC gettime: IO = 0 ' Set RTC to output CE = 1 ' Enable transfer ' Read all 7 RTC registers Shiftin SDATA, CLK, LSBPRE, [rtcyear, rtcmonth, rtcdate, rtcday\4, rtchr, rtcmin, rtcsec] CE = 0 ' Disable RTC Return ' Main program loop - in this case, it only updates the LCD with the time mainloop: Gosub gettime ' Read the time from the RTC ' Display time on LCD Lcdout $fe, 1, hex2 rtcmonth, "/", hex2 rtcdate, "/" , hex2 rtcyear,_ " ", hex2 rtchr, ":", hex2 rtcmin, ":", hex2 rtcsec Pause 300 ' Do it about 3 times a second Goto mainloop ' Do it forever End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to display key number on LCD ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DefineLOADER_USED1 ' Define LCD connections Define LCD_DREG PORTD Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 ' Define program variables col var byte ' Keypad column row var byte ' Keypad row key var byte ' Key value OPTION_REG.7 = 0 ' Enable PORTB pullups ADCON1 = 7 ' Make PORTA and PORTE digital Low PORTE.2 ' LCD R/W low (write) Pause 100 ' Wait for LCD to start Lcdout $fe, 1, "Press any key" ' Display sign on message loop: Gosub getkey ' Get a key from the keypad Lcdout $fe, 1, #key ' Display ASCII key number Goto loop ' Do it forever ' Subroutine to get a key from keypad getkey: Pause 50 ' Debounce getkeyu: ' Wait for all keys up PORTB = 0 ' All output pins low TRISB = $f0 ' Bottom 4 pins out, top 4 pins in If ((PORTB >> 4) != $f) Then getkeyu ' If any keys down, loop Pause 50 ' Debounce getkeyp: ' Wait for keypress For col = 0 to 3 ' 4 columns in keypad PORTB = 0 ' All output pins low TRISB = (dcd col) ^ $ff ' Set one column pin to output row = PORTB >> 4 ' Read row If row != $f Then gotkey ' If any keydown, exit Next col Goto getkeyp ' No keys down, go look again gotkey: ' Change row and column to key number 1 - 16 key = (col * 4) + (ncd (row ^ $f)) Return ' Subroutine over End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to display "hello world" on LCD, ' then use LCDIN to read the first letter of each line and ' change it to upper case. ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DEFINELOADER_USED1 ' Define LCD registers and bits DEFINE LCD_DREG PORTD DEFINE LCD_DBIT 4 DEFINE LCD_RSREG PORTE DEFINE LCD_RSBIT 0 DEFINE LCD_EREG PORTE DEFINE LCD_EBIT 1 DEFINELCD_RWREGPORTE DEFINELCD_RWBIT2 characterVARBYTE ADCON1 = 7 ' Set PORTA and PORTE to digital Low PORTE.2 ' LCD R/W line low (W) Pause 100 ' Wait for LCD to start up loop: LCDOut $FE, 1 ' Clear screen Pause 500 ' Wait .5 second LCDOut "hello" ' Display "hello" Pause 500 ' Wait .5 second LCDOut $fe, $C0, "world"' Move to line 2 and display "world" Pause 500 ' Wait .5 second LCDIN $80, [character]' Read value of first character, first line LCDOut $FE, $80, (character - $20)' Change character to upper case Pause 500' Wait .5 second LCDIN $C0, [character]' Read value of first character, second line LCDOut $FE, $C0, (character - $20)' Change character to upper case Pause 500' Wait .5 second GoTo loop ' Do it forever End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to display "Hello World" on LCD ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DefineLOADER_USED1 ' Define LCD registers and bits Define LCD_DREG PORTD Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 ADCON1 = 7 ' Set PORTA and PORTE to digital Low PORTE.2 ' LCD R/W line low (W) Pause 100 ' Wait for LCD to start up loop: Lcdout $fe, 1 ' Clear screen Pause 500 ' Wait .5 second Lcdout "Hello" ' Display "Hello" Pause 500 ' Wait .5 second Lcdout $fe, $c0, "World" ' Move to line 2 and display "World" Pause 500 ' Wait .5 second Goto loop ' Do it forever End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to read LTC1298 ADC ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DefineLOADER_USED1 ' Define LCD pins Define LCD_DREG PORTD Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 include "modedefs.bas" ' Alias pins CS var PORTC.5 ' Chip select CK var PORTC.3 ' Clock DI var PORTA.2 ' Data in DO var PORTC.1 ' Data out ' Allocate variables addr var byte ' Channel address / mode result var word x var word y var word z var word High CS ' Chip select inactive ADCON1 = 7 ' Set PORTA, PORTE to digital Low PORTE.2 ' LCD R/W line low (W) Pause 100 ' Wait for LCD to start Goto mainloop ' Skip subroutines ' Subroutine to read a/d convertor getad: CS = 0 ' Chip select active ' Send address / mode - Start bit, 3 bit addr, null bit] Shiftout DI, CK, MSBFIRST, [1\1, addr\3, 0\1] Shiftin DO, CK, MSBPRE, [result\12] ' Get 12-bit result CS = 1 ' Chip select inactive Return ' Subroutine to get x value (channel 0) getx: addr = $05 ' Single ended, channel 0, MSBF high Gosub getad x = result Return ' Subroutine to get y value (channel 1) gety: addr = $07 ' Single ended, channel 1, MSBF high Gosub getad y = result Return ' Subroutine to get z value (differential) getz: addr = $01 ' Differential (ch0 = +, ch1 = -), MSBF high Gosub getad z = result Return mainloop: Gosub getx ' Get x value Gosub gety ' Get y value Gosub getz ' Get z value Lcdout $fe, 1, "x=", #x, " y=", #y, " z=", #z ' Send values to LCD Pause 100 ' Do it about 10 times a second Goto mainloop ' Do it forever End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to read and write to Microwire SEEPROM 93LC56A ' ' Write to the first 16 locations of an external serial EEPROM ' Read first 16 locations back and send to LCD repeatedly ' Note: for SEEPROMs with byte-sized address ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DefineLOADER_USED1 ' Define LCD registers and bits Define LCD_DREG PORTD Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 include "modedefs.bas" CS var PORTA.5 ' Chip select pin CLK var PORTC.3 ' Clock pin DI var PORTC.4 ' Data in pin DO var PORTC.5 ' Data out pin addr var byte ' Address B0 var byte ' Data Low CS ' Chip select inactive ADCON1 = 7 ' Set PORTA and PORTE to digital Low PORTE.2 ' LCD R/W line low (W) Pause 100 ' Wait for LCD to start up Gosub eewriteen ' Enable SEEPROM writes For addr = 0 To 15 ' Loop 16 times B0 = addr + 100 ' B0 is data for SEEPROM Gosub eewrite ' Write to SEEPROM Pause 10 ' Delay 10ms after each write Next addr loop: For addr = 0 To 15 ' Loop 16 times Gosub eeread ' Read from SEEPROM Lcdout $fe,1,#addr,": ",#B0 ' Display Pause 1000 Next addr Goto loop ' Subroutine to read data from addr in serial EEPROM eeread: CS = 1 ' Enable serial EEPROM Shiftout DI, CLK, MSBFIRST, [%1100\4, addr] ' Send read command and address Shiftin DO, CLK, MSBPOST, [B0] ' Read data CS = 0 ' Disable Return ' Subroutine to write data at addr in serial EEPROM eewrite: CS = 1 ' Enable serial EEPROM Shiftout DI, CLK, MSBFIRST, [%1010\4, addr, B0] ' Send write command, address and data CS = 0 ' Disable Return ' Subroutine to enable writes to serial EEPROM eewriteen: CS = 1 ' Enable serial EEPROM Shiftout DI, CLK, MSBFIRST, [%10011\5, 0\7] ' Send write enable command and dummy clocks CS = 0 ' Disable Return End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to receive HEX file from PC and write ' data to I2C memory. Writes data in page mode, 16 bytes at one ' time. Memory device must be addressed with 16 bits and capable ' of receiving 16 bytes at once. ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DefineLOADER_USED1 ' Set receive register to receiver enabled DEFINE HSER_RCSTA 90h ' Set transmit register to transmitter enabled DEFINE HSER_TXSTA 20h ' Set baud rate DEFINE HSER_BAUD 2400 scl VAR PORTC.3 ' Clock pin sda VAR PORTC.4 ' Data pin pinin VARPORTC.7 ' Serial receive pin pinout VAR PORTC.6 ' Serial transmit pin addr VAR WORD ' Memory Address dta1 VAR BYTE[17] ' Data array with location for checksum bb VAR BYTE ' Byte count tt VAR BYTE ' Record type i VAR WORD ' Loop counter cs VAR BYTE ' Checksum ln VAR BYTE ' Line count Clear ' Clear RAM data ADCON1 = 7 ' Set PORTA and PORTE to digital ln = 0 ' Clear line count HSerout ["Erasing"] For i = 0 To 8192 Step 8 ' Store $00 to all locations (for testing) I2CWrite sda,scl,$A0,i,[STR dta1\8] If i//256 = 0 Then HSerout ["."] EndIf Pause 6 Next i HSerout [13,10,"Ready",13,10]' Notify: ready for file loop: cs = 0 ' Reset checksum byte HSerin [WAIT(":"),HEX2 bb,HEX4 addr,HEX2 tt] ' Receive line and parse cs = bb + addr.lowbyte + addr.highbyte + tt' Begin checksum calculation If (tt = 1) Then eof ' Check for end of file For i = 0 To bb ' Loop for each expected data-byte and checksum HSerin [HEX2 dta1[i]] ' Store each byte to location in array cs = cs + dta1[i] ' Add each byte to checksum calculation Next i ln = ln + 1 ' Count line received If (cs <> 0) Then sume ' Check for checksum error I2CWrite sda,scl,$A0,addr,[STR dta1\bb] ' Write data to device, checksum is dropped Goto loop' Go get another line sume: HSerout ["Checksum Error: line ",DEC ln,13,10] ' Notify: checksum error eof: HSerout [DEC ln," lines received",13,10] ' Notify: Confirm line count For i = 0 To (ln*16) ' Loop 16 times for each line received I2CRead sda,scl,$A0,i,[cs]' Read back each character HSerout [HEX2 cs]' Send each character If (i+1)//16 = 0 Then HSerout [13,10]' New line every 16 characters EndIf Next i HSerout [13,10,13,10] ' New Lines End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to receive HEX file from PC and write ' data to I2C memory. Writes data in page mode, 8 bytes at one ' time. Memory device must be addressed with 8 bits and capable ' of receiving 8 bytes at once. ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DefineLOADER_USED1 ' Set receive register to receiver enabled DEFINE HSER_RCSTA 90h ' Set transmit register to transmitter enabled DEFINE HSER_TXSTA 20h ' Set baud rate DEFINE HSER_BAUD 2400 scl VAR PORTC.3 ' Clock pin sda VAR PORTC.4 ' Data pin pinin VARPORTC.7' Serial receive pin pinout VARPORTC.6 ' Serial transmit pin addr VARBYTE ' Memory Address dta1 VARBYTE[9] ' Data array with location for checksum bb VARBYTE ' Byte count ttVARBYTE ' Record type iVARBYTE ' Loop counter csVARBYTE ' Checksum lnVARBYTE ' Line count Clear ' Clear RAM data ADCON1 = 7 ' Set PORTA and PORTE to digital ln = 0 ' Clear line count For i = 0 To 255 Step 8 ' Store $00 to first 256 locations (for testing) I2CWrite sda,scl,$A0,i,[STR dta1\8] Pause 10 Next i HSerout ["Ready",13,10]' Notify: ready for file loop: cs = 0 ' Reset checksum byte HSerin [WAIT(":"),HEX2 bb,HEX4 addr,HEX2 tt] ' Receive line and parse cs = bb + addr + tt ' Begin checksum calculation If (tt = 1) Then eof ' Check for end of file If (bb>8) Then ' Write twice if more that 8 bytes of data on line For i = 0 To 7 ' Loop for first 8 bytes of data HSerin [HEX2 dta1[i]] ' Store each byte to location in array cs = cs + dta1[i]' Add each byte to checksum calculation Next i I2CWrite sda,scl,$A0,addr,[STR dta1\8] ' Write 8 bytes of data to device bb = bb - 8 addr = addr + 8 For i = 0 To (bb)' Loop for remaining expected data-bytes and checksum HSerin [HEX2 dta1[i]] ' Store each byte to location in array cs = cs + dta1[i] ' Add each byte to checksum calculation Next i If (cs <> 0) Then sume ' Check for checksum error I2CWrite sda,scl,$A0,addr,[STR dta1\bb] ' Write remaining data to device Else ' Write once if 8 or less bytes of data For i = 0 To bb ' Loop for each expected data-byte and checksum HSerin [HEX2 dta1[i]] ' Store each byte to location in array cs = cs + dta1[i] ' Add each byte to checksum calculation Next i If (cs <> 0) Then sume ' Check for checksum error I2CWrite sda,scl,$A0,addr,[STR dta1\bb] ' Write data to device EndIf ln = ln + 1 ' Count line received Goto loop ' Go get another line sume: HSerout ["Checksum Error: line ",DEC ln,13,10] ' Notify: checksum error eof: HSerout [DEC ln," lines received",13,10]' Notify: Confirm line count For i = 0 To (ln*16)' Loop 16 times for each line received I2CRead sda,scl,$A0,i,[cs]' Read back each character HSerout [HEX2 cs] ' Send each character If (i+1)//16 = 0 Then HSerout [13,10]' New line every 16 characters EndIf Next i HSerout [13,10,13,10] ' New Lines End 0000000000000000000000000000000000000000000000000000000000 ' LCD clock program using Dallas1202/1302 RTC ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. DefineLOADER_USED1 Include "MODEDEFS.BAS" ' Include Shiftin/out modes Define LCD_DREG PORTD ' Define LCD connections Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 ' Alias pins RST var PORTA.2 IO var PORTC.1 SCLK var PORTC.3 ' Allocate variables rtcyear var byte rtcday var byte rtcmonth var byte rtcdate var byte rtchr var byte rtcmin var byte rtcsec var byte rtccontrol var byte Low RST ' Reset RTC Low SCLK ADCON1 = 7 ' PORTA and E digital Low PORTE.2 ' LCD R/W low = write Pause 100 ' Wait for LCD to startup ' Set initial time to 8:00:00AM 07/16/99 rtcyear = $99 rtcday = $06 rtcmonth = $07 rtcdate = $16 rtchr = $08 rtcmin = 0 rtcsec = 0 Gosub settime ' Set the time Goto mainloop ' Skip subroutines ' Subroutine to write time to RTC settime: RST = 1 ' Ready for transfer ' Enable write Shiftout IO, SCLK, LSBFIRST, [$8e, 0] RST = 0 ' Reset RTC RST = 1 ' Ready for transfer ' Write all 8 RTC registers in burst mode Shiftout IO, SCLK, LSBFIRST, [$be, rtcsec, rtcmin, rtchr, rtcdate, rtcmonth, rtcday, rtcyear, 0] RST = 0 ' Reset RTC Return ' Subroutine to read time from RTC gettime: RST = 1 ' Ready for transfer Shiftout IO, SCLK, LSBFIRST, [$bf] ' Read all 8 RTC registers in burst mode Shiftin IO, SCLK, LSBPRE, [rtcsec, rtcmin, rtchr, rtcdate, rtcmonth, rtcday, rtcyear, rtccontrol] RST = 0 ' Reset RTC Return ' Main program loop - in this case, it only updates the LCD with the time mainloop: Gosub gettime ' Read the time from the RTC ' Display time on LCD Lcdout $fe, 1, hex2 rtcmonth, "/", hex2 rtcdate, "/" , hex2 rtcyear,_ " ", hex2 rtchr, ":", hex2 rtcmin, ":", hex2 rtcsec Pause 300 ' Do it about 3 times a second Goto mainloop ' Do it forever End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to read and write to code space ' Flash Program Write must be enabled on your programmer ' ' Write to 8 locations of code space beginning at $1800 ' Read 8 locations back and send to LCD repeatedly ' Define LCD registers and bits Define LCD_DREG PORTD Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 I var byte ' Loop count D var byte ' Data A var word ' Address ADCON1 = 7 ' Set PORTA and PORTE to digital Low PORTE.2 ' LCD R/W line low (W) Pause 100 ' Wait for LCD to start up For I = 0 To 7 ' Loop 8 times, once for each address $1800 to $1807 A = $1800 + I' Increment Address D = I + $A0 ' Change Data Writecode A,D ' Send value in D to code space location A Next I loop: For I = 0 To 7 ' Loop 8 times, once for each address $1800 to $1807 A = $1800 + I' Increment Address Readcode A,D' Get data in location A Lcdout $fe,1,hex A,": ",hex D ' Display the location and data Pause 1000 Next I Goto loop End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to demonstrate an interrupt-driven ' input buffer for hardware USART receive using Assembly ' language interrupt. ' Pin definitions compatible with LAB-X1 and PIC16F877 ' Defines for LCD DEFINE LCD_DREG PORTD DEFINE LCD_DBIT 4 DEFINE LCD_RSREG PORTE DEFINE LCD_RSBIT 0 DEFINE LCD_EREG PORTE DEFINE LCD_EBIT 1 ' Define interrupt handler DEFINE INTHAND myint ' Configure internal registers ADCON1 = 7' Set PortA and E to digital operation RCSTA = $90' Enable USART receive TXSTA = $24' Set USART parameters SPBRG = 25' Set baud rate to 9600 LEDVARPORTD.0' Alias LED to PORTD.0 CRENVAR RCSTA.4' Alias CREN (Serial receive enable) 'Variables for saving state in interrupt handler wsaveVARBYTE $70 system' Saves W ssaveVARBYTE bank0 system' Saves STATUS psaveVARBYTE bank0 system' Saves PCLATH fsaveVARBYTE bank0 system' Saves FSR buffer_sizeCON32' Sets size of ring buffer bufferVARBYTE[buffer_size]' Array variable for holding received characters index_inVARBYTE bank0' Pointer - next empty location in buffer index_outVARBYTE bank0' Pointer - location of oldest character in buffer errflagVARBYTE bank0 ' Error flag bufcharVARBYTE' Stores the character retrieved from the buffer colVARBYTE' Stores location on LCD for text wrapping iVARBYTE' Loop counter GoTo start' Skip around interrupt handler ' Assembly language INTERRUPT handler Asm myint ; Uncomment the following if the device has less than 2k of code space ;movwfwsave; Save W ;swapfSTATUS, W; Swap STATUS to W (swap avoids changing STATUS) ;clrfSTATUS; Clear STATUS ;movwfssave; Save swapped STATUS ;movfPCLATH, W; Move PCLATH to W ;movwfpsave; Save PCLATH ; Save the FSR value for later movfFSR, W; Move FSR to W movwffsave; Save FSR ; Check for hardware overrun error btfscRCSTA,OERR; Check for usart overrun GoTo usart_err; jump to assembly error routine ; Find in which bank the compiler put buffer, and set IRP IF (_buffer > 0FFh); Find the bank where buffer is located bsfSTATUS,IRP; If bank 2 or 3 set IRP Else bcfSTATUS,IRP; If bank 0 or 1 clear IRP EndIF ; Test for buffer overrun incf_index_in, W; Increment index_in to W subwf_index_out, W; Subtract indexes to test for buffer overrun btfscSTATUS,Z; check for zero (index_in = index_out) GoTobuffer_err; jump to error routine if zero ; Increment the index_in pointer and reset it if it's outside the ring buffer incf_index_in, F; Increment index_in to index_in movf_index_in, W; Move new index_in to W sublw_buffer_size-1; Subtract index_in from buffer_size-1 btfssSTATUS,C; If index_in => buffer_size clrf_index_in; Clear index_in ; Set FSR with the location of the next empty location in buffer movlwLow _buffer; Get the location of buffer[0] addwf_index_in, W; Add index_in to point to next empty slot movwfFSR; Store pointer in FSR ; Read and store the character from the USART movf RCREG, W; Read the received character movwfINDF; Put the received character in FSR location ; Restore FSR, PCLATH, STATUS and W registers finished movffsave, W; retrieve FSR value movwfFSR; Restore it to FSR movfpsave, W; Retrieve PCLATH value movwfPCLATH; Restore it to PCLATH swapfssave, W; Retrieve the swapped STATUS value (swap to avoid changing STATUS) movwfSTATUS; Restore it to STATUS swapfwsave, F; Swap the stored W value swapfwsave, W; Restore it to W (swap to avoid changing STATUS) retfie; Return from the interrupt ; Error routines buffer_err; Jump here on buffer error bsf_errflag,1; Set the buffer flag usart_err; Jump here on USART error bsf_errflag,0; Set the USART flag movfRCREG, W; Trash the received character GoTofinished; Restore state and return to program EndAsm start: ' Initialize variables index_in = 0 index_out = 0 col = 1 errflag = 0 INTCON = %11000000' Enable interrupts PIE1.5 = 1' Enable interrupt on USART Low PORTE.2 ' LCD R/W line low (W) Pause 100 ' Wait for LCD to start LCDOut $fe,1' Clear LCD ' Main program starts here - blink an LED at 1Hz loop: High LED ' Turn on LED connected to PORTD.0 Pause 500 ' Pause 500mS Low LED ' Turn off LED connected to PORTD.0 Pause 500' Pause 500mS display:' dump the buffer to the LCD IF errflag Then error' Goto error routine if needed IF index_in = index_out Then loop' loop if nothing in buffer GoSub getbuf' Get a character from buffer LCDOut bufchar' Send the character to LCD col = col + 1' Increment LCD location IF col > 20 Then' Check for end of line col = 1' Reset LCD location LCDOut $fe,$c0,REP " "\20' Clear any error on line-2 of LCD LCDOut $FE,2' Tell LCD to return home EndIF GoTo display' Check for more characters in buffer ' Subroutines ' Get a character from the buffer getbuf:' Move the next character in buffer to bufchar intcon = 0' Disable interrupts while reading buffer index_out = index_out + 1' Increment index_out pointer (0 to 63) IF index_out => buffer_size Then index_out = 0' Reset pointer if outside buffer bufchar = buffer[index_out]' Read buffer location(index_out) INTCON = %11000000' Enable interrupts Return ' Display an error error:' Display error message INTCON = 0' Disable interrupts while in the error routine IF errflag.1 Then' Determine the error LCDOut $FE,$c0,"Buffer Overrun"' Display buffer error on line-2 Else LCDOut $FE,$c0,"USART Overrun"' Display usart error on line_2 EndIF LCDOut $fe,2' Send the LCD cursor back to line-1 home For i = 2 TO col' Loop for each column beyond 1 LCDOut $fe,$14' Put the cursor back where it was Next i errflag = 0' Reset the error flag CREN = 0' Disable continuous receive to clear hardware error CREN = 1' Enable continuous receive INTCON = %11000000' Enable interrupts GoTo display' Carry on End 0000000000000000000000000000000000000000000000000000000000 ' PicBasic Pro program to demonstrate an interrupt-driven ' input buffer for Hserin using On Interrupt. ' Pin definitions compatible with LAB-X1 and PIC16F877 ' Defines for LCD and USART DEFINE HSER_RCSTA 90h DEFINE HSER_TXSTA 24h DEFINE HSER_BAUD 9600 DEFINE LCD_DREG PORTD DEFINE LCD_DBIT 4 DEFINE LCD_RSREG PORTE DEFINE LCD_RSBIT 0 DEFINE LCD_EREG PORTE DEFINE LCD_EBIT 1 ADCON1 = 7' Set PortA and E to digital operation RCIFVARPIR1.5' Alias RCIF (USART Receive Interrupt Flag) OERRVARRCSTA.1' Alias OERR (USART Overrun Error Flag) CRENVARRCSTA.4' Alias CREN (USART Continuous Receive Enable) LED VARPORTD.0 ' Alias LED to PORTD.0 buffer_sizeCON32' Sets the size of the ring buffer bufferVARBYTE[buffer_size]' Array variable for holding received characters index_inVARBYTE' Pointer - next empty location in buffer index_outVARBYTE' Pointer - location of oldest character in buffer bufcharVARBYTE' Stores the character retrieved from the buffer iVARBYTE' loop counter colVARBYTE' Stores location on LCD for text wrapping errflagVARBYTE' Holds error flags ' Initialize variables index_in = 0 index_out = 0 i = 0 col = 1 Low PORTE.2 ' LCD R/W line low (W) Pause 100 ' Wait for LCD to start LCDOut $fe,1' Clear LCD INTCON = %11000000' Enable interrupts ON INTERRUPT GoTo serialin' Declare interrupt handler routine PIE1.5 = 1' Enable interrupt on USART ' Main program starts here - blink an LED at 1Hz loop: High LED ' Turn on LED connected to PORTD.0 For i = 0 to 250' Delay for .5 seconds (250*2mS) Pause 2 ' Use a short pause within a loop Next i' instead of one long pause Low LED ' Turn off LED connected to PORTD.0 For i = 0 to 250' Delay for .5 seconds (250*2mS) Pause 2 ' Use a short pause within a loop Next i' instead of one long pause display:' dump the buffer to the LCD IF errflag Then error' Handle error if needed IF index_in = index_out Then loop' loop if nothing in buffer GoSub getbuf' Get a character from buffer LCDOut bufchar' Send the character to LCD col = col + 1' Increment LCD location IF col > 20 Then' Check for end of line col = 1' Reset LCD location LCDOut $fe,$c0,REP " "\20' Clear line-2 of LCD LCDOut $FE,2' Tell LCD to return home EndIF GoTo display' Check for more characters in buffer ' Subroutines Disable' Don't check for interrupts in this section getbuf:' move the next character in buffer to bufchar index_out = (index_out + 1)' Increment index_out pointer (0 to 63) IF index_out > (buffer_size-1) Then index_out = 0' Reset pointer if outside of buffer bufchar = buffer[index_out]' Read buffer location Return error:' Display error message if buffer has overrun IF errflag.1 Then' Determine the error LCDOut $FE,$c0,"Buffer Overrun"' Display buffer error on line-2 Else LCDOut $FE,$c0,"USART Overrun"' Display usart error on line-2 EndIF LCDOut $fe,2' Send the LCD cursor back to line-1 home For i = 2 to col' Loop for each column beyond 1 LCDOut $fe,$14' Move the cursor right to the right column Next i errflag = 0' Reset the error flag CREN = 0' Disable continuous receive to clear overrun flag CREN = 1' Enable continuous receive GoTo display' Carry on ' Interrupt handler serialin:' Buffer the character received IF OERR Then usart_error' Check for USART errors index_in = (index_in + 1)' Increment index_in pointer (0 to 63) IF index_in > (buffer_size-1) Then index_in = 0'Reset pointer if outside of buffer IF index_in = index_out Then buffer_error' Check for buffer overrun HSerin [buffer[index_in]]' Read USART and store character to next empty location IF RCIF Then serialin' Check for another character while we're here Resume' Return to program buffer_error: errflag.1 = 1' Set the error flag for software ' Move pointer back to avoid corrupting the buffer. MIN insures that it ends up within the buffer. index_in = (index_in - 1) MIN (buffer_size - 1) HSerin [buffer[index_in]]' Overwrite the last character stored (resets the interrupt flag) usart_error: |