' {$STAMP BS2} ' {$PBASIC 2.5} ' -----[ Program Description ]--------------------------------------------- ' Frequency and duty cycle meter using BS2. The results are displayed on an ' parallel LCD. ' Tronicgr 2006 for Greekbotics.knows.it (26/5/2006) ' Η LCD συνδεεται με τον BS2 μεσω ενος 74HC595 shift register. ' ' Basic Stamp2, LCD and 74HC595 connections: ' NC = no connect ' PU = Pulled Up to +5V thru a 10K resistor ' 74HC595 ' ------\_/------ ' -NC- -| 1 16 |- Vcc +5V ' LCD 6 (E) -| 2 15 |- -NC- ' LCD 4 (RS) -| 3 14 |- BS2 P13 (Shift DATA) ' LCD 11 (D4) -| 4 13 |- GND ' LCD 12 (D5) -| 5 12 |- BS2 P15 (OUTPUT latch) ' LCD 13 (D6) -| 6 11 |- BS2 P14 (Shift clock) ' LCD 14 (D7) -| 7 10 |- PU Pulled Up TO +5V through 10K resistor ' GND -| 8 9 |- -NC- ' --------------- ' Power related connections of the LCD ' LCD 1 - GND ' LCD 2 - VDD +5V ' LCD 3 - GND ' LCD 5 - GND ' -----[ I/O Definitions ]------------------------------------------------- ' LCD control constants SData CON 11 ' 74HC595 serial data (14) Clk CON 14 ' 74HC595 shift clock (11) Latch CON 15 ' 74HC595 output latch (12) ' -----[ Constants ]------------------------------------------------------- mSec CON 100 ' Measurement time in msec - BS2 FreqPin CON 10 ' frequency input pin (on bs2) #DEFINE Lcd = 1 ' set to 0 for VFD οθονη #DEFINE BarGraph = 1 ' set to 0 for no graph LcdCls CON $01 ' clear the LCD LcdHome CON $02 ' move cursor home LcdCrsrL CON $10 ' move cursor left LcdCrsrR CON $14 ' move cursor right LcdDispL CON $18 ' shift chars left LcdDispR CON $1C ' shift chars right LcdDDRam CON $80 ' Display Data RAM control LcdCGRam CON $40 ' Character Generator RAM LcdLine1 CON $80 ' DDRAM address of line 1 LcdLine2 CON $C0 ' DDRAM address of line 2 ' -----[ Variables ]------------------------------------------------------- temp VAR Byte ' temp var used on LCD lcd_E VAR temp.BIT2 ' LCD Enable pin lcd_RS VAR temp.BIT3 freq VAR Word ' frequency t1 VAR Word pulselen VAR Word r VAR Word ' Remainder i VAR Nib ' Iterations point VAR Bit result VAR Word ' calculated float-point output char VAR Byte ' for LCD addr VAR Word ' ee pointer (for DATA) percent VAR Word ' % of max data value VAR Word ' value to print width VAR Nib ' width of print field pad VAR Nib ' spaces for rj printing idx VAR Byte ' loop counter cols VAR Byte ' total graph colums blox VAR Byte ' whole blocks for graph ' -----[ EEPROM Data ]----------------------------------------------------- Banner1 DATA " TronicGR 2006", 0 Banner2 DATA "Frequency meter", 0 DefaultL1 DATA " Hz 0 %", 0 #IF Lcd #THEN CC0 DATA $10, $10, $10, $10, $10, $10, $10, $00 CC1 DATA $18, $18, $18, $18, $18, $18, $18, $00 CC2 DATA $1C, $1C, $1C, $1C, $1C, $1C, $1C, $00 CC3 DATA $1E, $1E, $1E, $1E, $1E, $1E, $1E, $00 CC4 DATA $1F, $1F, $1F, $1F, $1F, $1F, $1F, $00 #ENDIF ' -----[ Initialization ]-------------------------------------------------- point = 1 Reset: LCDini: PAUSE 800 char = %0011 GOSUB LCD_Command PAUSE 5 GOSUB LCD_Command GOSUB LCD_Command char = %0010 GOSUB LCD_Command char = %00101000 GOSUB LCD_Command char = %00001100 GOSUB LCD_Command char = %00000110 GOSUB LCD_Command DL_Characters: #IF Lcd #THEN char = LcdCGRam ' point to CG RAM GOSUB LCD_Command ' prepare to write CG data FOR idx = CC0 TO (CC4 + 7) ' build 5 custom chars READ idx, char ' get byte from EEPROM GOSUB LCD_Write ' put into LCD CG RAM NEXT #ENDIF Banner: char = LcdCls GOSUB LCD_Command addr = Banner1 GOSUB LCD_Put_String char = LcdLine2 GOSUB LCD_Command addr = Banner2 GOSUB LCD_Put_String PAUSE 500 char = LcdCls GOSUB LCD_Command addr = DefaultL1 GOSUB LCD_Put_String ' -----[ Program Code ]---------------------------------------------------- Main: GOSUB freq_measure 'Κανει την μετρηση GOSUB Duty_cycle_measure GOSUB Show_data GOSUB Show_Percent GOTO Main ' -----[ Subroutines ]----------------------------------------------------- Duty_cycle_measure: PULSIN FreqPin,1,T1 'READ T1 PULSIN FreqPin,0,pulselen 'READ T2 pulselen = pulselen + t1 r = t1 // pulselen ' Remainder percent = 0 ' Clear fractional quotient FOR i = 1 TO 4 ' Four digits to right of decimal r = r * 10 ' Multiply remainder by 10 percent = (10 * percent) + (r / pulselen) ' Multiply quotient by 10 and add r = r // pulselen ' Calculate next remainder NEXT RETURN freq_measure: COUNT FreqPin, mSec, freq ' collect pulses for 1 second result= freq *10 RETURN Show_data: char = LcdLine1 GOSUB LCD_Command width = 5 point = 0 value = result GOSUB LCD_Put_RJ_Value RETURN Show_Percent: char = LcdLine1 + 10 GOSUB LCD_Command width = 4 point = 1 value = percent GOSUB LCD_Put_RJ_Value #IF BarGraph #THEN char = LcdLine2 ' position cursor GOSUB LCD_Command cols = (percent/100) */ 205 ' x 0.8 (100% = 80 pixels) blox = cols / 5 ' calculate whole blocks IF (blox > 0) THEN char = 4 FOR idx = 1 TO blox GOSUB LCD_Write NEXT ENDIF LOOKUP (cols // 5), [" ", 0, 1, 2, 3], char ' partial block GOSUB LCD_Write char = " " FOR idx = 0 TO (16 - blox) ' clear end of graph display GOSUB LCD_Write NEXT #ENDIF RETURN LCD_Put_String: DO READ addr, char addr = addr + 1 IF (char = 0) THEN EXIT GOSUB LCD_Write LOOP RETURN LCD_Put_RJ_Value: LOOKDOWN value, >=[10000, 1000, 100, 10, 0], pad pad = pad - (5 - width) IF (pad > 0) THEN char = " " FOR idx = 1 TO pad GOSUB LCD_Write NEXT ENDIF FOR idx = (width - pad - 1) TO 0 char = value DIG idx + "0" GOSUB LCD_Write IF idx = 2 THEN IF point THEN char = "." GOSUB LCD_Write ENDIF ENDIF NEXT RETURN ' -----[ LCD Subroutines ]----------------------------------------------------- ' ' LCD_Command: lcd_RS = 0 GOTO LCDout ' LCD_Write: lcd_RS = 1 GOSUB LCDout RETURN LCDout: temp.HIGHNIB = char.HIGHNIB lcd_E = 1 SHIFTOUT SData, Clk, MSBFIRST, [temp] PULSOUT Latch, 1 lcd_E = 0 SHIFTOUT SData, Clk, MSBFIRST, [temp] PULSOUT Latch, 1 temp.HIGHNIB = char.LOWNIB lcd_E = 1 SHIFTOUT SData, Clk, MSBFIRST, [temp] PULSOUT Latch, 1 lcd_E = 0 SHIFTOUT SData, Clk, MSBFIRST, [temp] PULSOUT Latch, 1 lcd_RS = 1 RETURN