' ********************************************************************** ' * File gmbade.bas - Rel. 1.1 con Bascom 8051 IDE e LIB 2.0.11.0 * ' * GRIFO(R) via Dell'Artigiano 8/6 40016 S. Giorgio di Piano (BO) * ' * Tel. +39 051 892052 Fax. +39 051 893661 * ' * http://www.grifo.com http://www.grifo.it * ' * sales@grifo.it tech@grifo.it grifo@grifo.it * ' * by Graziano Gaiba del 11.07.03 * ' ********************************************************************** ' ' ' ' Rel. 1.1 11.07.03 - By Graziano Gaiba ' ' According to Mini Module selected, if analog input signal on CN4 is available, ' this demo offers two possibilities: calibration or acquisition. ' First action determinates a calibration coefficent using an external reference ' voltage provided by the user and stored it in Mini Module internal EEPROM. ' Second action fetches calibration coefficent from EEPROM, acquires and shows ' continuously on console the analog input combination, both uncalibrated and ' calibrated. Demo can be used without problems with range 0..2.5 V and 0..10 V. ' '****************** Compiler directives ************************** ' $regfile = "grifo_mm.dat" $romstart = &H0 ' start address of code for FLASH $ramstart = &H0 ' start address of external RAM $ramsize = &H100 ' 256 bytes of external RAM $crystal = 14745600 ' Microcontroller clock $baud = 19200 ' RS-232 baud rate $large ' 16 bit addressing for jumps ' (Not for demo version) $map ' Generates address map ' '****************** Constants declaration *********************** ' Const Cret = 13 ' Carriage return Const Nl = 10 ' New line Const Clrscr = 12 ' Clear screen Const Bell = 7 ' Bell ' Board where the demo is running Const Can_gm1 = "1" Const Can_gm2 = "2" Const Gmm_5115 = "3" Const Ee_timeout = 5000 ' Timeout internal EEPROM programming ' '*********************** Variables declaration ************************* ' ' Generic use Dim S1 As String * 1 ' One character strings Dim S As Byte , T As Byte , M As Byte ' Generic use ' Board where the demo is running Dim Scheda As Byte 'Used by demo A/D Dim Cmb As Long , Kcmb As Long ' Theoric and effective combination Dim Kcal As Long 'Used to read and write CPU internal EEPROM and by A/D conversion Dim Ind As Word , Id As Word 'Used by correctly approximated division Dim Divisore As Long , Dividendo As Long Dim Q As Byte ' Quotient ' '****************** Procedures declaration ********************** ' Declare Sub Init() ' Initialization Declare Sub Synch() ' Synchronization Declare Sub Synch_0() Declare Sub Synch_1() Declare Sub Check_ready ' Check for hardware ready Declare Sub Demoad() ' Demo A/D converter Declare Sub Scrivi_eeprom(ind As Word , S As Byte) Declare Sub Leggi_eeprom(ind As Word) Declare Sub Adconv(m As Byte) ' Performs A/D conversion of channel m ' 8 bit integer quotient, correctly approximated Declare Sub Divappr(divisore As Long , Dividendo As Long) ' '**************************** Main program ********************************* ' Main: Call Init() ' Inzializza il modulo Print Chr(clrscr); ' Clears the screen Print "This demo has been made to run only on a CAN GM1." Print "Proceed only if you have the correct Mini Module!" Print "Press a key if you want to continue..." Do S = Inkey Loop Until S <> 0 Print Print "Module used:" Print "1) CAN GM1" Print "2) CAN GM2" Print Print "Select:"; Do Scheda = Inkey ' Wait for a key Loop Until Scheda <> 0 Print Chr(scheda) Print Call Check_ready Do Call Demoad Loop End ' '************************ Fine del programma *************************** ' ' '**************************** Procedure ******************************** ' ' Initialize demo Sub Init() Disable Interrupts ' Disables interrupts Auxr = &H0C ' Selects Eram on external data area Eecon = &H00 ' Disables write to micro Eeprom End Sub Sub Demoad Print Chr(clrscr) If Scheda = Can_gm1 Then Print "Analog input section of GMB HR84 is based on precision components anyway" Print "subject to small tollerances." Print "To compensate such tollerances it is suggersted to acquire analog input" Print "through a software calibration." Print Do Do Print "Select mode: Acquisition, Calibration, End: "; S1 = Waitkey S1 = Ucase(s1 ) Loop Until S1 = "A" Or S1 = "C" Or S1 = "E" Print S1 Adcf = &H01 ' Set P1.0 as A/D input Adclk = &H10 ' Set clock A/D If S1 = "C" Then ' Calibration mode Print "Connect an analog reference signal close to full scale to pin 8 of CN4:" Print "(2.5V if J6 in 1-2) or 10V (if J6 in 2-3) and input the value of this " Input "signal, in mV (0-10000): " , Kcal Kcmb = Kcal * 1023 ' Determine theorical combination If Kcal > 2500 Then Kcmb = Kcmb / 10000 Else Kcmb = Kcmb / 2500 End If Cmb = 0 ' Determine real combination For T = 1 To 64 ' Performs 64 conversions Call Adconv(0) ' Conversion input 0 Cmb = Cmb + Ind Next T Cmb = Cmb / 64 'Rotate Cmb , Right , 6 ' Calculates average of 64 combinations Kcmb = Kcmb * 10000 ' Calculates calibration coefficent with 4 decimals Kcal = Kcmb / Cmb Print Print "Calibration coefficent saved = " ; Kcal Print Auxr = &H2E ' Deselects Eram and extends Movx duration Eecon = &H02 ' Selects CPU internal EEPROM to be mapped on external data Call Scrivi_eeprom(&H07f9 , Low(kcal)) Call Scrivi_eeprom(&H07fa , High(kcal)) Auxr = &H0C ' Selects Eram on external data area Eecon = &H00 ' Disables write to micro Eeprom End If If S1 = "A" Then Auxr = &H2E ' Deselects Eram and extends Movx duration Eecon = &H02 ' Selects CPU internal EEPROM to be mapped on external data Call Leggi_eeprom(&H07f9) T = S Call Leggi_eeprom(&H07fa) Kcal = Makeint(t , S) ' Legge coefficiente di calibrazione Auxr = &H0C ' Selects Eram on external data area Eecon = &H00 ' Disables write to micro Eeprom Print "Calibration coefficent read = " ; Kcal Print "Connect to pin 8 of CN4 an analog signal in the range 0-2.5V (J6 in" Print "1-2) or 0-10V (J6 in 2-3) and test the combinations below." Print "Press a key" Print "CH0 acquired CH0 calibrated" Do Print Chr(cret); Call Adconv(0) ' Convert input 0 Print " " ; Ind; ' Shows combination acquired Kcmb = Ind * Kcal ' Determines combination calibred Cmb = Kcmb / 10000 Print " " ; Cmb; ' Shows combination calibrated Waitms 300 ' Prevents overflow on console S = Inkey Loop Until S <> 0 Print End If Adcf = &H00 ' Set P1 as digital I/O Loop Until S1 = "E" Else Print "A/D conversion input can be used only with CAN GM1." Do Loop End If End Sub ' Performs an A/D converter acquisition in polling ' Uses global variables m and ind Sub Adconv(m As Byte) Adcon = M Or &H20 ' Selects channel and prepared A/D Adcon = M Or &H28 ' Starts the conversion Do ' Waits for conversion end M = Adcon And &H10 Loop Until M = &H10 Adcon = 0 ' A/D in standby Ind = 0 ' Reads the combination Ind = Addh Rotate Ind , Left , 2 M = Addl And &H03 Ind = Ind Or M End Sub ' Scrive il byte fornito come secondo parametro nella EEPROM interna ' all'indirizzo fornito come primo parametro. ' Si aspetta che la EEPROM interna sia gia' abilitata. Sub Scrivi_eeprom(ind As Word , S As Byte) Out Ind , S ' Writes data to latch Eecon = &H52 ' Activates internal EEPROM write Eecon = &HA2 Ind = 0 ' Start timeout count Do Incr Id S = Eecon ' Reads busy EEPROM bit S = S And &H01 ' If bit is 1, EEPROM busy Loop Until S = 0 Or Ind = Ee_timeout End Sub ' Reads the byte in internal EEPROM at address specified by the parameter. ' Expects internal EEPROM already enabled. Sub Leggi_eeprom(ind As Word) S = Inp(ind) End Sub ' Procedure to calculate 8 bit integer quotient, correctly approximated ' between dividend and divisor passed as parameters, using successive ' subtractions technique. Sub Divappr(divisore As Long , Dividendo As Long) Q = 0 While Dividendo >= Divisore Dividendo = Dividendo - Divisore Incr Q Wend Rotate Divisore , Right , 1 ' Halfs divisor for remainder check If Dividendo >= Divisore Then Incr Q End If End Sub ' Synchronization Sub Synch() nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop End Sub Sub Synch_0() P2.1 = 0 P2.0 = 0 Call Synch() P2.0 = 1 Call Synch() P2.0 = 0 End Sub Sub Synch_1() P2.1 = 1 P2.0 = 0 Call Synch() P2.0 = 1 Call Synch() P2.0 = 0 End Sub Sub Check_ready Do ' Check hardware ready S = P2.1 I2cstart Call Synch_1() Call Synch_0() Call Synch_1() Call Synch_0() Call Synch_0() Call Synch_0() Call Synch_0() Call Synch_0() P2.1 = 1 P2.0 = 0 Call Synch() P2.0 = 1 T = P2.1 Call Synch() P2.0 = 0 Loop Until S <> 0 And T <> 1 End Sub