Vous êtes sur la page 1sur 13

PICBASIC PRO PROGRAM TO READ POTENTIOMETERS ON 16F887 ADC. ' Name : adcx.

pbp ' Compiler : PICBASIC PRO Compiler 2.60 ' Assembler : PM or MPASM ' Target PIC : 40-pin 16F887 ' Hardware : Lab-X1 ' Oscillator : 4MHz external crystal ' Keywords : ADC, ANALOG, LCDOUT, LCD ' Description : PICBASIC PRO program to read pots on 16F887 ADC ' 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 ' Define ADCIN parameters ******************************** ADCON1 = %00000000 ' Left-Justify result in ADRESH:ADRESL registers ANSEL = %00001011 ' Set AN0, AN1, AN3 to analog, others digital ANSELH = %00000000 ' Set AN8 and higher channels to digital operation '********************************************************** ' Allocate variables x Var Byte y Var Byte z Var Byte Low PORTE.2 Pause 100 Goto mainloop ' LCD R/W line low (W) ' Wait for LCD to start ' Skip subroutines

' Subroutine to read a/d convertor getad: Pauseus 100 ' Wait for channel to setup ADCON0.1 = 1 Pauseus 100 Return ' Subroutine to get pot x value getx: ADCON0 = $41 ' Set A/D to Fosc/8, Channel 0, On Gosub getad x = ADRESH Return ' Start conversion ' Wait for conversion

' Subroutine to get pot y value gety: ADCON0 = $45 ' Set A/D to Fosc/8, Channel 1, On Gosub getad y = ADRESH Return ' Subroutine to get pot z value getz: ADCON0 = $4D ' Set A/D to Fosc/8, Channel 3, On Gosub getad z = ADRESH Return mainloop: Gosub getx Gosub gety Gosub getz

' Get x value ' Get y value ' 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 End mainloop ' Do it forever

PICBASIC PRO PROGRAM FOR LCD CLOCK USING THE DALLAS 1202/1302 RTC. ' Name : RTCX.pbp ' Compiler : PICBASIC PRO Compiler 2.60 ' Assembler : PM or MPASM ' Target PIC : 40-pin 16F887 ' Hardware : LAB-X1 Experimenter Board ' Oscillator : 4MHz external crystal ' Keywords : LCDOUT, SHIFTIN, SHIFTOUT ' Description : PICBASIC PRO program for LCD clock using the ' Dallas 1202/1302 RTC ICs. ' ' Define LOADER_USED to allow use of the boot loader. ' This will not affect normal program operation. Define LOADER_USED 1 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 ANSEL = %00000000 ' Make AN0-AN7 digital ANSELH= %00000000 ' Make AN8-AN13 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

PICBASIC PRO PROGRAM TO DEMONSTRATE THE USE OF TIMER1 INTERRUPT FOR A REAL-TIME CLOCK. ' Name : TMR1CLKX.pbp ' Compiler : PICBASIC PRO Compiler 2.60 ' Assembler : PM or MPASM ' Target PIC : 40-pin 16F887 or similar ' Hardware : LAB-X1 Experimenter Board ' Oscillator : 4MHz external crystal ' Keywords : ASSEMBLY INTERRUPTS, LCDOUT, TIMER1 ' Description : PICBASIC PRO program that demonstrates the use of ' Timer1 interrupt for a real-time clock. Written for the LAB-X1 ' experimenter board with a 16F887. ' ' Define interrupt handler Define INTHAND myint wsave VAR BYTE $20 system wsave1 VAR BYTE $a0 system ' Necessary for devices with RAM in bank1 wsave2 VAR BYTE $120 system ' Necessary for devices with RAM in bank2 wsave3 VAR BYTE $1a0 system ' Necessary for devices with RAM in bank3 ssave VAR BYTE bank0 system psave VAR BYTE bank0 system TICK VAR BYTE bank0 ' make sure that the variables are in bank 0 ' if they are to be used in the interrupt handler seconds VAR BYTE minutes VAR WORD minutes = 0 seconds = 0 ' Elapsed seconds ' Elapsed minutes

' Clear time

T1CON = $01 ' Turn on Timer1, prescaler = 1 INTCON = $C0 ' Enable global interrupts, peripheral interrupts PIE1 = $01 ' Enable TMR1 overflow interrupt GoTo main ' jump over the interrupt handler and sub

' Assembly language interrupt handler Asm myint ; Uncomment the following if the device has less than 2k of code space ;movwf wsave ; Save W ;swapf STATUS,W ; Swap STATUS to W (swap avoids changing STATUS) ;clrf STATUS ; Clear STATUS ;movwf ssave ; Save swapped STATUS ;movf PCLATH,W ; Move PCLATH to W ;movwf psave ; Save PCLATH ; Set the high register of Timer1 to cause an interrupt every

; 16384 counts (65536-16384=49152 or $C000). At 4MHz, prescale ; set to 1, this equates to a tick every 16384uS. This works ; out to about 61 ticks per second, with a slight error. The ; error could be reduced substantially by setting the TMR1L ; register and playing with different values for the prescaler ; and the ticks per second. movlw 0C0h ; Prepare to set TMR1 high register movwf TMR1H ; Set TMR1H to C0h incf _TICK,F ; INCREMENT TICK COUNT bcf PIR1,0 ; Clear interrupt flag movf psave,W ; restore the state of everything movwf PCLATH swapf ssave,W movwf STATUS swapf wsave,F swapf wsave,W retfie ; Return from interrupt EndAsm ' PicBasic subroutine to update the minutes and seconds variables get_time: ' Update the time when needed. The TICK variable will ' overflow if you don't update within 4 seconds. This could ' be done in the interrupt handler, but it's easier to do ' it in PicBasic, and you usually want the interrupt handler ' to be as short and fast as possible. PIE1 = 0 ' Mask the interrupt while we're messing with TICK seconds = seconds + (tick/61) ' Add the accumulated seconds tick = tick // 61 ' Retain the left-over ticks PIE1 = $01 ' Interrupt on again minutes = minutes + (seconds / 60) ' Add the accumulated minutes seconds = seconds // 60 ' Retain the left-over seconds Return ' Return to the main program main ' Begin program code here. The minutes and seconds variables can ' be used in your code. The time will be updated when you call the ' get_time routine. Disable interrupts while executing timing-critical ' commands, like serial communications. DEFINE LCD_DREG PORTD DEFINE LCD_DBIT 4 DEFINE LCD_RSREG PORTE DEFINE LCD_RSBIT 0 DEFINE LCD_EREG PORTE DEFINE LCD_EBIT 1 loops VAR WORD loops = 0

ANSEL = %00000000 ' Make PORTA and PORTE digital ANSELH= %00000000 ' Make PORTA and PORTE digital Low PORTE.2 ' Enable the LCD Pause 150 ' Pause to allow LCD to initialize LCDOut $fe,1 ' Clear LCD mainloop: loops = loops + 1 LCDOut $fe,$C0,"Loops Counted: ", DEC5 loops GoSub get_time ' Update minutes and seconds LCDOut $fe, 2, "Time: ",DEC5 minutes, ":", DEC2 seconds ' Display the elapsed time GoTo mainloop ' Repeat main loop End

PICBASIC PRO PROGRAM TO MEASURE VOLTAGE (0-5VDC) AND DISPLAY ON LCD WITH 2 DECIMAL PLACES. THIS PROGRAM USES THE */ OPERATOR TO SCALE THE ADC RESULT FROM 01023 TO 0-500. THE */ PERFORMS A DIVIDE BY 256 AUTOMATICALLY, ALLOWING MATHS WHICH WOULD NORMALLY EXCEED THE LIMIT OF A WORD VARIABLE. ' Name : VMETERX.pbp ' Compiler : PICBASIC PRO Compiler 2.60 ' Assembler : PM or MPASM ' Target PIC : 40-pin 16F887 or similar ' Hardware : LAB-X1 Experimenter Board ' Oscillator : 4MHz external ' Keywords : ADCIN, LCDOUT ' Description : PICBASIC PRO program to measure voltage (0-5VDC) ' and display on LCD with 2 decimal places. ' This program uses the */ operator to scale the ADC result from 0-1023 ' to 0-500. The */ performs a divide by 256 automatically, allowing math ' which would normally exceed the limit of a word variable. ' Connect analog input to channel-0 (RA0) ' 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 10 ' Set number of bits in result Define ADC_SAMPLEUS 50 ' Set sampling time in uS 'Define ADC_CLOCK 3 ' This define is inoperative on 16F88x ADCON0 = %11000000 ' Set ADC_CLOCK to RC (DEFINE ACD_CLOCK inoperative on the 16F88x) ADCON1 = %10000000 ' Right-Justify result in ADRESH:ADRESL registers ANSEL = %00000001 ' Set AN0-AN7 to digital with the exeption of AN0 ANSELH = %00000000 ' Set AN8 and higher channels to digital operation '********************************************************** adval Var Word ' Create adval to store result

TRISA = %11111111 ' Set PORTA to all input Low PORTE.2 ' LCD R/W line low (W) Pause 500 ' Wait .5 second mainloop: Adcin 0, adval ' Read channel 0 to adval (0-1023) adval = (adval */ 500)>>2 ' Equates to: (adval * 500)/1024 Pause 100 ' Wait .1 second LCDOut $FE, $80, "DC Volts= ",DEC (adval/100),".", DEC2 adval ' Display the decimal value Goto mainloop ' Do it forever End

PICBASIC PRO PROGRAM FOR SERVO CONTROL USING ON INTERRUPT. USES TMR0 AND PRESCALER. WATCHDOG TIMER SHOULD BE SET TO OFF AT PROGRAM TIME AND NAP OR SLEEP SHOULD NOT BE USED. BUTTONS ON KEYPAD ARE USED TO MOVE SERVOS. ' Name : SERVOSX.pbp ' Compiler : PICBASIC PRO Compiler 2.60 ' Assembler : PM or MPASM ' Target PIC : 40-pin 16F887 ' Hardware : LAB-X1 Experimenter Board ' Oscillator : 4MHz external crystal ' Keywords : ON INTERRUPT, TIMER0 ' Description : PICBASIC PRO program for servo control 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 on LAB-X1 keypad are ' used to move servos. ' 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 Servo1Pos VAR Word ' Servo 1 position Servo2Pos VAR Word ' Servo 2 position ServoSelect VAR Bit ' Servo selection Servo1 VAR PORTC.1 ' Alias first servo pin Servo2 VAR PORTC.0 ' Alias second servo pin ServoSelect = 0 ' Set to first servo Low Servo1 ' Set up servos Low Servo2 Servo1Pos = 500 ' Center servos Servo2Pos = 500 ANSEL = %00000000 ' Make PORTA and PORTE digital ANSELH= %00000000 ' Make PORTA and PORTE digital Low PORTE.2 ' LCD R/W low = write Pause 100 ' Wait for LCD to startup Lcdout $fe, 1 ' Clear screen OPTION_REG = $7f ' Enable PORTB pullups ' 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 timerint ' Main program loop mainloop: PORTB = 0 ' PORTB lines low to read buttons

TRISB = $fe

' Enable first button row (RB0=output=LOW)

' Check for button press to move servo IF PORTB.4 = 0 Then ' SW1 on LAB-X1 keypad GoSub left1 Endif IF PORTB.5 = 0 Then ' SW2 on LAB-X1 keypad GoSub right1 Endif IF PORTB.6 = 0 Then ' SW3 on LAB-X1 keypad GoSub left2 Endif IF PORTB.7 = 0 Then ' SW4 on LAB-X1 keypad GoSub right2 Endif Lcdout $fe, $80, "Position1 = ", #Servo1Pos, " " Lcdout $fe, $c0, "Position2 = ", #Servo2Pos, " " GoTo mainloop ' Do it all forever ' Move servo 1 left left1: IF Servo1Pos < 1000 Then Servo1Pos = Servo1Pos + 1 Endif Pause 10 ' Debounce Return ' Move servo 1 right right1: IF Servo1Pos != 0 Then Servo1Pos = Servo1Pos - 1 Endif Pause 10 ' Debounce Return ' Move servo 2 left left2: IF Servo2Pos < 1000 Then Servo2Pos = Servo2Pos + 1 Endif Pause 10 ' Debounce Return ' Move servo 2 right right2: IF Servo2Pos != 0 Then Servo2Pos = Servo2Pos - 1 Endif Pause 10 ' Debounce Return ' Interrupt routine to handle timer

Disable ' Disable interrupts during interrupt handler timerint: IF ServoSelect Then tiservo2 Servo1 = 1 ' Do first servo PauseUs 1000 + Servo1Pos Servo1 = 0 GoTo tiexit tiservo2: Servo2 = 1 ' Do second servo PauseUs 1000 + Servo2Pos Servo2 = 0 tiexit: ServoSelect = ServoSelect + 1 ' Point to next servo INTCON.2 = 0 ' Reset timer interrupt flag Resume End

PICBASIC PRO PROGRAM TO DISPLAY RESULT OF 8-BIT A/D CONVERSION ON LCD. CONNECT ANALOGUE INPUTS TO CHANNELS 0, 1, 3 (RA0, 1, 3). ' Name : adcin3x.pbp ' Compiler : PICBASIC PRO Compiler 2.60 ' Assembler : PM or MPASM ' Target PIC : 40-pin 16F887 ' Hardware : Lab-X1 ' Oscillator : 4MHz external crystal ' Keywords : ADC, ADCIN, ANALOG, LCDOUT, LCD ' Description : 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 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_SAMPLEUS 50 ' Set sampling time in uS 'Define ADC_CLOCK 3 ' This define is inoperative on 16F88x ADCON0 = %11000000 ' Set ADC_CLOCK to RC (DEFINE ACD_CLOCK inoperative on the 16F88x) ADCON1 = %00000000 ' Left-Justify result in ADRESH:ADRESL registers ANSEL = %00001011 ' Set AN0, AN1, AN3 to analog, others digital ANSELH = %00000000 ' Set AN8 and higher channels to digital operation '********************************************************** adval Var Byte ' Create adval to store result

TRISA = %11111111 ' Set PORTA to all input Pause 500 mainloop: Lcdout $fe, 1 ' Wait .5 second

' Clear the LCD

Adcin 0, adval ' Read the first ADC channel Lcdout "0=", #adval ' Send it to the LCD Adcin 1, adval ' Read the second ADC channel Lcdout " 1=", #adval ' Send it to the LCD Adcin 3, adval ' Read the third ADC channel Lcdout " 3=", #adval ' Send it to the LCD

Pause 200 Goto mainloop End

' Delay for time to read the display ' Do it forever

Vous aimerez peut-être aussi