You are on page 1of 215

Application Notes

Application Notes
All application notes in one file! Thanks to Michael Akers.
Download application_notes.chm (600 KB)

BASCOM LT and BASCOM-8051 application notes

AN 01 , Evaluation board for the AT89C2051 and AT89C4051


This is a simple evaluation board for testing the AT89C2051.
AN 02, Reading the TLC2543 A/D converter
Written by Miguel Ziga from IBERCOMP SA.
AN 03, A Garden Watering Program
Written by Miguel Ziga from IBERCOMP SA.
AN 04, Read the Dallas temperature sensor DS1821.
This is an 1wire example written by Denis Bernard.
AN 05, Reading an AT PC Keyboard
Written by Dusko Djuricin.
AN 06, Reading the Dallas DS1820 temperature sensor.
Written by Bojan Ivancic
AN 07, Big Digit ThermoMeter
Written by RETI/Belgium.
AN 08, Flash programmer
An AT89Cx051 programmer.
Designed by MCS Electronics
AN 09, Controlling the X9CMME
Written by MCS Electronics
AN 10, BASCOM-LT and BASCOM-8051Hardware simulation
AN 11, Using an I2C clock device with the PCF8583.
AN 12, Using the TIMER interrupt to make a clock with LED-display by Mirko
Pelcl
AN 13, Keyboard decoder by Mike Gill
AN 14, How to implement a flow meter using the 80552
This application note was donated by Mike Crean
AN 15. LCD VU meter.
This aplication note was donated by Ger Langezaal.
AN 16, Using the Sharp GP2D02 distance sensor
The following application note was donated by Lex Bolkesteijn.
AN 17, Telephonecard reader
This application note was donated by Erich Linsmeier
AN 18, Page scanner
This application note was donated by Mike Gill
AN 19, Using the LM75 temperature sensor by Michael Akers
AN 20, How to decode SONY IR remote control signals

file:///F|/FrontPage Webs/Content/server/applicat.htm (1 of 2) [15-7-2000 23:50:10]


Application Notes

Not an AN but a PC program that generates a signal with an adjustable


frequency on pin 2 and ground of your LPT port. Donated by Clinton
McKinnon.
AN 21, ASCII input with 3x4 keyboard matrix by John van der Putte
AN 22, Two examples about Multi Tasking provided by David H. Lawrence
from Rhombus
AN 23, reading and writing the Dallas DS1991 secure I-button. By Evert
Dekker.
AN 24, how to increase resolution of DS1821 temperature sensor. By Dusko
Djuricin.
AN 25, using the T6963 based GRAPHIC DISPLAY. By Peter Huijssen
AN 26, LAB PLC, a PLC implementation by Mirko Bjelica. I have never seen a
so complete Application note before : circuit, software, documentation, it is al
there!
Yours next?

BASCOM AVR application notes.

AN 101, BASCOM-AVR example that demonstrates SNAP protocol.


This first AVR application note was donated by Mike Eitel
AN 102, Bit twiddle outputs on 74HC595 daisy chained shift registers to
control relays. By Jim Gillespie.
AN 103, Serial to GPIB converter. By Jan Petersen
AN 104, Measuring temperatur with 90S2313 and BASCOM-AVR. By Jorge
Ferrero
Yours next?

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: juli 11, 2000

file:///F|/FrontPage Webs/Content/server/applicat.htm (2 of 2) [15-7-2000 23:50:10]


Home

Our Company
We design professional hardware and software for embedded systems.
Our core business is designing BASIC compilers for the 8051 and AVR.
Our products are low priced and affordable for hobbyists.

Contact Information
Telephone
+31 75 6148799

FAX
+31 75 6144189

Postal address
MCS Electronics
G. Brautigamstraat 11, 1506WL
Zaandam
HOLLAND

Electronic mail
General Information: info@mcselec.com
Sales: info@mcselec.com
Webmaster: mark@mcselec.com

You are visitor number since 11 feb 2000

Current time in New York

Current time in Los Angeles

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: juni 01, 2000

file:///F|/FrontPage Webs/Content/server/index.htm [15-7-2000 23:50:18]


MCS Table of Contents Page

Home
MCS News Page
MCS Products Page
BASCOM-AVR
BASCOM LT
BASCOM-8051
SimmStick
PLM-24
CANDIP
ATMEGA103
ISP Programmer
F2 KIT and TIO-16
MCS Flashprogrammer
SE512-514
Test PCB
FPQP
Downloads
Pricelist
Resellers
Application Notes
AN 01, Evaluation board for the AT89C2051 and AT89C4051
AN 02, Reading the TLC2543 A/D converter
AN 03, A Garden Watering Program
AN 04, Reading the Dallas temperature sensor DS1821
AN 05, Reading the AT PC Keyboard
AN 06, Reading the DS1820 temperature sensor
AN 07, Big Digit ThermoMeter
AN 08 , Flash Programmer
AN 09, Controlling the X9CMME
AN 10, BASCOM-LT and BASCOM-8051 Hardware simulation
AN 11, Using an I2C clock device with the PCF8583.
AN 12, Using the TIMER interrupt to make a clock with
LED-display.

file:///F|/FrontPage Webs/Content/server/toc.htm (1 of 2) [15-7-2000 23:50:18]


MCS Table of Contents Page

AN 13, Keyboard decoder by Mike Gill


AN 14, How to implement a flow meter using the 80552
AN 15, LCD VU Meter
AN 16, Using the Sharp GP2D02 distance sensor
AN 17, Telephone card reader
AN 18, page scanner
AN 19, Using the LM75 with BASCOM
AN 20, how to decode Sony IR remote control signals
AN 21, ASCII input with 3x4 keyboard matrix
AN 22, Mutitasking with BASCOM-8051
AN 23, Reading and writing the Dallas DS1991 secure I-button
AN 24, how to increase resolution of DS1821 temperature sensor
AN 25, Using the T6963 based GRAPHIC DISPLAY
AN 26, LAB PLC, a PLC implementation in BASCOM-8051
AN 101, BASCOM-AVR SNAP protocol example
AN 102, Bit twiddle outputs on 74HC595 daisy chained shift
registers to control relays
AN 103, Serial to GPIB converter
Links
NCS Neff Computer Systeme
Holger Fritz, AT89S8252 uP board
Custom Engineering
BASCOM maillist
Support
Publications about BASCOM
MCS Table of Contents Page
MCS Search Page
MCS Feedback Page
FB Result

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: mei 17, 1999

file:///F|/FrontPage Webs/Content/server/toc.htm (2 of 2) [15-7-2000 23:50:18]


MCS Search Page

You may search our web site for all documents containing matching words or
patterns.

Search for:

Start Search Clear

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: mei 17, 1999

file:///F|/FrontPage Webs/Content/server/search.htm [15-7-2000 23:50:18]


MCS Feedback Page

Please tell us what you think about our web site, company,
products, or services. Please provide contact information so
that we will be able to reach you in case we have any
questions.
When you have a question it is better to send an
email because the results of the feedback page are
only read once in a few weeks.

Comments

Category

Web site

Contact Information

Name

E-mail

Submit Feedback Reset Form

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: maart 02, 2000

file:///F|/FrontPage Webs/Content/server/feedback.htm [15-7-2000 23:50:19]


Resellers

Argentina
Dinastia Soft
Oscar H. Gonzalez
Roca 2239 (1714)
Ituzaingo
Buenos Aires
Argentina

Phone: +54-1-4621-0237
Fax : +54-1-4621-0237
Email : dinastiasof@infovia.com.ar
WWW : http://www.dinastiasoft.com.ar

Australia & USA


DonTronics
Don McKenzie P.O.
Box 595
Tullamarine 3043
Australia
Email don@dontronics.com
WWW http://www.dontronics.com

Austria
RIBU ELEKTRONIK GMBH
Muehlgasse 18
A-8160 Weiz

Phone : 03172-64800
Fax : 03172-64806
Email : office@ribu.at
WWW :http://www.ribu.at

Brazil
WF AUTOMAO INDSTRIA COMRCIO SERVIOS LTDA ME

file:///F|/FrontPage Webs/Content/server/reseller.htm (1 of 8) [15-7-2000 23:50:20]


Resellers
Miguel Wisintainer
RUA 2 DE SETEMBRO, 733
CEP 89052-000
BLUMENAU S.C
BRASIL
Email: wf@blusoft.org.br
WWW:http://www.blusoft.org.br/wf/

Canada
Zanthic Technologies Inc
Steve Letkeman
75 Vintage Meadows Place. S.E.
Medicine Hat, Alberta
T1B 4G8 Canada
Phone: 403-526-8318
Fax : 403-528-9708

Email : zanthic@zanthic.com
WWW: http://www.zanthic.com

China, Japan, Singapore, Malaysia, Taiwan,


Thailand and Hongkong
DIY Electronics (HK) Ltd.
Peter Crowcroft
P.O. Box 88458
Sham Shui Po, Hong Kong
CHINA
Phone: +852 2720 0255
Fax : +852 2725 0610
Email : peter@kitsrus.com
WWW: http://kitsrus.com

Croatia, Bosnia, Macedonia and Slovenia


AX Elektronika d.o.o.
Managing Director: Jure Mikeln
p.p.5127
1001 Ljubljana
SLOVENIA
Phone: +386-61-14-914-00, -14-914-05 (ISDN)
Fax : +386-61-485-688
Email : jure.mikeln@svet-el.si
WWW: http://www.svet-el.si/english

Czech & Slovak

file:///F|/FrontPage Webs/Content/server/reseller.htm (2 of 8) [15-7-2000 23:50:20]


Resellers

LAMIA s.r.o.
Antonin Straka
Porici 20a
Blansko
678 01
CZECH REPUBLIC
Phone: +00420-506-418726
Fax : +00420-506-53988

France
SARL OPTIMINFO
M. Belouet
France
Phone: +(33) 03 80 57 14 17
Fax : +(33) 03 80 57 14 17
Email : Optiminfo@libertysurf.fr
WWW: www.optiminfo.com

Germany & Switserland


Consulting & Distribution
Dr. - Ing. Claus Kuehnel
Muehlenstrasse 9
D-01257 Dresden
GERMANY
Phone:+41.1.785.02.38
Fax :+41.1.785.02.75
Email : info@ckuehnel.ch
WWW: http://www.ckuehnel.ch

Germany
Elektronikladen Mikrocomputer GmbH
Martin Danne
Wilhelm.-Mellies-Str. 88
D- 32758 Detmold
GERMANY
Phone: +49 5232-8171
Fax : +49 5232-86197
E-Mail: sales@elektronikladen.de
WWW: www.elektronikladen.de
Vertriebsbros in Hamburg, Berlin, Leipzig, Frankfurt, Mnchen

Hungary
CODIX Ltd, Hungary
Imre Gaspar
Atilla u 1-3,
H-1013 Budapest
HUNGARY

file:///F|/FrontPage Webs/Content/server/reseller.htm (3 of 8) [15-7-2000 23:50:20]


Resellers

Phone: +361 156 6330


Fax : +361 156 4376
Email codix@mail.matav.hu
WWW http://www.hpconline.com/codix

Italy
Grifo(R)
Salvatore Damino
Via dell'Artigiano 8/6
40016 S.Giorgio di Piano BO
ITALY
Phone: +39 (51) 892.052
Fax : +39 (51) 893.661
Email : tech@grifo.it
WWW: http://www.grifo.com (Englisch)
WWW: http://www.grifo.it (Italian)

Japan (8051 related products)


MOMIZI DENSHI
Osamu Hamakawa
AOMADANI-NISHI-2-4-8-804
MINO-CITY
JAPAN 562-0023
Phone:+81-727-28-7855
Fax: +81-727-28-7855
Email momizi@mb.infoweb.ne.jp

Japan (AVR related products)


International Parts & Information Co.,Ltd.
Shuji Nonaka
Sengen 2-1-6 Tukuba City
Ibaraki Pref.
JAPAN 305-0047
Phone: +81-298-50-3113
Fax : +81-298-50-3114
Email sales@ipic.co.jp
WWW http://www.ipic.co.jp

Korea
SAMPLE Electronics Co.
Junghoon Kim
306 Jeshin 43-22 Shinkey Youngsan Seoul Korea
Postal code 140-090
Phone: 82-2-707-3882
Fax : 82-2-707-3884

file:///F|/FrontPage Webs/Content/server/reseller.htm (4 of 8) [15-7-2000 23:50:20]


Resellers

Email : info@sample.co.kr
WWW: http://www.sample.co.kr

Malaysia and Singapore


I-Pal Communications
Ling SM
14 Dickson Road
Singapore 209500
Singapore
Phone: 65-362 0950
Fax : 65-362-2437
Email : admin@i-pal.com
WWW: http://www.i-pal.com/embedded.html

Pakistan
ORRIS MICRO SYSTEM
Malik Muhammad Nawaz Awan
15/Y, TARIQ BIN ZIAD COLONY, SAHIWAL.
PAKISTAN
Phone: 0441-66982
Email : oms@brain.net.pk

Poland
RK-SYSTEM
Robert Kacprzycki
CHELMONSKIEGO 30
05-825 GRODZISK MAZ.
POLAND.

Phone: +4822 724 30 39


Fax: +4822 724 30 37
Email: robertk@univcomp.waw.pl
WWW: http://www.rk-system.com.pl

Portugal & Spain


Multidigital, Lda
Joaquim Boavida
P.O. Box 137
4435 Rio Tinto
PORTUGAL
Phone: +351 - 2 - 6102217
Fax : +351 - 2 - 4862173
Email: info@multidigital.com
WWW: http://www.multidigital.com

file:///F|/FrontPage Webs/Content/server/reseller.htm (5 of 8) [15-7-2000 23:50:20]


Resellers

Scandinavia (Sweden, Norway, Denmark)


High Tech Horizon
ChristerJohansson
Asbogatan 29 C
S-262 51 Angelholm
SWEDEN
Phone: +46 431-41 00 88
Fax : +46 431-41 00 88
Email: info@hth.com
WWW: http://www.hth.coml

Sweden
LAWICEL
Lars Wictorsson
Klubbgatan 3
SE-282 32 TYRINGE
SWEDEN
Phone: +46 (0)451 59877
Fax : +46 (0)451 59878
WWW: http://www.lawicel.com
Email : info@lawicel.com

Spain
Ibercomp
Miquel Zuniga
C/. del Parc, numero 8 (bajos)
E-07014
Palma de Mallorca
Spain
Phone: +34 (9) 71 45 66 42
Fax : +34 (9) 71 45 67 58
Email: ibercomp@atlas-iap.es
WWW: http://www.ibercomp.es

Turkey
IBD Limited Sirketi
379/1 Sokak A-Blok No: 2/101
AFA Sanayi Carsisi - II.Sanayi
35100 Bornova - Izmir

Phone: 0090-232-4627477 - 78
Fax: 0090-232-4627545
E-mail : ibdltd@superonline.com
E-mail : ibd@ibd-ltd.com
E-mail : sales@ibd-ltd.com
E-mail : faruk@ibd-ltd.com
WWW : www.ibd.com.tr

file:///F|/FrontPage Webs/Content/server/reseller.htm (6 of 8) [15-7-2000 23:50:20]


Resellers

UK
TECHMAIL SOLUTIONS LTD
Dogan Ibrahim
14 Dunvegan Road
Eltham
London SE9 1SA
Phone: 0171 343 5242 or 0181 488 9689
Fax : 0171 821 6744
Email: dogan@dircon.co.uk
WWW www.users.dircon.co.uk/~dogan/dogan/

UK
QUASAR ELECTRONICS
Simon Neil
Unit 14 Sunningdale
BISHOP'S STORTFORD
Herts
CM23 2PA
UNITED KINGDOM
TEL: +44 (0)1279 306504
FAX: +44 (0)870 7064222
Email: simon@quasarelectronics.com
WWW http://www.quasarelectronics.com/home.htm

USA
DonTronics
Don McKenzie P.O.
Box 595
Tullamarine 3043
Australia
Email don@dontronics.com
WWW http://www.dontronics.com

USA
Techniks, Inc.
Frank Capelle
PO Box 463
Ringoes, NJ 08551
USA

Phone: 908-788-8249

file:///F|/FrontPage Webs/Content/server/reseller.htm (7 of 8) [15-7-2000 23:50:20]


Resellers

Fax: 908-788-8837
Email: Techniks@techniks.com
WWW: http://www.techniks.com

USA
M. Akers Enterprises
Michael W. Akers, US BASCOM support
3800 Vineyard Avenue #E
Pleasanton, CA 94566-6734
USA

Phone: +1-925-640-3600
Fax: +1-925-640-3600
Email: info@mwakers.com
WWW: http://www.mwakers.com

USA
Rhombus
David H. Lawrence
1909 Old Mountain Creek Road
Greenville, SC 29609
USA

Phone: +1-864-233-8330
Fax: +1-864-233-8331
Email: webmaster@rhombusinc.com
WWW: http://www.rhombusinc.com

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: juni 27, 2000

file:///F|/FrontPage Webs/Content/server/reseller.htm (8 of 8) [15-7-2000 23:50:20]


Links

Links
Here is a list of links that can be of great interest
Gianni made a complete project based on the 89C2051 and bascom-8051 , in fact
few basic statement and lot of asm. But squeeze everything in 2Kb is quite hard .
http://www.geocities.com/SiliconValley/Lab/9128/gianni/analizzatore_nicd/nicd.html
Sorry but whole documentation is in italian.
Nico H.C.J. Veth, pa0nhc has a site for Radio Amateurs : www.pa0nhc.net
A new AVR Mega board is developed by Robert Bastubbe.
http://www.opticompo.com/letatwork_en.html
Roland Walter's AVR Programmer. Works with BASCOM-AVR too.
http://www.rowalt.de/mc/
Roland also has other information about AVR on his site available.
Grifo FMO52 special board with monitor. Supported by BASCOM.
NCS Neff Computer Systeme . 80535 uP board. Work very well.
Holger Fritz At89S8252 board. Very nice design with I2C controller chip.
Custom Soft and hardware design
Links to capable people that can help you on commercial base with your project.
Ben's HobbyCorner , 80535 projects with ASM code, a free monitor program and
PCB's. A must for the 80535 user!
Michael Wste is a journalist and Radio Amateur. so he has Radio Amateur related
info. He also founded the :
BASCOM software pool. Take a look at the code and code snippets or send some
code yourself! Contains many nice examples.
Michael Akers has an ftp site with BASCOM related samples and data sheets. The ftp
site also contains the BASCOM update files. Look at
ftp://ftp.mwakers.com/pub/clients/Bascom
Michael is also one of our US resellers.
Zlatko & Zeljko did a great job on interfacing IDE disks. Check it out on
http://www.angelfire.com/de2/zel/
Iguana Labs runned by James Atwell. He sells the PG302 programmer supported by
BASCOM.
Erich Linsmeier have done a lot of projects with BASCOM. Most of them are Radio
Amateur related.
-(HAM) T7F-Control (a controlunit for a 70cm-Amateur-transceiver
with AD-Converter and EEPROM, and LCD)
-Video-RGB-Converter for TFT-LCD (I2C controlled Videoprocessor)
-Controlunit for Philips-TV-Tuner via I2C
-VPS-Controller, displays information from line 16 (videosignal) in
a 2line LCD Cardreader (see application notes)
-I2C-Stamp (an controller and EEPROM, which sends cont. or one
time I2C-Command)

file:///F|/FrontPage Webs/Content/server/links.htm (1 of 3) [15-7-2000 23:50:20]


Links
Contrive. The Italian company that translated the BASCOM documentation into
Italian.

Contrive designes lots of industrial used products. They are specialised in


safety-related techniques and the
capability to reach the international certification for this.

Some of their products:

- burner managing devices


- flame monitoring devices
- plant supervisors
- TRAX, a custom industrial bus reliable for remote supervision in
harsh environments.
- ECC (electronic climate control) for auomotive purpose (Ferrari
F348, Maserati, Ford Mondeo after-market, Golf &
Passat, after-market, etc ... air conditioning controllers).

Contrive has also a complementary branch, raised through the years for internal
purposes and next proposed to the market.
The Manufacturing service Team, the service bureau for PCB manufacturers
(photoplotting, CNC, CAM...), with 10 years
experience have now the capability to produce 3 days guaranteed PCB prototypes, 1
o 2 sides thru-plated,
tin-plated, needs one day more if you want solder-mask and/or component
silkscreen.
http://space.tin.it/economia/gpedruz/
Eddie Mcmullen has a site with exiting products.

ATCPU , an extremely flexible and cost effective prototyping development board


based on the Atmel compatible and
AVR in circuit programmable flash microcontrollers.

ATISP provides an in circuit programming system for Atmel AT89S and AT90S
microcontroller based systems.
The ATISP PCB provides the required circuitry for downloading code via the PC
parallel port to the user's target
system.
ATISP PCB is connected to the parallel port via a user supplied 25 pin point to point
modem cable. A user cable is
also required to connect the 4 programming signals that are brought out on a 10 pin
header on ATISP into the user
target system. Software comes with full source code.
No dongle is required.
Telesystems company
A collection of links devoted to microcontrollers.
Support and detail information about PICPROG Microcontrollers and
E(E)PROM production quality programmer.

Telesystems company:

Electronic systems development and manufacturing.


Embedded systems custom design.
Electronic components import and distribution.
Technical literature publishing.

Telesystems products:

Microcontrollers and E(E)PROM production quality programmer

file:///F|/FrontPage Webs/Content/server/links.htm (2 of 3) [15-7-2000 23:50:20]


Links

PICPROG (PICmicro, KeeLoq, AVR, megaAVR, Scenix, Serial EEPROM,


EEPROM,EPROM etc...)
"PICmicro 16F(C)8x Copier" - handheld device operating in a standalone mode
which can copy a series of chips from
the original one. You can copy even if the original device is code-protected.
Phones with integrated Caller ID, Standalone Caller IDs, Computer telephony tools,
Micro PBX, Security systems,
Telephone line protection systems.
Unity Online
This is the Windows 95 software for the Mini Flash Programmer which was first
presented in Elektuur october 1996. It is
fully compatible with the presented hardware in Elektuur october 1996 and offers
full support for the ATMEL 89Cx051
series of micro controllers.

NCS Neff Computer Systeme


80535 based boards. Works very well.
Need info on a chip? http://www.findchips.com is what you need!
Mike Eitel http://home.sunrise.ch/meitel : some AVR applications. He also has
designed a STK200 dongle PCB. With Eagle files!
Do you need to know the pin out of a chip?
http://csgrad.cs.vt.edu/~tjohnson/pinouts is a great link!
Ingmar Meins. He created a nice Robot. He used some BASCOM-AVR code for the
servo's. http://www.ozemail.com.au/~intello/index.htm

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: juli 11, 2000

file:///F|/FrontPage Webs/Content/server/links.htm (3 of 3) [15-7-2000 23:50:20]


AN 01, Evaluation board for the AT89C2051 and AT89C4051

Evaluation board for the AT89C2051 and AT89C4051


This board is intended for the AT89C2051 but also supports the AT89C4051.
It supports the following hardware :
RS-232 interface, DB-9
Header for LCD display
I2C, PCF8574 I/O extender
AT24C04, I2C EEPROM
Evaluation board Schematic:

Evaluation board PCB component side:

Evaluation board PCB:

file:///F|/FrontPage Webs/Content/server/an01.htm (1 of 2) [15-7-2000 23:50:22]


AN 01, Evaluation board for the AT89C2051 and AT89C4051

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: januari 21, 2000

file:///F|/FrontPage Webs/Content/server/an01.htm (2 of 2) [15-7-2000 23:50:22]


AN 02, Reading the TLC2543 A/D converter

Reading the TLC2543 A/D converter


The TLC2543 A/D converter is on a new PLC from Ibercomp SA.
This PLC named DOMO, will have special BASCOM-DOMO BASIC.
Miguel Ziga, has written the following code to read the A/D converter.

'
' EXAMPLE PROGRAM FOR DOMO - I
'
' READ ANALOG INPUTS
'
' (C) 1999 IBERCOMP SA - Writen by MIGUEL ZUIGA
'
$large
Config Lcdpin , Db4 = P2.4 , Db5 = P2.5 , Db6 = P2.6 , Db7 = P2.7 , E = P2.1 , Rs
= P2.2
Config Sda = P1.0
Config Scl = P1.1

Dim Num As Byte


Dim State As Word
Declare Sub Rw_tlc2543c (num As Byte)
declare Sub Read_analog (num As Byte)
Init:
'Assembler code is needed because BASCOM do not handle R/-W line
'for LCD, so this must be put manually to low before initialise
'display.
$asm
MOV C, P2.0
CLR P2.0
JNC continue
LJMP 0
Continue:
$end Asm
Waitms 500 'Needed to prevent ISP
accesing (ATMEL ISP Bug)

Cls
Lcd " "
Locate 1 , 1
Lcd " ANALOG INPUTS "

Do
State = 9
Read_analog 0
Locate 2 , 3
Lcd State ; " "
Locate 2 , 1
Lcd " "
Waitms 500
Locate 2 , 1

file:///F|/FrontPage Webs/Content/server/an02.htm (1 of 3) [15-7-2000 23:50:22]


AN 02, Reading the TLC2543 A/D converter
Lcd "*"
Waitms 500
Loop

Eoc Alias P3.3 ' End of Conversin


Clk Alias P3.4 ' Comunications clock
Di Alias P3.5 ' Data In
Do Alias P1.2 ' Data Out
Cs Alias P1.3 ' Chip Select
'
' Routine that reads an analog Input
'
Sub Read_analog (num As Byte)
Num = Num * 16 ' Ask conversion on
requested chanel
Rw_tlc2543c Num
Rw_tlc2543c 0 'Read result of
conversion
End Sub
'
' Routine that access to TLC 2543C Anlog->Digital conversor
' (LOW LEVEL)
Sub Rw_tlc2543c (num As Byte)
$asm
mov DPL, {num}
setb CS ;Initially chip is not selected
clr CLK ;Clock signal is at low level
nop ;Wait at leat 1 us for stability
nop
clr CS ;Select conversor
mov B, #8 ;First write/read 8 bits
Bucle0:
mov A, DPL ;Puts the most significative bit on C
rlc A
mov DPL, A
mov DI, C ;Write C value to DI signal
mov C, DO ;Reads DO signal in Carry
mov A, DPH ;and save it with a carry rotation
rlc A
mov DPH, A
setb CLK ;Pulse on CLK signal
nop
nop
clr CLK
djnz B, bucle0
mov DPL, #0
mov B, #4 ;Now reads 4 bits
Bucle1:
mov C, DO ;Reads DO signal in Carry bit
mov A, DPL ;and save it with a carry rotation
rlc A
mov DPL, A
setb CLK ;Pulse on CLK signal
nop
nop
clr CLK
djnz B, bucle1
; Dpl Contents 4 Less Significant Bits
; Dph Contents 8 Most Significant Bits
setb CS

file:///F|/FrontPage Webs/Content/server/an02.htm (2 of 3) [15-7-2000 23:50:22]


AN 02, Reading the TLC2543 A/D converter
mov A, DPH
Swap A
push ACC
anl A, #15
mov DPH, A
pop ACC
anl A, #&H0F0
orl A, DPL
mov DPL, A
Bucle2:
jnb EOC, bucle2 ;Wait for conversion
mov {state}, DPL ;LSB
mov {state+1}, DPH ;MSB
$end Asm
End Sub
Download the source code of analog.zip

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: juli 20, 1999

file:///F|/FrontPage Webs/Content/server/an02.htm (3 of 3) [15-7-2000 23:50:22]


AN 03, A Garden Watering Program

A Garden Watering Program

A program written by Miguel Ziga from IBERCOMP SA.


It is an example for automatic watering the garden.
It can be easily changed for your own hardare.
Here is the comment from Miguel :
This programs I have instaled on my home garden. I have 8
watering zones (really only 6) and one motor pump. I can
program DOMO to watering at determinate time during a
programable time all zones. Also start or stop process from
keyboard.

In adition inputs can start manual watering on a zone. All


can be done
using only 3 buttons:

LOW BUTTON = Next option, increment variable, ....


MIDDLE BUTTON = OK, Accep, ...
HIGH BUTTON = ESC, Abort, ...
The program is intended for the new DOMO board from
IBERCOMP, but the program can be rewritten for your
hardware.

Download avanzado.zip

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: juli 20, 1999

file:///F|/FrontPage Webs/Content/server/an03.htm [15-7-2000 23:50:22]


AN 04, Reading the Dallas temperature sensor DS1821

Reading the Dallas temperature sensor DS1821


Here is a good example on how to read the Dallas DS1821.
It is written by Denis Bernard.
' Written by Denis Bernard
' bernard@xs4all.nl
' 1 wire communication with Dallas temperature sensor DS1821
' small PR35 Package, 3 pin , 2$. See Conrad elec.(europe)
' Temperatures are printed in degres when >-1 , <125
' for temperature <0 , 256 - Temp_buf will give from -55 to -1
$crystal = 24000000 : $baud = 2400
Config 1wire = P3.3 'use P3.3 for 1 wire communication
Enable Int1 : Enable Interrupts 'Int1 optional (24MHz)
Dim Temp_buf As Byte , Stat_buf As Byte
1wreset
Print Err ' optional
1wwrite &H0C ' write status
1wwrite &B01000010 ' continu convertion
Debut:
1wreset
1wwrite &HEE ' start conversion
1wreset
1wwrite &HAA ' get temperature
Temp_buf = 1wread()
1wreset ' optional
1wwrite &HAC ' optional read status
Stat_buf = 1wread() ' optional 82 when DS1821 run
Print Temp_buf ; " " ; Stat_buf ; " " ; Tcon ' temperature is Temp_buf
Goto Debut
End
'Note that int1 pin is used because of the 24 Mhz Crystal
'this slow-down the communication (with out Isr code) just enough.
'make sure Tcon.2 (IT1) remain zero. if not [ Reset tcon.2 ]
'with a 12 MHh crystal any pin can be used and no need for interrupt.
' DS1821 pin1 = Gnd / pin2 = data in/out / pin 3 = +5v
' tested on Bascom-8151 + Bascom Lt

Download source 1wire.bas

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: juli 20, 1999

file:///F|/FrontPage Webs/Content/server/an04.htm [15-7-2000 23:50:22]


AN 05, Reading the AT PC Keyboard

Reading an AT-PC Keyboard


The following program was submitted by Dusko Djuricin.
It shows how to read a keyboard from an AT compatible PC.

' =========================================================================================
'
' Program: ATPCKBD.BAS
' Author: Dusko Djuricin
' E-mail: djdusko@eunet.yu
'
' This program demonstrates how to interface AT PC keyboard to 8031 microcontrollers family.
' Program was originally written and tested for ATMEL 89C2051. For keyboard interfacing it
' uses only two I/O lines with two pull up resistors. At the output, through serial channel,
' it sends ASCII code of pressed key. Other used I/O lines are not necessary.
' Complete description of PC keyboard operation, could be found at the following address:
'
' http://www.geocities.com/SiliconValley/Bay/8302/keybrd.htm#1
'
' =========================================================================================
Dim B1 As Byte , B2 As Byte , N As Byte , Status As Byte , Key As Byte
Dim Caps As Bit , Caps_lock As Bit , Ctrl As Bit , Alt As Bit , Tmp As Bit
Dim Temp As String * 1
Declare Sub Tx_byte(b1 As Byte)
Declare Sub Rx_byte
Declare Sub Kbd_status
Kbd_data Alias P1.1 ' connected with 4K7 pull up resistor
Kbd_clk Alias P1.0 ' connected with 4K7 pull up resistor
Buzzer Alias P3.7 ' for details see BASCOM51 documentation
Res_sw Alias P3.5 ' optional output (see code)
Dim Frequency As Const 2048
Dim Duration As Const 50
Dim L_shift As Const &H12
file:///F|/FrontPage Webs/Content/server/an05.htm (1 of 8) [15-7-2000 23:50:23]
AN 05, Reading the AT PC Keyboard
Dim R_shift As Const &H59
Dim Ctrl_key As Const &H14
Dim Alt_key As Const &H11
Dim Caps_key As Const &H58
Dim Scroll_key As Const &H7E
'---------------------------[Beginning of Program]-------------------------------
Reset Kbd_clk ' disable the Keyboard
Waitms 100
Do
Tx_byte &HFF ' reset the Keyboard and wait
Rx_byte ' till the Keyboard answer with
If B1 = &HFA Then Exit Do ' acknowledge byte
If B1 = &HAA Then Exit Do ' or Power On Self Test OK code
Loop
Print
Print "*** AT PC Keyboard Interface ***"
Print " author: Dusko Djuricin"
Print " E-mail: djdusko@eunet.yu"
Print "********************************"
Print
' KBD LED: Status.0 - Scroll Lock, Status.1 - Num Lock, Status.2 - Caps Lock
Status = 2 ' initially Num Lock On
Kbd_status
Do
' KEY variable will hold ASCII value of pressed key
Key = 0 ' initial value
Rx_byte ' read scan code from PC keyboard into B1
Select Case B1
Case Ctrl_key:
Set Ctrl ' mark that CTRL key is pressed
B1 = 0
Case Alt_key:
Set Alt ' same as above but for ALT key ...
B1 = 0
Case L_shift:
Set Caps ' same as above but for Left SHIFT key ...
B1 = 0
Case R_shift:
Set Caps ' same as above but for Right SHIFT key ...
B1 = 0
Case &HE0: ' extended codes are not handled!
file:///F|/FrontPage Webs/Content/server/an05.htm (2 of 8) [15-7-2000 23:50:23]
AN 05, Reading the AT PC Keyboard
B1 = 0
Case &HF0: ' BREAK CODE is detected (key depressed)
Rx_byte ' read again to see which key is depressed
If B1 = L_shift Then ' and keep tracking flags...
Reset Caps
Elseif B1 = R_shift Then
Reset Caps
End If
If B1 = Ctrl_key Then
Reset Ctrl
Elseif B1 = Alt_key Then
Reset Alt
End If
B1 = 0
Case Caps_key: ' in a case of CAPS LOCK key
Caps_lock = Caps_lock Xor 1 ' there must be calculated status of it's LED
Status = Status Xor 4
Kbd_status ' and then we must send it to keyboard
B1 = 0
Case Scroll_key: ' I use combination of Ctrl + Alt + ScrLock
Tmp = Ctrl And Alt ' keys to generate reset signal...
If Tmp = 1 Then
Reset Res_sw ' ...for my host controller
Status = Status Xor 1 ' (Scroll Lock LED will lit and buzzer beeps)
Kbd_status
Sound Buzzer , Duration , 512
Waitms 100
Sound Buzzer , Duration , 512
Waitms 100
Sound Buzzer , Duration , 512
Waitms 100
Set Res_sw
Status = Status Xor 1 ' turn off Scroll Lock LED
Kbd_status
End If
B1 = 0
Case Else: ' handling of "printable" characters
If B1 > 131 Then ' this program handles only lower part
B1 = 0 ' of ASCII code table (with exception of
End If ' function keys - see lookup table)
If Caps = 1 Then
Key = Lookup(b1 , With_shift) ' one table is for SHIFT + key combination
Else
file:///F|/FrontPage Webs/Content/server/an05.htm (3 of 8) [15-7-2000 23:50:23]
AN 05, Reading the AT PC Keyboard
Key = Lookup(b1 , No_shift) ' and another is for key WITHOUT SHIFT
End If
If Caps_lock = 1 Then
If Caps = 0 Then ' if CAPS LOCK was ON and there is no
Temp = Chr(key) ' SHIFT + key combination, then convert
Temp = Ucase(temp) ' pressed key into upper case letter
Key = Asc(temp)
End If
End If
End Select
If B1 <> 0 Then
Sound Buzzer , Duration , Frequency ' beep
Print Chr(key); ' and print pressed key
End If
Waitms 10 ' dummy delay ...
Loop
'-----------------------[Receive Byte from Keyboard]----------------------------
Sub Rx_byte
Set Kbd_clk ' enable Keyboard
mov {n},#0
jb Kbd_clk,*+0 ' wait CLK to become zero
' START bit
jnb Kbd_data,L_cont ' if START bit is zero continue
sjmp .L_error ' if not exit via error label
' DATA bits
!L_cont:
Incr N ' this is counter of received bits
acall zero2one
mov a,{b1} ' prepare buffer
mov c,Kbd_data ' read DATA bit
rrc a ' read it into the buffer
mov {b1},a ' store buffer value
mov a,{n}
cjne a,#8,L_cont ' if it isn't last bit repeat
' PARITY bit
acall zero2one
mov a,{b2} ' prepare buffer
mov c,Kbd_data ' read ODD PARITY bit
rrc a ' store it into the buffer
' STOP bit
acall zero2one
mov c,Kbd_data ' read STOP bit
file:///F|/FrontPage Webs/Content/server/an05.htm (4 of 8) [15-7-2000 23:50:23]
AN 05, Reading the AT PC Keyboard
rrc a ' store it into the buffer
rrc a ' now align bits to right...
rrc a
rrc a
rrc a
rrc a
rrc a
anl a,#3 ' extract valuable bits and
mov {b2},a ' store to buffer
' check STOP bit
anl a,#2
jz .L_error
' PARITY checking
mov a,{b1}
mov c,psw.0 ' this is EVEN PARITY
rlc a
anl a,#1
xch a,{b2}
anl a,#1
xrl a,{b2}
jz .L_error
sjmp .L_end
L_error: ' exit in case of an error
Waitms 1 ' wait end of transmission
mov a,#0
mov {b1},a
L_end:
Reset Kbd_clk ' stop the Keyboard
End Sub
'------------------------[Transmit Byte to Keyboard]----------------------------
Sub Tx_byte(b1 As Byte)
B2 = 8
Reset Kbd_clk ' break the Keyboard
Delay ' (safety reasons)
Delay
Delay
Delay
Delay
Delay
Reset Kbd_data ' request to send
Set Kbd_clk ' enable the Keyboard
' START BIT
file:///F|/FrontPage Webs/Content/server/an05.htm (5 of 8) [15-7-2000 23:50:23]
AN 05, Reading the AT PC Keyboard
acall zero2one
' DATA BITS
mov a,{b1}
!L_tx_data:
rrc a
mov Kbd_data,c
acall zero2one
djnz {b2},L_tx_data
' PARITY BIT
mov a,{b1} ' calculate parity bit
mov c,psw.0 ' this is Even parity
cpl c ' and Keyboard needs Odd parity
mov Kbd_data,c ' send parity bit
acall zero2one
' STOP BIT
Set Kbd_data ' send stop bit
acall zero2one
' KBD ACK BIT
acall zero2one
Reset Kbd_clk ' stop the keyboard
End Sub
'------------------[ASM Subroutine wait for falling edge]-----------------------
!zero2one:
jnb Kbd_clk,*+0 ' wait till CLK rise
jb Kbd_clk,*+0 ' now wait till CLK fall down
ret
'------------[Subroutine for sending LED status to the Keyboard]----------------
Sub Kbd_status:
Tx_byte &HED
Rx_byte
Tx_byte Status
Rx_byte
End Sub
'---------------------[Scan Code to ASCII conversion table]---------------------
' Here are two lookup tables, one for handling ordinary keys and other for
' handling combination of SHIFT + key. I gave (under block remark) same tables
' written as strings, so matching with ASCII codes could be easier.
'
' Note that function keys (F1 to F12) are coded as one byte. F1 is coded as 129,
' F2 gives 130, F3 gives 131 and so on. This was OK for my application and it is
' because of simplicity.

file:///F|/FrontPage Webs/Content/server/an05.htm (6 of 8) [15-7-2000 23:50:23]


AN 05, Reading the AT PC Keyboard
'
' Gray keys are not handled (INS, DEL, HOME, ARROWS etc)! These keys returns ASCII
' value of appropriate key on numeric keypad (HOME will give 7, END gives 1, etc).
'
' Pressing of Num Lock key have no effects. Num Lock LED is always ON and serves
' as indicator that controller is turned on (if the keyboard is connected).
'
' Keyboard mapping is for ordinary 101 keys keyboard (standard US layout).
'
No_shift:
'(
Data ""
Data "F9" , "" , "F5" , "F3" , "F1" , "F2" , "F12" , "" , "F10" , "F8"
Data "F6" , "F4" , "TAB" , "`" , "" , "" , "LAlt" , "LSh" , "" , "LCtr" , "q"
Data "1" , "" , "" , "" , "z" , "s" , "a" , "w" , "2" , ""
Data "" , "c" , "x" , "d" , "e" , "4" , "3" , "" , "" , " "
Data "v" , "f" , "t" , "r" , "5" , "" , "" , "n" , "b" , "h"
Data "g" , "y" , "6" , "" , "" , "" , "m" , "j" , "u" , "7"
Data "8" , "" , "" , "," , "k" , "i" , "o" , "0" , "9" , ""
Data "" , "." , "/" , "l" , ";" , "p" , "-" , "" , "" , ""
Data "'" , "" , "[" , "=" , "" , "" , "Caps" , "RSht" , "Enter" , "]"
Data "" , "\" , "" , "" , "" , "" , "" , "" , "" , ""
Data "BkSp" , "" , "" , "1" , "" , "4" , "7" , "" , "" , ""
Data "0" , "." , "2" , "5" , "6" , "8" , "ESC" , "NumLck" , "F11" , "+"
Data "3" , "-" , "*" , "9" , "ScrLck" , "" , "" , "" , "" , "F7"
')
Data 0
Data 137 , 0 , 133 , 131 , 129 , 130 , 140 , 0 , 138 , 136
Data 134 , 132 , 9 , 96 , 0 , 0 , 0 , 0 , 0 , 0 , 113
Data 49 , 0 , 0 , 0 , 122 , 115 , 97 , 119 , 50 , 0
Data 0 , 99 , 120 , 100 , 101 , 52 , 51 , 0 , 0 , 32
Data 118 , 102 , 116 , 114 , 53 , 0 , 0 , 110 , 98 , 104
Data 103 , 121 , 54 , 0 , 0 , 0 , 109 , 106 , 117 , 55
Data 56 , 0 , 0 , 44 , 107 , 105 , 111 , 48 , 57 , 0
Data 0 , 46 , 47 , 108 , 59 , 112 , 45 , 0 , 0 , 0
Data 39 , 0 , 91 , 61 , 0 , 0 , 0 , 0 , 13 , 93
Data 0 , 92 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
Data 8 , 0 , 0 , 49 , 0 , 52 , 55 , 0 , 0 , 0
Data 48 , 46 , 50 , 53 , 54 , 56 , 27 , 0 , 139 , 43
Data 51 , 45 , 42 , 57 , 0 , 0 , 0 , 0 , 0 , 135
With_shift:
'(

file:///F|/FrontPage Webs/Content/server/an05.htm (7 of 8) [15-7-2000 23:50:23]


AN 05, Reading the AT PC Keyboard
Data ""
Data "F9" , "" , "F5" , "F3" , "F1" , "F2" , "F12" , "" , "F10" , "F8"
Data "F6" , "F4" , "TAB" , "~" , "" , "" , "LAlt" , "LSh" , "" , "LCtr" , "Q"
Data "!" , "" , "" , "" , "Z" , "S" , "A" , "W" , "@" , ""
Data "" , "C" , "X" , "D" , "E" , "$" , "#" , "" , "" , " "
Data "V" , "F" , "T" , "R" , "%" , "" , "" , "N" , "B" , "H"
Data "G" , "Y" , "^" , "" , "" , "" , "M" , "J" , "U" , "&"
Data "*" , "" , "" , "<" , "K" , "I" , "O" , ")" , "(" , ""
Data "" , ">" , "?" , "L" , ":" , "P" , "_" , "" , "" , ""
Data 34 , 0 , "" , "{" , "+" , "" , "" , "Caps" , "RSht" , "Enter" , "}"
Data "" , "|" , "" , "" , "" , "" , "" , "" , "" , ""
Data "BkSp" , "" , "" , "1" , "" , "4" , "7" , "" , "" , ""
Data "0" , "." , "2" , "5" , "6" , "8" , "ESC" , "NumLck" , "F11" , "+"
Data "3" , "-" , "*" , "9" , "ScrLck" , "" , "" , "" , "" , "F7"
')
Data 0
Data 137 , 0 , 133 , 131 , 129 , 130 , 140 , 0 , 138 , 136
Data 134 , 132 , 9 , 126 , 0 , 0 , 0 , 0 , 0 , 0 , 81
Data 33 , 0 , 0 , 0 , 90 , 83 , 65 , 87 , 64 , 0
Data 0 , 67 , 88 , 68 , 69 , 36 , 35 , 0 , 0 , 32
Data 86 , 70 , 84 , 82 , 37 , 0 , 0 , 78 , 66 , 72
Data 71 , 89 , 94 , 0 , 0 , 0 , 77 , 74 , 85 , 38
Data 42 , 0 , 0 , 60 , 75 , 73 , 79 , 41 , 40 , 0
Data 0 , 62 , 63 , 76 , 58 , 80 , 95 , 0 , 0 , 0
Data 34 , 0 , 123 , 43 , 0 , 0 , 0 , 0 , 13 , 125
Data 0 , 124 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
Data 8 , 0 , 0 , 49 , 0 , 52 , 55 , 0 , 0 , 0
Data 48 , 46 , 50 , 53 , 54 , 56 , 27 , 0 , 139 , 43
Data 51 , 45 , 42 , 57 , 0 , 0 , 0 , 0 , 0 , 135
'-----------------------------[End of Program]----------------------------------

Download sourecode atpckbd.bas

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: juli 20, 1999

file:///F|/FrontPage Webs/Content/server/an05.htm (8 of 8) [15-7-2000 23:50:23]


AN 06, Reading the DS1820 temperature sensor

Reading the DS1820 Temperature Sensor


This example is written by Bojan Ivancic.
Email : nicrodesign@siol.net
It has 0.1 C resolution and with 8-bit CRC.
Download the file 1820.bas

' ----------------------------------------------------------------
'Author : Bojan Ivancic
' Email : nicrodesign@siol.net
' Example measuring temperature using Dallas DS1820,
' with calculated for 0.1 C resolution and with 8-bit CRC!
' ----------------------------------------------------------------
$CRYSTAL = 12000000 ' we are using this frequency
declare sub Read1820
declare sub CRCit
declare sub Temperature
dim bd(9) as byte
dim i as byte , tmp as byte
dim CRC as byte
dim T as integer , T1 as integer
dim v as byte
Config 1wire = P1.0 ' DS1820 on pin 12 (pull up)
cursor off noblink
cls
locate 1 , 1 : lcd "DEMO for DS1820"
locate 2 , 1 : lcd "T="
do
Temperature
waitms 250
loop
End
'//////////////////////////////////////////////////////////////////////////////
sub Temperature ' actual measuring
1wwrite &hcc : 1wwrite &h44 ' start measure
waitms 300 ' wait for end of conversion
Read1820 ' read 9 bytes
if Err = 1 then ' if there is no sensor
locate 2 , 4 : lcd "-- " ' we put "-- " on LCD
else
if CRC = 0 then ' sensor present, check CRC
locate 2 , 4 : lcd T ' CRC OK, print T*10 on LCD
else
locate 2 , 4 : lcd "** " ' CRC NOT OK, "** " on LCD
end if
end if
end sub
'//////////////////////////////////////////////////////////////////////////////
sub Read1820 ' reads sensor ans calculate
' T for 0.1 C

file:///F|/FrontPage Webs/Content/server/an06.htm (1 of 2) [15-7-2000 23:50:23]


AN 06, Reading the DS1820 temperature sensor
1wreset ' reset the bus
1wwrite &hcc ' read internal RAM
1wwrite &Hbe ' read 9 data bytest
bd(1) = 1wread(9) ' read bytes in array
1wreset ' reset the bus
CRCit ' ckeck CRC
if CRC = 0 then ' if is OK, calculate for
tmp = bd(1) and 1 ' 0.1C precision
if tmp = 1 then decr bd(1)
T = makeint(bd(1) , bd(2))
T = T * 50 : T = T - 25 : T1 = bd(8) - bd(7) : T1 = T1 * 100
T1 = T1 / bd(8) : T = T + T1 : T = T / 10
end if
end sub
'//////////////////////////////////////////////////////////////////////////////
sub CRCit ' calculate 8 bit CRC
' bigger but faster
CRC = 0 ' needs a 256 elements table
for i = 1 to 9
tmp = CRC xor bd(i)
CRC = lookup(tmp , crc8)
next
end sub
'//////////////////////////////////////////////////////////////////////////////
crc8:
data 0 , 94 , 188 , 226 , 97 , 63 , 221 , 131 , 194 , 156
data 126 , 32 , 163 , 253 , 31 , 65 , 157 , 195 , 33 , 127
data 252 , 162 , 64 , 30 , 95 , 1 , 227 , 189 , 62 , 96
data 130 , 220 , 35 , 125 , 159 , 193 , 66 , 28 , 254 , 160
data 225 , 191 , 93 , 3 , 128 , 222 , 60 , 98 , 190 , 224
data 2 , 92 , 223 , 129 , 99 , 61 , 124 , 34 , 192 , 158
data 29 , 67 , 161 , 255 , 70 , 24 , 250 , 164 , 39 , 121
data 155 , 197 , 132 , 218 , 56 , 102 , 229 , 187 , 89 , 7
data 219 , 133 , 103 , 57 , 186 , 228 , 6 , 88 , 25 , 71
data 165 , 251 , 120 , 38 , 196 , 154 , 101 , 59 , 217 , 135
data 4 , 90 , 184 , 230 , 167 , 249 , 27 , 69 , 198 , 152
data 122 , 36 , 248 , 166 , 68 , 26 , 153 , 199 , 37 , 123
data 58 , 100 , 134 , 216 , 91 , 5 , 231 , 185 , 140 , 210
data 48 , 110 , 237 , 179 , 81 , 15 , 78 , 16 , 242 , 172
data 47 , 113 , 147 , 205 , 17 , 79 , 173 , 243 , 112 , 46
data 204 , 146 , 211 , 141 , 111 , 49 , 178 , 236 , 14 , 80
data 175 , 241 , 19 , 77 , 206 , 144 , 114 , 44 , 109 , 51
data 209 , 143 , 12 , 82 , 176 , 238 , 50 , 108 , 142 , 208
data 83 , 13 , 239 , 177 , 240 , 174 , 76 , 18 , 145 , 207
data 45 , 115 , 202 , 148 , 118 , 40 , 171 , 245 , 23 , 73
data 8 , 86 , 180 , 234 , 105 , 55 , 213 , 139 , 87 , 9
data 235 , 181 , 54 , 104 , 138 , 212 , 149 , 203 , 41 , 119
data 244 , 170 , 72 , 22 , 233 , 183 , 85 , 11 , 136 , 214
data 52 , 106 , 43 , 117 , 151 , 201 , 74 , 20 , 246 , 168
data 116 , 42 , 200 , 150 , 21 , 75 , 169 , 247 , 182 , 232
data 10 , 84 , 215 , 137 , 107 , 53

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: augustus 20, 1999

file:///F|/FrontPage Webs/Content/server/an06.htm (2 of 2) [15-7-2000 23:50:23]


AN 07, Big Digit ThermoMeter

Big Digit ThermoMeter


This example was written by RETI from Belgium.
Email : RETI

BIG DIGIT THERMOMETER USING DALLAS DS1820 1WIRE SENSOR.


LCD-DISPLAY SHOWS TEMPERATURE WITH A RESOLUTION FROM 1/10 C
UP TO 5 DIGITS CAN BE USED ON THE DISPLAY. IDEAL FOR CLOCKS,ETC...
Download the file bigdigit.bas

' BIG DIGIT THERMOMETER USING DALLAS DS1820 1WIRE SENSOR


' LCD-DISPLAY SHOWS TEMPERATURE WITH A RESOLUTION FROM 1/10 C
' UP TO 5 DIGITS CAN BE USED ON THE DISPLAY. IDEAL FOR CLOCKS,ETC...
'
' 1WIRE : P1.0 ...4K7 to VCC
'
' CODE BY RETI/BELGIUM : CONTACT ME ... rETi@nettaxi.com
$crystal = 11059200
$iramstart = &H60
$ramstart = 0
$ramsize = &H7FFF
$default Xram
$large
Config 1wire = P1.0
1wreset
Config Lcd = 20 * 4
Config Lcdbus = 4
Cursor Off
Display On
Cls
Deflcdchar 1 , 224 , 224 , 224 , 240 , 248 , 252 , 254 , 255 ' \ B
Deflcdchar 2 , 224 , 224 , 224 , 255 , 255 , 255 , 255 , 255 ' = O
Deflcdchar 3 , 255 , 255 , 255 , 255 , 254 , 252 , 248 , 240 ' !/ O
Deflcdchar 4 , 255 , 255 , 255 , 255 , 239 , 231 , 227 , 225 ' !\ O
Deflcdchar 5 , 224 , 224 , 224 , 225 , 227 , 231 , 239 , 255 ' / B
Deflcdchar 6 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ' ! N
' SYMBOL ARRAYS : INCLUDE DATA TO DISPLAY BIG DIGITS USING 6 CUSTOM LCD SYMBOLS
Dim L1(17) As String * 4 , L2(17) As String * 4 , L3(17) As String * 4 , L4(17) As
String * 4

file:///F|/FrontPage Webs/Content/server/an07.htm (1 of 4) [15-7-2000 23:50:24]


AN 07, Big Digit ThermoMeter
' EACH DIGIT EXISTS OF 12 BYTES DISPLAYING EACH ONE OF THE ABOVE DEFLCDCHAR'S
' NUMBER 1
L1(1) = " " + Chr(5) + Chr(2) + " "
L2(1) = " " + " " + Chr(7) + " "
L3(1) = " " + " " + Chr(7) + " "
L4(1) = " " + " " + Chr(7) + " "
' NUMBER 2
L1(2) = Chr(5) + Chr(2) + Chr(1) + " "
L2(2) = Chr(5) + Chr(2) + Chr(3) + " "
L3(2) = Chr(6) + " " + " " + " "
L4(2) = Chr(6) + Chr(2) + Chr(2) + " "
' NUMBER 3
L1(3) = Chr(5) + Chr(2) + Chr(1) + " "
L2(3) = " " + Chr(2) + Chr(6) + " "
L3(3) = Chr(2) + " " + Chr(6) + " "
L4(3) = Chr(4) + Chr(2) + Chr(3) + " "
' NUMBER 4
L1(4) = Chr(5) + " " + Chr(2) + " "
L2(4) = Chr(6) + Chr(2) + Chr(6) + " "
L3(4) = " " + " " + Chr(6) + " "
L4(4) = " " + " " + Chr(6) + " "
' NUMBER 5
L1(5) = Chr(2) + Chr(2) + Chr(2) + " "
L2(5) = Chr(6) + Chr(2) + Chr(1) + " "
L3(5) = Chr(2) + " " + Chr(6) + " "
L4(5) = Chr(4) + Chr(2) + Chr(3) + " "
' NUMBER 6
L1(6) = Chr(5) + Chr(2) + Chr(2) + " "
L2(6) = Chr(6) + Chr(2) + Chr(1) + " "
L3(6) = Chr(6) + " " + Chr(6) + " "
L4(6) = Chr(4) + Chr(2) + Chr(3) + " "
' NUMBER 7
L1(7) = Chr(2) + Chr(2) + Chr(2) + " "
L2(7) = " " + Chr(5) + Chr(3) + " "
L3(7) = " " + Chr(6) + " " + " "
L4(7) = " " + Chr(6) + " " + " "
' NUMBER 8
L1(8) = Chr(5) + Chr(2) + Chr(1) + " "
L2(8) = Chr(4) + Chr(2) + Chr(3) + " "
L3(8) = Chr(6) + " " + Chr(6) + " "
L4(8) = Chr(4) + Chr(2) + Chr(3) + " "
' NUMBER 9
L1(9) = Chr(5) + Chr(2) + Chr(1) + " "
L2(9) = Chr(4) + Chr(2) + Chr(6) + " "
L3(9) = " " + " " + Chr(6) + " "
L4(9) = Chr(4) + Chr(2) + Chr(3) + " "
' NUMBER 0
L1(10) = Chr(5) + Chr(2) + Chr(1) + " "
L2(10) = Chr(6) + " " + Chr(6) + " "
L3(10) = Chr(6) + " " + Chr(6) + " "
L4(10) = Chr(4) + Chr(2) + Chr(3) + " "
' DEGREE SYMBOL
L1(11) = Chr(5) + Chr(2) + Chr(1) + " "
L2(11) = Chr(4) + Chr(2) + Chr(3) + " "
L3(11) = " " + " " + " " + " "
L4(11) = " " + " " + " " + " "
' LETTER C
L1(12) = Chr(5) + Chr(2) + Chr(2) + " "
L2(12) = Chr(6) + " " + " " + " "
L3(12) = Chr(6) + " " + " " + " "
L4(12) = Chr(4) + Chr(2) + Chr(2) + " "
' LETTER F
L1(13) = Chr(5) + Chr(2) + Chr(2) + " "
L2(13) = Chr(6) + Chr(2) + Chr(2) + " "
L3(13) = Chr(6) + " " + " " + " "

file:///F|/FrontPage Webs/Content/server/an07.htm (2 of 4) [15-7-2000 23:50:24]


AN 07, Big Digit ThermoMeter
L4(13) = Chr(6) + " " + " " + " "
' LETTER H
L1(14) = Chr(2) + " " + " " + " "
L2(14) = Chr(6) + Chr(5) + Chr(2) + " "
L3(14) = Chr(6) + " " + Chr(6) + " "
L4(14) = Chr(6) + " " + Chr(6) + " "
' SYMBOL :
L1(15) = " " + " " + " " + " "
L2(15) = " " + Chr(2) + " " + " "
L3(15) = " " + Chr(2) + " " + " "
L4(15) = " " + " " + " " + " "
' SYMBOL .
L1(16) = " " + " "
L2(16) = " " + " "
L3(16) = " " + " "
L4(16) = Chr(3) + " "
' UNKNOW
L1(17) = "?" + " "
L2(17) = "?" + " "
L3(17) = "?" + " "
L4(17) = "?" + " "
Declare Sub Showstring(stri As String * 5)
Dim Stri As String * 5
Declare Sub Rd1820(valu As Single)
Dim Valu As Single
Dim E1 As String * 5
Dim E2 As String * 5
Dim E3 As String * 5
' /**** MAIN LOOP ****/
Do
Call Rd1820(valu)
E1 = Str(valu)
E2 = Left(e1 , 4)
Print E2
E3 = E2 + ""
Call Showstring(e3)
Loop
' /**** END LOOP ****/

Sub Rd1820(valu As Single)


Dim T1 As Byte , T11 As Single , T2 As Single , T3 As Single , T4 As Single , T7
As Single , T8 As Single
Dim Ar(9) As Byte , I As Byte
Dim X1 As Const 0.25
1wreset
1wwrite &HCC ' Skip ROM command ,
only one DS1820
1wwrite &H44 ' Convert Temp
1wreset
1wwrite &HCC ' Skip ROM Command
1wwrite &HBE ' Read Scratchpad
command
For I = 1 To 9
Ar(i) = 1wread ' Read out 9 registers
(Bytes)
Next I
T1 = Ar(1) / 2
T11 = T1 ' Conversion of Byte to
Single
T7 = Ar(7) ' Count Remain
T8 = Ar(8) ' Counts per C
T2 = T8 - T7 ' Calculate High
resolution
T3 = T2 / T8

file:///F|/FrontPage Webs/Content/server/an07.htm (3 of 4) [15-7-2000 23:50:24]


AN 07, Big Digit ThermoMeter
T4 = T11 - X1
Valu = T4 + T3 ' Return Value to the
Main Program
1wreset
End Sub
Sub Showstring(stri As String * 5)
If Len(stri) > 5 Then Stri = Left(stri , 5)
Dim A1 As Byte
Dim A2 As String * 1
Dim A3 As Byte
Dim A4 As Byte
Dim B1 As String * 20
Dim B2 As String * 20
Dim B3 As String * 20
Dim B4 As String * 20
B1 = "" : B2 = "" : B3 = "" : B4 = ""
A4 = Len(stri)
For A1 = 1 To A4
A2 = Mid(stri , A1 , 1)
Select Case A2
Case Is = "1" : A3 = 1
Case Is = "2" : A3 = 2
Case Is = "3" : A3 = 3
Case Is = "4" : A3 = 4
Case Is = "5" : A3 = 5
Case Is = "6" : A3 = 6
Case Is = "7" : A3 = 7
Case Is = "8" : A3 = 8
Case Is = "9" : A3 = 9
Case Is = "0" : A3 = 10
Case Is = "" : A3 = 11
Case Is = "C" : A3 = 12
Case Is = "c" : A3 = 12
Case Is = "F" : A3 = 13
Case Is = "f" : A3 = 13
Case Is = "H" : A3 = 14
Case Is = "h" : A3 = 14
Case Is = "X" : A3 = 15
Case Is = "." : A3 = 16
Case Else : A3 = 17
End Select
B1 = B1 + L1(a3)
B2 = B2 + L2(a3)
B3 = B3 + L3(a3)
B4 = B4 + L4(a3)
Next A1
Upperline
Lcd B1
Lowerline
Lcd B2
Thirdline
Lcd B3
Fourthline
Lcd B4
End Sub

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: augustus 20, 1999

file:///F|/FrontPage Webs/Content/server/an07.htm (4 of 4) [15-7-2000 23:50:24]


AN 08 , Flash Programmer

Flash Programmer
This application note is for a parallel printer port based Flash programmer for the At89Cx051.

Flash Programmer Schematic:

Programmer PCB component side:

file:///F|/FrontPage Webs/Content/server/an08.htm (1 of 2) [15-7-2000 23:50:26]


AN 08 , Flash Programmer

Programmer PCB:

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: augustus 29, 1999

file:///F|/FrontPage Webs/Content/server/an08.htm (2 of 2) [15-7-2000 23:50:26]


AN 09, Controlling the X9CMME

Controlling the X9CMME


This application note shows how to control an EEPOT from XICOR.
The chip needs only 3 port pins to be controlled.
And if the chip enable line isn't used you can control it with 2 port pins.
A LCD display is used in the sample to display the value of the EEPOT.

file:///F|/FrontPage Webs/Content/server/an09.htm (1 of 2) [15-7-2000 23:50:26]


AN 09, Controlling the X9CMME

Download an09.bas

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: augustus 29, 1999

file:///F|/FrontPage Webs/Content/server/an09.htm (2 of 2) [15-7-2000 23:50:26]


AN 10, BASCOM-LT and BASCOM-8051 Hardware simulation

BASCOM-LT and BASCOM-8051 Hardware simulation


BASCOM LT and BASCOM-8051 hardware simulation.
This application note shows how to emulate PORT 1 and 3 so you can test the various port
statements from within the BASCOM IDE.

The schematic is almost the same as for the MCS


Flashprogrammer.
2 PCF 8574 I/O extenders are used which are controlled by an I2C interface.

Users of the MCS Flashprogrammer can use the programmer to simulate PORT 1 (port 3 not supported).
You can make a cable which connects P1 of the flashprogrammer (with a piggy-back) to the
target system(the AT89C2051 socket).
Take care not to insert a chip into the programmer when used as a simulator!

A simple program demonstrates the simulator :


Connect 8 LED via 330 ohm resistors to P1. Simulate the program and see what is happening.

I used a dontronics DT003 power-board as a basis, a DT203 led/button board for the leds and a
dontronics prototypeboard to connect P1 of the flashprogrammer to the datalines of the SIMM-bus.
For info on these boards http://www.dontronics.com

Dim a As Byte
P1 = 1
For a = 1 to 8
Rotate P1 , Left
Next
For a = 1 to 8
Rotate P1 , Right
Next
End

Schematic:

file:///F|/FrontPage Webs/Content/server/an10.htm (1 of 2) [15-7-2000 23:50:27]


AN 10, BASCOM-LT and BASCOM-8051 Hardware simulation

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: augustus 29, 1999

file:///F|/FrontPage Webs/Content/server/an10.htm (2 of 2) [15-7-2000 23:50:27]


AN 11, Using an I2C clock device with the PCF8583.

Using an I2C clock device with the


PCF8583
Using an I2C clock device with the PCF8583.
This application note shows how to use the PCF8583 I2C
clock
It has been tested in the Simulation Hardware mode.

The schematic is very simple since the IC only uses an XTAL


and a capacitor

I used a Dontronics DT003 power-board as a basis, and a


Dontronics prototypeboard for the PCF8583
With some modifications the DT104 could be used also.

Schematic:

Download clock.bas source code

file:///F|/FrontPage Webs/Content/server/an11.htm (1 of 2) [15-7-2000 23:50:27]


AN 11, Using an I2C clock device with the PCF8583.

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: augustus 29, 1999

file:///F|/FrontPage Webs/Content/server/an11.htm (2 of 2) [15-7-2000 23:50:27]


AN 12, Using the TIMER interrupt to make a clock with LED-display.

Using the TIMER interrupt to make a


clock with LED-display.
Using the TIMER interrupt to make a clock with LED-display
by Mirko Pelcl
This application note shows how the TIMER interrupt can be
used to make a software clock
This AN is donated by our Slovenian customer Mirko Pelcl.

Connect a common cathode LED display as following :


a = P1.0
b = P1.1
c = P1.2
d = P1.3
e = P1.4
f = P1.5
g = P1.6
ones display P3.7
thens display P3.5

Download clock.bas source code

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: december 12, 1999

file:///F|/FrontPage Webs/Content/server/an12.htm [15-7-2000 23:50:27]


AN 13, Keyboard decoder by Mike Gill

Keyboard decoder
The following example was donated by Mike Gill.
' Reads a standard 3X4 keypad and assembles No in Digits
variable, then displays
' Led used is just to show program running 2K2 from port pin via
Led to +
' Setup for 89S8252. Use appropriate port assignments for other
processors
' Uses Active Low, so no extra components needed. Chip internal
tieups are utilised
' Mike Gill . B M Electronics UK 01422 839321

Startup:
Config DeBounce = 40 ' Set Key Pad Debounce to 40 Ms
Config Lcd = 16 * 1
Cursor OFF
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'OUTPUTS All Active High
StatusLed Alias P2.7 ' Operational Status
Col1 Alias P2.6 ' Keyboard Column Drivers
Col2 Alias P2.5
Col3 Alias P2.4 ' Add Another Col for 4X4 Kpad
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'INITIAL OUTPUT STATES
StatusLed = 1
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'INPUTS All Active Low
Row1 Alias P2.0 ' Keyboard Rows (Read)
Row2 Alias P2.1
Row3 Alias P2.2
Row4 Alias P2.3
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'VARIABLES
Dim Check As Byte ' Detects Key Released
Dim KeyRead As Byte ' Actual Button Value
Dim Digits As Word ' Actual Dialled Number
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'INITIALISE VARIABLES

file:///F|/FrontPage Webs/Content/server/an13.htm (1 of 3) [15-7-2000 23:50:28]


AN 13, Keyboard decoder by Mike Gill

Digits = 0
KeyRead = 0
Check = 0
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
KeyScan: ' Keypad Read Routine (Assignments can be changed
for different connections)
StatusLed = 0 ' Status Led OFF
Col1 = 0 : Col2 = 1 : Col3 = 1 ' Turns Columns On (Low) 1 by 1
KeyRead = 1 : DeBounce Row1,0,GotKey,Sub ' Gosub if Key
Pressed
(Reads LOW Input)
KeyRead = 4 : DeBounce Row2,0,GotKey,Sub
KeyRead = 7 : DeBounce Row3,0,GotKey,Sub
KeyRead = 11 : DeBounce Row4,0,GotKey,Sub ' CALL Button *
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Col1 = 1 : Col2 = 0 : Col3 = 1 ' Assign KeyRead to Any No You
Like <256
KeyRead = 2 : DeBounce Row1,0,GotKey,Sub
KeyRead = 5 : DeBounce Row2,0,GotKey,Sub
KeyRead = 8 : DeBounce Row3,0,GotKey,Sub
KeyRead = 0 : DeBounce Row4,0,GotKey,Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Col1 = 1 : Col2 = 1 : Col3 = 0 ' Add Another Section After this
for 4X4 Kpad
KeyRead = 3 : DeBounce Row1,0,GotKey,Sub
KeyRead = 6 : DeBounce Row2,0,GotKey,Sub
KeyRead = 9 : DeBounce Row3,0,GotKey,Sub
KeyRead = 12 : DeBounce Row4,0,GotKey,Sub ' CANCEL Button
#
WaitMs 50 ' Status Led OFF Time
StatusLed = 1 ' Turns Status Led ON
WaitMs 15 ' Status Led ON Time (Only to show Program Running)
Goto KeyScan
End
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
GotKey:
CheckAgain: ' Reads P2 Directly and Waits for all Keys Released
Check = P2 And 15 ' Appropriate Port
If Check <> 15 Then : Goto CheckAgain : End If ' Check for Key
Release
If Keyread = 12 Then : Goto StartUp : End If ' CANCEL Button
If Keyread = 11 Then : Goto CallNumber : End If ' CALL Button
Digits = Digits * 10 ' Assemble Dialling No in Digits Variable
Digits = Digits + Keyread
Cls : Lcd Digits ' Display Accumulating Number
KeyRead = 0 ' Clear Keypad Read Variables
Check = 0

file:///F|/FrontPage Webs/Content/server/an13.htm (2 of 3) [15-7-2000 23:50:28]


AN 13, Keyboard decoder by Mike Gill

Return
End
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

CallNumber: ' What You Like Here. When call key pressed
Goto StartUp

Download keypad.bas

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: augustus 29, 1999

file:///F|/FrontPage Webs/Content/server/an13.htm (3 of 3) [15-7-2000 23:50:28]


AN 14, How to implement a flow meter using the 80552

How to implement a flow meter using the 80552


The following application note was donated by Mike Crean
The program shows how to use the A/D converter of the
80552.
The sensor for this flow meter was made from a turbine
(fan) with
2 * magnets mounted on it seperated by 180deg's opposite
polarity's
out.
A Hall sensor that switches on with one polarity and of with
the other
was mounted on the out side of a pice of polly pipe.
This signal is then fed to a 4018 chip running in / by 10
mode, it's output is sent to P4.0 as the input signal for the
80C552.

If this setup was to be used in another application it would


be wise to
use / switches on the 4018 to allow for more calibration.

This code is far from complete or bug free, but it might be


usefull to you.

Ps. The flow rate is output on the LCD or to a terminal when


requested.
Four buttons allow you to scroll menu's on the LCD

Download flm.bas

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: september 02, 1999

file:///F|/FrontPage Webs/Content/server/an14.htm [15-7-2000 23:50:28]


AN 15, LCD VU Meter

LCD VU Meter
The following example was donated by Ger Langezaal.
Note that BASCOM-8051 was used and that it doesn't work
with
BASCOM LT without modifications , since arrays are used.

This program shows a bar dispay peak-hold VU meter on a


LCD 16 *
2.
Resolution is 32 elements for a 32 dB range based on the
internal 8 bit
A/D converter.

The scale range is -26dB - +5dB for 0.125 to 5.00 Volt DC


input.
The display will be updated every 50mS on Timer0 interrupt
base.
Log conversion is done with a log table. At initialization a
log table will
be created and stored in the array Vu(256).
VU meter can be disabled by Vu_flag = 0.
Peak Hold can be disabled by Peak_hold_flag = 0.
Setup for 80C535 at 12 Mhz, VAREF = 5Volt, A/D input =
P6.0
(channal # 0).

Note: Use a 47K resistor from the input to P6.0 for input
protection.

Download file vu_032.bas

file:///F|/FrontPage Webs/Content/server/an15.htm (1 of 2) [15-7-2000 23:50:28]


AN 15, LCD VU Meter

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: september 02, 1999

file:///F|/FrontPage Webs/Content/server/an15.htm (2 of 2) [15-7-2000 23:50:28]


AN 16, Using the Sharp GP2D02 distance sensor

Using the Sharp GP2D02 distance sensor


Using the Sharp GP2D02 distance sensor

The following application note was donated by Lex


Bolkesteijn.
Lex is using the GP2D02 in his robots but there are many
applications
for this part.
The GP2D02 from Sharp is a distance sensor that can
measure
distances from 7cm to 1.2 meter.
It uses an optical transmitter and receiver to measure the
distance and
outputs the distance in 8 bit serial format.

The datasheet of the GP2D02 can be downloaded from :


http://www.sharp.co.jp/ecg/sys/gp2d02/gp2d02-fea.html

A more in depth desciption of the GP2D02 is also available.


Dr.-Ing. Claus Kuehnel donated one of the chapters of his
BASIC
STAMP book that decripes the GP2D02.
In fact the BASIC STAMP book is a good source for
interfacing all
kind of hardware.
Download the GP2DO2 PDF file (76KB)

'--------------------------------------------------------------
' (c) 1999 Lex Bolkesteijn
'--------------------------------------------------------------
' file: GP2D02.BAS
'
' Sample program to use a Sharp GP2D02 distance sensor
' with a 89C2051. The GP2D02 is non lineair. The shorter
' the distance between object and sensor the higher the
output.
'

file:///F|/FrontPage Webs/Content/server/an16.htm (1 of 2) [15-7-2000 23:50:28]


AN 16, Using the Sharp GP2D02 distance sensor

' The GP2D02 is availlible at Conrad Electronics


' http://www.sharp.co.jp/ecg/sys/gp2d02/gp2d02-fea.html
'
' GP2D02 89C2051
' pin 1 : Gnd -> Gnd +-- connect Vin/P1.0 here
' pin 2 : Vin -> P1.0 (Vcc - 1K --X-- 1K - Gnd)
' pin 3 : Vcc -> Vcc
' pin 4 : Vout -> P1.1 (GP2D02 12K internal pull up)
'--------------------------------------------------------------
'$sim

Dim D As Byte 'distance value


Dim T As Byte
Dim I As Byte
Dim S As String * 20
Config Lcd = 16 * 2 'configure lcd screen

Cls

Set P1.0 'set powerdown for sensor


Waitms 10 'default wait

Do
Reset P1.0 'Start cycle
Waitms 70 'time to calculate
Set P1.0
Shiftin P1.1 , P1.0 , D , 0 'clock bits in MSB first on falling
edge
Set P1.0 'set powerdown for sensor
Waitms 2 'minimum delay for sensor
Cls
T = D / 16 'we use a 16 char. display (255/x)= 16 max
Lcd "Distance : " ; D 'display the distance
Lowerline
If T > 0 Then 'else string will fail
S = String(t , 61)
Lcd S
End If
Loop
End

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: september 02, 1999

file:///F|/FrontPage Webs/Content/server/an16.htm (2 of 2) [15-7-2000 23:50:28]


AN 17, Telephone card reader

Telephone Card Reader

The following example was donated by Erich Linsmeier.


The software reads a telephone card and displays the info
on a LCD screen.
It works for German telephone cards and I think it will work
for most countries.
You only have to change the currency of course.
When you have tried it and it works for your country, it
would be a nice idea to send Erich a message so that he
knows it
works in other countries as well.
As a matter of fact I am also interested!

New : 19-9-1998
Erich has enhanced the program and even provided a PCB
in laserjet image format.
Here is the content of the readme file which is in the !ic.exe
file.

Project: CARD-READER for GERMAN TELEPHONE CARDS

Hello BASCOM-USER!

In this files you get my Card-reader-project for german


cards! Please use an ATMEL
89C4051 Controller, because BIN-file use about 3KB flash.
But you can optimize the
basic file if possible (let me know if possible :-)!

Following files have you get:

- readme.txt this info


- cardread.bom bill of materials
- cardread.lx1 layout bottom reflected *
- cardread.lx2 upper side cardreader *

file:///F|/FrontPage Webs/Content/server/an17.htm (1 of 2) [15-7-2000 23:50:29]


AN 17, Telephone card reader

- cardread.prn cardreader circuit *

- telcard.bas BASCOM file


- telcard.bin bin-file for 89C4051

For printing use an laserprinter with following command:

copy filename LPT1

(only for files with * extension)

Use only for non comercial use!


Puplishing and distribute in mailbox and internet only with
my compliance!

Contact via EMail: DL2RCG@AMSAT.ORG

via letter: Erich Linsmeier


Lindenstr. 1
93483 Poesing
Germany

Download file cr.zip This is a self extracting EXE

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: oktober 11, 1999

file:///F|/FrontPage Webs/Content/server/an17.htm (2 of 2) [15-7-2000 23:50:29]


AN 18, page scanner

Page Scanner by Mike Gill

The following example was donated by Mike Gill.


A schematic is not available but here is some additional info
from the author:

No Schematic, it just connects via the serial port and gives


appropriate codes to a purpose built UHF transmitter.
Typically
pager code followed by bleep code, then message string or
variable. The transmitters are built by Scope/ MB
Electronics and
no doubt others in different countries.

Download file pagescan.bas

' 32 Way Scanner and Potsag Pager Interface MKG


08/06/98 Bascom 8052 Compiler for 89S8252
' Reads PCF8574s on I2C Bus. Inputs to these are active
LOW via Opto Couplers
' Inputs are latched until cancelled at source. Change Ports
and remove Watchdod if other CPU used
' Should be easy to alter if you require momentery inputs,
Scan routine is fast enough.
' Configure for what Serial O/P you need, i.e Moving
Message display/Terminal.

StartUp:
Config WatchDog = 2048
Start WatchDog
Config SCL = P2.0 ' I2C Bus Pin Assignments
Config SDA = P2.1
Config Lcd = 16 * 2
WaitMs 50 ' Allow Display time to Initialise
$Baud = 300 ' Output to paging TX
$Crystal = 12000000
Cursor OFF

file:///F|/FrontPage Webs/Content/server/an18.htm (1 of 4) [15-7-2000 23:50:29]


AN 18, page scanner

Cls
Lcd "B M Electronics" ' Start Up Message, What you like
Dim Check As Bit ' Check for Call
Dim DelayTime As Byte ' Used in Loop for Time Between
Calls
Dim AlarmBlips As Byte ' Counter for No of Bleeps on
Sounders
Dim I2cAddress As Byte ' Address to Read
Dim I2cRead As Byte ' Data from PCF8574
Dim I2cStage As Byte ' Individual PCF8574 Location
Dim RealNo As Byte ' Actual Position Number
Dim Result As Byte ' Result of Input Present Test
Dim Message As String * 16 ' Displayed Pager/Lcd Message
StatusLed Alias P0.0 ' Inverted 1=OFF 0=ON
Sounder Alias P2.2 ' True 1=ON 0=OFF
BackLight Alias P2.3 ' True
Relay Alias P2.4 ' True
Sounder = 0 ' Sounder OFF
Relay = 0 ' Relay OFF (If Used)
BackLight = 0 ' Back Light OFF
Check = 0 ' Reset Call Check Bit for Immediate Page
StatusLed = 1 ' OFF

MainLoop:
Gosub ScanInputs
Reset WatchDog
StatusLed = 0 ' Status Led ON
WaitMs 10 ' Led Flash Time (Once Per Scan of 32 Points)
StatusLed = 1 ' Status Led OFF - Disable if faster scan
needed
WaitMs 150
If Check = 1 Then : Gosub DelayIt : Goto StartUp : End
If
Goto MainLoop
End

ScanInputs: ' Reads all PCF8574 Inputs in Sequence


For I2cAddress = 64 To 70 Step 2 ' Select 1 of 4 ICs In Turn
If I2cAddress = 64 Then : I2cStage = 0 : End If ' 1st 4
codes for PCF8574
If I2cAddress = 66 Then : I2cStage = 8 : End If
If I2cAddress = 68 Then : I2cStage = 16 : End If
If I2cAddress = 70 Then : I2cStage = 24 : End If
I2cReceive , I2cAddress , I2cRead
Result = I2cRead And 1 : If Result = 0 Then : RealNo = 0 +
I2cStage : Gosub Display : End If

file:///F|/FrontPage Webs/Content/server/an18.htm (2 of 4) [15-7-2000 23:50:29]


AN 18, page scanner

Result = I2cRead And 2 : If Result = 0 Then : RealNo = 1 +


I2cStage : Gosub Display : End If
Result = I2cRead And 4 : If Result = 0 Then : RealNo = 2 +
I2cStage : Gosub Display : End If
Result = I2cRead And 8 : If Result = 0 Then : RealNo = 3 +
I2cStage : Gosub Display : End If
Result = I2cRead And 16 : If Result = 0 Then : RealNo = 4
+ I2cStage : Gosub Display : End If
Result = I2cRead And 32 : If Result = 0 Then : RealNo = 5
+ I2cStage : Gosub Display : End If
Result = I2cRead And 64 : If Result = 0 Then : RealNo = 6
+ I2cStage : Gosub Display : End If
Result = I2cRead And 128 : If Result = 0 Then : RealNo = 7
+ I2cStage : Gosub Display : End If
Next I2cAddress
Return
End

Display:
Reset WatchDog
BackLight = 1 ' Display Back Light ON
Check = 1 ' Enables Loop Delay Counter
StatusLed = 0 ' Flashes Led
Message = LookupStr(RealNo , List)
Cls
Lcd "Number Calling.." ' Print to Lcd
Lowerline
Lcd Message ' Alarm message to Lcd
Reset WatchDog
Print "L0012000A" ; Message ' TX Message to Pagers Or
other serial 'device
Gosub Alarm
Return
End

Alarm:
For AlarmBlips = 0 to 5 ' Modify for faster scan
Reset WatchDog
Sounder = 1 ' Alarm ON
Wait 1
Reset WatchDog
Sounder = 0 ' Alarm OFF
Wait 1
Next AlarmBlips
Return
End

file:///F|/FrontPage Webs/Content/server/an18.htm (3 of 4) [15-7-2000 23:50:29]


AN 18, page scanner

DelayIt: ' Routine needed instead of simple Wait


For DelayTime = 0 To 45 ' To allow WatchDog to Reset
periodically
Reset WatchDog
Wait 1
Next DelayTime ' Remove this routine for fast scan
Return
End

List:
Data "One " , "Two " , "Three " , "Four " ' Change these for
whatever
Data "Five " , "Six " , "Seven " , "Eight "
Data "Nine " , "Ten " , "Eleven " , "Twelve "
Data "Thirteen " , "Fourteen " , "Fifteen " , "Sixteen "
Data "Seventeen " , "Eighteen " , "Nineteen " , "Twenty "
Data "Twenty One " , "Twenty Two " , "Twenty Three " ,
"Twenty Four "
Data "Twenty Five " , "Twenty Six " , "Twenty Seven " ,
"Twenty Eight "
Data "Twenty Nine " , "Thirty " , "Thirty One " , "Thirty Two
"
End

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: oktober 10, 1999

file:///F|/FrontPage Webs/Content/server/an18.htm (4 of 4) [15-7-2000 23:50:29]


AN 19, Using the LM75 with BASCOM

Using the LM75 Temperature sensor with


BASCOM
The LM75 is a popular chip to read the temperature.
But this chip also is giving some problems. Michael Akers
who was part of the design team wrote this application note
than reveals how to interface the chip with BASCOM-8051.

Download the PDF lm75.pdf


Or download the BASCOM-8051 source code lm75full.bas.

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: oktober 23, 1999

file:///F|/FrontPage Webs/Content/server/an19.htm [15-7-2000 23:50:29]


AN 20, how to decode Sony IR remote control signals

How to decode Sony IR remote control signals


The sample source code of this application note shows that you don't have to use ASM.
Kantor Zoltan who wrote this program shows you how to do the job with just BASCOM-BASIC.

Just connect a SFH506-36 to the INT0 of the 8051 compatible chip.


Here is the code:

' (c)1999, By Kantor Zoltan


'foprogi
'*******************************************************************************************
'compiler opciok
'*******************************************************************************************
$baud = 19200 'baudrate
$crystal = 11059200 'frequency
$romstart = &H8200 'rom starting address
$ramsize = &H0200 'size of RAM
$ramstart = &H3000
$large
$iramstart = &H30
$map
'Hardware
'int0 IR sensor
'if there is an infra signal then the pin is 1
'number of received bit: 12+1 start
'device code:5 bit
'button code:7 bit
'if you have question please let me know:
'mailto:kantor@mail.matav.hu
'mailto:kantor@freemail.c3.hu
'mailto:kantor@tar.hu
'*******************************************************************************************
'konfig
file:///F|/FrontPage Webs/Content/server/an20.htm (1 of 4) [15-7-2000 23:50:30]
AN 20, how to decode Sony IR remote control signals
'*******************************************************************************************
Config Timer0 = Timer , Gate = Internal , Mode = 2
'Timer0 = timer : timer0 operates as a timer
'Gate = Internal : no external gate control
'Mode = 2 : 8-bit reload
Th0 = 0
Set Tcon.0 'edge trig
Set Tcon.2
On Timer0 Timer_0_int
On Int0 Int0_int
Enable Interrupts 'enable the use of interrupts
Enable Timer0
Enable Int0
Start Timer0 'start the timer
'*******************************************************************************************
'valtozo definiciok
'*******************************************************************************************
Triac Alias P1.0
Led Alias P3.3
Dim New_ir_command As Bit
Dim Infra_count As Byte
Dim Infra_count_old As Byte
Dim Infra_command As Word
Dim Segb1 As Byte
Dim Segbit1 As Bit
Dim N As Byte
Dim Segw1 As Word
Dim Segb2 As Byte
New_ir_command = 0
Ide:
If New_ir_command = 0 Then Goto Ide
Infra_count_old = 0
Segw1 = Infra_command
Print N ; " Number of received bit "
Print "Received command ";
Printhex Segw1
Shift Segw1 , Right , 2
Segb2 = High(segw1)
Print "Device " ; Segb2
Segb2 = Low(segw1) / 2
Print "Button " ; Segb2
file:///F|/FrontPage Webs/Content/server/an20.htm (2 of 4) [15-7-2000 23:50:30]
AN 20, how to decode Sony IR remote control signals
Print
Goto Ide
'*******************************************************************************************
'* int rutinok
'*******************************************************************************************
'****************************************
'* timer0 rutin
'****************************************
Rem The Interrupt Handler For The Timer0 Interrupt
Rem .27.. ms each irq
Timer_0_int:
If Infra_count < 150 Then
Incr Infra_count
New_ir_command = 0
Else
New_ir_command = 0
If Infra_count_old <> 0 Then
New_ir_command = 1
End If
End If
Timer_0_int_end:
Return
'****************************************
'* int0 rutin
'****************************************
Rem The Interrupt Handler For The INT0 Interrupt
Rem infra falling edge trigger the irq
Int0_int:
If Infra_count = 150 Then
Infra_count = 0 'start receive (Infra_count=0)
New_ir_command = 0
Infra_count_old = 0
Infra_command = 0
N = 0
End If
Segb1 = Infra_count - Infra_count_old
If Segb1 > 5 Then Set Infra_command.15 Else Reset Infra_command.15
Infra_count_old = Infra_count
Shift Infra_command , Right
Incr N
Int0_int_end:
Return
file:///F|/FrontPage Webs/Content/server/an20.htm (3 of 4) [15-7-2000 23:50:30]
AN 20, how to decode Sony IR remote control signals

Or download the file ir2.bas

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: december 11, 1999

file:///F|/FrontPage Webs/Content/server/an20.htm (4 of 4) [15-7-2000 23:50:30]


AN 21, ASCII input with 3x4 keyboard matrix

ASCII input with 3x4 keyboard matrix


This application note is written by John van der Putte.
The program uses a 3x4 keyboard matrix to input ASCII.
The output is placed on the LCD-display and will be saved in the variable TEXT.
If one key is keyed several times the characters of that key rotates at the cursor.
When no key is pressed the cursor shifts to the next display-position after a while.
This time can easely be changed.

' *************************************************
' * MATRIXINPUT V1.0 07-12-99
' *
' * Author: John van der Putte
' * E-mail: joconiki@hotmail.com
' * icq: 47666030
' *
' * Program:
' * This program uses a 3x4 keyboard matrix to input
' * ASCII. The output is placed on the LCD-display and
' * will be saved in the variable TEXT.
' * If one key is pushed several times the characters
' * of that key rotates at the cursor. When no key is
' * pressed the cursor shifts to the next display-
' * position after a while. This time can easely be changed.
' *
' * The keys have the following layout:
' *
' * 1 2 3
' * .,?!-& ABC DEF
' *
' * 4 5 6
' * GHI JKL MNO
' *
' * 7 8 9
' * PQRS TUV WXYZ
' *
' * * 0 #
' * <BACKSPACE> <SPACE> <ENTER>
' *
' *
' *
' * The procedure which looks to the keyboard matrix returns the
' * following values:
' * no key = 17

file:///F|/FrontPage Webs/Content/server/an21.htm (1 of 5) [15-7-2000 23:50:30]


AN 21, ASCII input with 3x4 keyboard matrix
' * 0...9 = 0...9
' * * = 10
' * # = 11
' *
$romstart = &H4000
$ramstart = &HC000
$lcd = &H2000
$map
Config Lcd = 20 * 2
Config Debounce = 25 ' Set Key Pad Debounce to 40 Ms
Col1 Alias P4.7
Col2 Alias P4.6
Col3 Alias P4.5
Row1 Alias P4.3
Row2 Alias P4.2
Row3 Alias P4.1
Row4 Alias P4.0
Dim Keyread As Byte ' key being scanned
Dim Key As Byte ' key being pressed
Dim Keyold As Byte ' key being pressed before
Dim Number As Byte ' pointer to charactertable
Dim Index As Byte ' pointer to character for the pressed key
Dim Character As String * 1 ' character selected
Dim Count As Byte ' time for automatic cursormovement
Dim Text As String * 20 ' text inputted so far
Dim I As Byte ' used by for-next loops
Dim Begin As Byte ' pointer to character in charactertable
Dim Name As String * 20
Const Countmax = 30 ' change this value for different time of automatic
cursormovement
Cls ' clear lcd-display
Cursor Off Blink ' no cursor but blinking character
' time for automatic cursormovement is controlled bij timer0.
' when timer0 is needed for other purposes you can replace it
' with a simple incrementation of a variable
' timer0 is configured as a 16-bit timer
Config Timer0 = Timer , Gate = Internal , Mode = 1
On Timer0 Timer_0_int
Enable Interrupts
Enable Timer0
Print "Give your textinput with keyboardmatrix."
Print "Input is displayed on LCD, result is displayed on screen"
Gosub Matrix_input
Print
Print "This is your input: >" ; Text ; "<"
End

Matrix_input:
Index = 0 ' reset index
Keyold = 16 ' reset keyold (16 is used to prevent automatic cursormovement)
Count = 0 ' reset count

file:///F|/FrontPage Webs/Content/server/an21.htm (2 of 5) [15-7-2000 23:50:30]


AN 21, ASCII input with 3x4 keyboard matrix
Text = "" ' reset text
Do
L0:
Gosub Keyscan
L1:
If Row1 = 0 Then Goto L1
If Row2 = 0 Then Goto L1
If Row3 = 0 Then Goto L1
If Row4 = 0 Then Goto L1
If Count = Countmax Then ' if it is time for automatic cursormovement then
Shiftcursor Right ' move cursor to the right on display
Text = Text + Character ' save character in text
Stop Timer0 ' stop automatic cursormovement
Count = 0 ' reset counter
Index = 0 ' reset index
Keyold = 16 ' pretend an other keypress to suppress automatic
cursormovement
End If
If Key < 16 Then
If Keyold = 16 Then ' prevent automaic cursormovement
Keyold = Key
Stop Timer0
End If
If Key = 10 Then ' BACKSPACE-keywas pressed
Gosub Key10
Goto L0
End If
If Key = 11 Then Goto Key11 ' ENTER-key was pressed
Restore Keylength ' get startpoint in keytable
Begin = 1 ' point at start of keytable
For I = 0 To Key '
Read Number ' read number of characters available on key
If I < Key Then ' calculate startpoint in keytable
Begin = Begin + Number '
End If '
Next I '
If Key <> Keyold Then ' if other key is pressed then
Index = 0 ' reset index
Shiftcursor Right ' move cursor to the right on display
Text = Text + Character ' save character in text
End If '
If Index = Number Then ' index must not exceed the numer of available characters
Index = 0 '
End If '
Begin = Begin + Index ' set pointer in keytable
Restore Keydata ' get character from keytable
For I = 1 To Begin '
Read Character '
Next I '
Lcd Character ' show character to display
Shiftcursor Left ' and move cursor to the left
Count = 0 ' reset count
Start Timer0 ' start timer for automatic cursormovement

file:///F|/FrontPage Webs/Content/server/an21.htm (3 of 5) [15-7-2000 23:50:30]


AN 21, ASCII input with 3x4 keyboard matrix
Keyold = Key ' save the pressed key
Incr Index ' increment index
End If '
Loop
' BACKSPACE-key was pressed
Key10:
I = Len(text) ' number of characters of endresult
If I > 0 Then ' only remove character it there are characters
If Tcon.4 = 1 Then ' if timer0 is still runnuning then:
Stop Timer0 ' stop the timer
Count = 0 ' and reset counting
Lcd " " ' clear lcd at position of cursor
Shiftcursor Left ' and place cursor at the right position
Else
Shiftcursor Left ' move cursor to the left
Lcd " " ' and remove character from lcd
Shiftcursor Left ' place the cursor at the right position
Decr I ' remove last character from result
Text = Left(text , I)
If I = 0 Then ' if no more characters in result then clear result
Text = ""
End If
End If
Keyold = 16 ' prevent automatic cursormovement
End If
Return
' ENTER-key was pressed
Key11:
If Tcon.4 = 1 Then ' if timer0 is still running the keypress isn't added to
endresult
Text = Text + Character ' so add it now
End If
Return
Keyscan: ' Keypad Read Routine (Assignments can be changed for different
connections)
Key = 17
Col1 = 0 : Col2 = 1 : Col3 = 1 ' Turns Columns On (Low) 1 by 1
Keyread = 1 : Debounce Row1 , 0 , Gotkey ' Goto if Key Pressed (Reads LOW Input)
Keyread = 4 : Debounce Row2 , 0 , Gotkey
Keyread = 7 : Debounce Row3 , 0 , Gotkey
Keyread = 10 : Debounce Row4 , 0 , Gotkey ' BACKSPACE Button *
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Col1 = 1 : Col2 = 0 : Col3 = 1
Keyread = 2 : Debounce Row1 , 0 , Gotkey
Keyread = 5 : Debounce Row2 , 0 , Gotkey
Keyread = 8 : Debounce Row3 , 0 , Gotkey
Keyread = 0 : Debounce Row4 , 0 , Gotkey
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Col1 = 1 : Col2 = 1 : Col3 = 0
Keyread = 3 : Debounce Row1 , 0 , Gotkey
Keyread = 6 : Debounce Row2 , 0 , Gotkey
Keyread = 9 : Debounce Row3 , 0 , Gotkey
Keyread = 11 : Debounce Row4 , 0 , Gotkey ' ENTER Button #
file:///F|/FrontPage Webs/Content/server/an21.htm (4 of 5) [15-7-2000 23:50:30]
AN 21, ASCII input with 3x4 keyboard matrix
Return
Gotkey:
Key = Keyread
Return
' everytime TIMER0 overflows it generates an interrupt and jumps to this place
Timer_0_int:
Incr Count ' increment count
Return
' This table holds the number of available characters for each key (0...9)
Keylength:
Data 2 , 7 , 4 , 4 , 4 , 4 , 4 , 5 , 4 , 5
' This table holds the characters available for each key (0...9)
' If you changes this table than you must change the keylength-table too.
Keydata:
Data " " , "0"
Data "." , "," , "?" , "!" , "-" , "&" , "1"
Data "A" , "B" , "C" , "2"
Data "D" , "E" , "F" , "3"
Data "G" , "H" , "I" , "4"
Data "J" , "K" , "L" , "5"
Data "M" , "N" , "O" , "6"
Data "P" , "Q" , "R" , "S" , "7"
Data "T" , "U" , "V" , "8"
Data "W" , "X" , "Y" , "Z" , "9"
Or download the file textmatrix.bas

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: december 11, 1999

file:///F|/FrontPage Webs/Content/server/an21.htm (5 of 5) [15-7-2000 23:50:30]


AN 22, Mutitasking with BASCOM-8051

Multitasking with BASCOM-8051


The following two application notes are provided by David H Lawrence one of our US resellers. As
you will find out at http://www.rhombusinc.com David is specialized in Industrial Embedded
Processing.
The application note code and another example can be downloaded to :
rtc_1.bas rtc_2.bas

'-------------------------------------------------------------------------------
' (c) Copyright 2000 Rhombus Greenville SC
'Code can be used by others providing this header is included in the source.
'===============================================================================
'Getting started in Real-Time Control using BASCOM Part 1
'===============================================================================
'INTRO
'For those who have not yet applied themselves to real-time control using 8-bit
' MCU/MPUs, then these notes and segments of code may help you get started.
'Or if you normally avoid Interrupts, then this first part may change that by
' showing how Timer0 can be expanded into as many timers as you wish, and with
' very little code.
'I am experienced with the 51 at assembler level but new to the Bascom compiler.
' What surprises me the most is that despite the convenience of using a
' compiler, it does not appear to be restricting in any way - hence I hope to
' avoid the use of any assembler code.
'
'Whilst most of what will be described was written a good 15-25 years ago, I
' have checked and it does appear to fit in neatly with present day theory for
' simple real-time control and is classified as 'Co-operative Multi-tasking'.
' There is no forced switching of tasks as with a RTOS, and hence all CPU time
' is devoted to 'getting the job done' and no storage is needed to hold all the
' intermediate states of pre-empted tasks.
'OVERVIEW OF MACHINE CONTROL
'All but the most simple machines require multiple tasks operating in parallel.
' Each task consist of a series of states(steps) with clearly defined logic that
' determines the transition from one state to the next.For example a tank drain
' valve is open, the low level float switch indicates empty but it is known that
' an additional 40 secs needs to be timed for a complete drain and to finally
' close the valve. In parallel a safety locking sequence must be performed on
' another part of the machine before a steam valve is opened.
'
'It is that sort of parallel control that is easily handled by PLCs where there
' is a continuous loop scanning all Inputs, then based on pre-defined logic so
' each task progresses from one stage(step) to the next and resulting in a new
' set of Outputs. With fast loops of Inputing, Processing and Outputing the
' tasks are effectively being controlled in parallel.
'
'When I/O is added that cannot be included in that main I/O loop, such as
' operator interfaces and host serial communication, then the software must use
' interrupts to take whatever time is needed from the main I/O loop to service
' the needs of those asynchronous events. It was at this stage of the PLC's
' history that the limitations of relay ladder logic became more than apparent.
' The PLC solutions to handle these new demands were far from elegant,whereas
' for MPU/MPCs the solutions are a natural and can be achieved very simply
' using the Bascom compiler.

file:///F|/FrontPage Webs/Content/server/an_22.htm (1 of 3) [15-7-2000 23:50:31]


AN 22, Mutitasking with BASCOM-8051

'The methods to be described here have handled slow process control as mentioned
' above, and together with both serial & operator interfaces, They have also
' allowed an 11Mhz 8052 to precisely control a knitting machine's 100+ pneumatic
' outputs in perfect sync with needles flying by at 800 per second, and as the
' operator keyed in a new batch and the host collected production data.
'
'The sharing of CPU time is based on a priority ordered list of tasks and with
' all asyncronous or time critical events being interrupt driven. The main I/O
' tasks are prompted by timer set flags (only one in example) which can also
' serve to distribute CPU demands. Analog inputs can also benefit from using a
' timer rate related to the supply frequency. When each task is completed it
' returns execution to the top of the list.
'Interrupt routines are kept at an absolute minimum and any excessive processing
' needs are off-loaded to the main loop. This holds interrupt service latencies
' to a minimum and avoids the need for either hardware or software priority
' handling to satisfy critical timing issues.
'An example of off-loading interrupt servicing time would be to merely flag the
' timer event shown below, avoid all needs for stacking (it would not change the
' value of any registers, nor even the status flags), and carry out the updates
' in the main loop. For simplicity, the timer ISR below does its processing
' during the interrupt and that will normally be OK but for the most demanding
' applications.
'
'Timer0 ISR code is very small and should be self explicit. In order to show it
' working there is a main loop using those new timers as inputs, a little logic
' for reloading them, and their run status is output to a set of pins to allow
' scoping. For a steady trace the timers are running very fast at a resolution
' of 2mS. If using the Timer0 expansion code in your own applications then it is
' only a matter of defining a new constant for loading the timer.
'Using P3.5 as a scope trigger will show P3.2.3.4 effectively operating in
' parallel and from the same Timer0.
'Part 2 will add transparent keypad input to change the timer values whilst they
' are running & without affecting their operation until the Enter key finalises
' their new value and they snap to the new timing.
'----- INITIALISATION
Dim Timers(4) As Byte , Tic_cnt0 As Byte , Isr_temp As Byte , Io_flag As Bit
Const 2ms = -1793 ' (2/1000)*(11059200/12)-50reload
Config Timer0 = Timer , Gate = Internal , Mode = 1 '16 bit,own code reloads
On Timer0 Timer_0_int
Enable Interrupts 'enable the use of interrupts
Enable Timer0
Priority Set Timer0 'highest priority
Counter0 = 2ms
Start Timer0
'----- MAIN LOOP
'Dumb code to show a set of timers (Timer0 expanded) each running with their own
' individual values, and controlling their own output(a port pin) and effectively
' in parallel.
Main_loop:
Do
'--Test for I/O prompt
If Io_flag = 1 Then Goto Io_control 'Dummy machine control
'--Test for waiting Host messages 'Nothing currently implemented
'If Msg_flag Then Goto Msg_rtn
'--Test for keypad activity
'If Key_flag Then GoTo Key_rtn
Loop
'----- MACHINE CONTROL
Io_control:
'The 3 stages of Read_Inputs/Process/Write_Outputs
'All inputs here are Timer values and hence readily available internally.

file:///F|/FrontPage Webs/Content/server/an_22.htm (2 of 3) [15-7-2000 23:50:31]


AN 22, Mutitasking with BASCOM-8051
'The processing here is merely to watch for Timers(1) to count down to zero
' and then reset its associated P3.5. On the next pass (when Io_flag is found
' set in the Main_loop) we reload all 4 timers with their individual values &
' set their individual flags.
'All subsequent passes with Timer(1)<>0 has pins P3.2.3.4 updated to reflect
' when their counts have reached zero.
'That is not a separate Output stage as such, but if we had remote I/O then
' the equivalents of P3.2.. would be internal bits and once all processing
' was complete, we would output them as a distinct & separate operation as in
' a PLC.
Io_flag = 0
If Timers(1) = 0 Then
If P3.5 = 1 Then 'Dont restart till 1 pass later
Reset P3.5
Else
Timers(1) = 20 : Set P3.5
Timers(2) = 15 : Set P3.2
Timers(3) = 10 : Set P3.3
Timers(4) = 5 : Set P3.4
End If
Else
If Timers(2) = 0 Then Reset P3.2 'Could avoid multiple resets
If Timers(3) = 0 Then Reset P3.3 ' but no real savings
If Timers(4) = 0 Then Reset P3.4
End If
Goto Main_loop
'We return at the highest priority level ignoring the tasks below this one
' but know that they will be reached on the next pass, now that the Io_flag
' is reset. *Except* if the interval set between scans is not realistic: eg
' if the Control routines take 50mS and the Io_flag is set every 40mS then
' all other functions will be blocked out. Timing the different functions in
' the Main_loop and allocating realistic intervals is not a difficult task.
'----- INTERRUPT SERVICE ROUTINE
'On-chip Timer0 over-flow interrupts steal insignificant slices of CPU time in
' order to update any number of independent timers. The timer values halt at zero
' thereby doubling as 'Done' flags. Where timing ranges cannot be covered by
' single byte values it may be more economical to group them with multiple
' Tic_cnts in preference to expanding all timers to use multiple bytes.
Timer_0_int:
Counter0 = 2ms
Start Timer0
Set Io_flag
Inc Tic_cnt0
If Tic_cnt0 => 1 Then '1=2mS for easy scoping
Tic_cnt0 = 0 '5/50 =10mS/100mS more typical
For Isr_temp = 1 To 4
If Timers(isr_temp) <> 0 Then Decr Timers(isr_temp)
Next
'If Timers(0) <> 0 Then Decr Timers(0) 'Alternatively trade code size
'If Timers(1) <> 0 Then Decr Timers(1) ' for speed
'If Timers(2) <> 0 Then Decr Timers(2)
'If Timers(3) <> 0 Then Decr Timers(3)
End If
Return

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: februari 29, 2000

file:///F|/FrontPage Webs/Content/server/an_22.htm (3 of 3) [15-7-2000 23:50:31]


AN 23, Reading and writing the Dallas DS1991 secure I-button

Reading and writing the Dallas DS1991 secure I-button

This application note is written by Evert K. Dekker

Download the 1991.pdf file.


Download the ds1991.bas file
'Demonstration of reading and writing the Dallas DS1991
'secure I-button. Using the 1-wire statements.
'--------------------------------------------------------------
'
' You must use Bascom-8051 1.09 or higher !!
'
'
' pull-up of 4K7 required to VCC from P3.2
' DS1991 serial button connected to P3.2
'--------------------------------------------------------------
' E.K.Dekker 1999 Lampje@Xs4all.nl
'--------------------------------------------------------------
Config 1wire = P3.2 'use this pin
Dim Ar(16) As Byte , I As Byte , Temp As Byte
Dim Text As String * 16 , Temp2 As String * 1
Main:
'Reading first the ROM-number
1wreset 'reset the device
1wwrite &H33 'read ROM command
Ar(1) = 1wread(8) 'read 8 bytes
Print "ROM number : ";
For I = 1 To 8
Printhex Ar(i); 'print ROM-number
Next
Wait 1 'wait a moment
'Writing scratchpad
'It is possible to write 64 bytes of data to the scratchpad. In this example
'i only used 16 bytes.You can write/read the other bytes if you change the
'array or start address.
Text = "Scratchpad data."
Ar(1) = &H96 'Write scratch command
Ar(2) = &HC0 'Start address + C0H
Ar(3) = &HFF - Ar(2) 'Complement of Ar(2)
1wreset 'reset the device
1wwrite &HCC 'Skip read ROM command
1wwrite Ar(1) , 3 'Write command to
DS1991
Gosub Fill_write_array 'Fill array with "Text"
1wwrite Ar(1) , 16 'Write 16 bytes to
DS1991
Wait 1 'wait a moment
'Reading scratchpad back
Ar(1) = &H69 'Read scratch command
Ar(2) = &HC0 'Start adress + COH
Ar(3) = &HFF - Ar(2) 'Complement of Ar(2)
1wreset 'reset the device
1wwrite &HCC 'Skip read ROM command
1wwrite Ar(1) , 3 'Write command to
DS1991

file:///F|/FrontPage Webs/Content/server/an_23.htm (1 of 3) [15-7-2000 23:50:31]


AN 23, Reading and writing the Dallas DS1991 secure I-button
Ar(1) = 1wread(16) 'Read 16 bytes from
DS1991
Print "Scratch pad : "; '
For I = 1 To 16 'Prints the contents of
the
Temp = Ar(i) ' scratchpad
Print Chr(temp); '
Next I '
Wait 1 'wait a moment
'Writing subkeyid and password
'Writing new subkeyid and password will destroy all data in subkey.
'The DS1991 has 3 Subkeys, 1=00H , 2=40H , 3=80H
'The variable "text" must be exactly 16 bytes, the first 8 for Subkey-id and the
'last 8 for password. Every subkey has it's own password.
Text = "Subkyid1PASSWORD" 'New subkey-id and
password
Ar(1) = &H5A 'Change password
command
Ar(2) = &H00 'Subkey-id to change
Ar(3) = &HFF - Ar(2) 'Complement of Ar(2)
1wreset 'reset the device
1wwrite &HCC 'Skip read ROM command
1wwrite Ar(1) , 3 'Write command to
DS1991
Ar(1) = 1wread(8) 'Read old-id
1wwrite Ar(1) , 8 'Write old-id back to
DS1991
Gosub Fill_write_array 'Fill array with "Text"
1wwrite Ar(1) , 16 'Write New-id and
password
Wait 1 'wait a moment
'Writing subkey
'It is possible to write 64 bytes of data to the subkey. In this example
'i only used 16 bytes.You can write/read the other bytes if you change the
'array or start address.
Text = "Hello world!!!!!" 'New subkey
Ar(1) = &H99 'Writing subkey command
Ar(2) = &H10 'Subkey(00H) + Start
address (10H)
Ar(3) = &HFF - Ar(2) 'Complement of Ar(2)
1wreset 'reset the device
1wwrite &HCC 'Skip read ROM command
1wwrite Ar(1) , 3 'Write subkey write
command
Text = "Subkyid1" 'Must be the same as
the first 8
Gosub Fill_write_array ' bytes of "writing
subkeyid & passw."
1wwrite Ar(1) , 8 'Write Subkeyid for
conformation
Text = "PASSWORD" 'Must be the same as
the last 8
Gosub Fill_write_array ' bytes of "writing
subkeyid & passw."
1wwrite Ar(1) , 8 'Write password to
DS1991
Text = "Hello world !!!!" 'New subkey data
Gosub Fill_write_array
1wwrite Ar(1) , 16 'Write 16 bytes to
DS1991
Wait 1
'Reading subkey
Ar(1) = &H66 'Read secured subkey
command

file:///F|/FrontPage Webs/Content/server/an_23.htm (2 of 3) [15-7-2000 23:50:31]


AN 23, Reading and writing the Dallas DS1991 secure I-button
Ar(2) = &H10 'Subkey(00H) + Start
adress (10H)
Ar(3) = &HFF - Ar(2) 'Complement of Ar(2)
1wreset 'reset the device
1wwrite &HCC 'Skip read ROM command
1wwrite Ar(1) , 3 'Write subkey read
command
Ar(1) = 1wread(8) 'DS1991 respons with
the Subkey-id
Text = "PASSWORD" 'Must be the same as
the last 8
Gosub Fill_write_array ' bytes of "writing
subkeyid & passw."
1wwrite Ar(1) , 8 'Write password to
DS1991
Ar(1) = 1wread(16) 'Reads 16 bytes from
DS1991
Print "Sub key : "; '
For I = 1 To 16 '
Temp = Ar(i) 'Prints the contents of
the
Print Chr(temp); ' subkey.
Next I '
Wait 1 'wait a moment
Goto Main 'And do it again

Fill_write_array:
For I = 1 To 16
Temp2 = Mid(text , I , 1)
Ar(i) = Asc(temp2)
Next I
Return

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: maart 01, 2000

file:///F|/FrontPage Webs/Content/server/an_23.htm (3 of 3) [15-7-2000 23:50:31]


AN 24, how to increase resolution of DS1821 temperature sensor

How to increase resolution of the DS1821 temperature sensor


This application note was written by Dusko Djuricin.
It shows how to expand the resolution of the DS1821.
Dusko included the schematic in ASCII too.
' =========================================================================================
'
' Program: DS1821HI.BAS
' Author: Dusko Djuricin
' E-mail: djdusko@eunet.yu
'
' This program demonstrates how to increase resolution of DS1821 temperature sensor.
' According to Dallas Application Note 105, there is an undocumented command for reading
' remain value in DS1821 counter, which is used in standard application for rounding the
' readout (1 Celsius degree resolution). Using this technique it is possible to achive
' 0.5 Celsius degree resolution and an real (not integer) readout!
' Test bed for this program was 89S8252 with minimal hardware, 2x16 LCD and DS1821 connected
' in the following way:
'
' |
' | ---------
' P1.1 +-----o----------------| 270E |-----------o +5V
' | | ---------
' | |
' | | ---------
' P1.0 +-----|---------o------| 4K7 |-----------o +5V
' | | | ---------
' | | |
' AT89S8252 | o o
' -------------- VDD DQ
'
' Third pin of DS1821 (GND pin) should be connected directly to GND.
'
' =========================================================================================
file:///F|/FrontPage Webs/Content/server/an_24.htm (1 of 4) [15-7-2000 23:50:32]
AN 24, how to increase resolution of DS1821 temperature sensor
'-----------------------[Subroutine declarations]---------------------------------
Declare Sub Write_ds1821(addr As Byte , N As Byte)
Declare Sub Mode_toggle_ds1821
Declare Sub Write_stat_ds1821(n As Byte)
'------------------------[variable declarations]---------------------------------
Dim N As Byte
Dim Addr As Byte
Dim Temp_w As Word
Dim Count_remain As Word
Dim Count_per_degree As Word
Dim T As Single
Dim T1 As Single
Dim Sign As String * 1
Dim Tc$ As String * 8
Dq Alias P1.0
Vdd Alias P1.1
'-------------------------[Beginning of Code]------------------------------------
Config 1wire = Dq ' define 1WIRE pin
Cursor Off
Cls
Lcd " DS1821 in "
Lowerline
Lcd " high resolution"
Wait 2
Cls
Lcd " presented by"
Lowerline
Lcd "djdusko@eunet.yu"
Wait 3
For N = 1 To 16
Shiftlcd Right
Waitms 150
Next N
Cls
'-----[initialize DS1821]--------------
Mode_toggle_ds1821 ' put device into 1wire mode
Write_stat_ds1821 &H01 ' write in status register:
' oneshot measure (IMPORTANT!)
' active output low,
' power up in 1wire mode

file:///F|/FrontPage Webs/Content/server/an_24.htm (2 of 4) [15-7-2000 23:50:32]


AN 24, how to increase resolution of DS1821 temperature sensor
'----------[main loop]------------------
Do
1wreset ' reset 1WIRE bus
1wwrite &HEE ' start conversion (one shot)
!L_wait: ' now...
1wreset ' reset 1WIRE bus,
1wwrite &HAC ' read status register,
N = 1wread() ' and check,
mov a,{n} ' does conversion is finished...
rlc a ' if not,
jnc L_wait ' loop for a while
1wreset ' reset 1WIRE bus
1wwrite &HAA ' and read
N = 1wread() ' measured value
Sign = "" ' prepare sign variable
If N.7 = 1 Then ' if temperature is < 0
N = 256 - N ' convert it from 2nd complement
Sign = "-" ' and mark sign
End If ' (so far it was standard procedure).
1wreset ' reset 1WIRE bus
1wwrite &HA0 ' now read remaind part of DS1821 counter
Count_remain = 1wread(2) ' (it is 9 bit long!)
1wreset ' reset 1WIRE bus
1wwrite &H41 ' send LOAD COUNTER command which prepares
1wreset ' (reset 1WIRE bus)
1wwrite &HA0 ' for reading the internal parameter
Count_per_degree = 1wread(2) ' needed for further calculations (9 bits)
Temp_w = Count_per_degree - Count_remain ' (see details in DALLAS AN105)
T1 = Count_per_degree 'For T >= 0:
T = Temp_w / T1 ' Count_per_degree - Count_re
T1 = N 'T = N - 1/2LSB + ---------------------------
If Sign = "" Then ' Count_per_degree
T1 = T1 - 0.5 '
T = T1 + T 'For T < 0:
Else ' Count_per_degree - Count_re
T1 = T1 + 0.5 'T = N + 1/2LSB - ---------------------------
T = T1 - T ' Count_per_degree
End If '
Tc$ = Fusing(t , ##.##) ' format the readout and
Locate 1 , 4 : Lcd "T=" ; Sign ; Tc$ ; "[C] " ' display measured temperature
Loop ' loop forever
'-------------------------------[DS1821 subroutines]-------------------------------

file:///F|/FrontPage Webs/Content/server/an_24.htm (3 of 4) [15-7-2000 23:50:32]


AN 24, how to increase resolution of DS1821 temperature sensor
Sub Write_ds1821(addr As Byte , N As Byte)
1wreset ' reset 1WIRE bus
1wwrite Addr ' write command
1wwrite N ' and then data
End Sub
Sub Mode_toggle_ds1821
$asm
setb Dq ' rise DQ line
nop ' (settling time required by DS1821)
clr Vdd ' now drop VDD line and
mov a,#15 ' clock DQ line 16 times ...
L_clk: ' (this is the way how to put device
clr dq ' into 1WIRE mode, if it was previously
nop ' programmed in thermostat mode)
setb dq
djnz a,l_clk
nop
setb Vdd ' now rise VDD line (back to normal operation
$end Asm
End Sub
Sub Write_stat_ds1821(n As Byte)
1wreset ' reset 1WIRE bus
1wwrite &H0C ' address status register (write command)
1wwrite N ' and write data
End Sub
'---------------------------------[End of Code]----------------------------------

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: maart 01, 2000

file:///F|/FrontPage Webs/Content/server/an_24.htm (4 of 4) [15-7-2000 23:50:32]


AN 25, Using the T6963 based GRAPHIC DISPLAY

Using the T6963 based GRAPHIC DISPLAY


Peter Huijssen figured out how to use the graphical displays that are equipped with the T6963 chip.

The following document describes how you can create your own bitmaps: convert bitmap.pdf

The document writing software to control t6963c based displays.pdf , you can download for
reference.

A part of the BASCOM-8051 sample is shown below.


Since it is much work to include these DATA lines, I will create a special compiler directive so that
TIF files can be included without modification!
'DEMO PROGRAM T6963 BASED GRAPHIC DISPLAYS USING BASCOM-8051
'Author : P. Huijssen
' The Netherlands
'This program shows a bitmap and some text on a graphic display type : TLX1741-C3M
'which uses the T6963 controller.
'The display has a screenresolution of 240x128 pixels
'The display uses a data/command line to determine of a databyte or command byte is
sent.
'In this application it's connected to A14 which makes it easy te sent data or a
command.
'Data is sent to &H8000 (C/D line low)
'Commands/statuscheck written/read at &HC000 (C/D line high)
'The software is really an experiment and may not match the 'rules' of proper
programming
'All of the used settings regarding the display are very well described in the
datasheet
'The displayscreen should show 'TOSHIBA' in large characters (bitmap) and two lines
of text

'******************************************************************
'INIT
'******************************************************************
$regfile = "REG51.DAT" 'your uC
$crystal = 11059200 'your crystal. Not
important to control the display
'as long if you don't
exceed an instruction time of 200ns
'VARIABELS DISPLAY AND TO SHOW GRAPHICS
Dim Data_display As Byte
Dim Status As Byte
Dim Mask_status As Byte
Dim Dta_1 As Byte
Dim Dta_2 As Byte
Dim Cmdo_1 As Byte
Dim Adres_pointer As Integer
Dim Dummy_adres_pointer As Integer
Dim Dummy As Integer
'VARIABELS USED TO SHOW TEXT

file:///F|/FrontPage Webs/Content/server/an_25.htm (1 of 4) [15-7-2000 23:50:32]


AN 25, Using the T6963 based GRAPHIC DISPLAY
Dim Text As String * 21
Dim String_length As Byte
Dim String_scanner As Byte
Dim Temp_string As String * 2
'*****************************************************************
'*****************************************************************
'START PROGRAMME
'*****************************************************************
'*****************************************************************
Gosub Set_display 'init display
Gosub Display_blank 'clear screen
Gosub Show_bitmap 'place bitmap
Text = "T6963 DEMO SOFTWARE"
Adres_pointer = &H1831 'set adres_pointer in
text ram
Gosub Show_text 'calculate display data
Text = "PH 2000"
Adres_pointer = &H1891
Gosub Show_text
End
'**************************
'DISPLAY SETUP
'************************
Set_display:
P1.0 = 1 'Reset display. Active
low
Nop : Nop 'I thought I might need
it during
P1.0 = 0 'the execution of the
code so I didn't
Nop : Nop 'use a hardware reset
from a watchdog for
P1.0 = 1 'instance.
Restore Dta_init 'init display. see also
datasheet
For dummy = 1 To 7
Read Dta_1
Data_display = Dta_1
Gosub Writed
Read Dta_2
Data_display = Dta_2
Gosub Writed
Read Cmdo_1
Data_display = Cmdo_1
Gosub Writec
Next Dummy
Return
Dta_init:
Data &H00 , &H00 , &H42 'home adress graphical
ram.upperleft corner
Data &H1E , &H00 , &H43 'linewidth graphics
(bytes per line)
Data &H00 , &H17 , &H40 'home adres text
ram.upperleft corner
Data &H1E , &H00 , &H41 'lijnbreedte grafisch
(characters per line)
Data &H00 , &H00 , &H81 'modeset intern
CharRom,XOR mode
Data &H00 , &H00 , &H9E 'displaymode mixed text
and graphics
Data &H00 , &H00 , &H24
'**********************************************************

file:///F|/FrontPage Webs/Content/server/an_25.htm (2 of 4) [15-7-2000 23:50:32]


AN 25, Using the T6963 based GRAPHIC DISPLAY
'CLEAR SCREEN (ERASE GRAPHIC+TEXT RAM)
'**********************************************************
Display_blank:
Adres_pointer = &H00 'upperleft corner
graphic ram
Gosub Set_adres
For dummy = 1 To 3840 'clear graphic ram
'by writing '0'
Data_display = &H00
Gosub Writed
Data_display = &H00
Gosub Writed
Data_display = &HC0 'auto increment
adres_pointer by 1
Gosub Writec
Next Dummy
Adres_pointer = &H1700 'upperleft corner text
ram
Gosub Set_adres
For dummy = 1 To 480 'clear text ram
'by writing '0'
Data_display = &H00
Gosub Writed
Data_display = &H00
Gosub Writed
Data_display = &HC0 'auto increment
adres_pointer by 1
Gosub Writec
Next Dummy
Return
'*********************************************************
' PLACE ADRES POINTER DISPLAY
'*********************************************************
Set_adres: 'set adres display
Dta_1 = Adres_pointer And &H00FF 'calculate msb/lsb
Dummy_adres_pointer = Adres_pointer And &HFF00
Dummy_adres_pointer = Dummy_adres_pointer / &HFF
Dta_2 = Dummy_adres_pointer
Data_display = Dta_1 'send adres to display
Gosub Writed
Data_display = Dta_2
Gosub Writed
Data_display = &H24 'data sent is adres
data
Gosub Writec
Return
'*********************************************************
'PLACE TEXT.
'*********************************************************
Show_text:
Gosub Set_adres 'set adres pointer
String_length = Len(text) 'calculate string
length
For String_scanner = 1 To String_length 'send string to display
one
'character at the time
Temp_string = Mid(text , String_scanner , 1)
Dta_2 = Asc(temp_string)
Dta_2 = Dta_2 - &H20 'ascii codes in the
char rom
'have an offset of -
&H20. see datasheet

file:///F|/FrontPage Webs/Content/server/an_25.htm (3 of 4) [15-7-2000 23:50:32]


AN 25, Using the T6963 based GRAPHIC DISPLAY
Data_display = &H00
Gosub Writed
Data_display = Dta_2
Gosub Writed
Data_display = &HC0 'auto increment
adres_pointer by 1
Gosub Writec
Next String_scanner 'loop until whole
string is sent
Return
'*****************************************************
'WRITE COMMAND AND DATA NAAR DISPLAY + STATUSCHECK
'*****************************************************
Writec: 'write display command
Gosub Status_check
Out &H3800 , Data_display
Return
'***********
Writed: 'write display data
Gosub Status_check
Out &H3000 , Data_display
Return
'***********
Status_check: 'check status
controller
Status_1:
Status = Inp(&H3800)
Mask_status = Status And 3
If Mask_status = 3 Then : Return
End If
Goto Status_1
'*****************************************************************
'SHOW BITMAP
'*****************************************************************
Show_bitmap:
Gosub Display_blank
Adres_pointer = 0
Gosub Set_adres
Restore Bitmap_data
For dummy = 1 To 3840
Read Dta_2 'read bitmap data and
send to display
Data_display = 0
Gosub Writed
Data_display = Dta_2
Gosub Writed
Data_display = &HC0
Gosub Writec
Next Dummy
Return
Bitmap_data: 'TOSHIBA in large
characters
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00 , &H00
THE REST IS DELETED. So you need the SAMPLE!

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: mei 02, 2000

file:///F|/FrontPage Webs/Content/server/an_25.htm (4 of 4) [15-7-2000 23:50:32]


AN 26, LAB PLC, a PLC implementation in BASCOM-8051

LAB PLC
Lab PLC is written by Mirko Bjelica.
He wrote it for his exam and after reading this project you will admit that he deserves the 10 he got
for his work!
This project is well suited for educational purposes. Mirko supplied all the source and is willing to
help if you have a question. Of course he also likes to know if his design is useful for you.
Now what is this LAB PLC you might wonder?
LAB PLC is a PLC Compiler written in VB DOS.
The PLC software is written in BASCOM-8051 and runs in a small 20 pins 8051 chip.

Lab PLC documentation.

Lab PLC circuit


labplc.zip with all the project files.

And here is the At89C2051 BASCOM-8051 source.


'-----------------------------------------------------------------
' 1999 Mirko Bjelica, Yugoslavia
'
' Contact: mikanb@EUnet.yu
'
' Lab-PLC
' -------
' This program is a part of whole laboratory PLC project which
'I realized as my final exam on Polytechnical Engineering College.
'Lab-PLC has 4 inputs, 4 outputs and one timer and it is created
'for educational purposes. There is also 10 memory markers used
'as temporary bits between gates. At this moment Lab-PLC is installed
'at the college laboratory to control one 3 phase electromotor. I used
'ATMEL's microcontroller AT89C2051 because of its simplicity and because it
'had enough I/O pins for this project. Project also includes software
'written in Visual Basic for DOS, which is used to load RAM memory of
'AT89C2051, PCB, Schematic and a user's manual.
'NOTE:
' Timer - Timer in PLC Device
'uTimer - Timer in AT89C2051 micro controller
'Input_1, Input_2 - Two inputs of single logic gate or Timer (Input_1)
'Output_ - Output of logic gate or Timer
'-----------------------------------------------------------------
'Variable dimensioning
Dim Output_ As Bit , Input_1 As Bit , Input_2 As Bit , Temporary As Bit , Jump As Bit
Dim Working As Bit , Ctrlbit As Bit , Edge As Bit , Tmpmem As Byte , Interval As Byte
Dim K As Byte , Pc_input As Byte , Countr As Integer , Ir As Bit
Dim M0 As Bit : Dim M1 As Bit : Dim M2 As Bit : Dim M3 As Bit : Dim M4 As Bit
Dim M5 As Bit : Dim M6 As Bit : Dim M7 As Bit : Dim M8 As Bit : Dim M9 As Bit
O1 Alias P1.0 : O2 Alias P1.1 : O3 Alias P1.2 : O4 Alias P1.3
I1 Alias P1.4 : I2 Alias P1.5 : I3 Alias P1.6 : I4 Alias P1.7
'Initialization of uTimer
Config Timer0 = Timer , Gate = Internal , Mode = 2
On Timer0 Timer0_interapt

file:///F|/FrontPage Webs/Content/server/an_26.htm (1 of 5) [15-7-2000 23:50:33]


AN 26, LAB PLC, a PLC implementation in BASCOM-8051
Load Timer0 , 250
Enable Interrupts
Enable Timer0
Priority Set Timer0
'Definition of Baud Rate for RS232 communication between PC and PLC
$baud = 4800
$crystal = 12000000
Set P3.7 'Turn led "RECEIVED
DATA" OFF
Reset P3.3 'Led "READY FOR
RECEIVING" starts to blink
P1 = &B11111111 'Clear all inputs and
outputs
K = 67 'RAM Memory address
from where starts writing PLC program
Do 'Routine for loading
RAM memory
Pc_input = Waitkey 'Wait for data
mov R0,{k} 'generating indirect
address
Acc = Pc_input 'proceed data to
accumulator
mov @R0,A 'Write received data to
indirectly addressed memory location
inc k
Loop Until Pc_input = 99 'Code for "End Of
Transfer"
Reset P3.7 'Turn led "RECEIVED
DATA" ON
Set P3.3 'Led "READY FOR
RECEIVING" stops to blink
Tmpmem = 0 '{
Countr = 0 '{
Jump = 0 '{Initialization of
used variables
Edge = 0 '{
Ctrlbit = 0 '{
Prgstart: 'Inception
K = 66 'address-1 because of
increment in next subroutine
Gosub Readram 'Go and read RAM memory
'Program
Nastavi:
'Detection of logic function and timer
Select Case Tmpmem
Case 10 : Gosub Inputs 'Take logic conditions
of input1 and input2
Output_ = Input_1 And Input_2 'AND
Gosub Outp 'Set output of current
logic gate
Goto Checkend
Case 11 : Gosub Inputs 'Take logic conditions
of input1 and input2
Output_ = Input_1 Or Input_2 'OR
Gosub Outp 'Set output of current
logic gate
Goto Checkend
Case 12 : Gosub Inputs 'Take logic conditions
of input1 and input2
Output_ = Input_1
Output_ = Not Output_ 'NOT

file:///F|/FrontPage Webs/Content/server/an_26.htm (2 of 5) [15-7-2000 23:50:33]


AN 26, LAB PLC, a PLC implementation in BASCOM-8051
Gosub Outp 'Set output of current
logic gate
Goto Checkend
Case 13 : Gosub Inputs 'Take logic conditions
of input1 and input2
Output_ = Input_1 And Input_2
Output_ = Not Output_ 'NAND
Gosub Outp 'Set output of current
logic gate
Goto Checkend
Case 14 : Gosub Inputs 'Take logic conditions
of input1 and input2
Output_ = Input_1 Or Input_2
Output_ = Not Output_ 'NOR
Gosub Outp 'Set output of current
logic gate
Goto Checkend
Case 15 : Gosub Inputs 'Take logic conditions
of input1 and input2
Output_ = Input_1 Xor Input_2 'XOR
Gosub Outp 'Set output of current
logic gate
Goto Checkend
Case 24 : Gosub Tajmer 'TIMER
Gosub Outp 'Set output of Timer
Goto Checkend
End Select
'Input detection
Inputs:
Gosub Readram ' /
Gosub Inpt '| Find first input of
current log.gate
Input_1 = Temporary ' \
Gosub Readram ' /
Gosub Inpt '| Find second input of
current log.gate
Input_2 = Temporary ' \
Return 'Return from subroutine
Inputs
'Finding if input in current log.gate is phisical input,phisical output or memory
marker
Inpt:
Select Case Tmpmem
Case 16 : Temporary = I1
Case 17 : Temporary = I2
Case 18 : Temporary = I3
Case 19 : Temporary = I4
Case 20 : Temporary = O1
Temporary = Not Temporary
Case 21 : Temporary = O2
Temporary = Not Temporary
Case 22 : Temporary = O3
Temporary = Not Temporary
Case 23 : Temporary = O4
Temporary = Not Temporary
Case 30 : Temporary = M0
Case 31 : Temporary = M1
Case 32 : Temporary = M2
Case 33 : Temporary = M3
Case 34 : Temporary = M4
Case 35 : Temporary = M5
Case 36 : Temporary = M6
Case 37 : Temporary = M7
Case 38 : Temporary = M8
Case 39 : Temporary = M9

file:///F|/FrontPage Webs/Content/server/an_26.htm (3 of 5) [15-7-2000 23:50:33]


AN 26, LAB PLC, a PLC implementation in BASCOM-8051
End Select
Return
'Finding if output from current log.gate is phisical output or memory marker
Outp:
Gosub Readram
Select Case Tmpmem
Case 20 : Output_ = Not Output_
O1 = Output_
Case 21 : Output_ = Not Output_
O2 = Output_
Case 22 : Output_ = Not Output_
O3 = Output_
Case 23 : Output_ = Not Output_
O4 = Output_
Case 30 : M0 = Output_
Case 31 : M1 = Output_
Case 32 : M2 = Output_
Case 33 : M3 = Output_
Case 34 : M4 = Output_
Case 35 : M5 = Output_
Case 36 : M6 = Output_
Case 37 : M7 = Output_
Case 38 : M8 = Output_
Case 39 : M9 = Output_
End Select
Return
'Timer routine
Tajmer:
Gosub Readram ' /
Gosub Inpt '| Find input of Timer
Input_1 = Temporary ' \
If Jump = 1 Then 'Control bit for
bypassing Timer input scan when Timer Workings
Goto L1
End If
Edge = Input_1
If Edge = 0 Then 'If input Timer input
is low SET control bit
Set Jump
End If
L1:
If Input_1 = 1 Then 'These are 3
conditions which have to be accomplished to start uTimer
If Edge = 0 Then
If Working = 0 Then
Start Timer0
Set Working
End If
Goto L2
End If
End If
Stop Timer0
Countr = 0 'Reset elapsed time
counter
Working = 0 'Reset Timer condition
bit
Output_ = 0 'Reset output of Timer
Ctrlbit = 0
L2:
If Ctrlbit = 1 Then
K = K + 1
Else
Gosub Readram
Interval = Tmpmem

file:///F|/FrontPage Webs/Content/server/an_26.htm (4 of 5) [15-7-2000 23:50:33]


AN 26, LAB PLC, a PLC implementation in BASCOM-8051
Ctrlbit = 1
End If
If Interval = 0 Then
Stop Timer0
Countr = 0
Reset Output_
Jump = 0
Reset Working
Ctrlbit = 0
Else
If Working = 1 Then
Set Output_
Else
Reset Output_
End If
End If
Return
'Checking if it is end of PLC program and if it is, go again from start
Checkend:
Gosub Readram
If Tmpmem = 99 Then
Goto Prgstart
Else
Goto Nastavi
End If
'Interrupt routine for Timer interval
Timer0_interapt:
Countr = Countr + 1 'Elapsed time counter
If Countr = 4000 Then '4000x250=1s
Interval = Interval - 1 'Previously set
interval by user
Countr = 0 'Reset elapsed time
counter
End If
Return
'Routine for reading RAM memory in Execution mode
Readram:
inc k 'Increment address value
mov R0,{k} 'Move value to indirect address register
mov A,@R0 'Move value from addressed location to
accumulator
Tmpmem = Acc 'Store this value in
temporary register because-
'leaving data in accumulator can cause
loss-
'of that data while accumulator is used for
other purposes
Return
End

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: juni 01, 2000

file:///F|/FrontPage Webs/Content/server/an_26.htm (5 of 5) [15-7-2000 23:50:33]


AN 101, BASCOM-AVR SNAP protocol example

BASCOM-AVR SNAP protocol


example
This first AVR application note is donated by Mike Eitel.
The program shows how to implement the S.N.A.P protocol
in BASCOM
and is a simple example to turn a LED ON or OFF. It uses
PLM-24 Power Line Modems to communicate over the
power lines (mains).
This example uses 16-bit CRC-CCITT as error detection
method which gives secure data transfer.
This small program gives you some starter for AVR 8515
with S.N.A.P protocol.

It is tested with original STK200 kit.


I use 8 additional LED on Port C and 1 LED from MISC pin
OC1B to see results. (LED + 1k to VCC)

You can see:


Port A : Not used
Port B : The value of the so called commands
Port C : The value of the send data
Port D : Not used
Pin OC1B : The frequency of the Timer1 ( slower if interrupt
enabled)

I used the SNAP16 and the DEMO2 program from HTH as


base of my modifications.

AVR is node 4, the PC (NT4 SP5) is node 1.


Preambles are "M" for the master and "S" for the slave.

All telegrams use 1 Byte data.

To AVR you send via SEND or +1 button. See result at Port

file:///F|/FrontPage Webs/Content/server/an101.htm (1 of 2) [15-7-2000 23:50:33]


AN 101, BASCOM-AVR SNAP protocol example

C.

For data request I implemented command codes,


means you can give a command ( 0 to 255 ) in the field and
press the READ button.
Then the AVR send his data to the master.

There are momentary 3 commands implemented:

128 requests the momentary value of timer1's low byte.


129 starts interrupt timer1 ( decrementing value of db1 and
sends value to master )
130 stops interrupt timer1

The VB program is written with VB5 called SNAP.BAS


The AVR is written with BASCOM AVR called _Mike_SNAP.
Download the aplication note [140 KB]
Note that SNAP is copyright material of High Tech Horizon

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: oktober 10, 1999

file:///F|/FrontPage Webs/Content/server/an101.htm (2 of 2) [15-7-2000 23:50:33]


AN 102, Bit twiddle outputs on 74HC595 daisy chained shift registers to control relays

Bit twiddle outputs on 74HC595 daisy chained shift registers to control


relays.
Jim Gillespie created this second AVR application note. It shows how to control relays or
other devices by using 74HC595 shift registers. All is controlled by the RS-232 interface and
so is indepenand of the operating system. Just send the right code with a terminal emulator
and control your home.

' Jim Gillespie


' Revised 12-2-99
' Bit twiddle outputs on 74HC595 daisy chained shift registers.
' Automatically determines shift register length.
' Uses 5 port B pins on an ATMEL 90S8515.
' Written to control a large number of relays.
' Command set:
' Snn Set and latch bit nn. Echos command.
' Cnn Clear and latch bit nn. Echos command.
' R Reset and latch all 0's. Echos command
' T Test shift registers and sets length in bits. Returns bit length
' Does not affect 595 outputs.
' V Version. Return a string giving software version.
' I Initialize. Starts program from scratch. echos command.
$baud = 9600 ' development board uses 4 MHZ XTAL
$crystal = 4000000
'$crystal = 7372800 ' use these 2 for production version
'$baud = 2400 ' uses a 7.3728 MHZ XTAL
Const Max_in_len = 3 ' define maximum input chars
Const Max_bytes = 10 ' define max shift reg bytes possible
Const Shift_delay = 50 ' shift delay in microseconds
Const Test_pattern = &HAA ' shift reg test pattern
Dim Bytes(max_bytes) As Byte ' byte shift reg output buffer
Dim String_input As String * Max_in_len ' dim to maximum input characters
Dim Raw_echo As String * Max_in_len
Dim Value As Byte ' becomes numeric value of command
Dim Opcode As String * 1 ' one character opcode goes here
Dim Temp As String * 2 ' temp string work variable
Dim Tempbyte1 As Byte ' more temp vars
Dim Tempbyte2 As Byte
Dim I As Byte
Dim J As Byte
Dim K As Byte
Dim Max_shift_len As Byte ' Test sets this to max bits found
Dim Arry_end As Byte ' Test sets this to last array element
Dim Set_clear_flag As Bit ' flag used to set or clear a bit
' readability definitions
Clock_out Alias Portb.0 ' 74hc595 shift reg signals
Data_out Alias Portb.1 ' port assignments
Data_in Alias Portb.2
Data_in_read Alias Pinb.2 ' NOTE AVR port reads need PIN to get real data
Latch_out Alias Portb.3

file:///F|/FrontPage Webs/Content/server/an102.htm (1 of 4) [15-7-2000 23:50:34]


AN 102, Bit twiddle outputs on 74HC595 daisy chained shift registers to control relays
Clear_out Alias Portb.4
Clock_out_dir Alias Ddrb.0
Data_out_dir Alias Ddrb.1
Data_in_dir Alias Ddrb.2
Latch_out_dir Alias Ddrb.3
Clear_out_dir Alias Ddrb.4
' sub definitions
Declare Sub
Clearbytes(byval Bytecnt As Byte) ' clear byte array
Declare Sub
Latchbytes() ' xfer shift reg to latch outputs
Declare Sub
Clearshift() ' clear shift reg
Declare Sub
Test_shift_reg() ' test and determine shift reg length
Declare Sub
Set_clear_bit() ' set or clear bit based on flag
Declare Sub
Send_bytes() ' send byte array to shift registers
Init: ' set initial conditions for I/O
' MAIN starts here
Set Clock_out
Reset Data_out
Reset Latch_out
Set Clear_out
' set the data direction for I/O
Set Clock_out_dir
Set Data_out_dir
Reset Data_in_dir
Set Latch_out_dir
Set Clear_out_dir
Call Clearshift() ' clear shift reg
Call Latchbytes() ' xfer zeros to outputs

Tempbyte1 = Max_bytes
Call Clearbytes(tempbyte1) ' clear output byte array
Call Test_shift_reg() ' test and set shift reg length
If Max_shift_len = 0 Then
Print "Control Board Failure !!"
Else
Print "Control Board OK !!"
End If
Do ' main loop
String_input = Space(max_in_len) ' clear input string to spaces
Input String_input ' read input string
Raw_echo = String_input ' form echo string
String_input = Trim(string_input) ' trim lead and trail spaces
Opcode = Left(string_input , 1) ' extract opcode
Opcode = Ucase(opcode) ' convert to upper case
Temp = Mid(string_input , 2 , Max_in_len) ' get numeric string
Temp = Trim(temp)
Value = Val(temp) ' convert string to numeric
If Value > Max_shift_len Then ' setting or clearing beyond bit range?
Opcode = " " ' yes. set a bogus command code
End If
Print
Select Case Opcode
Case "S" ' Set a bit
If Value = 0 Then ' improper bit value or format
Print "ERR 7"
Else
Set Set_clear_flag ' flag to set a bit
Call Set_clear_bit() ' go set the bit in array
Call Send_bytes() ' send to shift regs
Call Latchbytes() ' latch the bit pattern to outputs

file:///F|/FrontPage Webs/Content/server/an102.htm (2 of 4) [15-7-2000 23:50:34]


AN 102, Bit twiddle outputs on 74HC595 daisy chained shift registers to control relays
Print Raw_echo ' echo command
End If
Case "C" ' Clear a bit
If Value = 0 Then ' improper bit value or format
Print "ERR 8"
Else
Reset Set_clear_flag ' flag to clear a bit
Call Set_clear_bit() ' clear the bit in the array
Call Send_bytes() ' send to shift regs
Call Latchbytes() ' latch the bit pattern to outputs
Print Raw_echo ' echo command
End If
Case "V" ' print Version etc.
Print "version 1.0.3 11-29-99 Jim Gillespie"
Case "T" ' Test interface
Call Clearshift() ' set shift reg to all zeros
Call Test_shift_reg()
Call Clearshift() ' clear shift reg again
If Max_shift_len = 0 Then ' if failure, give error message
Print "ERR 1"
Else
Print Max_shift_len ' otherwise, echo shift reg length found
End If
Case "R" ' Reset all outputs low
Call Clearshift() ' clear shift reg
Call Latchbytes() ' latch shift reg
Tempbyte2 = Max_bytes
Call Clearbytes(tempbyte2) ' clear byte array
Print Raw_echo ' echo command input
Case "I" ' Initialize
Print Raw_echo ' echo command input
Exit Do ' re-start this program
Case Else ' unknown or improper command format
Print "ERR 4"
End Select
Loop
Print "Control Board Reset and Initialized"
Goto Init ' I command. restart program
Sub clearbytes(byval bytecnt as byte) ' clear output byte array
For I = Bytecnt Downto 0 ' NOTE: for AVR compiler we had to use zero
Bytes(i) = 0 ' to make FOR loop terminate at 1
Next I
End Sub
Sub latchbytes()
Set Latch_out ' latch the shift reg to outputs
Waitms 1
Reset Latch_out
End Sub
Sub clearshift() ' clear shift reg to all 0's
Reset Clear_out
Waitms 1
Set Clear_out
End Sub
Sub Test_shift_reg() ' send byte pattern &hAA to
Tempbyte1 = Test_pattern ' shift reg and count how many 8 bit shifts til
' the pattern appears in cpu input shift reg
Shiftout Data_out , Clock_out , Tempbyte1 , 0 , 8 , Shift_delay
For I = 1 To Max_bytes + 1
Shiftin Data_in_read , Clock_out , Tempbyte2 , 0 , 8 , Shift_delay

file:///F|/FrontPage Webs/Content/server/an102.htm (3 of 4) [15-7-2000 23:50:34]


AN 102, Bit twiddle outputs on 74HC595 daisy chained shift registers to control relays
If Tempbyte2 = Test_pattern Then
Exit For ' we got a match to pattern
End If
Next I
If Tempbyte2 <> Test_pattern Then
Max_shift_len = 0 ' no match. hardware problem
Arry_end = 0
Else
Max_shift_len = I * 8 ' match! calc. and save number of bits found
Arry_end = I ' last array element
End If
End Sub
Sub Set_clear_bit() ' set or clear a bit in byte array
K = 1
I = Value - 1 : I = I \ 8 : I = I + 1 ' calc array index
J = Value - 1 : J = J Mod 8 ' calc bit position
Tempbyte1 = Bytes(i)
Rotate K , Left , J ' put a 1 in proper bit position
If Set_clear_flag = 1 Then
Tempbyte1 = Tempbyte1 Or K ' sets the bit position
Else
K = Not K
Tempbyte1 = Tempbyte1 And K ' clear bit position
End If
Bytes(i) = Tempbyte1 ' update array byte
'Print Hex(tempbyte1) ' ********* debug ***********
End Sub
Sub Send_bytes()
For I = Arry_end Downto 0 ' send byte array to shift regs
Tempbyte1 = Bytes(i)
Shiftout Data_out , Clock_out , Tempbyte1 , 0 , 8 , Shift_delay
Next I
End Sub
End

Or download the file bitbang1.bas

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: december 11, 1999

file:///F|/FrontPage Webs/Content/server/an102.htm (4 of 4) [15-7-2000 23:50:34]


AN 103, Serial to GPIB converter

Serial to GPIB converter


This AN was created by Jan Petersen.
The description is from the Serial2Gpib.txt file and when
you read 'my' it means 'Jans' because he wrote it!
This soft/hardware is made specific for my Tektronix 4662
flatbed plotter with GPIB (IEE488) interface, and a strange
GDU coordinate system..!
Now it communicates with a HPGL device-driver trough a
normal RS 232 serial port.

Introduction:
Some years ago I got the idea of making a PCB with a
plotter and finally found an old Tektronix A3 flatbed plotter
from the early 80'.
But I never really got it to work for that purpose I had in
mind, mainly because of the strange old GDU coordinate
system used on Tektronix Plot10 and Plot50 graphic work
station from that period.

Later on I got a newer Roland DXY990 plotter with


Serial/Parallel interface and I have made many fine PCB
since.
I plot direct on the copper foil with a permanent ink pen,
and the quality is very good.
A quick, easy and clean way of doing some rapidly
prototype boards.

Now I have gone a step further doing quick PCB's and for
that I needed a X-Y machine.
So the old Tektronix got an Atmel 90S2313 chip
implemented, and voila...
So thanks to MCS electronic for there fantastic compiler. :o)

I now just need to finish the milling machine to replace the


pen on the plotter, and I am ready to Countour Milling a

file:///F|/FrontPage Webs/Content/server/an_103.htm (1 of 2) [15-7-2000 23:50:34]


AN 103, Serial to GPIB converter

board with the Eagle Layout-editor and CAM processor I


use. And for that purpose the Tektronix plotter is ideal with
it's robust motor system
and very smooth micro step drive.

Software/Hardware:
I don't think this software is usable in this form for other
than myself, but if you can use fragments of it, maybe the
GPIB protocol procedure, you are welcome to do so.
In this case, I'll be glad when you post me a message.

I have included lots of comments in the source code, so


there isn't much to say about it, except for the size of the
hex file generated.! 7EC (2028) is the actual
ROMIMAGE size, and It took me some time to get it fit in.
Lot of memory was used every time a string needed to be
cleared... (Result="")
By collecting this in a single Sub routine instead, up to 300
byte was saved...!

Click picture to see design.


download serial2gpib.bas
download serial2gpib.gif
download serial2gpib.sch
download serial2gpib.txt

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: februari 26, 2000

file:///F|/FrontPage Webs/Content/server/an_103.htm (2 of 2) [15-7-2000 23:50:34]


AN 104, Measuring a temperature with a 90S2313 and BASCOM-AVR

Measuring a temperature with a 90S2313 and Bascom


AVR
This AN was written by Jorge Ferrero

This is a very simple application in BASCOM-AVR Basic oriented


to hobbyist and beginners (like me) who needs obvious
explanations of simple stuffs to understand how it works. I hope
this will be useful for somebody.
I have measured the temperature with an analog device, since
the temperature sensor gives a voltage signal proportional to
temperature, so I must to convert the analog signal in a digital
one, in order to send data to the AVR chip properly.

Besides, any sensor which gives analog voltage signals could be


read by a MCU with this method, so it is applicable to a wide
spread of possibilities.

I have used as hardware....

Dontronics DT 006, with a 4 Mhz crystal and two caps 22 pf,


with a MAX 232 plug in their socket, and connected to the serial
port of a PC. Obviously, you need also the parallel connection to
the PC.
ATMEL 90S2313-10 (but configured as 4 Mhz in the compiler),
Diode-temperature sensor LM35 from National in TO-92 plastic
package.
ADC 0831 as a analog-digital converter, 8 pin DIP, 8 bits
resolution.

I have used as software....

file:///F|/FrontPage Webs/Content/server/an_104.htm (1 of 4) [15-7-2000 23:50:35]


AN 104, Measuring a temperature with a 90S2313 and BASCOM-AVR

BASCOM-AVR compiler (standard version 1.0.0.9.c)


A lot of help from Mark Alberts (Thank you, Mark!)

The temperature sensor, the ADC and pins from


2313 are wired as shown in the figure:

The temperature sensor has a range from -55 to 150 C, with an


output of 10 mV per C. If we measure with a tester the voltage
between VOUT and GND, will have 0,25 V for 25 C and so on.

The ADC0831 has a synchronous serial interface Microwire from


National semiconductors, which needs 3 wires for sending the
digital signals: CS (CS=0: chip select), CLK and Do.

Do (8-bits) will range from 0 to 255, so if we set the reference


voltage Vref at 2,55 V for the 0831, we will have a digital
measuring range from 0 to 255 C for the output, as we
measure at 10 mV/C with a minimum resolution of 1 C at the
ADC output. Of course there are another limits, as the maximum
operating temperature of chip and electronics circuits.

file:///F|/FrontPage Webs/Content/server/an_104.htm (2 of 4) [15-7-2000 23:50:35]


AN 104, Measuring a temperature with a 90S2313 and BASCOM-AVR

How it works...

When you select the chip (with CS = 0) from the MCU sending a
low by pinb.3, the ADC "wakes up", and it is ready to take a
measurement and output it one bit at a time through D0. The
MCU controls this process through the clock pinb.2. Each pulse of
this clock indicates to the ADC to place a bit on D0. The MCU
grabs that bit, and adds it to a byte variable in which it will
accumulate all eight bits.

Of course there are plenty of ways to do this kind of measures,


but this one it is very simple, and I think it is a good opportunity
to start with BASCOM-AVR compiler. Enjoy!

Here is the code:

'aduc0831 example
Dim As Byte 'hold each bit coming from the ADC

Dim Temp As Byte 'each tick of the clock

Dim T As Byte 'var that will hold result


Config portb = &B11111110'pinb.0 as input; b.1..b.7 as
' output

Clk Alias Portb.2


Cs Alias Portb.3

file:///F|/FrontPage Webs/Content/server/an_104.htm (3 of 4) [15-7-2000 23:50:35]


AN 104, Measuring a temperature with a 90S2313 and BASCOM-AVR

Set cs 'begin with high

Do
Reset Clk
Reset Cs 'select chip
Gosub Pulse

Gosub Pulse 'extra clock for sync

A = 0 : T = 0
For Temp = 1 To 8 'start a new measure

T = T * 2 'send the bit (i) one place to left

Gosub Pulse 'send a clock pulse

T = T + A 'grab the last bit

If Pinb.0 = 1 Then 'read a new bit


A = 1
Else
A = 0
End If

Next
Set Cs
Print T
Wait 1
Loop

End

Pulse:
Set clk
Waitus 10 ' 10 us wait
Reset Clk
Return

Send mail to mark@mcselec.com with questions or comments about this web site.
Last modified: juli 11, 2000

file:///F|/FrontPage Webs/Content/server/an_104.htm (4 of 4) [15-7-2000 23:50:35]


LabPLC
Users manual for LabPLC software

Projected and designed by Mirko Bjelica (mikanb@Eunet.yu)


May 2000.
I would like to express very special gratitude to Mr.
Mark C. Alberts who sponsored me with the BASCOM-8051
software and helped me to create LabPLC, my final work at
Polytechnic Engineering College.
Short introduction to PLCs
(Originally taken from Panayiotis Stassinopoulos)

A typical industrial automation system, consist of three discrete


parts:
Inputs, which represent the senses of the system and has to do with
the facts that are taking place at the environment of the application. Those
inputs could be pressure sensors, temperature sensors, velocity sensors,
approach sensors, buttons, switches etc.
Outputs, with which the system affects its environment, such as
relays, actuators etc.
Control unit, which is the brain of the entire automation system.
The operation of the system is realized with a combination of the above
three parts. The data flow from the inputs through the control unit, in
which they are processed, to the outputs.
Once, a control unit was consisted of analog circuits or digital
circuits who made an excessive usage of logic components or relays. Last
years, with the great development of computer science many
microcomputer-based systems have started to come on the foreground.
The most popular device that was designed is the PLC (Programmable
Logic Controller). A PLC is a complete computer system, specialized for
use with automation systems. It contains a microprocessor, ROM, RAM
for storing its program and a battery to protect its data due to a low
voltage condition.
The inputs and outputs of the application are connected on the
PLC. First implemented PLCs, were supporting control only on digital
signals, so inputs and outputs should be in digital format. Later, there
were designed PLCs which could control analog signals through analog
inputs and outputs.
Programming PLCs

In order to realize the required automation, a PLC should first be


programmed. There have been developed three PLC programming
languages.
STL: It is the most popular and powerful language. It consists of
instructions' list.
For example:
L I3
O T1
= M1
L I2
...
LAD: It's a graphical programming language which looks like the
auxiliary circuit of a relay-based system.
For example:

CSF: It is also a graphical programming language which is the same


with the circuit of the automation made of logic gates.
For example:

Although the basic programming instructions are the same, their


usage may differ from one PLC to another, depending on its model and
manufacturer. Modern PLCs offer advanced programming techniques,
including program blocks, subroutines and functions which can be
accessed from different points of the main program.
In order to import a program in a PLC we must use a special device
called Programmer, or a PC that runs the appropriate software.
Once a program is stored in the PLCs memory, it starts executing
cyclically. By saying this we mean that after the execution of the last
instruction of the program, PLCs controller goes back to the beginning
of the program and executes it again. Acting this way there is a
continuous scanning and processing of the inputs (polling method).
LabPLC Software

For the proper work of PLC device its necessary to put in his
memory a program on which it will work. It can be accomplished in
several ways, and one, that I used, is to use personal computer for
downloading program into PLC. This is of course possible if PC has
installed proper software and in further reading I will explain how to use
software that I made. Application is created using programming language
Visual Basic 1.0 for DOS. Its been realized to maximally simplify
functions entering by only selecting them and not entering logic
functions, inputs, outputs or memory markers by writing names from
keyboard. Next table shows codes of logic functions, inputs, outputs and
memory markers. Of course, this codes are completely useless for user,
but they could be useful for future upgrades or if someone would wish to
make other versions of this software (Windows version for example).

NAME CODE NAME CODE


AND 10 OUTPUT 3 22
OR 11 OUTPUT 4 23
NOT 12 MARKER 0 30
NAND 13 MARKER 1 31
NOR 14 MARKER 2 32
EXOR 15 MARKER 3 33
TIMER 24 MARKER 4 34
INPUT 1 16 MARKER 5 35
INPUT 2 17 MARKER 6 36
INPUT 3 18 MARKER 7 37
INPUT 4 19 MARKER 8 38
OUTPUT 1 20 MARKER 9 39
OUTPUT 2 21 END CODE 99
Table 1. Codes

Software starts when user changes path into directory where


LabPLC files are copied and types into command line labplc.exe. The
path could be C:\LABPLC\labplc.exe. After this action, start screen will
show.
Picture 1. Start Screen

After starting the program, user should select proper


communication port (COM Port) for correct connecting with LabPLC.
Default setting is for COM1. Selection is made from Port menu.

Picture 2. COM Port selection

In order to consider program working and explaining the function


of some elements from start menu it can be split into three parts. Part for
logic elements and their inputs and outputs selection, which consists of
four combo box controls, keypad and window for showing entered
functions.
Picture 3. Combo Box controls for logic function selection and one of inputs

If Timer function is selected, list box will appear instead of combo


box for second input selection and in this list box user can select preset
time for timer in range from 1 to 99 seconds. When timer gets high logic
level on his input, timer will set output to high level and this level will
hold for preset time.

Picture 4. Timer properties

After first selection is made, it is necessary to interpret (Compile)


logic function or timer into code that microcontroller would
understand. This action could be achieved by activating (Compile)
key, which is located on the keypad or selecting this function from
Command menu. After activation of this option, entered logic function
is shown in Entered functions window and pointer is incremented.
Picture 5. Part of the screen, which indicates entered functions and keypad

Besides Port falling menu, there is two more menus,


Commands menu and File menu. In menu File there are four
standard options: New, Load, Save As and Exit. Selecting first option,
completely new input will be started and all previous functions will be
erased. Load and Save As options are used for file manipulations. It
is often in other programs that File menu has these two options. Option
Exit is used to exit program.

Picture 6. File menu

Menu Commands consists of five options with theirs shortcuts


and these options also could be found on keypad. It should be mentioned
that Compile isnt real compile (There is no compiler software), it is
more like interpreter but in this program word compile is more
appropriate for use. Next picture shows this menu.
Picture 7. Commands menu

FUNCTION SHORTCUT
NEW Ctrl+N
LOAD F3
SAVE F2
EXIT Ctrl+X
COMPILE F7
NEXT F6
PREVIOUS F5
TRANSFER F9
DELETE F8
Table2. Shortcut codes

HOW TO HANDLE LabPLC

It is very easy to use LabPLC. When you turn on switch PR1 you
are connecting 24V power supply to PLC and LED L1 (POWER ON)
goes on. I used 24V because it is a standard for industrial voltage levels
for supply and for control signals. At the same time LED L2 starts to
blink and that signifies that PLC is READY for data transmission.
Transmission between PC and PLC goes with a speed of 4800 bits per
second with 8 data bits, none parity and 1 stop bit. When transfer ends,
L2 goes off and L11 (READY) starts to shine. From that moment PLC
starts cyclical program execution. Changing logic states on inputs would
directly affect logic states on outputs and its controlled by the logic,
implemented true program.
EXAMPLES

When I finished construction of PLC I decided to make few


examples of electro-motor drive in order to show its use. First example
illustrates how to start electro-motor using the PLC. Next example shows
changing direction of shaft rotation and finally, the last example
demonstrates starting of three phase electro-motor in star-delta mode.

Example1:

MARKER 0
INPUT 1
START

K1
OUT 1

INPUT 2
STOP
MARKER 1

Example1. Electro-motor starting

Example1-1. Program window of entered functions


Example2:

MARKER0
MARKER3
INPUT 1
LEFT OUT1
K1

`
MARKER5

INPUT 2 MARKER1
RIGHT

MARKER6

OUT2
INPUT 3 K2
STOP
MARKER2 MARKER4

Example2. Changing direction of shaft rotation

Example2-2. Program window of entered functions


Example3:

OUT1
K1
INPUT 1 MARKER0
STOP
OUT2
K2

INPUT 2
START
MARKER1 MARKER3
OUT3
MARKER2 K3

Example3. Starting 3 phase electro-motor in star-delta mode

Example3-3. Program window of entered functions


R26
VCC 560R K1
Q2 L3 IN4
BC557 R9 R10
1
R6 220R 560R
2K2
IN4 R27

R5 560R K2
K11 1K L4 IN3
1 R11 R12
TxD
Q1 1
U1 220R 560R
R3 BC547
AT89C2051
K12 22K R4 19 IN3 R28
FROM PC RxD
1
1K 3
P3.1 (TxD)
P1.7
560R K3
18 L5 IN2
P1.6 R13 R14
VCC 2
P3.0 (RxD) 1
VCC 17 220R 560R
1 P1.5
K14
TRANSFER GROUND C1 16 IN2 R29
P1.4
1uF 560R K4
SW1 R2 15 IN1
P1.3 L6
RESET 100R 1 R15 R16
RST/VPP 1
14 220R 560R
P1.2
R1 C2
10K 27p 4 13 IN1 U2A
XTAL2 P1.1 (AIN2)
1 2
1
XTAL 12 L7
P1.0 (AIN0)
12MHz SN7404 K5
C3 R17 OUT4
VCC
27p 5 11 560R
XTAL1 P3.7 OUT4 U2B
U3 3 4
PR1 1
K9 LM317T VCC 9 L8
P3.5 (T1)
3 2 8 SN7404 K6
1 Vin Vout P3.4 (T0) R18
POWER 7 OUT3
C8 Adj R24 C9 R25 P3.3 (INT1) VCC
+24V 6 560R
100nF 820R 100nF 560R P3.2 (INT0) OUT3 U2C
R33 5 6
1

C4 560R 1
K10 L9
ROUND 1000uF/35V SN7404 K7
R22 L1 R19 OUT2
2K2 VCC
1

+5V
560R
L2 OUT2 U2D
READY 9 8
1
L10
R23 SN7404 K8
270R Q3 R20 OUT1
VCC
BC214B 560R
R32 L11 OUT1
2K2 DATA RECEIVED
C6
R34
560R
47uF
U2E U2F
SN7404 C7 SN7404
11 10 13 12 VCC

47uF
R30 R31
3K3 3K3
file:///F|/FrontPage Webs/Content/server/download/appnotes/vu_032.bas

'---[ Title ]-------------------------------------------------------------------


'
' File : VU_032.bas
' Version : 1.02
' Author : Ger Langezaal, Uiverstraat 13, 1171GX Badhoevedorp, The Netherlands
'
'---[ Program Description ]-----------------------------------------------------
'
' This program shows a bar dispay peak-hold VU meter on a LCD 16 * 2.
' Resolution is 32 elements for a 32 dB range based on the internal 8 bit
' A/D converter.
' The scale range is -26dB - +5dB for 0.125 to 5.00 Volt DC input.
' The display will be updated every 50mS on Timer0 interrupt base.
' Log conversion is done with a log table. At initialization a log table
' will be created and stored in the array Vu(256).
' VU meter can be disabled by Vu_flag = 0.
' Peak Hold can be disabled by Peak_hold_flag = 0.
' Setup for 80C535 at 12 Mhz, VAREF = 5Volt, A/D input = P6.0 (channal # 0).
' Compiler is BASCOM-8051 from MCS Electronics.
'
' note: Use a 47K resistor from the input to P6.0 for input protectection.
'
'---[ Compiler and Hardware related statements ]--------------------------------
'
$ramstart = &H8000
$ramsize = &H7FFF
$large

Config Lcdbus = 4
Config Lcd = 16 * 2
Config Timer0 = Timer , Gate = Internal , Mode = 2

'---[ Variables ]---------------------------------------------------------------


'
Dim Vu_flag As Bit ' VU meter on/off flag
Dim Peak_hold_flag As Bit ' Peak Hold on/off flag
Dim Odd_flag As Bit ' Odd/even flag
Dim Ad_value As Byte ' A/D converter output
Dim Vu_value As Byte ' Log conv. to bar elements
Dim Count0 As Byte ' Interrupt counter
Dim Temp_byte1 As Byte
Dim Temp_byte2 As Byte
Dim Temp_byte3 As Byte
Dim Temp_byte4 As Byte
Dim Temp_byte5 As Byte
Dim Temp_count1 As Byte
Dim Vu(256) As Xram Byte ' Log tabel array
Dim Vu_bar As Xram String * 16 ' LCD row characters

'---[ Constants ]---------------------------------------------------------------


'
Dim Vu_bars As Const 32 ' Number of bar elements
Dim Int_counts As Const 199 ' 200 * 250uS = 50mS
Dim Peak_hold As Const 29 ' 30 * 50mS = 1.5 Sec

'---[ Interrupt settings ]------------------------------------------------------


'
On Timer0 Timer0_int ' Execute subroutine
Load Timer0 , 250 ' Auto reload value 250 (uS)
Priority Set Timer0 ' Set highest priority
Enable Interrupts

file:///F|/FrontPage Webs/Content/server/download/appnotes/vu_032.bas (1 of 4) [15-7-2000 23:54:09]


file:///F|/FrontPage Webs/Content/server/download/appnotes/vu_032.bas

Enable Timer0

'---[ Initialization ]----------------------------------------------------------


'
Cls
Cursor Off
Locate 1 , 1 : Lcd "VU-meter" ' Intro text
Waitms 250 : Waitms 250 ' Show intro message

Temp_byte1 = 0 ' 1 - 32 bar element


Temp_byte2 = 0 ' Data value
Temp_byte3 = 0 ' 0 - 255
Vu(temp_byte3) = 1 ' First array element = 1
Restore Log_table
' Create Log Array Tabel
For Temp_byte1 = 1 To 32 ' 32 bar elements
Read Temp_byte2 ' Read data
Do
Incr Temp_byte3 ' Next array element
Vu(temp_byte3) = Temp_byte1 ' assign element to array
Loop Until Temp_byte3 = Temp_byte2 ' Read next data
Next

'---[ Character Generator RAM ]-------------------------------------------------


'
Deflcdchar 0 , 12 , 18 , 18 , 18 , 12 , 00 , 08 , 08 ' 0
Deflcdchar 1 , 02 , 06 , 02 , 02 , 07 , 00 , 00 , 08 ' 1
Deflcdchar 2 , 06 , 09 , 02 , 04 , 15 , 00 , 00 , 08 ' 2
Deflcdchar 3 , 00 , 00 , 07 , 00 , 00 , 00 , 00 , 08 ' -
Deflcdchar 4 , 00 , 00 , 00 , 00 , 00 , 00 , 00 , 08 ' Marker
Deflcdchar 5 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 00 ' Vu bar
Deflcdchar 6 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 00 ' Vu bar Left
Deflcdchar 7 , 03 , 03 , 03 , 03 , 03 , 03 , 03 , 00 ' Vu bar Right

'---[ Draw scale: -26dB - +5dB ]------------------------------------------------


'
Cls
Locate 1 , 1 : Lcd Chr(4) ; Chr(3) ; Chr(2) ; Chr(0) ; Chr(4) ; Chr(4)
Locate 1 , 7 : Lcd Chr(3) ; Chr(1) ; Chr(0) ; Chr(4) ; Chr(4) ; Chr(4)
Locate 1 , 13 : Lcd Chr(4) ; Chr(0) ; Chr(4) ; Chr(4)

Temp_byte1 = 0
Temp_byte2 = 0
Temp_byte3 = 0
Temp_byte4 = 0
Temp_byte5 = 0
Ad_value = 0
Vu_value = 0
Vu_flag = 1 ' Enable Vu_meter Interrupt
Peak_hold_flag = 1 ' Enable Peak Hold
Start Timer0

'---[ Main loop ]---------------------------------------------------------------


'
Do
' Application program
Loop

End

'---[ Vu meter Subroutine ]-----------------------------------------------------

file:///F|/FrontPage Webs/Content/server/download/appnotes/vu_032.bas (2 of 4) [15-7-2000 23:54:09]


file:///F|/FrontPage Webs/Content/server/download/appnotes/vu_032.bas

'
Vu_meter:
Vu_bar = ""
Ad_value = Getad(0 , 0) ' A/D Ch#1 ,range 0-5Volt
Vu_value = Vu(ad_value) ' Get log value
Temp_byte1 = Vu_bars - Vu_value
Temp_byte1 = Temp_byte1 \ 2 ' Number of fill spaces
Temp_byte2 = Vu_value \ 2 ' Number of Vu bars
Temp_byte3 = Vu_value Mod 2 ' Bar position odd or even
If Temp_byte2 > 0 Then Vu_bar = String(temp_byte2 , 5) ' Assemble Vu bar
If Temp_byte3 = 1 Then Vu_bar = Vu_bar + Chr(6) ' Odd then add 1/2 Vu bar
If Temp_byte1 > 0 Then Vu_bar = Vu_bar + String(temp_byte1 , 32)
Locate 2 , 1 : Lcd Vu_bar ' Show Vu bar

'---[ Peak Hold ]---------------------------------------------------------------


'
If Peak_hold_flag = 0 Then Return
If Temp_count1 > Peak_hold Then ' Reset after 50mS * 30
Temp_count1 = 0 ' Reset peak hold timer
Temp_byte4 = 0 ' Reset peak value
End If

If Ad_value >= Temp_byte4 Then ' New peak value


Temp_byte4 = Ad_value ' Update peak value
Temp_byte5 = Temp_byte2 ' Save peak bar position
Temp_count1 = 0 ' Reset peak hold timer
If Temp_byte3 = 1 Then ' Peak position odd
Odd_flag = 1 ' Set odd flag
Incr Temp_byte5 ' Position single bar element
Else
Odd_flag = 0 ' Reset odd flag
End If
Else
If Temp_byte5 > Temp_byte2 Then
Locate 2 , Temp_byte5 ' Set peak char position
If Odd_flag = 1 Then
Lcd Chr(6) ' Odd = left bar element
Else
Lcd Chr(7) ' Even = right bar element
End If
End If
End If
Incr Temp_count1 ' Increment Peak hold timer
Return

'---[ Interrupt counter ]-------------------------------------------------------


'
Timer0_int:
Incr Count0 ' Count interrupts
If Count0 > Int_counts Then '
Count0 = 0 ' At 200, reset counter
If Vu_flag = 1 Then Gosub Vu_meter ' Every 50mS (250uS * 200)
End If
Return

'---[ Log tabel 1.00 dB/step Step factor 1.122 ]------------------------------


'
Log_table:
Data 7 , 8 , 9 , 10 , 11 , 13 , 14 , 16 , 18 , 20 , 23 , 26 , 29 , 32 , 36 , 40
Data 45 , 51 , 57 , 64 , 72 , 81 , 90 , 102 , 114 , 128 , 143 , 161 , 181 , 203
Data 227 , 255

file:///F|/FrontPage Webs/Content/server/download/appnotes/vu_032.bas (3 of 4) [15-7-2000 23:54:09]


file:///F|/FrontPage Webs/Content/server/download/appnotes/vu_032.bas

'-------------------------------------------------------------------------------

file:///F|/FrontPage Webs/Content/server/download/appnotes/vu_032.bas (4 of 4) [15-7-2000 23:54:09]


Sharp GP2DO2 - a sensor for distance depending control
Description and application of a simple distance measuring system

Claus Khnel

If the simple Yes/No decision of a light barrier or a proximation circuit as an answer of


monitoring is not sufficient than the distance measurement can deliver additional information.
Simple systems for distance measurement should be not more expensive as light barrier
systems. In this article Sharp's position sensitive photo detector GP2DO2 will be described
relating to function and application.

The sensor GP2DO2 contains an infrared transmitting diode, a position sensitive photo
detector, some optics and a signal processing unit in a compact casing of 29 x 14 x 14,4
mm3. Only four pins give the electrical contact to the sensor. Two of them are power supply
and the other two builds a simple serial interface for the data handling during the
measurement. Fig. 1 gives an impression of the Sharp's sensor GP2DO2.

SHARP

Fig. 1 Sharp's GP2D02 for distance measurement

On the left side of the case there is the IR LED and on the right side is the position sensitive
photo detector behind an optical lens. The method of distance measurement is very simple.
Fig. 2 shows the method.

Dist_eng.doc Januar 1, 1999 Page 1 of 10


far object plane

near object plane

IR LED photo detector

Fig. 2 Distance measurement by triangulation

The IR LED transmits a bundled beam to the object plane to be measured. From the photo
detector a reflected beam will be received. The angle of the received beam is dependant of
the distance of the object plane. For two different object planes the situation is displayed in
Fig. 2. If the photo detector is able to process a position sensitive input signal then there is
an information of the distance of an object given.

Photo diodes with a big light sensitive area have position sensitivity on principle. Based on
this physical effect there was position sensitive photo detectors developed. Fig. 3 displays
the principle of a position sensitive photo diode.

P
I
N

I1 I2

Fig. 3 Structure of a position sensitive photo diode

Dist_eng.doc Januar 1, 1999 Page 2 of 10


The vertical structure of the position sensitive photo detector is identically to the structure of
general pin diodes. Based on a n-conductive substrate layer is an isolation layer. Embedded
in this isolation layer is the p-conductive layer from IR irradiated. The contacting of the p-
layer (anode) is made on the left and on the right side.

If there is a spot irradiation in the centre of the p-layer then both currents I1 and I2 will have
the same value. If the spot irradiation goes to the left the current I1 wills grow and the current
I2 will drop with the same value. The difference between the currents I1 and I2 describe the
location of a spot irradiation on the light sensitive surface (between the contacts) of the
position sensitive photo diode.

To process the measured distance the signal processing unit has to exploit the difference in
the currents I1 and I2. After an analog-to-digital conversion the result of measurement is
ready for serial transmission to a microcontroller or other processing unit.

For the processing of optical signals comparable conditions are valid:

 The daylight (or the light of the environment in more general terms) may not influence
the measuring procedure.

 Related to distance and reflection of objects to be measured the reflection behaviour of


these objects shows strong changes in value.

 The very high dynamic range of the measuring signal requires signal compression for
working with normal voltages for power supply.

Disregarding special circuit techniques in bipolar integrated circuit technology (like I2L) that
convert an irradiation into a digital signal directly than one can find circuits based on
logarithmic current-to-voltage converters always again. For logarithmic current-to-voltage
converters there are excellent technological solutions with a very good performance.

Fig. 4 shows the principle of a circuit for position sensitive current-to-voltage conversion.

Dist_eng.doc Januar 1, 1999 Page 3 of 10


VCC
I1

-UT ln(I1/I0)
FD1
VEE R1 R2

VCC

FD2
VCC UT ln(I1/I2)
R3

VEE
I2 -UT ln(I2/I0) R4
VEE
R1 = R2 = R3 = R4 = R

Fig. 4 Circuit for position sensitive current-to-voltage conversion

In Fig. 4 the position sensitive photo detector is described through the photo diodes FD1 and
FD2. Both anodes are connected with identical circuits for current-to-voltage conversion. The
diodes in the opamp's feedback give a logarithmic behaviour of the current-to-voltage
conversion.

To achieve the required accuracy the diodes are build by bipolar transistors with a grounded
base. In a good approach the following equation is valid:

VBE
I C I 0 e xp ( ) (1)
VT

VT describes the temperature voltage proportional to the absolute temperature by eq. (2)

kT
V=
T with k = Boltzmann's constant and e = elementary charge (2)
e
I0 describes very strong temperature dependant saturation current of the bipolar transistor.

For the output voltage of the logarithmic current-to-voltage converter the following equation
is valid:

Dist_eng.doc Januar 1, 1999 Page 4 of 10


IC
V=- T
O Vln( ) (3)
I0

The collector current IC is identically to the current I1 in the upper circuit part of fig. 4 and to
I2 in the lower part. The third opamp processes the difference of the two output voltages.
There is only one condition for accuracy - the resistor values have to be equal.

The output signal of the third opamp is described by eq. (4):

I
VO = VT ln ( 1 ) (4)
I2

The influence of the saturation current I0 is cancelled in eq. (4). It remains only the influence
of the temperature voltage. Because this influence is linear it can be eliminated easily.
Changes of intensity (daylight) will be suppressed because they affect both currents. For
further digital processing the output voltage in eq. (4) is to convert to digital.

With the timing diagram in fig. 5 some statements to the inner processes for distance
measurement can be derived.

min. 70 ms (for 16 LED emissions)


Vin

Vout
MSB LSB

Fig. 5 Timing diagram for measurement and data handling

For controlling the measurement and data handling the two lines Vin and Vout are available.
Vin is to drive by an open-drain output. Vout gives an output compatible to CMOS and/or
TTL [1].

To start the distance measurement the control line Vin must drop to Lo for a time of 70 msec
in minimum. In this time the IR LED transmits 16 pulses in the direction of the measuring

Dist_eng.doc Januar 1, 1999 Page 5 of 10


object. These 16 measurements allow the calculation of the mean value for reducing
possible errors.

After this measuring phase the result can be called from the sensor. The control line Vin has
in this phase the function of a synchronous clock input. Starting with the most significant bit
(MSB) the eight data bits are available at Vout.

The control program for a connected microcontroller has a very simple structure (Fig. 6).

Start

Initialisation I/O-Port

Start of measurement
by Vin = Lo

no
Measurement ready?

yes

Serial readout of result

End

Fig. 6 Structure of control program

Controlling the sensor requires only few resources of a connected microcontroller. Quick
results for evaluation (for example) can be achieved by microcontrollers programmable in

Dist_eng.doc Januar 1, 1999 Page 6 of 10


high-level languages. The BASIC-programmable BASIC Stamp (BS1-IC or BS2-IC) from
Parallax Inc. is a very good example. Fig. 7 shows a minimum system for distance
measurement and display. Additional I/O pins can serve as status outputs.

VCC
10u//47n
D1
LED
C1
U2
UB1
VCC
U3
GND
R1
NC 680 +5VDC
U1
D7
VO D6 GND
D5
VCC D4 SERIAL
D3
VIN D2 GND
D1
GND D0 +5VDC
Q1
GP2DO2 BS1_IC LCD_BACKPACK

MOSFET N
GND

Fig. 7 Minimum system for distance measurement and display

All three units of the whole circuit are powered from the same supply voltage of +5
VDC. I/O line D0 transmits the data to the LCD serial backpack [2]. I/O line D1 drives the
LED to visualize the start of measurement. The input Vin of the sensor GP2DO2 is
connected to the FET Q1, to fulfill the requirements for an open-drain driver. Over I/O line
D3 the serial result of distance measurement will be readout.

The following listing shows the control program for cyclic distance measurements in PBASIC
for BASIC Stamp I. Changes for BASIC Stamp II should be a minimum.

Dist_eng.doc Januar 1, 1999 Page 7 of 10


' -----[ Title ]------------------------------------------------------
'
' File...... GP2DO2.BAS
' Purpose... Test of Distance Measuring Sensor Sharp GP2DO2
' Author.... Claus Khnel
' Started... 18.03.95
' Updated...

' -----[ Program Description ]----------------------------------------


'
' The distance measuring sensor Sharp GP2DO2 Type 1 measures
' distances between 10 cm and 80 cm.
' The result of 16 measurements is given serial as a count byte.
' The BASIC Stamp controls the starts the measurements, reads the
' result and send it serial to an LCD.

' -----[ Revision History ]-------------------------------------------


'
' 18.03.95: Version 1.0

' -----[ Constants ]--------------------------------------------------


'
symbol LCD = 0 ' serial output to LCD
symbol LED = 1 ' LED control
symbol Vin = 2 ' sensor control
symbol baud = N2400 ' Baudrate

' -----[ Variables ]--------------------------------------------------


'
symbol count = b0 ' result of measurement
symbol i = b1 ' loop variable
symbol Vo = pin3 ' sensor data

' -----[ Initialization ]---------------------------------------------


'
init: low Vin
high LED
count = 0
gosub LCD_clear

Dist_eng.doc Januar 1, 1999 Page 8 of 10


' -----[ Main Code ]--------------------------------------------------
'
start:pulsout LED,20000
gosub sensor_control
gosub LCD_print
pause 1000
goto start

' -----[ Subroutines ]------------------------------------------------


'
sensor_control:
'debug cls
high Vin
pause 70
count = 0
for i = 0 to 7
pulsout Vin,10
count = count * 2 + Vo
'debug %count
next i
low Vin
'debug count
return

LCD_clear:
serout LCD,baud,(254,1,254)
serout LCD,baud,("Count:")
return

LCD_print:
serout LCD,baud,(254,136,254,#count," ")
return

Listing Control program GP2DO2.BAS

On the start of each cycle the LED flashes. In the subroutine sensor_control happens
the start of measurement followed from the serial readout of the result. After the readout the
result is stored in the variable Count. The subroutine LCD_print works like a "print-at"
instruction for the LCD and writes the result as decimal number to a defined position. After a
waiting period of one second the whole procedure will be repeated.

The following table shows test results for a reflector build from white copy paper.

Distance in cm 10 20 30 40 50 60 70 >80
Counts on display 147 91 71 55 47 44 42 40

Fig. 8 shows a graphical representation of these measuring results.

Dist_eng.doc Januar 1, 1999 Page 9 of 10


160
140
120
100
Counts
80
60
40
20
0
10 20 30 40 50 60 70 >80
Distanz in cm

Fig. 8 Characteristic of sensor GP2DO2

An important parameter describing the sensitivity of the sensor is the output distance
characteristic Vo. This parameter will be represented by an output change as a result of a
distance change from 80 cm to 20 cm. The values of Vo are between 45 and 65 (typical
55). The measured value here was 51 counts and so a little bit smaller as the typical value.
The measuring distance range is limited to distances from 10 cm to 80 cm. Distances
smaller then 10 cm give angles for the received beam which cannot proceed.

Literature:

[1] Sharp Spec. ED-92024


Distance Measuring Sensor GP2DO2 Type 1
March 12, 1992

[2] Scott Edwards:


LCD Serial Backpack

Dist_eng.doc Januar 1, 1999 Page 10 of 10


file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.bas

'******************************************************************************
' (c) Jan Petersen
' Orevej 6
' DK 4760 Vordingborg
' jan_p@post8.tele.dk
'------------------------------------------------------------------------------
' Date: 24.02.2000
' Compiler: Bascom AVR 1.0.8b
' File: Serial2Gpib.bas
' Description: RS232 to GPIB converter +
' HPGL to GDU converter
'
' This program is made specific for my Tektronix 4662 flatbed plotter
' with GPIB (IEE488) interface, and a strange GDU coordinate system..!
' Now it communicate whit a HPGL device-driver trough a normal
' RS 232 serialport. Hey man...
'------------------------------------------------------------------------------
'
' Input:
' RS232 :19200N81R
' Handshake :RTS/CTS specific for (Eagle CAM processor)
'
' Output:
' GPIB :DATA[0..7] (Inverted !Activ Low!)
' Handshake :DAV (DataValid)
' Handshake :NDAC (NoDataAccepted)
' Handshake :NRFD (NotReadyForData)
'------------------------------------------------------------------------------
'
' HPGL commands: Tektronix 4662 Plotter Commands:
' PU; (PenUp) M[cr]
' PD; (PenDown) D[cr]
' PA xxx,yyy; (PlotAbsolut) Dxxx,yyy[cr]
' VS xx; (VelocitySpeed) BYxx[cr]
' SP 0; (SelectPen) End Of File so goto home = M150,100[cr]
'
' GDU = GraphicDataUnit
' HPGL = HeweletPackardGraphicLanguage
'
' 1 GDU = 2.54 mm
' 1 HPGL unit = 0.025 mm
'
' 100 HPGL units = 1 GDU
' 1 HPGL units = 0.01 GDU
'
' All coordinates are divided by 100
'
' A typical input format would look like this (Eagle Cam processor-HPGL driver)
'
' IN; IP 0,0,100,100; SC 0,100,0,100;
' VS 120
' SP 2;
' PU;
' PA 19,18;
' PD;
' PA 1035,18;
' PU; SP 0; PA 0,0;
'
' Converted output to Tektronix plotter
'
' BY120

file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.bas (1 of 5) [15-7-2000 23:55:36]


file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.bas

' M0.19,0.18
' D10.35,0.18
' M150.100
'******************************************************************************

$regfile = "2313def.dat"
$crystal = 7372800 '7.372800 MHz crystal
$baud = 19200 '@ 19.2 Kbaud error is 0.0%

Dim Result As String * 15


Dim Value_x As String * 7
Dim Value_y As String * 7
Dim Low_ As String * 2
Dim High_ As String * 3
Dim Command As String * 1
Dim A As Byte , B As Byte
Dim H As Byte , L As Byte , Data_inv As Byte

' Init ports ---------------------------------------


Ddrd = &B00010100
Config Portb = Output

Data_out Alias Portb 'Data byte to GPIB PortB


'RX PortD.0
'TX PortD.1
Rts_cts Alias Portd.2 'RTS/CTS handshake PortD.2
Dav Alias Portd.4 'DAV PortD.4
'NDAC PortD.5
'NRFD PortD.6

' Start --------------------------------------------


set dav 'No DataValid on GPIB port
Command = "M" 'set Command to MOVE
Gosub _reset 'reset variable
Reset Rts_cts 'uP ready

' Main loop ----------------------------------------


Do
A = Waitkey() 'wait for a character
set Rts_cts 'uP NOT ready

Select Case A
Case 10 : Gosub _reset 'linefeed
Case 13 : Gosub _reset 'carriage return
Case 32 : Gosub _space 'space
Case 44 : Gosub _comma 'comma
Case 59 : Gosub _semicolon 'semicolon
Case Else : Result = Result + Chr(a) 'add the character to string
End Select

Reset Rts_cts 'uP ready


Loop

_space:
' SPACE
'***************************************************
Select Case Result
Case "VS" : Command = "V" 'VelocitySpeed
Case "SP" : Command = "S" 'SelectPen
Case "PU" : Command = "M" 'PenUp

file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.bas (2 of 5) [15-7-2000 23:55:36]


file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.bas

Case "PD" : Command = "D" 'PenDown


End Select

Gosub _reset
Return

_comma:
' COMMA
'***************************************************
Value_x = Result 'value_x = X-coordinate
Result = "" 'clear Result
Return

_semicolon:
' SEMICOLON
'***************************************************
Select Case Command
Case "V" : Gosub _vs 'Velocity
Case "S" : Gosub _sp 'Select Pen
Case "R" : Gosub _reset '/Dummy Chr...!
End Select '/SP 0 command was detected
'/in the _sp SUB
'/means ..EOF..
Select Case Result
Case "PU" : Command = "M" 'Move
Case "PD" : Command = "D" 'Draw
Case Else : Gosub _make_string 'value_y is in result
End Select

Gosub _reset
Return

_vs:
' PEN SPEED (velocity speed)
'***************************************************
If Result <> "0" Then
Result = "BY" + Result + Chr(13)
Gosub _gpib_out 'BYxx[cr]
End If

Gosub _reset : Command = "M"


Return

_sp:
' SELECT PEN
' if a "SP 0" command is recived
' it means "MOVE HOME" and EOF
'***************************************************
If Result = "0" Then
Result = "M150," + "100" + Chr(13)
Gosub _gpib_out 'M150,100[cr]
Command = "R" '/R means EOF
'/and is at dummy Chr
'/used in _semicolon SUB
Else
Command = "M"
End If

file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.bas (3 of 5) [15-7-2000 23:55:36]


file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.bas

Gosub _reset
Return

_make_string:
' Prepare the string to send to GPIB
'***************************************************
If Result = "" Then Return

If Value_x = "" Then


Gosub _reset '/happens on the first line
Return '/when value_x is NUL
End If

Gosub _divide 'value_Y is in result


Value_y = Result 'value_Y = value_y / 100

Result = Value_x 'now value_X is in result

Gosub _divide
Value_x = Result 'value_X = value_x / 100

' Assemble the string -----------------------------


Result = Command + Value_x + "," + Value_y + Chr(13)

Gosub _gpib_out 'eg.Result = "M12.78,56[cr]"


Gosub _reset
Return

_reset:
' Reset some variable
' This SUB saves lot of ROM Space.. :o)
'***************************************************
Result = "" 'saves some program memory
Value_x = "" 'when variables are cleared
Value_y = "" 'in one SUB
Return

_divide:
' divide by 100
' SINGLE aritmic don't work yet, so we do It like this..!
'***************************************************
High_ = "" : Low_ = ""

If Result = "0" Then Return 'don't divide, value is zero

L = Len(result) 'length of string

If L > 2 Then H = L - 2

If L = 1 Then Low_ = Right(result , 1) '1'st decimal value


If L > 1 Then Low_ = Right(result , 2) '2'nd decimal value
If L > 2 Then High_ = Mid(result , 1 , H) 'real value

If L = 1 Then Result = "0.0" + Low_ '1 decimal


If L = 2 Then Result = "0." + Low_ '2 decimal
If L > 2 Then Result = High_ + "." + Low_ 'real + decimal

file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.bas (4 of 5) [15-7-2000 23:55:36]


file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.bas

B = Val(low_)
If B = 0 Then Result = High_ 'ONLY real
Return

_gpib_out:
' Output data to GPIB port
' Data is inverted
' NRFS,NDAC and DAV is handshake
'***************************************************
L = Len(result) 'how long is the string..?

For H = 1 To L 'loop the string


Low_ = "" 're use a old variable

Low_ = Mid(result , H , 1) 'pick out the character


Data_inv = 255 - Asc(low_) 'invert the character

Bitwait Pind.6 , Set 'wait until (NRFD) goes HIGH

Data_out = Data_inv 'Set the data on the port

Reset Dav 'DataValid on port

Bitwait Portd.6 , Reset 'wait until (NRFD) goes LOW

Bitwait Pind.5 , Set 'wait until (NDAC) goes HIGH

set dav 'Data NOT Valid on port

Bitwait Portd.5 , Reset 'wait until (NDAC) goes LOW


Next H

Bitwait Pind.6 , Set 'wait until (NRFD) goes HIGH


Return

End

file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.bas (5 of 5) [15-7-2000 23:55:36]


0$NHUV(QWHUSULVHV
3800 Vineyard Ave #E
Pleasanton, California 94566
Voice: +1-925-640-3600
Email: mwakers@home.com

1DWLRQDO6HPLFRQGXFWRU/0
'LJLWDO7HPSHUDWXUH6HQVRU

Using the LM75 with an 8-bit microcontroller


I2C interface.

Attention
The information contained in this document is neither supported, nor sanctioned, by any of the
corporations referenced within. This document and the information it contains is solely the opinion
and view of its creator. Use of the information contained in this document is at the risk of the user of
the information. Neither the creator of the document, nor M. Akers Enterprises, can or will, be held
accountable for any damages or loss of profits resulting from the use of this information.

Created by Michael W. Akers, M. Akers Enterprises, October 18, 1999



Section

7KH/0
What exactly is the LM75
2YHUYLHZ

The LM75 was created by National Semiconductor Corporation to fill a crying need in the
PC industry for detecting over temperature conditions in a personal computer. This device
has a built-in 9 bit ADC that will convert the analog thermal reference to a digital value
usable by the PC. But for this document we are going to explore how to access this device
using a Atmel 89C4051 flash microcontroller using the MCS Electronics BASCOM-8051
basic language compiler.
2
Communication with the LM75 is through the I C interface (created by the Phillips
Corporation). This is a 2-wire communications protocol used to communicate serially with
various types of devices similarly configured. The LM75, designed as a slave device, can
2
be configured through the I C interface to alert, through various methods, the PC system
that an over temperature condition has happened.
1
At certain times, direct quotations or excerpts of the LM75 Datasheet will be reproduced
in this document. The information will be displayed with a gray background, and will
contain the page of the LM75 Datasheet. The LM75 Datasheet will, at all times, be the
sole authority. If there is a conflict of information, the LM75 Datasheet will be considered
the correct source.

6FRSH

It is the intent of this document to show the relative ease to which the LM75 Digital
Temperature Sensor can be utilized. This author has reviewed several programs that use
different programming languages to interact with the LM75 DTS. Except for the MCS
Electronics BASCOM-8051 Basic Compiler, all other high level languages require a large
amount of code to perform a simple task (although the compiled object code is as small as
can be). BASCOM-8051 is 99% syntax compatible with Microsoft Qbasic, thus anyone
who can program using MS Qbasic can program a microcontroller. MCS Electronics
2
BASCOM-8051 Basic Compiler has built-in commands for handling the I C protocol,
making the coding process much easier.

The programming examples given in this document will be presented as subroutines that
you can use in your project. Appendix A will contain an example program that will read the
temperature from the LM75 DTS and display it on a LCD display module.
7KH/0

The easiest way to think of the LM75 is as a digital thermal alarm clock. You can read the
thermal time, set the thermal alarm, and its thermal snooze button. You can configure the
device to switch on a fan or an audible alarm. As seen in the diagram below the LM75 is a
fairly simple device.

Figure 1. Block diagram of LM75 device. (extracted from page 1 of the LM75 Datasheet)

The Lm75 has four registers that you can read and write to, depending upon what you
want the device to do. Mostly though, you will be reading the temperature. Upon power up
the device is set to the default mode:

n Comparator Mode

n TOS = 80 C

n THYST = 75 C

n O.S. Active Low

n Pointer = 00
2
The LM75 registers are accessible through the I C port. This port is comprised of Pin 1
SDA (Serial DAta) and Pin 2 SCL (Serial CLock). Also, since this device is addressable
2
(you can have up to eight devices on the I C bus), you have three address pins; Pin 7 A0,
Pin 6 A1, and Pin 5 A2. For purposes of simplicity, A0 to A2 are considered tied to


ground. A thorough reading of the LM75 Datasheet will aquatint you with the operational
fundamentals of the device.

There are some apparent errors in the LM75 Datasheet. As stated, the errors are only
apparent and not actual. The errors, if they are errors, are in the omission of information.
The following is how the information should have been presented:

Address word format: (the waveforms in the LM75 Datasheet are correct)

1 0 0 1 A2 A1 A0 R/W

MSB LSB

n The address for a read function would be 1001XXX1

n The address for a write function would be 1001XXX0

This is the correct way to represent the address word.

Many people who read the LM75 Datasheet often make the mistake of thinking that the
registers in the LM75 are accessed as a 16-bit word. Not, as the waveforms clearly
delineate, as two 8-bit words, in high byte, low byte, order. So most people make the
2
mistake of using the read word or write word I C function when communicating with the
LM75. Although the registers are 16-bit, the access method is 8-bit!

&RQFOXVLRQ

In the next section, I will be going through each register and, with code, explain how to
access and interpret the information.



Section

/P,2
Basic Communications
7HPSHUDWXUH

D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0

SGN MSB 0 0 0 0 0 0 LSB X X X X X X X

MSB LSB MSB LSB

High Byte Low Byte

In the table above is the accurate way to think of the temperature register. Remember that
upon power-up the device is in the default mode, (Pointer = 00) read temperature. With
this in mind, lets look at the table above.

The temperature register is 16 bits wide. Only bits D7 through D15 mean anything. The
High Byte of the temperature word contains the Sign bit (D15) and the whole value
temperature, and the Low Byte contains the fractional temperature (D7). The rest of the
bits in the Low Byte have no meaning (D0 to D6).

To read the LM75 temperature will require sending the address and read command to the
LM75 and then reading the High Byte and then the Low Byte. In addition, the temperature
data is in twos compliment form. This means that when the temperature goes below 0C
the sign bit is set and the data is now a twos compliment of the actual temperature value.

Twos compliment simply means that the information is negated. (Real clear isnt it?) As an
example, zero is the compliment of one, and one is the compliment of zero. The
compliment of falling down is falling up. Get the picture? The math for it though is a little
tricky. In doing the math we loose 1 LSB, so it must be replaced when converting back.

Original 00011001

Compliment 11100111

As seen in the example above the compliment to 00011001 (Hex 19) is 11100111 (Hex
E7). But if we negate 11100111 we get 00011000 (Hex 18). But we know that we lost 1
LSB when the conversion was performed, so we just add it back. So 00011000 (Hex 18) +
1 gives us 00011001 (Hex19), the original number. (Believe it or not, this gives first year
Computer Science students NIGHTMARES!)

So with the above in mind, lets get to the code! In BASCOM-8051 syntax, you must
declare the Subroutines and the variables associated with them.

Declare Sub Readlm75(Lm75addr as Byte)


Dim Lm75read As Byte Read address base
Dim Lm75write As Byte Write address base
Dim Lm75addr As Byte Lm75 Address
Dim Lm75high As Byte Lm75 High Byte
Dim Lm75low As Byte Lm75 Low Byte
Dim Lm75sign As Bit Lm75 Sign Bit

Now setup the Read and write addresses.

Lm75read = &B10010001
Lm75write = &B10010000

And now the subroutine!

Sub Readlm75(Lm75Addr)
Call Setaddr Lm75addr, 0
I2cstart Start the I2C process.
I2cwbyte Lm75read, 8 Send the LM75 address and read Info.
I2crbyte Lm75high , 8 Get 8 bits and get ACK from LM75
I2crbyte Lm75low , 9 Get 8 bits and send NACK to LM75
I2Cstop Stop the I2C system
If Lm75high > 127 Then
Lm75high = Not Lm75high Flip the bits Bob!
Incr Lm75high Add 1 to the value
Lm75sign = 1 Yup, we be negative!
End If
Lm75low = Lm75low And &B10000000 Mask out the lower 7 bits.
If Lm75Low = &B10000000 Then
Lm75low = 5
End If
Lm75read = &B10010001 Reset Lm75read
End Sub

This leaves the variables Lm75high with the whole temperature value, Lm75low with the
fractional temperature value, and the Lm75sign bit denoting the polarity of the temperature
value.


3RLQWHU

P7 P6 P5 P4 P3 P2 P1 P0
0 0 0 0 0 0 Register
Select

As seen above the Pointer register is 8 bits in length. The Pointer register is used to Point
to the register that you would like to read from or write to. The only bits that we need to
concern ourselves with are P0 and P1. Bits P2 to P7 are for test purposes only, and a
write operation into these registers could damage or destroy the Lm75. So, leave them
alone.

The breakdown of the Pointer register is as follows:


P0 P1 Register Pointed To
0 0 Temperature (Read only)(Power-up default)
0 1 Configuration (Read/Write)
1 0 THYST (Read/Write)
1 1 TOS (Read/Write)

As it is unnecessary to specifically set the pointer before performing a Read/Write


operation on a different register as a separate process, I will not create a subroutine to
access this register.

&RQILJXUDWLRQ

D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 Fault O.S. Cmp/Int Shutdown
Queue Polarity

The Configuration register controls the O.S polarity, whether or not the output is in
Comparator or Interrupt mode, fault queue (for noisy environments), and a way to put the
device to sleep.

6KXWGRZQ0RGH

To put the device in shutdown mode D0 is set. The device goes into a quiescent but
nominally active state and will draw around 1 A. The I C bus remains active and you can
2

still Read/Write the Configuration, THYST, and TOS registers. Resetting theis bit will bring the
device back up to full operation.

&RPSDUDWRU,QWHUUXSW0RGH

With D1 = 0 the device is in comparator mode. When the temperature goes above the
TOS value, the O.S. will go low. When the temperature falls below the THYST value then the
O.S. goes high. This assumes that the Polarity bit is low. With D1=1, the device is in
Interrupt mode. When the temperature goes above the TOS value, the O.S. will start


pulsing low. To reset the Interrupt the temperature must be below TOS and any device read
function will then reset the Interrupt.

263RODULW\

With D2=0 (default) the O.S. output is Active Low, when D2=1 then O.S. output is Active
High.

)DXOW4XHXH

D4 D3 Number of Faults
0 0 1 (default)
0 1 2
1 0 4
1 1 6

As the temperature nears the TOS level, any noise will cause the device to false trigger.
The Fault Queue allows you to determine how many times a false trigger happens before
the device triggers for real.

Now for the code!

Sub Getconfig(lm75addr)
Call Setaddr Lm75addr , 2
I2cstart
I2cwbyte Lm75write Send write address
I2cwbyte &B00000001 , 8 Set Pointer to point to Configuration register
I2cstart Restart I2C
I2cwbyte Lm75read Send read address
I2crbyte Lm75config , 9 Read the config register
I2cstop
Resetpointer Reset the pointer to 00
End Sub

Sub Setconfig(lm75addr)
Call Setaddr Lm75addr , 1
I2cstart Start I2C
I2cwbyte Lm75write Send write address
I2cwbyte &B00000001 , 8 Set Pointer to point to Configuration register
I2cwbyte Lm75config Send the Lm75config byte to write
I2cstop
Resetpointer Reset the pointer to 00
End Sub


726DQG7+<67

D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0

SGN MSB 0 0 0 0 0 0 LSB X X X X X X X

MSB LSB MSB LSB

High Byte Low Byte

TOS Register

D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0

SGN MSB 0 0 0 0 0 0 LSB X X X X X X X

MSB LSB MSB LSB

High Byte Low Byte

THYST Register

The TOS and THYST registers are exactly like the Temperature register except that you can
write to them. Everything that pertains to the temperature register pertains to the TOS and
THYST registers.

On power-up the TOS register contains &B0101000000000000 (Hex 5000) or 80C. And
the THYST register contains &B0100101100000000 (Hex 4800) or 75C. The following
four subroutines will show how to set and get data on these registers.

Sub Gettos(lm75addr)
Call Setaddr Lm75addr , 2
I2cstart
I2cwbyte Lm75write Send write address
I2cwbyte &B00000011 , 8 Set Pointer to Tos
I2cstart
I2cwbyte Lm75read Send read address
I2crbyte Lm75toshi , 8 Read Tos high byte
I2crbyte Lm75toslo , 9 Read Tos low byte
I2cstop
Resetpointer Reset the pointer to 00
End Sub

Sub Settos(lm75addr)
Call Setaddr Lm75addr , 1
I2cstart
I2cwbyte Lm75write Send write address
I2cwbyte &B00000011 Set Pointer to Tos
I2cwbyte Lm75toshi Send Tos high byte
I2cwbyte Lm75toslo Send Tos low byte
I2cstop


Resetpointer Reset the pointer to 00
End Sub

Sub Getthyst(lm75addr)
Call Setaddr Lm75addr , 2
I2cstart
I2cwbyte Lm75write Send write address
I2cwbyte &B00000010 , 8 Set pointer to Thyst
I2cstart
I2cwbyte Lm75read Send read address
I2crbyte Lm75thysthi , 8 Read Thyst high byte
I2crbyte Lm75thystlo , 9 Read Thyst low byte
I2cstop
Resetpointer Reset the pointer to 00
End Sub

Sub Setthyst(lm75addr)
Call Setaddr Lm75addr , 1
I2cstart
I2cwbyte Lm75write Send write address
I2cwbyte &B00000010 Set pointer to Thyst
I2cwbyte Lm75thysthi Send Thyst high byte
I2cwbyte Lm75thystlo Send Thyst low byte
I2cstop
Resetpointer Reset the pointer to 00
End Sub

&RQFOXVLRQ

2
Well, thats it! Not as hard as you were thinking was it. Using the I C interface code in
BASCOM-8051 makes accessing and controlling the LM75 a snap.

Appendix A contains the full core code file, along with a schematic of a circuit that will work
with the code. All you need to do now is complete the program to read and write to the
LM75.


$
Appendix

/0&RUH&RGH
------------------------------------------------------------------------------
Program Name : Lm75Full.bas
Program Date : October 15,1999
Program Written By : M. Akers Enterprises
Michael W. Akers
3800 Vineyard Ave. #E
Pleasanton, California 94566
Voice: +1 925 484 4750
Email: mwakers@home.com
Program Purpose : This program will demonstrate how to interface to,
and communicate With The National Semiconductor LM75
Digital Temperature Sensor.
Target Processor : Atmel 89C52
------------------------------------------------------------------------------
Programmer Date Comments
------------------- ---------- --------------------------------------------
Michael Akers 10/15/99 Initial creation of program.
-----------------------------------------------------------------------------
Define the processor (the regfile goes here!)
$regfile = "8052.DAT"
Define all meta-commands that must beinserted before all other commands.
Define all subroutines
Declare Sub Readlm75(lm75addr As Byte)
Declare Sub Getconfig(lm75addr As Byte)
Declare Sub Setconfig(lm75addr As Byte)
Declare Sub Gettos(lm75addr As Byte)
Declare Sub Settos(lm75addr As Byte)
Declare Sub Gethyst(lm75addr As Byte)
Declare Sub Sethyst(lm75addr As Byte)
Declare Sub Setaddr(lm75addr As Byte , Flagrw As Byte)
Declare Sub Resetpointer()
Declare Sub Val2temp(lm75tmphi As Byte , Lm75tmplo As Byte , Lm75tmpsign As Bit)
Define all variables and constants
Dim Lm75read As Byte Read address base
Dim Lm75write As Byte Write address base
Dim Lm75addr As Byte Lm75 Address
Dim Lm75high As Byte Lm75 Temperature High Byte
Dim Lm75low As Byte Lm75 Temperature Low Byte
Dim Lm75sign As Bit Lm75 Temperature Sign Bit
Dim Lm75config As Byte Lm75 Configuration
Dim Lm75toshi As Byte Lm75 Tos high byte
Dim Lm75toslo As Byte Lm75 Tos low byte
Dim Lm75tossign As Bit Lm75 Tos sign bit
Dim Lm75thysthi As Byte Lm75 Thyst high byte
Dim Lm75thystlo As Byte Lm75 Thyst low byte
Dim Lm75thystsign As Bit Lm75 Thyst sign bit
Dim Flagrw As Byte Read/Write Flag
Dim Lm75tmphi As Byte Lm75 Temp hi byte
Dim Lm75tmplo As Byte Lm75 Temp lo byte
Dim Lm75tmpsign As Bit Lm75 Temp sign bit
Define all Configurations and Pin assignments
Config Sda = P1.0
Config Scl = P1.1
Config I2cdelay = 1
Config Lcd = 40 * 4
Config Lcdpin , Db4 = P1.4 , Db5 = P1.5 , Db6 = P1.6 , Db7 = P1.7 , E = P1.3 , Rs = P1.2
Initialize variables as needed.
Lm75read = &B10010001
Lm75write = &B10010000
Program start.
Start:

Goto Start
Program end.
Begin subroutine section.
Sub Readlm75(lm75addr)
Call Setaddr Lm75addr , 0
I2cstart Start the I2C process.
I2cwbyte Lm75read Send the LM75 address and read Info.
I2crbyte Lm75high , 8 Get 8 bits and get ACK from LM75
I2crbyte Lm75low , 9 Get 8 bits and send NACK to LM75
I2cstop Stop the I2C system
Call Val2temp Lm75high , Lm75low , Lm75sign Convert the value (if needed)
Lm75high = Lm75tmphi
Lm75low = Lm75tmplo
Lm75sign = Lm75tmpsign
Lm75read = &B10010001 Reset Lm75read
End Sub
Sub Getconfig(lm75addr)
Call Setaddr Lm75addr , 2
I2cstart
I2cwbyte Lm75write Send write address
I2cwbyte &B00000001 , 8 Set pointer register to point
at the configuration register.
I2cstart Restart I2C
I2cwbyte Lm75read Send read address
I2crbyte Lm75config , 9 Read the config register
I2cstop
Resetpointer Reset the pointer to 00
End Sub
Sub Setconfig(lm75addr)
Call Setaddr Lm75addr , 1
I2cstart Start I2C
I2cwbyte Lm75write Send write address
I2cwbyte &B00000001 , 8 Set Pointer to point to Config register
I2cwbyte Lm75config Send the Lm75config byte to write
I2cstop


Resetpointer Reset the pointer to 00
End Sub
Sub Gettos(lm75addr)
Call Setaddr Lm75addr , 2
I2cstart
I2cwbyte Lm75write Send write address
I2cwbyte &B00000011 , 8 Set Pointer to Tos
I2cstart
I2cwbyte Lm75read Send read address
I2crbyte Lm75toshi , 8 Read Tos high byte
I2crbyte Lm75toslo , 9 Read Tos low byte
I2cstop
Resetpointer Reset the pointer to 00
End Sub
Sub Settos(lm75addr)
Call Setaddr Lm75addr , 1
I2cstart
I2cwbyte Lm75write Send write address
I2cwbyte &B00000011 Set Pointer to Tos
I2cwbyte Lm75toshi Send Tos high byte
I2cwbyte Lm75toslo Send Tos low byte
I2cstop
Resetpointer Reset the pointer to 00
End Sub
Sub Getthyst(lm75addr)
Call Setaddr Lm75addr , 2
I2cstart
I2cwbyte Lm75write Send write address
I2cwbyte &B00000010 , 8 Set pointer to Thyst
I2cstart
I2cwbyte Lm75read Send read address
I2crbyte Lm75thysthi , 8 Read Thyst high byte
I2crbyte Lm75thystlo , 9 Read Thyst low byte
I2cstop
Resetpointer Reset the pointer to 00
End Sub
Sub Setthyst(lm75addr)
Call Setaddr Lm75addr , 1
I2cstart
I2cwbyte Lm75write Send write address
I2cwbyte &B00000010 Set pointer to Thyst
I2cwbyte Lm75thysthi Send Thyst high byte
I2cwbyte Lm75thystlo Send Thyst low byte
I2cstop
Resetpointer Reset the pointer to 00
End Sub
Sub Setaddr(lm75addr , Flagrw)
If Lm75addr <> 0 Then
Lm75addr = Lm75addr * 2 Shift the address 1 bit left
Select Case Flagrw
Case 0 : Lm75read = Lm75read + Lm75addr Add the offset to the read address
Case 1 : Lm75write = Lm75write + Lm75addr Add the offset to the write address
Case 2 :


Lm75read = Lm75read + Lm75addr Add the offset to read and write address
Lm75write = Lm75write + Lm75addr
Case Else
End Select
End If
End Sub
Sub Resetpointer()
Only call this routine from within a subroutine that has called Setaddr()!
I2cstart
I2cwbyte Lm75write Send write address
I2cwbyte &B00000000 , 9 Set pointer to 00
I2cstop
Lm75read = &B10010001
Lm75write = &B10010000
End Sub
Sub Val2temp(lm75tmphi , Lm75tmplo , Lm75tmpsign)
This routine will convert the hi and lo bytes into a temperature value
If Lm75tmphi > 127 Then
Lm75tmphi = Not Lm75tmphi
Incr Lm75tmphi
Lm75tmpsign = 1
End If
Lm75tmplo = Lm75tmplo And &B10000000
If Lm75tmplo = &B10000000 Then
Lm75tmplo = 5
End If
End Sub
Sub Temp2val(lm75tmphi , Lm75tmplo , Lm75tmpsign)
This routine will convert a temperature value into the prober hi and lo byte values.
If Lm75tmpsign = 1 Then
Lm75tmphi = Not Lm75tmphi
Incr Lm75tmphi
End If
If Lm75tmplo <> 0 Then
Lm75tmplo = &B10000000
End If
End Sub
Insert include files here.
End of subroutines and actual end of program.


+5
U1
31 39
EA/VP P0.0 38
P0.1

14
19 37
OSC1 X1 P0.2 36
P0.3 35
Vcc 18 P0.4 34
R1 X2 P0.5 33
1 8 10K P0.6 32
N/C OUT +5 9 P0.7
24 MHz Os cil lato r RESET 21
Gnd

P2.0 22
C1 12 P2.1 23
CO100- 24 0.1uf 13 INT0 P2.2 24
14 INT1 P2.3 25
7

R2 R3 R4 15 T0 P2.4 26
5K 5K 330 R5 T1 P2.5 27
330 1 P2.6 28
2 P1.0 P2.7
RS 3 P1.1 17
EN 4 P1.2 RD 16
DB 4 5 P1.3 WR 29
LCD Module DB 5 6 P1.4
P1.5
PSEN
ALE/P
30
DB 6 7 11
DB 7 8 P1.6 TXD 10
P1.7 RXD
AT89C52

+5

U2 U3 U4 U5
8

8
7 7 7 7
+VS

+VS

+VS

+VS
6 A0 1 6 A0 1 6 A0 1 6 A0 1
5 A1 SDA 3 5 A1 SDA 3 5 A1 SDA 3 5 A1 SDA 3
A2 O.S. A2 O.S. A2 O.S. A2 O.S.
GND

GND

GND

GND
2 2 2 2
SCL SCL SCL SCL
LM75_S LM75_S LM75_S LM75_S
4

4
U6 U7 U8 U9
8

8
7 7 7 7
+VS

+VS

+VS

+VS
6 A0 1 6 A0 1 6 A0 1 6 A0 1
5 A1 SDA 3 5 A1 SDA 3 5 A1 SDA 3 5 A1 SDA 3
A2 O.S. A2 O.S. A2 O.S. A2 O.S.
GND

GND

GND

GND
2 2 2 2
SCL SCL SCL SCL
LM75_S LM75_S LM75_S LM75_S
4

4
M. Akers Enterprises
Title
LM75 Demo (handles 8 LM75 devices)

Size Document Number Rev


A MAE-LM75DEMO-001 --

Date: Monday, October 18, 1999 Sheet 1 of 1


file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.gif

file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.gif [16-7-2000 19:48:49]


file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.txt

Serial to GPIB converter

This soft/hardware is made specific for my Tektronix 4662 flatbed plotter with
GPIB (IEE488) interface, and a strange GDU coordinate system..!
Now it communicate with a HPGL device-driver trough a normal RS 232 serialport.

Introduction:

Some years ago I got the idea of making PCB with a plotter and finally found a old
Tektronix A3 flatbed plotter from the early 80'.
But I newer really got it to work for that purpose I had in mind, mainly because of the
strange old GDU cordinate system used on Tektronix Plot10 and Plot50 graphic work
station from that periode.

Later on I got a newer Roland DXY990 plotter with Serial/Parallel interface and have
made many fine PCB since.
I plot direct on the copper foil with a permanent ink pen, and the quality is very good.
A quick, easy and clean way of doing some rapidly prototype boards.

Now I have gone a step further doing quick PCB's and for that I need a X-Y machine.
So the old Tektronix got a Atmel 90S2313 chip implemented, and voila...
So thanks to MCS electronic for there fantastic compiler. :o)

I now just need to finish the milling machine to replace the pen on the plotter, and
I'am ready to Countour Milling a board with the Eagle Layout-editor and CAM processor
I use. And for that purpose the Tektronix plotter is ideal with it's robust motor system
and very smoth microstep drive.

Software/Hardware:

I don't think this software is usable in this form for other than myself, but if you
can use fragments of it, maby the GPIB protocol procedure, you are welcome to do so.
In this case, I'll be glad when you post me a message.

I have included lots of comments in the source code, so there isn't mutch to say about
it, except for the size of the hex file generated.! 7EC (2028) is the actual
ROMIMAGE size, and It took me some time to get it fit in.
Lot of memory was used every time a string needed to be cleared... (Result="")
By collecting this in a single Sub routine instead, up to 300 byte was saved...!

Files Contents:
Serial2Gpib.ZIP ---Serial2Gpib.bas
---Serial2Gpib.gif
---Serial2Gpib.sch
---Serial2Gpib.txt

Posted at:
MCS electronic --- http://www.mcselec.com/applicat.htm
Bascom Users Software Pool --- http://www.qsl.net/dg5dbz/bascompool/

file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.txt (1 of 2) [16-7-2000 19:49:19]


file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.txt

Links:
MCS electronic --- http://www.mcselec.com/
Eagle Layout Editor --- http://www.cadsoft.de/
Jan Petersen --- http://home8.inet.tele.dk/jan_p

Author:
Jan Petersen
Orevej 6
DK 4760 Vordingborg
Denmark

EMail: jan_p@post8.tele.dk

Date: 24.02.2000

file:///F|/FrontPage Webs/Content/server/download/appnotes/serial2gpib.txt (2 of 2) [16-7-2000 19:49:19]


file:///F|/FrontPage Webs/Content/server/download/appnotes/bitbang1.bas

' Jim Gillespie


' Revised 12-2-99
' Bit twiddle outputs on 74HC595 daisy chained shift registers.
' Automatically determines shift register length.
' Uses 5 port B pins on an ATMEL 90S8515.
' Written to control a large number of relays.

' Command set:

' Snn Set and latch bit nn. Echos command.


' Cnn Clear and latch bit nn. Echos command.
' R Reset and latch all 0's. Echos command
' T Test shift registers and sets length in bits. Returns bit length
' Does not affect 595 outputs.
' V Version. Return a string giving software version.
' I Initialize. Starts program from scratch. echos command.

$baud = 9600 ' development board uses 4 MHZ XTAL


$crystal = 4000000
'$crystal = 7372800 ' use these 2 for production version
'$baud = 2400 ' uses a 7.3728 MHZ XTAL
Const Max_in_len = 3 ' define maximum input chars
Const Max_bytes = 10 ' define max shift reg bytes possible
Const Shift_delay = 50 ' shift delay in microseconds
Const Test_pattern = &HAA ' shift reg test pattern

Dim Bytes(max_bytes) As Byte ' byte shift reg output buffer


Dim String_input As String * Max_in_len ' dim to maximum input characters
Dim Raw_echo As String * Max_in_len
Dim Value As Byte ' becomes numeric value of command
Dim Opcode As String * 1 ' one character opcode goes here
Dim Temp As String * 2 ' temp string work variable
Dim Tempbyte1 As Byte ' more temp vars
Dim Tempbyte2 As Byte
Dim I As Byte
Dim J As Byte
Dim K As Byte
Dim Max_shift_len As Byte ' Test sets this to max bits found
Dim Arry_end As Byte ' Test sets this to last array element
Dim Set_clear_flag As Bit ' flag used to set or clear a bit

' readability definitions


Clock_out Alias Portb.0 ' 74hc595 shift reg signals
Data_out Alias Portb.1 ' port assignments
Data_in Alias Portb.2
Data_in_read Alias Pinb.2 ' NOTE AVR port reads need PIN to get real data
Latch_out Alias Portb.3
Clear_out Alias Portb.4

Clock_out_dir Alias Ddrb.0


Data_out_dir Alias Ddrb.1
Data_in_dir Alias Ddrb.2
Latch_out_dir Alias Ddrb.3
Clear_out_dir Alias Ddrb.4

' sub definitions


Declare Sub Clearbytes(byval Bytecnt As Byte) ' clear byte array
Declare Sub Latchbytes() ' xfer shift reg to latch outputs
Declare Sub Clearshift() ' clear shift reg
Declare Sub Test_shift_reg() ' test and determine shift reg length

file:///F|/FrontPage Webs/Content/server/download/appnotes/bitbang1.bas (1 of 4) [16-7-2000 19:49:47]


file:///F|/FrontPage Webs/Content/server/download/appnotes/bitbang1.bas

Declare Sub Set_clear_bit() ' set or clear bit based on flag


Declare Sub Send_bytes() ' send byte array to shift registers

Init: ' set initial conditions for I/O


' MAIN starts here
Set Clock_out
Reset Data_out
Reset Latch_out
Set Clear_out
' set the data direction for I/O
Set Clock_out_dir
Set Data_out_dir
Reset Data_in_dir
Set Latch_out_dir
Set Clear_out_dir

Call Clearshift() ' clear shift reg


Call Latchbytes() ' xfer zeros to outputs

Tempbyte1 = Max_bytes
Call Clearbytes(tempbyte1) ' clear output byte array

Call Test_shift_reg() ' test and set shift reg length


If Max_shift_len = 0 Then
Print "Control Board Failure !!"
Else
Print "Control Board OK !!"
End If

Do ' main loop

String_input = Space(max_in_len) ' clear input string to spaces


Input String_input ' read input string
Raw_echo = String_input ' form echo string
String_input = Trim(string_input) ' trim lead and trail spaces
Opcode = Left(string_input , 1) ' extract opcode
Opcode = Ucase(opcode) ' convert to upper case
Temp = Mid(string_input , 2 , Max_in_len) ' get numeric string
Temp = Trim(temp)
Value = Val(temp) ' convert string to numeric
If Value > Max_shift_len Then ' setting or clearing beyond bit range?
Opcode = " " ' yes. set a bogus command code
End If

Print

Select Case Opcode

Case "S" ' Set a bit


If Value = 0 Then ' improper bit value or format
Print "ERR 7"
Else
Set Set_clear_flag ' flag to set a bit
Call Set_clear_bit() ' go set the bit in array
Call Send_bytes() ' send to shift regs
Call Latchbytes() ' latch the bit pattern to outputs
Print Raw_echo ' echo command
End If

Case "C" ' Clear a bit

file:///F|/FrontPage Webs/Content/server/download/appnotes/bitbang1.bas (2 of 4) [16-7-2000 19:49:47]


file:///F|/FrontPage Webs/Content/server/download/appnotes/bitbang1.bas

If Value = 0 Then ' improper bit value or format


Print "ERR 8"
Else
Reset Set_clear_flag ' flag to clear a bit
Call Set_clear_bit() ' clear the bit in the array
Call Send_bytes() ' send to shift regs
Call Latchbytes() ' latch the bit pattern to outputs
Print Raw_echo ' echo command
End If

Case "V" ' print Version etc.


Print "version 1.0.3 11-29-99 Jim Gillespie"

Case "T" ' Test interface


Call Clearshift() ' set shift reg to all zeros
Call Test_shift_reg()
Call Clearshift() ' clear shift reg again
If Max_shift_len = 0 Then ' if failure, give error message
Print "ERR 1"
Else
Print Max_shift_len ' otherwise, echo shift reg length found
End If

Case "R" ' Reset all outputs low


Call Clearshift() ' clear shift reg
Call Latchbytes() ' latch shift reg
Tempbyte2 = Max_bytes
Call Clearbytes(tempbyte2) ' clear byte array
Print Raw_echo ' echo command input

Case "I" ' Initialize


Print Raw_echo ' echo command input
Exit Do ' re-start this program

Case Else ' unknown or improper command format


Print "ERR 4"

End Select

Loop

Print "Control Board Reset and Initialized"


Goto Init ' I command. restart program

Sub clearbytes(byval bytecnt as byte) ' clear output byte array


For I = Bytecnt Downto 0 ' NOTE: for AVR compiler we had to use zero
Bytes(i) = 0 ' to make FOR loop terminate at 1
Next I
End Sub

Sub latchbytes()
Set Latch_out ' latch the shift reg to outputs
Waitms 1
Reset Latch_out
End Sub

Sub clearshift() ' clear shift reg to all 0's


Reset Clear_out
Waitms 1
Set Clear_out
End Sub

file:///F|/FrontPage Webs/Content/server/download/appnotes/bitbang1.bas (3 of 4) [16-7-2000 19:49:47]


file:///F|/FrontPage Webs/Content/server/download/appnotes/bitbang1.bas

Sub Test_shift_reg() ' send byte pattern &hAA to


Tempbyte1 = Test_pattern ' shift reg and count how many 8 bit shifts til
' the pattern appears in cpu input shift reg
Shiftout Data_out , Clock_out , Tempbyte1 , 0 , 8 , Shift_delay
For I = 1 To Max_bytes + 1
Shiftin Data_in_read , Clock_out , Tempbyte2 , 0 , 8 , Shift_delay
If Tempbyte2 = Test_pattern Then
Exit For ' we got a match to pattern
End If
Next I
If Tempbyte2 <> Test_pattern Then
Max_shift_len = 0 ' no match. hardware problem
Arry_end = 0
Else
Max_shift_len = I * 8 ' match! calc. and save number of bits found
Arry_end = I ' last array element
End If
End Sub

Sub Set_clear_bit() ' set or clear a bit in byte array


K = 1
I = Value - 1 : I = I \ 8 : I = I + 1 ' calc array index
J = Value - 1 : J = J Mod 8 ' calc bit position
Tempbyte1 = Bytes(i)
Rotate K , Left , J ' put a 1 in proper bit position
If Set_clear_flag = 1 Then
Tempbyte1 = Tempbyte1 Or K ' sets the bit position
Else
K = Not K
Tempbyte1 = Tempbyte1 And K ' clear bit position
End If
Bytes(i) = Tempbyte1 ' update array byte
'Print Hex(tempbyte1) ' ********* debug ***********
End Sub

Sub Send_bytes()
For I = Arry_end Downto 0 ' send byte array to shift regs
Tempbyte1 = Bytes(i)
Shiftout Data_out , Clock_out , Tempbyte1 , 0 , 8 , Shift_delay
Next I
End Sub

End

file:///F|/FrontPage Webs/Content/server/download/appnotes/bitbang1.bas (4 of 4) [16-7-2000 19:49:47]


file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas

'DEMO PROGRAM T6963 BASED GRAPHIC DISPLAYS USING BASCOM-8051

'Author : P. Huijssen
' The Netherlands

'This program shows a bitmap and some text on a graphic display type : TLX1741-C3M
'which uses the T6963 controller.
'The display has a screenresolution of 240x128 pixels

'The display uses a data/command line to determine of a databyte or command byte is sent.
'In this application it's connected to A14 which makes it easy te sent data or a command.
'Data is sent to &H8000 (C/D line low)
'Commands/statuscheck written/read at &HC000 (C/D line high)

'The software is really an experiment and may not match the 'rules' of proper programming

'All of the used settings regarding the display are very well described in the datasheet

'The displayscreen should show 'TOSHIBA' in large characters (bitmap) and two lines of
text

'******************************************************************
'INIT
'******************************************************************

$regfile = "REG51.DAT" 'your uC


$crystal = 11059200 'your crystal. Not
important to control the display
'as long if you don't
exceed an instruction time of 200ns

'VARIABELS DISPLAY AND TO SHOW GRAPHICS


Dim Data_display As Byte
Dim Status As Byte
Dim Mask_status As Byte

Dim Dta_1 As Byte


Dim Dta_2 As Byte
Dim Cmdo_1 As Byte
Dim Adres_pointer As Integer
Dim Dummy_adres_pointer As Integer

Dim Dummy As Integer

'VARIABELS USED TO SHOW TEXT


Dim Text As String * 21
Dim String_length As Byte
Dim String_scanner As Byte
Dim Temp_string As String * 2

'*****************************************************************
'*****************************************************************
'START PROGRAMME
'*****************************************************************
'*****************************************************************

file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas (1 of 13) [16-7-2000 19:50:50]


file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas

Gosub Set_display 'init display

Gosub Display_blank 'clear screen


Gosub Show_bitmap 'place bitmap

Text = "T6963 DEMO SOFTWARE"


Adres_pointer = &H1831 'set adres_pointer in text
ram
Gosub Show_text 'calculate display data

Text = "PH 2000"


Adres_pointer = &H1891
Gosub Show_text

End

'**************************
'DISPLAY SETUP
'************************
Set_display:

P1.0 = 1 'Reset display. Active low


Nop : Nop 'I thought I might need it
during
P1.0 = 0 'the execution of the code
so I didn't
Nop : Nop 'use a hardware reset from
a watchdog for
P1.0 = 1 'instance.

Restore Dta_init 'init display. see also


datasheet

For dummy = 1 To 7

Read Dta_1
Data_display = Dta_1
Gosub Writed
Read Dta_2
Data_display = Dta_2
Gosub Writed
Read Cmdo_1
Data_display = Cmdo_1
Gosub Writec

Next Dummy

Return

Dta_init:

Data &H00 , &H00 , &H42 'home adress graphical


ram.upperleft corner
Data &H1E , &H00 , &H43 'linewidth graphics (bytes
per line)
Data &H00 , &H17 , &H40 'home adres text
ram.upperleft corner
Data &H1E , &H00 , &H41 'lijnbreedte grafisch
(characters per line)
Data &H00 , &H00 , &H81 'modeset intern CharRom,XOR
mode

file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas (2 of 13) [16-7-2000 19:50:50]


file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas

Data &H00 , &H00 , &H9E 'displaymode mixed text and


graphics
Data &H00 , &H00 , &H24

'**********************************************************
'CLEAR SCREEN (ERASE GRAPHIC+TEXT RAM)
'**********************************************************
Display_blank:

Adres_pointer = &H00 'upperleft corner graphic


ram
Gosub Set_adres

For dummy = 1 To 3840 'clear graphic ram


'by writing '0'
Data_display = &H00
Gosub Writed
Data_display = &H00
Gosub Writed
Data_display = &HC0 'auto increment
adres_pointer by 1
Gosub Writec

Next Dummy

Adres_pointer = &H1700 'upperleft corner text ram


Gosub Set_adres

For dummy = 1 To 480 'clear text ram


'by writing '0'
Data_display = &H00
Gosub Writed
Data_display = &H00
Gosub Writed
Data_display = &HC0 'auto increment
adres_pointer by 1
Gosub Writec

Next Dummy

Return

'*********************************************************
' PLACE ADRES POINTER DISPLAY
'*********************************************************
Set_adres: 'set adres display

Dta_1 = Adres_pointer And &H00FF 'calculate msb/lsb


Dummy_adres_pointer = Adres_pointer And &HFF00
Dummy_adres_pointer = Dummy_adres_pointer / &HFF
Dta_2 = Dummy_adres_pointer

Data_display = Dta_1 'send adres to display


Gosub Writed
Data_display = Dta_2
Gosub Writed
Data_display = &H24 'data sent is adres data
Gosub Writec

Return

file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas (3 of 13) [16-7-2000 19:50:50]


file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas

'*********************************************************
'PLACE TEXT.
'*********************************************************
Show_text:

Gosub Set_adres 'set adres pointer

String_length = Len(text) 'calculate string length

For String_scanner = 1 To String_length 'send string to display one


'character at the time
Temp_string = Mid(text , String_scanner , 1)
Dta_2 = Asc(temp_string)
Dta_2 = Dta_2 - &H20 'ascii codes in the char
rom
'have an offset of - &H20.
see datasheet
Data_display = &H00
Gosub Writed
Data_display = Dta_2
Gosub Writed
Data_display = &HC0 'auto increment
adres_pointer by 1
Gosub Writec

Next String_scanner 'loop until whole string is


sent

Return

'*****************************************************
'WRITE COMMAND AND DATA NAAR DISPLAY + STATUSCHECK
'*****************************************************
Writec: 'write display command

Gosub Status_check
Out &H3800 , Data_display
Return

'***********
Writed: 'write display data

Gosub Status_check
Out &H3000 , Data_display
Return

'***********
Status_check: 'check status controller

Status_1:

Status = Inp(&H3800)
Mask_status = Status And 3
If Mask_status = 3 Then : Return
End If
Goto Status_1

'*****************************************************************
'SHOW BITMAP
'*****************************************************************
Show_bitmap:

file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas (4 of 13) [16-7-2000 19:50:50]


file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas

Gosub Display_blank

Adres_pointer = 0
Gosub Set_adres

Restore Bitmap_data

For dummy = 1 To 3840

Read Dta_2 'read bitmap data and send


to display
Data_display = 0
Gosub Writed
Data_display = Dta_2
Gosub Writed
Data_display = &HC0
Gosub Writec

Next Dummy

Return

Bitmap_data: 'TOSHIBA in large


characters

Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00


Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H01 , &HFF , &HFF , &HFF
Data &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF ,
&HFF , &HFF , &HFF , &HFF
Data &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFC , &H00 , &H01 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H04 , &H00 , &H01 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00

file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas (5 of 13) [16-7-2000 19:50:50]


file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas

Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H04 , &H00 , &H01 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H04 , &H00 , &H01 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H04 , &H00 , &H01 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H04 , &H00
Data &H01 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H04 , &H00 , &H01 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &HFE , &H00 , &H00 , &H00 , &H7F , &HC0 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H04 , &H00 ,
&H01 , &H03 , &HFF , &HFF
Data &HFF , &HC0 , &H07 , &HFF , &HC0 , &H00 , &H01 , &HFF , &HF0 , &H00 , &H7C , &H00 ,
&H00 , &HF8 , &H0F , &H00
Data &H7F , &HFF , &HE0 , &H00 , &H00 , &H3F , &H00 , &H00 , &H04 , &H00 , &H01 , &H03 ,
&HFF , &HFF , &HFF , &HC0
Data &H1F , &HFF , &HF0 , &H00 , &H03 , &HFF , &HFC , &H00 , &H7C , &H00 , &H00 , &HF8 ,
&H0F , &H00 , &H7F , &HFF
Data &HF8 , &H00 , &H00 , &H3F , &H00 , &H00 , &H04 , &H00 , &H01 , &H03 , &HFF , &HFF ,
&HFF , &HC0 , &H7F , &HFF
Data &HFC , &H00 , &H1F , &HFF , &HFF , &H00 , &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 ,
&H7F , &HFF , &HFE , &H00
Data &H00 , &H3F , &H80 , &H00 , &H04 , &H00 , &H01 , &H03 , &HFF , &HFF , &HFF , &HC0 ,
&HFF , &H03 , &HFE , &H00
Data &H1F , &HC0 , &H7F , &H80 , &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 , &H7F , &HFF ,
&HFF , &H00 , &H00 , &H7F
Data &H80 , &H00 , &H04 , &H00 , &H01 , &H00 , &H00 , &H3C , &H00 , &H01 , &HFC , &H00 ,
&H7F , &H00 , &H3F , &H00
Data &H1F , &HC0 , &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 , &H7C , &H00 , &H3F , &H80 ,
&H00 , &H7B , &H80 , &H00
Data &H04 , &H00 , &H01 , &H00 , &H00 , &H3C , &H00 , &H03 , &HF0 , &H00 , &H1F , &H00 ,
&H3C , &H00 , &H07 , &HC0
Data &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 , &H7C , &H00 , &H0F , &HC0 , &H00 , &HFB ,
&HC0 , &H00 , &H04 , &H00
Data &H01 , &H00 , &H00 , &H3C , &H00 , &H03 , &HE0 , &H00 , &H0F , &H80 , &H7C , &H00 ,
&H03 , &HC0 , &H7C , &H00
Data &H00 , &HF8 , &H0F , &H00 , &H7C , &H00 , &H07 , &HC0 , &H00 , &HF3 , &HC0 , &H00 ,
&H04 , &H00 , &H01 , &H00
Data &H00 , &H3C , &H00 , &H07 , &HC0 , &H00 , &H07 , &HC0 , &H7C , &H00 , &H03 , &HC0 ,
&H7C , &H00 , &H00 , &HF8
Data &H0F , &H00 , &H7C , &H00 , &H07 , &HC0 , &H01 , &HF3 , &HE0 , &H00 , &H04 , &H00 ,
&H01 , &H00 , &H00 , &H3C
Data &H00 , &H07 , &H80 , &H00 , &H07 , &HC0 , &H7C , &H00 , &H03 , &HE0 , &H7C , &H00 ,
&H00 , &HF8 , &H0F , &H00
Data &H7C , &H00 , &H03 , &HC0 , &H01 , &HE1 , &HE0 , &H00 , &H04 , &H00 , &H01 , &H00 ,
&H00 , &H3C , &H00 , &H0F
Data &H80 , &H00 , &H03 , &HE0 , &H7C , &H00 , &H03 , &HE0 , &H7C , &H00 , &H00 , &HF8 ,
&H0F , &H00 , &H7C , &H00
Data &H03 , &HC0 , &H01 , &HE1 , &HF0 , &H00 , &H04 , &H00 , &H01 , &H00 , &H00 , &H3C ,
&H00 , &H1F , &H80 , &H00
Data &H03 , &HF0 , &H7C , &H00 , &H00 , &H00 , &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 ,

file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas (6 of 13) [16-7-2000 19:50:50]


file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas

&H7C , &H00 , &H03 , &HC0


Data &H01 , &HC0 , &HF0 , &H00 , &H04 , &H00 , &H01 , &H00 , &H00 , &H3C , &H00 , &H1F ,
&H00 , &H00 , &H01 , &HF0
Data &H7C , &H00 , &H00 , &H00 , &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 , &H7C , &H00 ,
&H03 , &HC0 , &H03 , &HC0
Data &HF0 , &H00 , &H04 , &H00 , &H01 , &H00 , &H00 , &H3C , &H00 , &H1F , &H00 , &H00 ,
&H01 , &HF0 , &H3F , &H80
Data &H00 , &H00 , &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 , &H7C , &H00 , &H07 , &HC0 ,
&H03 , &HC0 , &H70 , &H00
Data &H04 , &H00 , &H01 , &H00 , &H00 , &H3C , &H00 , &H3E , &H00 , &H00 , &H01 , &HF0 ,
&H3F , &HC0 , &H00 , &H00
Data &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 , &H7C , &H00 , &H0F , &HC0 , &H07 , &HC0 ,
&H78 , &H00 , &H04 , &H00
Data &H01 , &H00 , &H00 , &H3C , &H00 , &H3E , &H00 , &H00 , &H00 , &HF0 , &H3F , &HF8 ,
&H00 , &H00 , &H7C , &H00
Data &H00 , &HF8 , &H0F , &H00 , &H7C , &H00 , &H1F , &H80 , &H07 , &H80 , &H78 , &H00 ,
&H04 , &H00 , &H01 , &H00
Data &H00 , &H3C , &H00 , &H3E , &H00 , &H00 , &H00 , &HF0 , &H0F , &HFF , &HE0 , &H00 ,
&H7F , &HFF , &HFF , &HF8
Data &H0F , &H00 , &H7F , &HFF , &HFE , &H00 , &H0F , &H80 , &H7C , &H00 , &H04 , &H00 ,
&H01 , &H00 , &H00 , &H3C
Data &H00 , &H3E , &H00 , &H00 , &H00 , &HF0 , &H03 , &HFF , &HFC , &H00 , &H7F , &HFF ,
&HFF , &HF8 , &H0F , &H00
Data &H7F , &HFF , &HFC , &H00 , &H0F , &H00 , &H3C , &H00 , &H04 , &H00 , &H01 , &H00 ,
&H00 , &H3C , &H00 , &H3E
Data &H00 , &H00 , &H00 , &HF0 , &H01 , &HFF , &HFE , &H00 , &H7F , &HFF , &HFF , &HF8 ,
&H0F , &H00 , &H7F , &HFF
Data &HFC , &H00 , &H0F , &H00 , &H3E , &H00 , &H04 , &H00 , &H01 , &H00 , &H00 , &H3C ,
&H00 , &H3E , &H00 , &H00
Data &H00 , &HF0 , &H00 , &H0F , &HFF , &H80 , &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 ,
&H7F , &HFF , &HFF , &H80
Data &H1E , &H00 , &H1F , &H00 , &H04 , &H00 , &H01 , &H00 , &H00 , &H3C , &H00 , &H3E ,
&H00 , &H00 , &H00 , &HF0
Data &H00 , &H01 , &HFF , &HC0 , &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 , &H7C , &H00 ,
&H1F , &HC0 , &H1E , &H00
Data &H1F , &H00 , &H04 , &H00 , &H01 , &H00 , &H00 , &H3C , &H00 , &H3E , &H00 , &H00 ,
&H00 , &HF0 , &H00 , &H00
Data &H3F , &HC0 , &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 , &H7C , &H00 , &H0F , &HC0 ,
&H3E , &H00 , &H0F , &H00
Data &H04 , &H00 , &H01 , &H00 , &H00 , &H3C , &H00 , &H3E , &H00 , &H00 , &H00 , &HF0 ,
&H00 , &H00 , &H0F , &HE0
Data &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 , &H7C , &H00 , &H03 , &HE0 , &H3F , &HFF ,
&HFF , &H00 , &H04 , &H00
Data &H01 , &H00 , &H00 , &H3C , &H00 , &H1F , &H00 , &H00 , &H01 , &HF0 , &H00 , &H00 ,
&H03 , &HF0 , &H7C , &H00
Data &H00 , &HF8 , &H0F , &H00 , &H7C , &H00 , &H03 , &HF0 , &H7F , &HFF , &HFF , &H80 ,
&H04 , &H00 , &H01 , &H00
Data &H00 , &H3C , &H00 , &H1F , &H00 , &H00 , &H01 , &HF0 , &H00 , &H00 , &H03 , &HF0 ,
&H7C , &H00 , &H00 , &HF8
Data &H0F , &H00 , &H7C , &H00 , &H01 , &HF0 , &H7F , &HFF , &HFF , &H80 , &H04 , &H00 ,
&H01 , &H00 , &H00 , &H3C
Data &H00 , &H1F , &H00 , &H00 , &H01 , &HF1 , &HF0 , &H00 , &H01 , &HF0 , &H7C , &H00 ,
&H00 , &HF8 , &H0F , &H00
Data &H7C , &H00 , &H01 , &HF0 , &HFF , &HFF , &HFF , &HC0 , &H04 , &H00 , &H01 , &H00 ,
&H00 , &H3C , &H00 , &H0F
Data &H80 , &H00 , &H03 , &HE1 , &HF0 , &H00 , &H01 , &HF0 , &H7C , &H00 , &H00 , &HF8 ,
&H0F , &H00 , &H7C , &H00
Data &H01 , &HF0 , &HF8 , &H00 , &H07 , &HC0 , &H04 , &H00 , &H01 , &H00 , &H00 , &H3C ,
&H00 , &H0F , &H80 , &H00
Data &H07 , &HE1 , &HF8 , &H00 , &H01 , &HF0 , &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 ,
&H7C , &H00 , &H01 , &HF0

file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas (7 of 13) [16-7-2000 19:50:50]


file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas

Data &HF0 , &H00 , &H03 , &HE0 , &H04 , &H00 , &H01 , &H00 , &H00 , &H3C , &H00 , &H07 ,
&H80 , &H00 , &H07 , &HC0
Data &HF8 , &H00 , &H01 , &HF0 , &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 , &H7C , &H00 ,
&H01 , &HF0 , &HF0 , &H00
Data &H03 , &HE0 , &H04 , &H00 , &H01 , &H00 , &H00 , &H3C , &H00 , &H03 , &HE0 , &H00 ,
&H0F , &H80 , &HFC , &H00
Data &H03 , &HE0 , &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 , &H7C , &H00 , &H03 , &HE1 ,
&HF0 , &H00 , &H01 , &HE0
Data &H04 , &H00 , &H01 , &H00 , &H00 , &H3C , &H00 , &H03 , &HF0 , &H00 , &H1F , &H00 ,
&H7C , &H00 , &H03 , &HE0
Data &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 , &H7C , &H00 , &H03 , &HE1 , &HF0 , &H00 ,
&H01 , &HE0 , &H04 , &H00
Data &H01 , &H00 , &H00 , &H3C , &H00 , &H03 , &HF0 , &H00 , &H3F , &H00 , &H3F , &H00 ,
&H07 , &HC0 , &H7C , &H00
Data &H00 , &HF8 , &H0F , &H00 , &H7C , &H00 , &H07 , &HC3 , &HE0 , &H00 , &H00 , &HF0 ,
&H04 , &H00 , &H01 , &H00
Data &H00 , &H3C , &H00 , &H00 , &HFF , &H03 , &HFE , &H00 , &H3F , &HE0 , &H3F , &HC0 ,
&H7C , &H00 , &H00 , &HF8
Data &H0F , &H00 , &H7F , &HFF , &HFF , &HC7 , &HE0 , &H00 , &H00 , &HF8 , &H04 , &H00 ,
&H01 , &H00 , &H00 , &H3C
Data &H00 , &H00 , &H7F , &HFF , &HFC , &H00 , &H1F , &HFF , &HFF , &H80 , &H7C , &H00 ,
&H00 , &HF8 , &H0F , &H00
Data &H7F , &HFF , &HFF , &H87 , &HC0 , &H00 , &H00 , &HF8 , &H04 , &H00 , &H01 , &H00 ,
&H00 , &H3C , &H00 , &H00
Data &H3F , &HFF , &HF8 , &H00 , &H0F , &HFF , &HFF , &H00 , &H7C , &H00 , &H00 , &HF8 ,
&H0F , &H00 , &H7F , &HFF
Data &HFF , &H07 , &HC0 , &H00 , &H00 , &HF8 , &H04 , &H00 , &H01 , &H00 , &H00 , &H3C ,
&H00 , &H00 , &H0F , &HFF
Data &HE0 , &H00 , &H03 , &HFF , &HFC , &H00 , &H7C , &H00 , &H00 , &HF8 , &H0F , &H00 ,
&H7F , &HFF , &HFC , &H07
Data &HC0 , &H00 , &H00 , &HFC , &H04 , &H00 , &H01 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &HFE , &H00 , &H00
Data &H00 , &H3F , &HE0 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H04 , &H00 , &H01 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H04 , &H00 , &H01 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H04 , &H00
Data &H01 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H04 , &H00 , &H01 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H04 , &H00 ,
&H01 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H04 , &H00 , &H01 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H04 , &H00 , &H01 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H04 , &H00 , &H01 , &HFF , &HFF , &HFF , &HFF , &HFF ,

file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas (8 of 13) [16-7-2000 19:50:50]


file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas

&HFF , &HFF , &HFF , &HFF


Data &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF , &HFF ,
&HFF , &HFF , &HFF , &HFF
Data &HFF , &HFF , &HFC , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00

file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas (9 of 13) [16-7-2000 19:50:50]


file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas

Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,

file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas (10 of 13) [16-7-2000 19:50:50]


file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas

&H00 , &H00 , &H00 , &H00


Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00

file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas (11 of 13) [16-7-2000 19:50:50]


file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas

Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,

file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas (12 of 13) [16-7-2000 19:50:51]


file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas

&H00 , &H00 , &H00 , &H00


Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 ,
&H00 , &H00 , &H00 , &H00
Data &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00

file:///F|/FrontPage Webs/Content/server/download/appnotes/t6963.bas (13 of 13) [16-7-2000 19:50:51]


file:///F|/FrontPage Webs/Content/server/download/appnotes/ds1991.bas

'Demonstration of reading and writing the Dallas DS1991


'secure I-button. Using the 1-wire statements.
'--------------------------------------------------------------
'
' You must use Bascom-8051 1.09 or higher !!
'
'
' pull-up of 4K7 required to VCC from P3.2
' DS1991 serial button connected to P3.2
'--------------------------------------------------------------
' E.K.Dekker 1999 Lampje@Xs4all.nl
'--------------------------------------------------------------
Config 1wire = P3.2 'use this pin
Dim Ar(16) As Byte , I As Byte , Temp As Byte
Dim Text As String * 16 , Temp2 As String * 1

Main:
'Reading first the ROM-number
1wreset 'reset the device
1wwrite &H33 'read ROM command
Ar(1) = 1wread(8) 'read 8 bytes
Print "ROM number : ";
For I = 1 To 8
Printhex Ar(i); 'print ROM-number
Next
Wait 1 'wait a moment

'Writing scratchpad
'It is possible to write 64 bytes of data to the scratchpad. In this example
'i only used 16 bytes.You can write/read the other bytes if you change the
'array or start address.
Text = "Scratchpad data."
Ar(1) = &H96 'Write scratch command
Ar(2) = &HC0 'Start address + C0H
Ar(3) = &HFF - Ar(2) 'Complement of Ar(2)
1wreset 'reset the device
1wwrite &HCC 'Skip read ROM command
1wwrite Ar(1) , 3 'Write command to DS1991
Gosub Fill_write_array 'Fill array with "Text"
1wwrite Ar(1) , 16 'Write 16 bytes to DS1991
Wait 1 'wait a moment

'Reading scratchpad back


Ar(1) = &H69 'Read scratch command
Ar(2) = &HC0 'Start adress + COH
Ar(3) = &HFF - Ar(2) 'Complement of Ar(2)
1wreset 'reset the device
1wwrite &HCC 'Skip read ROM command
1wwrite Ar(1) , 3 'Write command to DS1991
Ar(1) = 1wread(16) 'Read 16 bytes from DS1991
Print "Scratch pad : "; '
For I = 1 To 16 'Prints the contents of the
Temp = Ar(i) ' scratchpad
Print Chr(temp); '
Next I '
Wait 1 'wait a moment

'Writing subkeyid and password


'Writing new subkeyid and password will destroy all data in subkey.
'The DS1991 has 3 Subkeys, 1=00H , 2=40H , 3=80H
'The variable "text" must be exactly 16 bytes, the first 8 for Subkey-id and the

file:///F|/FrontPage Webs/Content/server/download/appnotes/ds1991.bas (1 of 3) [16-7-2000 19:51:11]


file:///F|/FrontPage Webs/Content/server/download/appnotes/ds1991.bas

'last 8 for password. Every subkey has it's own password.


Text = "Subkyid1PASSWORD" 'New subkey-id and password
Ar(1) = &H5A 'Change password command
Ar(2) = &H00 'Subkey-id to change
Ar(3) = &HFF - Ar(2) 'Complement of Ar(2)
1wreset 'reset the device
1wwrite &HCC 'Skip read ROM command
1wwrite Ar(1) , 3 'Write command to DS1991
Ar(1) = 1wread(8) 'Read old-id
1wwrite Ar(1) , 8 'Write old-id back to
DS1991
Gosub Fill_write_array 'Fill array with "Text"
1wwrite Ar(1) , 16 'Write New-id and password
Wait 1 'wait a moment

'Writing subkey
'It is possible to write 64 bytes of data to the subkey. In this example
'i only used 16 bytes.You can write/read the other bytes if you change the
'array or start address.
Text = "Hello world!!!!!" 'New subkey
Ar(1) = &H99 'Writing subkey command
Ar(2) = &H10 'Subkey(00H) + Start
address (10H)
Ar(3) = &HFF - Ar(2) 'Complement of Ar(2)
1wreset 'reset the device
1wwrite &HCC 'Skip read ROM command
1wwrite Ar(1) , 3 'Write subkey write command

Text = "Subkyid1" 'Must be the same as the


first 8
Gosub Fill_write_array ' bytes of "writing
subkeyid & passw."
1wwrite Ar(1) , 8 'Write Subkeyid for
conformation

Text = "PASSWORD" 'Must be the same as the


last 8
Gosub Fill_write_array ' bytes of "writing
subkeyid & passw."
1wwrite Ar(1) , 8 'Write password to DS1991

Text = "Hello world !!!!" 'New subkey data


Gosub Fill_write_array
1wwrite Ar(1) , 16 'Write 16 bytes to DS1991
Wait 1

'Reading subkey
Ar(1) = &H66 'Read secured subkey
command
Ar(2) = &H10 'Subkey(00H) + Start adress
(10H)
Ar(3) = &HFF - Ar(2) 'Complement of Ar(2)
1wreset 'reset the device
1wwrite &HCC 'Skip read ROM command
1wwrite Ar(1) , 3 'Write subkey read command
Ar(1) = 1wread(8) 'DS1991 respons with the
Subkey-id
Text = "PASSWORD" 'Must be the same as the
last 8
Gosub Fill_write_array ' bytes of "writing

file:///F|/FrontPage Webs/Content/server/download/appnotes/ds1991.bas (2 of 3) [16-7-2000 19:51:11]


file:///F|/FrontPage Webs/Content/server/download/appnotes/ds1991.bas

subkeyid & passw."


1wwrite Ar(1) , 8 'Write password to DS1991
Ar(1) = 1wread(16) 'Reads 16 bytes from DS1991
Print "Sub key : "; '
For I = 1 To 16 '
Temp = Ar(i) 'Prints the contents of the
Print Chr(temp); ' subkey.
Next I '
Wait 1 'wait a moment

Goto Main 'And do it again

Fill_write_array:
For I = 1 To 16
Temp2 = Mid(text , I , 1)
Ar(i) = Asc(temp2)
Next I
Return

file:///F|/FrontPage Webs/Content/server/download/appnotes/ds1991.bas (3 of 3) [16-7-2000 19:51:11]


file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_1.bas

'-------------------------------------------------------------------------------
' (c) Copyright 2000 Rhombus Greenville SC
'Code can be used by others providing this header is included in the source.
'===============================================================================
'Getting started in Real-Time Control using BASCOM Part 1
'===============================================================================

'INTRO

'For those who have not yet applied themselves to real-time control using 8-bit
' MCU/MPUs, then these notes and segments of code may help you get started.
'Or if you normally avoid Interrupts, then this first part may change that by
' showing how Timer0 can be expanded into as many timers as you wish, and with
' very little code.

'I am experienced with the 51 at assembler level but new to the Bascom compiler.
' What surprises me the most is that despite the convenience of using a
' compiler, it does not appear to be restricting in any way - hence I hope to
' avoid the use of any assembler code.
'
'Whilst most of what will be described was written a good 15-25 years ago, I
' have checked and it does appear to fit in neatly with present day theory for
' simple real-time control and is classified as 'Co-operative Multi-tasking'.
' There is no forced switching of tasks as with a RTOS, and hence all CPU time
' is devoted to 'getting the job done' and no storage is needed to hold all the
' intermediate states of pre-empted tasks.

'OVERVIEW OF MACHINE CONTROL

'All but the most simple machines require multiple tasks operating in parallel.
' Each task consist of a series of states(steps) with clearly defined logic that
' determines the transition from one state to the next.For example a tank drain
' valve is open, the low level float switch indicates empty but it is known that
' an additional 40 secs needs to be timed for a complete drain and to finally
' close the valve. In parallel a safety locking sequence must be performed on
' another part of the machine before a steam valve is opened.
'
'It is that sort of parallel control that is easily handled by PLCs where there
' is a continuous loop scanning all Inputs, then based on pre-defined logic so
' each task progresses from one stage(step) to the next and resulting in a new
' set of Outputs. With fast loops of Inputing, Processing and Outputing the
' tasks are effectively being controlled in parallel.
'
'When I/O is added that cannot be included in that main I/O loop, such as
' operator interfaces and host serial communication, then the software must use
' interrupts to take whatever time is needed from the main I/O loop to service
' the needs of those asynchronous events. It was at this stage of the PLC's
' history that the limitations of relay ladder logic became more than apparent.
' The PLC solutions to handle these new demands were far from elegant,whereas
' for MPU/MPCs the solutions are a natural and can be achieved very simply
' using the Bascom compiler.

'The methods to be described here have handled slow process control as mentioned
' above, and together with both serial & operator interfaces, They have also
' allowed an 11Mhz 8052 to precisely control a knitting machine's 100+ pneumatic
' outputs in perfect sync with needles flying by at 800 per second, and as the
' operator keyed in a new batch and the host collected production data.
'
'The sharing of CPU time is based on a priority ordered list of tasks and with
' all asyncronous or time critical events being interrupt driven. The main I/O
' tasks are prompted by timer set flags (only one in example) which can also

file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_1.bas (1 of 4) [16-7-2000 19:51:23]


file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_1.bas

' serve to distribute CPU demands. Analog inputs can also benefit from using a
' timer rate related to the supply frequency. When each task is completed it
' returns execution to the top of the list.

'Interrupt routines are kept at an absolute minimum and any excessive processing
' needs are off-loaded to the main loop. This holds interrupt service latencies
' to a minimum and avoids the need for either hardware or software priority
' handling to satisfy critical timing issues.

'An example of off-loading interrupt servicing time would be to merely flag the
' timer event shown below, avoid all needs for stacking (it would not change the
' value of any registers, nor even the status flags), and carry out the updates
' in the main loop. For simplicity, the timer ISR below does its processing
' during the interrupt and that will normally be OK but for the most demanding
' applications.
'
'Timer0 ISR code is very small and should be self explicit. In order to show it
' working there is a main loop using those new timers as inputs, a little logic
' for reloading them, and their run status is output to a set of pins to allow
' scoping. For a steady trace the timers are running very fast at a resolution
' of 2mS. If using the Timer0 expansion code in your own applications then it is
' only a matter of defining a new constant for loading the timer.

'Using P3.5 as a scope trigger will show P3.2.3.4 effectively operating in


' parallel and from the same Timer0.

'Part 2 will add transparent keypad input to change the timer values whilst they
' are running & without affecting their operation until the Enter key finalises
' their new value and they snap to the new timing.

'----- INITIALISATION

Dim Timers(4) As Byte , Tic_cnt0 As Byte , Isr_temp As Byte , Io_flag As Bit

Const 2ms = -1793 ' (2/1000)*(11059200/12)-50reload

Config Timer0 = Timer , Gate = Internal , Mode = 1 '16 bit,own code reloads
On Timer0 Timer_0_int
Enable Interrupts 'enable the use of interrupts
Enable Timer0

Priority Set Timer0 'highest priority


Counter0 = 2ms
Start Timer0

'----- MAIN LOOP

'Dumb code to show a set of timers (Timer0 expanded) each running with their own
' individual values, and controlling their own output(a port pin) and effectively
' in parallel.

Main_loop:
Do
'--Test for I/O prompt
If Io_flag = 1 Then Goto Io_control 'Dummy machine control

'--Test for waiting Host messages 'Nothing currently implemented


'If Msg_flag Then Goto Msg_rtn

file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_1.bas (2 of 4) [16-7-2000 19:51:23]


file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_1.bas

'--Test for keypad activity


'If Key_flag Then GoTo Key_rtn

Loop

'----- MACHINE CONTROL

Io_control:
'The 3 stages of Read_Inputs/Process/Write_Outputs
'All inputs here are Timer values and hence readily available internally.
'The processing here is merely to watch for Timers(1) to count down to zero
' and then reset its associated P3.5. On the next pass (when Io_flag is found
' set in the Main_loop) we reload all 4 timers with their individual values &
' set their individual flags.
'All subsequent passes with Timer(1)<>0 has pins P3.2.3.4 updated to reflect
' when their counts have reached zero.
'That is not a separate Output stage as such, but if we had remote I/O then
' the equivalents of P3.2.. would be internal bits and once all processing
' was complete, we would output them as a distinct & separate operation as in
' a PLC.
Io_flag = 0
If Timers(1) = 0 Then
If P3.5 = 1 Then 'Dont restart till 1 pass later
Reset P3.5
Else
Timers(1) = 20 : Set P3.5
Timers(2) = 15 : Set P3.2
Timers(3) = 10 : Set P3.3
Timers(4) = 5 : Set P3.4
End If
Else
If Timers(2) = 0 Then Reset P3.2 'Could avoid multiple resets
If Timers(3) = 0 Then Reset P3.3 ' but no real savings
If Timers(4) = 0 Then Reset P3.4
End If
Goto Main_loop

'We return at the highest priority level ignoring the tasks below this one
' but know that they will be reached on the next pass, now that the Io_flag
' is reset. *Except* if the interval set between scans is not realistic: eg
' if the Control routines take 50mS and the Io_flag is set every 40mS then
' all other functions will be blocked out. Timing the different functions in
' the Main_loop and allocating realistic intervals is not a difficult task.

'----- INTERRUPT SERVICE ROUTINE

'On-chip Timer0 over-flow interrupts steal insignificant slices of CPU time in


' order to update any number of independent timers. The timer values halt at zero
' thereby doubling as 'Done' flags. Where timing ranges cannot be covered by
' single byte values it may be more economical to group them with multiple
' Tic_cnts in preference to expanding all timers to use multiple bytes.

Timer_0_int:
Counter0 = 2ms
Start Timer0
Set Io_flag
Inc Tic_cnt0
If Tic_cnt0 => 1 Then '1=2mS for easy scoping
Tic_cnt0 = 0 '5/50 =10mS/100mS more typical
For Isr_temp = 1 To 4
If Timers(isr_temp) <> 0 Then Decr Timers(isr_temp)

file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_1.bas (3 of 4) [16-7-2000 19:51:23]


file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_1.bas

Next
'If Timers(0) <> 0 Then Decr Timers(0) 'Alternatively trade code size
'If Timers(1) <> 0 Then Decr Timers(1) ' for speed
'If Timers(2) <> 0 Then Decr Timers(2)
'If Timers(3) <> 0 Then Decr Timers(3)
End If
Return

file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_1.bas (4 of 4) [16-7-2000 19:51:23]


file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_2.bas

'-------------------------------------------------------------------------------
' (c) Copyright 2000 Rhombus Greenville SC
'Code can be used by others providing this header is included in the source.
'===============================================================================
'Getting started in Real-Time Control using BASCOM Part 2
'===============================================================================

'Adding transparent keypad input

'To maintain consistent processing of the I/O tasks in Part 1 we cannot leave
' the main loop, start scanning a keypad and wait for user input. Any keypad
' activity needs to be flagged and brought into the main loop by one means or
' another - and at a pre-determined priority level with respect to other tasks.

'A key encoder chip could take care of full-time scanning, separation of
' multiple keys, debouncing, and we would just watch for its data ready flag.
' For example a 74C922 would need 5 port pins from an MCU or a decode of one
' address for an MPU, to handle 16 keys - they are somewhat more expensive than
' 51 micro itself, but would serve our purpose well.

'An alternative is shown below where the existing Timer0 ISR takes on the
' additional task of sinking just one of the 4 row signals connected to a
' keypad matrix. Everytime the Scan-tics reach a specific count (shown for 10x2
' =20mS) then the next row becomes active low, until the columns indicate a key
' is depressed. Then the active row is maintained and the columns must read the
' same after a further 20mS in order for the key to be accepted. That takes 3
' extra port pins for a total of 8, but no additional logic is required. It
' also scans full-time.

'Either solution will allow detection of an active key in the main loop. The
' code shown for key detection below becomes 'If Key_flag Then Goto Key_10' when
' using an MCU with a 74C922. The Row_col was read and saved at the 20mS point,
' the 922 also saved after debounce and the operator will not be sensitive to a
' few hundred mS of other tasks being completed prior to acting on the last key.
' So key detection receives one of the lowest priorities and will be close to
' the bottom of the loop.

'If fixed and pre-determined functions were associated with each key, then
' keypad input would already be complete. Each key would have an associated
' Goto and they would all return to the top of the main loop (standard practice,
' and no stack used). They may only require one or two bits to be set/reset and
' occupy just a few uSecs. But often that one key will be the first step to an
' operator dialog taking seconds or even minutes and each operator response
' may well consist of several keys as a numeric value is entered and edited.

'That operator dialog routine needs to be a subroutine to allow for multiple


' callers, yet it must immediately hand execution back to the main loop to
' satisfy the needs of other tasks, and further to receive its own key input.
' The first such key pressed will exit the main loop in a manner identical to
' the function key that started the dialog. However, its non-function code will
' allow it be handled differently. When complete, again the key code common to
' both function and dialog keys will be able to distinguish between the cases
' and this time will execute a Return rather than Goto top of main loop. Then
' the calling routine itself will pass the execution to the top of the main loop
' once it has retrieved its dialog data.

' The common code could be included in the main loop, but it will become lengthy
' if code for key masks,lengths,min/max values etc are added, and that would
' detract from the loop's clarity.

'At this stage we can now enter new data for each of the timers in parallel

file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_2.bas (1 of 6) [16-7-2000 19:51:27]


file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_2.bas

' with normal operation of the 'machine'. Using a scope on P3.5 as a reference.
' the only visual influence of keyboard activity will be when the final Enter
' key causes the trace to snap to the new timing.

'Part 3 will add transparent host communication.

'----- INITIALISATION

Dim Timers(4) As Byte , Isr_temp As Byte , Temp1 As Byte , Temp2 As Byte


Dim Timer_tics As Byte , Key_tics As Byte , Io_tics As Byte
Dim Old_rowcol As Byte , Row_col As Byte , Key_val As Byte
Dim Key_len As Byte , Key$ As String * 5
Dim New_key As Bit , No_key As Bit , Pad_active As Bit , Io_flag As Bit
Dim Set_pt1 As Byte , Set_pt2 As Byte , Set_pt3 As Byte , Set_pt4 As Byte

Set_pt1 = 20 : Set_pt2 = 15 : Set_pt3 = 10 : Set_pt4 = 5


Row_col = &HFF
Key_len = 3
Const 2ms = -1793 ' (2/1000)*(11059200/12)-50reload
Declare Sub Key_rtn()
$baud = 9600

Config Timer0 = Timer , Gate = Internal , Mode = 1 '16 bit, code reloads
Counter0 = 2ms
On Timer0 Timer_0_int
Enable Interrupts 'enable the use of interrupts
Enable Timer0

Priority Set Timer0 'highest priority


Start Timer0

'For demo purposes the 'machine' consists of 4 timers cycling & driving 4 port
' pins. There are 4 keypad function keys that initiate a dialog sequence with the
' machine operator to setup new timer values in real-time whilst the 'machine'
' continues normally.
'The keypad is scanned continously in the background and collects the user's
' input without interrupting the control of the machine - a scope can be used
' to monitor the machine's cycling pins as the timers are changed.

'----- MAIN LOOP (task priorities in descending order)

Main_loop:
Do
'--Test for I/O prompt
If Io_flag = 1 Then Goto Io_control 'Dummy machine control

'--Test for waiting Host messages 'Will be added in Part 3


'If Msg_flag Then Goto Msg_rtn

' (ADDED with Part2)


'--Test for keypad activity
If New_key = 0 Then 'Look for new keys
Temp1 = Row_col And &H0F '4 LSbits represent 4 Colmns
If Temp1 <> &H0F Then 'If a key is 'Active'
If Old_rowcol <> Row_col Then ' and a new pattern
Old_rowcol = Row_col ' then record first stage &
Reset No_key
Row_col = &HFF ' ensure Row_col not re-used
Else
Goto Key_10 'Now 2nd stage & definitely
End If

file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_2.bas (2 of 6) [16-7-2000 19:51:27]


file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_2.bas

End If ' have a key to process


End If
Loop

' (ADDED with Part2)


'----- KEYBOARD DECODER

Sub Key_rtn 'Call from any dialog routine


Key$ = ""
'LCD ....
Pad_active = 1
Goto Main_loop 'Get next key

'-- From here upto Key_return could be included as part of main loop - but see text
'Each new character causes a 'Jump' from main loop to Key_10
Key_10:
Temp1 = Lookup(temp1 , Xlate_col) 'Translate Column to = 0,1,2,3
Temp2 = Row_col And &HF0 ' isolate Row to = 70,B0,D0,EO
Select Case Temp2
Case &H70 : Key_val = Lookup(temp1 , Row0) ' then use that Row's lookup
Case &HB0 : Key_val = Lookup(temp1 , Row1)
Case &HD0 : Key_val = Lookup(temp1 , Row2)
Case &HE0 : Key_val = Lookup(temp1 , Row3)
Case Else :
End Select
Set New_key ' and avoid repeat keys
'Function Key cases
If Temp1 = 0 Then 'Left hand column of 4 keys
If Pad_active = 0 Then 'Reject new Funxs during Dialog
On Key_val Goto Edit_sp1 , Edit_sp2 , Edit_sp3 , Edit_sp4
Else
Goto Main_loop
End If
Else
'Dialog key cases
'Filtering shown for backspace & CR only - also Max_len
Temp1 = Len(key$)
If Key_val <> 13 Then 'CR terminates dialog in example
If Key_val = 08 Then ' and falls thru to Key_return
Temp1 = Temp1 - 1
If Temp1 < 0 Then Temp1 = 0
Key$ = Left(key$ , Temp1)
Elseif Temp1 < Key_len Then
Key$ = Key$ + Chr(key_val)
End If
Print Key$;
'Locate Y , X : Lcd Key$
Goto Main_loop
Elseif Temp1 = 0 Then
Goto Main_loop
End If
End If
'Goto Key_return
'-- End of code that could be included in the main loop - would need immediately
' above line additionally

Key_return:
Print "CR"
Pad_active = 0
Return
End Sub

file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_2.bas (3 of 6) [16-7-2000 19:51:27]


file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_2.bas

' (ADDED with Part2)


'----- FUNCTIONS USING DIALOG (stripped down to keys only - (& no LCD to test with))

Edit_sp1:
'LCD prompt for operator 'Enter new Setpoint Routine
Print "SP1"
Key_rtn 'Returns with an Enter Key
Set_pt1 = Val(key$) 'Makes new value effective
' when timer is loaded next
'Wasn't Called so can 'Jump' to highest priority task
Goto Main_loop:

Edit_sp2: ' As above


'LCD prompt for operator
Print "SP2"
Key_rtn
Set_pt2 = Val(key$)
Goto Main_loop:

Edit_sp3: ' As above


'LCD prompt for operator
Print "SP3"
Key_rtn
Set_pt3 = Val(key$)
Goto Main_loop:

Edit_sp4: ' As above


'LCD prompt for operator
Print "SP4"
Key_rtn
Set_pt4 = Val(key$)
Goto Main_loop:

'----- MACHINE CONTROL


Io_control:
'The 3 stages of Read_Inputs/Process/Write_Outputs
'All inputs here are Timer values and hence readily available internally.
'The processing here is merely to watch for Timers(1) to count down to zero
' and then reset its associated P3.5. On the next pass (when Io_flag is found
' set in the Main_loop) we reload all 4 timers with their individual values &
' set their individual flags.
'All subsequent passes with Timer(1)<>0 has pins P3.2.3.4 updated to reflect
' when their counts have reached zero.
'That is not a separate Output stage as such, but if we had remote I/O then
' the equivalents of P3.2.. would be internal bits and once all processing
' was complete, we would output them as a distinct & separate operation as in
' a PLC.
Io_flag = 0
If Timers(1) = 0 Then
If P3.5 = 1 Then 'Dont restart till 1 pass later
Reset P3.5
Else
Timers(1) = Set_pt1 : Set P3.5 'In Part1 we had fixed values
Timers(2) = Set_pt2 : Set P3.2 ' now we need vars Set_ptx to
Timers(3) = Set_pt3 : Set P3.3 ' allow the KeyPad input.
Timers(4) = Set_pt4 : Set P3.4
End If
Else
If Timers(2) = 0 Then Reset P3.2 'Could avoid multiple resets
If Timers(3) = 0 Then Reset P3.3 ' but no real savings

file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_2.bas (4 of 6) [16-7-2000 19:51:27]


file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_2.bas

If Timers(4) = 0 Then Reset P3.4


End If
Goto Main_loop

'We return at the highest priority level ignoring the tasks below this one
' but know that they will be reached on the next pass, now that the Io_flag
' is reset. *Except* if the interval set between scans is not realistic: eg
' if the Control routines take 50mS and the Io_flag is set every 40mS then
' all other functions will be blocked out. Timing the different functions in
' the Main_loop and allocating realistic intervals is not a difficult task.

'----- INTERRUPT DRIVEN TIMERS (Keyboard Scanning added to code of Part 1)

Timer_0_int:
Counter0 = 2ms
Start Timer0
Set Io_flag
Inc Timer_tics
If Timer_tics => 1 Then '01 and fast to allow scoping
Timer_tics = 0 '05/50 = 10mS/100mS more typical
For Isr_temp = 1 To 4
If Timers(isr_temp) <> 0 Then Decr Timers(isr_temp)
Next

' (ADDED with Part2)


'Keyboard Scanning
End If
Inc Key_tics
If Key_tics >= 25 Then
Key_tics = 0
Row_col = P1
Isr_temp = Row_col And &H0F '&H0F says no Cols driven low
If Isr_temp = &H0F Then 'Continue scanning whilst no key
If No_key = 1 Then Reset New_key Else Set No_key
Select Case Row_col 'Rows rotate '0' Cols always I/Ps
Case &H7F : Row_col = &HBF '0111 1111 Row0->1 1011 1111
Case &HBF : Row_col = &HDF '1011 1111 Row1->2 1101 1111
Case &HDF : Row_col = &HEF '1101 1111 Row2->3 1110 1111
Case &HEF : Row_col = &H7F '1110 1111 Row3->0 0111 1111
Case Else : Row_col = &H7F
End Select
P1 = Row_col
End If
End If
Return

Xlate_col:
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 3
'Col# * * * * * * * 0 * * * 1 * 2 3 Posn15not possible
' '*' due multiple keys
Row0:
Data 00 , 49 , 50 , 51 'F0 1 2 3
Row1:
Data 01 , 52 , 53 , 54 'F1 4 5 6
Row2:
Data 02 , 55 , 56 , 57 'F2 7 8 9
Row3:
Data 03 , 08 , 48 , 13 'F3 BS 0 CR

'Above lookup tables assume following relationship between port bits and keyboard

file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_2.bas (5 of 6) [16-7-2000 19:51:27]


file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_2.bas

'Rows/Columns:
'Port Bits: 7 6 5 4 3 2 1 0
'Rows Top to Bottom: 0 1 2 3
'Columns Left to Right 0 1 2(3)
'Code assumes Port.0 bit to be high when 4x3 pad

'Xlate_col shown for leftmost column taking priority when multiple keys on same
' row are depressed.
'Multiple keys on same column are resolved by the scanning - it halts on first
' key scanned, going down.
'Good for 3 or 4 column key pads - extend Xlate_col with 7'0s'to avoid bad data
' with multiple key cases

file:///F|/FrontPage Webs/Content/server/download/appnotes/rtc_2.bas (6 of 6) [16-7-2000 19:51:27]


file:///F|/FrontPage Webs/Content/server/download/appnotes/textmatrix.bas
' *************************************************
' * MATRIXINPUT V1.0 07-12-99
' *
' * Author: John van der Putte
' * E-mail: joconiki@hotmail.com
' * icq: 47666030
' *
' * Program:
' * This program uses a 3x4 keyboard matrix to input
' * ASCII. The output is placed on the LCD-display and
' * will be saved in the variable TEXT.
' * If one key is pushed several times the characters
' * of that key rotates at the cursor. When no key is
' * pressed the cursor shifts to the next display-
' * position after a while. This time can easely be changed.
' *
' * The keys have the following layout:
' *
' * 1 2 3
' * .,?!-& ABC DEF
' *
' * 4 5 6
' * GHI JKL MNO
' *
' * 7 8 9
' * PQRS TUV WXYZ
' *
' * * 0 #
' * <BACKSPACE> <SPACE> <ENTER>
' *
' *
' *
' * The procedure which looks to the keyboard matrix returns the
' * following values:
' * no key = 17
' * 0...9 = 0...9
' * * = 10
' * # = 11
' *

$romstart = &H4000
$ramstart = &HC000
$lcd = &H2000
$map

Config Lcd = 20 * 2
Config Debounce = 25 ' Set Key Pad Debounce to 40 Ms

Col1 Alias P4.7


Col2 Alias P4.6
Col3 Alias P4.5
Row1 Alias P4.3
Row2 Alias P4.2
Row3 Alias P4.1
Row4 Alias P4.0

Dim Keyread As Byte ' key being scanned


Dim Key As Byte ' key being pressed
Dim Keyold As Byte ' key being pressed before
Dim Number As Byte ' pointer to charactertable
Dim Index As Byte ' pointer to character for the pressed key
Dim Character As String * 1 ' character selected
Dim Count As Byte ' time for automatic cursormovement
Dim Text As String * 20 ' text inputted so far
Dim I As Byte ' used by for-next loops
Dim Begin As Byte ' pointer to character in charactertable
Dim Name As String * 20

Const Countmax = 30 ' change this value for different time of


automatic cursormovement

Cls ' clear lcd-display


Cursor Off Blink ' no cursor but blinking character

' time for automatic cursormovement is controlled bij timer0.


' when timer0 is needed for other purposes you can replace it
' with a simple incrementation of a variable
' timer0 is configured as a 16-bit timer

file:///F|/FrontPage Webs/Content/server/download/appnotes/textmatrix.bas (1 of 4) [16-7-2000 19:51:39]


file:///F|/FrontPage Webs/Content/server/download/appnotes/textmatrix.bas
Config Timer0 = Timer , Gate = Internal , Mode = 1
On Timer0 Timer_0_int
Enable Interrupts
Enable Timer0

Print "Give your textinput with keyboardmatrix."


Print "Input is displayed on LCD, result is displayed on screen"
Gosub Matrix_input
Print
Print "This is your input: >" ; Text ; "<"
End

Matrix_input:

Index = 0 ' reset index


Keyold = 16 ' reset keyold (16 is used to prevent
automatic cursormovement)
Count = 0 ' reset count
Text = "" ' reset text
Do
L0:
Gosub Keyscan
L1:
If Row1 = 0 Then Goto L1
If Row2 = 0 Then Goto L1
If Row3 = 0 Then Goto L1
If Row4 = 0 Then Goto L1

If Count = Countmax Then ' if it is time for automatic


cursormovement then
Shiftcursor Right ' move cursor to the right on display
Text = Text + Character ' save character in text
Stop Timer0 ' stop automatic cursormovement
Count = 0 ' reset counter
Index = 0 ' reset index
Keyold = 16 ' pretend an other keypress to suppress
automatic cursormovement
End If
If Key < 16 Then
If Keyold = 16 Then ' prevent automaic cursormovement
Keyold = Key
Stop Timer0
End If
If Key = 10 Then ' BACKSPACE-keywas pressed
Gosub Key10
Goto L0
End If
If Key = 11 Then Goto Key11 ' ENTER-key was pressed
Restore Keylength ' get startpoint in keytable
Begin = 1 ' point at start of keytable
For I = 0 To Key '
Read Number ' read number of characters available on
key
If I < Key Then ' calculate startpoint in keytable
Begin = Begin + Number '
End If '
Next I '
If Key <> Keyold Then ' if other key is pressed then
Index = 0 ' reset index
Shiftcursor Right ' move cursor to the right on display
Text = Text + Character ' save character in text
End If '
If Index = Number Then ' index must not exceed the numer of
available characters
Index = 0 '
End If '
Begin = Begin + Index ' set pointer in keytable
Restore Keydata ' get character from keytable
For I = 1 To Begin '
Read Character '
Next I '
Lcd Character ' show character to display
Shiftcursor Left ' and move cursor to the left
Count = 0 ' reset count
Start Timer0 ' start timer for automatic cursormovement
Keyold = Key ' save the pressed key

file:///F|/FrontPage Webs/Content/server/download/appnotes/textmatrix.bas (2 of 4) [16-7-2000 19:51:39]


file:///F|/FrontPage Webs/Content/server/download/appnotes/textmatrix.bas
Incr Index ' increment index
End If '
Loop

' BACKSPACE-key was pressed


Key10:
I = Len(text) ' number of characters of endresult
If I > 0 Then ' only remove character it there are
characters
If Tcon.4 = 1 Then ' if timer0 is still runnuning then:
Stop Timer0 ' stop the timer
Count = 0 ' and reset counting
Lcd " " ' clear lcd at position of cursor
Shiftcursor Left ' and place cursor at the right position
Else
Shiftcursor Left ' move cursor to the left
Lcd " " ' and remove character from lcd
Shiftcursor Left ' place the cursor at the right position
Decr I ' remove last character from result
Text = Left(text , I)
If I = 0 Then ' if no more characters in result then
clear result
Text = ""
End If
End If
Keyold = 16 ' prevent automatic cursormovement
End If
Return

' ENTER-key was pressed


Key11:
If Tcon.4 = 1 Then ' if timer0 is still running the keypress
isn't added to endresult
Text = Text + Character ' so add it now
End If
Return

Keyscan: ' Keypad Read Routine (Assignments can be


changed for different connections)
Key = 17
Col1 = 0 : Col2 = 1 : Col3 = 1 ' Turns Columns On (Low) 1 by 1
Keyread = 1 : Debounce Row1 , 0 , Gotkey ' Goto if Key Pressed (Reads LOW Input)
Keyread = 4 : Debounce Row2 , 0 , Gotkey
Keyread = 7 : Debounce Row3 , 0 , Gotkey
Keyread = 10 : Debounce Row4 , 0 , Gotkey ' BACKSPACE Button *
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Col1 = 1 : Col2 = 0 : Col3 = 1
Keyread = 2 : Debounce Row1 , 0 , Gotkey
Keyread = 5 : Debounce Row2 , 0 , Gotkey
Keyread = 8 : Debounce Row3 , 0 , Gotkey
Keyread = 0 : Debounce Row4 , 0 , Gotkey
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Col1 = 1 : Col2 = 1 : Col3 = 0
Keyread = 3 : Debounce Row1 , 0 , Gotkey
Keyread = 6 : Debounce Row2 , 0 , Gotkey
Keyread = 9 : Debounce Row3 , 0 , Gotkey
Keyread = 11 : Debounce Row4 , 0 , Gotkey ' ENTER Button #
Return

Gotkey:
Key = Keyread
Return

' everytime TIMER0 overflows it generates an interrupt and jumps to this place
Timer_0_int:
Incr Count ' increment count
Return

' This table holds the number of available characters for each key (0...9)
Keylength:
Data 2 , 7 , 4 , 4 , 4 , 4 , 4 , 5 , 4 , 5

' This table holds the characters available for each key (0...9)
' If you changes this table than you must change the keylength-table too.
Keydata:
Data " " , "0"

file:///F|/FrontPage Webs/Content/server/download/appnotes/textmatrix.bas (3 of 4) [16-7-2000 19:51:39]


file:///F|/FrontPage Webs/Content/server/download/appnotes/textmatrix.bas
Data "." , "," , "?" , "!" , "-" , "&" , "1"
Data "A" , "B" , "C" , "2"
Data "D" , "E" , "F" , "3"
Data "G" , "H" , "I" , "4"
Data "J" , "K" , "L" , "5"
Data "M" , "N" , "O" , "6"
Data "P" , "Q" , "R" , "S" , "7"
Data "T" , "U" , "V" , "8"
Data "W" , "X" , "Y" , "Z" , "9"

file:///F|/FrontPage Webs/Content/server/download/appnotes/textmatrix.bas (4 of 4) [16-7-2000 19:51:39]


file:///F|/FrontPage Webs/Content/server/download/appnotes/ir2.bas

'foprogi
'*******************************************************************************************
'compiler opciok
'*******************************************************************************************

$baud = 19200 'baudrate


$crystal = 11059200 'frequency
$romstart = &H8200 'rom starting address
$ramsize = &H0200 'size of RAM
$ramstart = &H3000
$large
$iramstart = &H30
$map

'Hardware
'int0 IR sensor
'if there is an infra signal then the pin is 1

'number of received bit: 12+1 start


'device code:5 bit
'button code:7 bit

'if you have question please let me know:


'mailto:kantor@mail.matav.hu
'mailto:kantor@freemail.c3.hu
'mailto:kantor@tar.hu

'*******************************************************************************************
'konfig
'*******************************************************************************************

Config Timer0 = Timer , Gate = Internal , Mode = 2


'Timer0 = timer : timer0 operates as a timer
'Gate = Internal : no external gate control
'Mode = 2 : 8-bit reload

Th0 = 0
Set Tcon.0 'edge trig
Set Tcon.2

On Timer0 Timer_0_int
On Int0 Int0_int

Enable Interrupts 'enable the use of


interrupts
Enable Timer0
Enable Int0

Start Timer0 'start the timer

'*******************************************************************************************
'valtozo definiciok
'*******************************************************************************************
Triac Alias P1.0
Led Alias P3.3

Dim New_ir_command As Bit


Dim Infra_count As Byte
Dim Infra_count_old As Byte
Dim Infra_command As Word
Dim Segb1 As Byte

file:///F|/FrontPage Webs/Content/server/download/appnotes/ir2.bas (1 of 3) [16-7-2000 19:51:48]


file:///F|/FrontPage Webs/Content/server/download/appnotes/ir2.bas

Dim Segbit1 As Bit


Dim N As Byte
Dim Segw1 As Word
Dim Segb2 As Byte

New_ir_command = 0

Ide:
If New_ir_command = 0 Then Goto Ide
Infra_count_old = 0

Segw1 = Infra_command
Print N ; " Number of received bit "
Print "Received command ";
Printhex Segw1

Shift Segw1 , Right , 2


Segb2 = High(segw1)
Print "Device " ; Segb2
Segb2 = Low(segw1) / 2
Print "Button " ; Segb2
Print

Goto Ide

'*******************************************************************************************
'* int rutinok
'*******************************************************************************************

'****************************************
'* timer0 rutin
'****************************************
Rem The Interrupt Handler For The Timer0 Interrupt
Rem .27.. ms each irq
Timer_0_int:
If Infra_count < 150 Then
Incr Infra_count
New_ir_command = 0
Else
New_ir_command = 0
If Infra_count_old <> 0 Then
New_ir_command = 1
End If
End If

Timer_0_int_end:
Return

'****************************************
'* int0 rutin
'****************************************
Rem The Interrupt Handler For The INT0 Interrupt
Rem infra falling edge trigger the irq
Int0_int:
If Infra_count = 150 Then
Infra_count = 0 'start receive
(Infra_count=0)
New_ir_command = 0
Infra_count_old = 0

file:///F|/FrontPage Webs/Content/server/download/appnotes/ir2.bas (2 of 3) [16-7-2000 19:51:48]


file:///F|/FrontPage Webs/Content/server/download/appnotes/ir2.bas

Infra_command = 0
N = 0
End If

Segb1 = Infra_count - Infra_count_old


If Segb1 > 5 Then Set Infra_command.15 Else Reset Infra_command.15
Infra_count_old = Infra_count

Shift Infra_command , Right

Incr N

Int0_int_end:
Return

file:///F|/FrontPage Webs/Content/server/download/appnotes/ir2.bas (3 of 3) [16-7-2000 19:51:48]


file:///F|/FrontPage Webs/Content/server/download/appnotes/lm75full.bas

'------------------------------------------------------------------------------
' Program Name : Lm75Full.bas
' Program Date : October 15,1999
' Program Written By : M. Akers Enterprises
' Michael W. Akers
' 3800 Vineyard Ave. #E
' Pleasanton, California 94566
' Voice: +1 925 484 4750
' Email: mwakers@home.com
' Program Purpose : This program will demonstrate how to interface to,
' and communicate With The National Semiconductor LM75
' Digital Temperature Sensor.
' Target Processor : Atmel 89C52
'------------------------------------------------------------------------------
' Programmer Date Comments
' ------------------- ---------- --------------------------------------------
' Michael Akers 10/15/99 Initial creation of program.
' -----------------------------------------------------------------------------
' Define the processor (the regfile goes here!)
$regfile = "8052.DAT"
' Define all meta-commands that must beinserted before all other commands.
' Define all subroutines
Declare Sub Readlm75(lm75addr As Byte)
Declare Sub Getconfig(lm75addr As Byte)
Declare Sub Setconfig(lm75addr As Byte)
Declare Sub Gettos(lm75addr As Byte)
Declare Sub Settos(lm75addr As Byte)
Declare Sub Gethyst(lm75addr As Byte)
Declare Sub Sethyst(lm75addr As Byte)
Declare Sub Setaddr(lm75addr As Byte , Flagrw As Byte)
Declare Sub Resetpointer()
Declare Sub Val2temp(lm75tmphi As Byte , Lm75tmplo As Byte , Lm75tmpsign As Bit)
' Define all variables and constants
Dim Lm75read As Byte ' Read address base
Dim Lm75write As Byte ' Write address base
Dim Lm75addr As Byte ' Lm75 Address
Dim Lm75high As Byte ' Lm75 Temperature High
Byte
Dim Lm75low As Byte ' Lm75 Temperature Low Byte
Dim Lm75sign As Bit ' Lm75 Temperature Sign Bit
Dim Lm75config As Byte ' Lm75 Configuration
Dim Lm75toshi As Byte ' Lm75 Tos high byte
Dim Lm75toslo As Byte ' Lm75 Tos low byte
Dim Lm75tossign As Bit ' Lm75 Tos sign bit
Dim Lm75thysthi As Byte ' Lm75 Thyst high byte
Dim Lm75thystlo As Byte ' Lm75 Thyst low byte
Dim Lm75thystsign As Bit ' Lm75 Thyst sign bit
Dim Flagrw As Byte ' Read/Write Flag
Dim Lm75tmphi As Byte ' Lm75 Temp hi byte
Dim Lm75tmplo As Byte ' Lm75 Temp lo byte
Dim Lm75tmpsign As Bit ' Lm75 Temp sign bit
' Define all Configurations and Pin assignments
Config Sda = P1.0
Config Scl = P1.1
Config I2cdelay = 1
Config Lcd = 40 * 4
Config Lcdpin , Db4 = P1.4 , Db5 = P1.5 , Db6 = P1.6 , Db7 = P1.7 , E = P1.3 , Rs =
P1.2
' Initialize variables as needed.
Lm75read = &B10010001
Lm75write = &B10010000

file:///F|/FrontPage Webs/Content/server/download/appnotes/lm75full.bas (1 of 4) [16-7-2000 19:51:54]


file:///F|/FrontPage Webs/Content/server/download/appnotes/lm75full.bas

' Program start.


Start:

Goto Start
'Program end.
' Begin subroutine section.
Sub Readlm75(lm75addr)
Call Setaddr Lm75addr , 0
I2cstart ' Start the I2C process.
I2cwbyte Lm75read ' Send the LM75 address and
read Info.
I2crbyte Lm75high , 8 ' Get 8 bits and get ACK
from LM75
I2crbyte Lm75low , 9 ' Get 8 bits and send NACK
to LM75
I2cstop ' Stop the I2C system
Call Val2temp Lm75high , Lm75low , Lm75sign ' Convert the value (if
needed)
Lm75high = Lm75tmphi
Lm75low = Lm75tmplo
Lm75sign = Lm75tmpsign
Lm75read = &B10010001 ' Reset Lm75read
End Sub
Sub Getconfig(lm75addr)
Call Setaddr Lm75addr , 2
I2cstart
I2cwbyte Lm75write ' Send write address
I2cwbyte &B00000001 , 8 ' Set pointer register to
point at the configuration register.
I2cstart ' Restart I2C
I2cwbyte Lm75read ' Send read address
I2crbyte Lm75config , 9 ' Read the config register
I2cstop
Resetpointer ' Reset the pointer to '00'
End Sub
Sub Setconfig(lm75addr)
Call Setaddr Lm75addr , 1
I2cstart ' Start I2C
I2cwbyte Lm75write ' Send write address
I2cwbyte &B00000001 , 8 ' Set Pointer to point to
Configuration register
I2cwbyte Lm75config ' Send the Lm75config byte
to write
I2cstop
Resetpointer ' Reset the pointer to '00'
End Sub
Sub Gettos(lm75addr)
Call Setaddr Lm75addr , 2
I2cstart
I2cwbyte Lm75write ' Send write address
I2cwbyte &B00000011 , 8 ' Set Pointer to Tos
I2cstart
I2cwbyte Lm75read ' Send read address
I2crbyte Lm75toshi , 8 ' Read Tos high byte
I2crbyte Lm75toslo , 9 ' Read Tos low byte
I2cstop
Resetpointer ' Reset the pointer to '00'
End Sub
Sub Settos(lm75addr)

file:///F|/FrontPage Webs/Content/server/download/appnotes/lm75full.bas (2 of 4) [16-7-2000 19:51:54]


file:///F|/FrontPage Webs/Content/server/download/appnotes/lm75full.bas

Call Setaddr Lm75addr , 1


I2cstart
I2cwbyte Lm75write ' Send write address
I2cwbyte &B00000011 ' Set Pointer to Tos
I2cwbyte Lm75toshi ' Send Tos high byte
I2cwbyte Lm75toslo ' Send Tos low byte
I2cstop
Resetpointer ' Reset the pointer to '00'
End Sub
Sub Getthyst(lm75addr)
Call Setaddr Lm75addr , 2
I2cstart
I2cwbyte Lm75write ' Send write address
I2cwbyte &B00000010 , 8 ' Set pointer to Thyst
I2cstart
I2cwbyte Lm75read ' Send read address
I2crbyte Lm75thysthi , 8 ' Read Thyst high byte
I2crbyte Lm75thystlo , 9 ' Read Thyst low byte
I2cstop
Resetpointer ' Reset the pointer to '00'
End Sub
Sub Setthyst(lm75addr)
Call Setaddr Lm75addr , 1
I2cstart
I2cwbyte Lm75write ' Send write address
I2cwbyte &B00000010 ' Set pointer to Thyst
I2cwbyte Lm75thysthi ' Send Thyst high byte
I2cwbyte Lm75thystlo ' Send Thyst low byte
I2cstop
Resetpointer ' Reset the pointer to '00'
End Sub
Sub Setaddr(lm75addr , Flagrw)
If Lm75addr <> 0 Then
Lm75addr = Lm75addr * 2 ' Shift the address 1 bit
left
Select Case Flagrw
Case 0 : Lm75read = Lm75read + Lm75addr ' Add the address offset to
the read address
Case 1 : Lm75write = Lm75write + Lm75addr ' Add the address offset to
the write address
Case 2 :
Lm75read = Lm75read + Lm75addr ' Add the address offset to
both read and write addresses
Lm75write = Lm75write + Lm75addr
Case Else
End Select
End If
End Sub
Sub Resetpointer()
' Only call this routine from within a subroutine that has called Setaddr()!
I2cstart
I2cwbyte Lm75write ' Send write address
I2cwbyte &B00000000 , 9 ' Set pointer to '00'
I2cstop
Lm75read = &B10010001
Lm75write = &B10010000
End Sub
Sub Val2temp(lm75tmphi , Lm75tmplo , Lm75tmpsign)
' This routine will convert the hi and lo bytes into a temperature value
If Lm75tmphi > 127 Then
Lm75tmphi = Not Lm75tmphi

file:///F|/FrontPage Webs/Content/server/download/appnotes/lm75full.bas (3 of 4) [16-7-2000 19:51:54]


file:///F|/FrontPage Webs/Content/server/download/appnotes/lm75full.bas

Incr Lm75tmphi
Lm75tmpsign = 1
End If
Lm75tmplo = Lm75tmplo And &B10000000
If Lm75tmplo = &B10000000 Then
Lm75tmplo = 5
End If
End Sub
Sub Temp2val(lm75tmphi , Lm75tmplo , Lm75tmpsign)
' This routine will convert a temperature value into the prober hi and lo byte values.
If Lm75tmpsign = 1 Then
Lm75tmphi = Not Lm75tmphi
Incr Lm75tmphi
End If
If Lm75tmplo <> 0 Then
Lm75tmplo = &B10000000
End If
End Sub

' Insert include files here.


' End of subroutines and actual end of program.

file:///F|/FrontPage Webs/Content/server/download/appnotes/lm75full.bas (4 of 4) [16-7-2000 19:51:54]


file:///F|/FrontPage Webs/Content/server/download/appnotes/pagescan.bas

' 32 Way Scanner and Potsag Pager Interface MKG 08/06/98 Bascom 8052 Compiler for
89S8252
' Reads PCF8574s on I2C Bus. Inputs to these are active LOW via Opto Couplers
' Inputs are latched until cancelled at source. Change Ports and remove Watchdod if other
CPU used
' Should be easy to alter if you require momentery inputs, Scan routine is fast enough.
' Configure for what Serial O/P you need, i.e Moving Message display/Terminal.

StartUp:
Config WatchDog = 2048
Start WatchDog
Config SCL = P2.0 ' I2C Bus Pin Assignments
Config SDA = P2.1
Config Lcd = 16 * 2
WaitMs 50 ' Allow Display time to
Initialise
$Baud = 300 ' Output to paging TX
$Crystal = 12000000
Cursor OFF
Cls
Lcd "B M Electronics" ' Start Up Message, What you
like
Dim Check As Bit ' Check for Call
Dim DelayTime As Byte ' Used in Loop for Time Between
Calls
Dim AlarmBlips As Byte ' Counter for No of Bleeps on
Sounders
Dim I2cAddress As Byte ' Address to Read
Dim I2cRead As Byte ' Data from PCF8574
Dim I2cStage As Byte ' Individual PCF8574 Location
Dim RealNo As Byte ' Actual Position Number
Dim Result As Byte ' Result of Input Present Test
Dim Message As String * 16 ' Displayed Pager/Lcd Message
StatusLed Alias P0.0 ' Inverted 1=OFF 0=ON
Sounder Alias P2.2 ' True 1=ON 0=OFF
BackLight Alias P2.3 ' True
Relay Alias P2.4 ' True
Sounder = 0 ' Sounder OFF
Relay = 0 ' Relay OFF (If Used)
BackLight = 0 ' Back Light OFF
Check = 0 ' Reset Call Check Bit for
Immediate Page
StatusLed = 1 ' OFF

MainLoop:
Gosub ScanInputs
Reset WatchDog
StatusLed = 0 ' Status Led ON
WaitMs 10 ' Led Flash Time (Once Per Scan
of 32 Points)
StatusLed = 1 ' Status Led OFF - Disable if
faster scan needed
WaitMs 150
If Check = 1 Then : Gosub DelayIt : Goto StartUp : End If
Goto MainLoop
End

ScanInputs: ' Reads all PCF8574 Inputs in


Sequence
For I2cAddress = 64 To 70 Step 2 ' Select 1 of 4 ICs In Turn
If I2cAddress = 64 Then : I2cStage = 0 : End If ' 1st 4 codes for PCF8574

file:///F|/FrontPage Webs/Content/server/download/appnotes/pagescan.bas (1 of 3) [16-7-2000 19:51:58]


file:///F|/FrontPage Webs/Content/server/download/appnotes/pagescan.bas

If I2cAddress = 66 Then : I2cStage = 8 : End If


If I2cAddress = 68 Then : I2cStage = 16 : End If
If I2cAddress = 70 Then : I2cStage = 24 : End If
I2cReceive , I2cAddress , I2cRead
Result = I2cRead And 1 : If Result = 0 Then : RealNo = 0 + I2cStage : Gosub Display :
End If
Result = I2cRead And 2 : If Result = 0 Then : RealNo = 1 + I2cStage : Gosub Display :
End If
Result = I2cRead And 4 : If Result = 0 Then : RealNo = 2 + I2cStage : Gosub Display :
End If
Result = I2cRead And 8 : If Result = 0 Then : RealNo = 3 + I2cStage : Gosub Display :
End If
Result = I2cRead And 16 : If Result = 0 Then : RealNo = 4 + I2cStage : Gosub Display :
End If
Result = I2cRead And 32 : If Result = 0 Then : RealNo = 5 + I2cStage : Gosub Display :
End If
Result = I2cRead And 64 : If Result = 0 Then : RealNo = 6 + I2cStage : Gosub Display :
End If
Result = I2cRead And 128 : If Result = 0 Then : RealNo = 7 + I2cStage : Gosub Display :
End If
Next I2cAddress
Return
End

Display:
Reset WatchDog
BackLight = 1 ' Display Back Light ON
Check = 1 ' Enables Loop Delay Counter
StatusLed = 0 ' Flashes Led
Message = LookupStr(RealNo , List)
Cls
Lcd "Number Calling.." ' Print to Lcd
Lowerline
Lcd Message ' Alarm message to Lcd
Reset WatchDog
Print "L0012000A" ; Message ' TX Message to Pagers Or other
serial device
Gosub Alarm
Return
End

Alarm:
For AlarmBlips = 0 to 5 ' Modify for faster scan
Reset WatchDog
Sounder = 1 ' Alarm ON
Wait 1
Reset WatchDog
Sounder = 0 ' Alarm OFF
Wait 1
Next AlarmBlips
Return
End

DelayIt: ' Routine needed instead of


simple Wait
For DelayTime = 0 To 45 ' To allow WatchDog to Reset
periodically
Reset WatchDog
Wait 1
Next DelayTime ' Remove this routine for fast
scan

file:///F|/FrontPage Webs/Content/server/download/appnotes/pagescan.bas (2 of 3) [16-7-2000 19:51:58]


file:///F|/FrontPage Webs/Content/server/download/appnotes/pagescan.bas

Return
End

List:
Data "One " , "Two " , "Three " , "Four " '
Change these for whatever
Data "Five " , "Six " , "Seven " , "Eight "
Data "Nine " , "Ten " , "Eleven " , "Twelve "
Data "Thirteen " , "Fourteen " , "Fifteen " , "Sixteen "
Data "Seventeen " , "Eighteen " , "Nineteen " , "Twenty "
Data "Twenty One " , "Twenty Two " , "Twenty Three " , "Twenty Four "
Data "Twenty Five " , "Twenty Six " , "Twenty Seven " , "Twenty Eight "
Data "Twenty Nine " , "Thirty " , "Thirty One " , "Thirty Two "
End

file:///F|/FrontPage Webs/Content/server/download/appnotes/pagescan.bas (3 of 3) [16-7-2000 19:51:58]


file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas

'************************************************************************
'*** ***
'*** FLM.BAS is the sorce for a Flow Meter using the 80C552 ***
'*** ***
'*** Started on 15-12-1998 by Mike Crean, Email autlec@nw.com.au ***
'*** ***
'*** This code will run on a 80C552 Micro with 64K bit of ROM and ***
'*** 64K bit of non volatile RAM with RTC ***
'*** ***
'*** The sensor for this flow meter was made from a turbine (fan) ***
'*** with 2 * magnets mounted on it seperated by 180deg's. & ***
'*** opposite polarity's out. A Hall sensor that switches on with ***
'*** one polarity and of with the other was mounted on the out side ***
'*** of a pice of polly pipe. This signal is then fed to a 4018 chip ***
'*** running in / by 10 mode, it's out put is sent to P4.0 as the ***
'*** input signal for the 80C552. ***
'*** ***
'*** If this setup was to be used in another application it would be ***
'*** wise to use / switches on the 4018 to allow for more ***
'*** calibration. ***
'*** ***
'*** I have sent this to Mark Alberts C/O MCS Electronics. As the ***
'*** code listed may give some helpfull ideas to some of the many ***
'*** Bascomlt user's out there. This code is far from complete or ***
'*** bug free, so I hope that Mark will place it on his web site. ***
'*** ***
'*** Ps. The flow rate is output on the LCD or to a terminal when ***
'*** requested. Four buttons allow you to scroll menu's on the LCD ***
'*** ***
'************************************************************************

$large
$baud = 9600
$crystal = 11059200
Config Lcd = 16 * 2
Dim W1 As Integer , W2 As Integer , W3 As Integer , W4 As Integer
Dim W5 As Integer , Cal As Integer , Adc As Integer , Ad As Integer
Dim Rtc As Byte , Rx As Byte , Ck As Byte , Ckgfm As Byte , Min As Byte
Dim Gf As Long
Ck = 0 : Ckgfm = 0 : Gf = 0 : Cal = 0 : W1 = 0 : W2 = 0 : W3 = 0
W4 = 0 : W5 = 0 : Adc = 0 : Min = 0 : Ad = 8299
Cursor Off
Out 16376 , 0 : Out 16377 , 0
Cal = Inp(8194)

If Cal = 0 Then
Cal = 1
End If

Print : Print
Print "; = Version"
Print "f = Flow in m3"

Startone:

W4 = Inp(8202)
Gf = W4 * 255
W3 = Inp(8201)
Gf = Gf + W3
Gf = Gf * 255

file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas (1 of 10) [16-7-2000 19:52:20]


file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas

W2 = Inp(8200)
Gf = Gf + W2

Start:

Cls
Locate 1 , 1 : Lcd " Flow Meter"
Locate 2 , 1 : Lcd " fL m3"
Locate 2 , 5 : Lcd Gf

Do

If Ck > 103 Then


Goto Getgasreading
End If

If Ck = 0 Then

Getgasreading:

Min = Inp(16378)

If Min = 48 Then
Goto Skipone
End If

If Min > 1 Then


If Ck = 200 Then
Ck = 0
End If
End If

Skipone:

If Min = 48 Then
If Ck = 0 Then
Gosub Saveit
End If
End If

If Min = 1 Then
If Ck = 0 Then
Gosub Saveit
End If
End If

If P4.0 = 1 Then
If Ckgfm = 0 Then
W1 = W1 + 1
Ckgfm = 1
End If
End If

If P4.0 = 0 Then
If Ckgfm = 1 Then
Ckgfm = 2
End If
End If

If P4.0 = 1 Then
If Ckgfm = 2 Then

file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas (2 of 10) [16-7-2000 19:52:20]


file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas

Ckgfm = 0
End If
End If

If W1 > Cal Then


If W2 = 10 Then
If Ck = 0 Then
Locate 2 , 5 : Lcd " "
End If
End If

If W2 = 100 Then
If Ck = 0 Then
Locate 2 , 5 : Lcd " "
End If
End If

If Ck = 0 Then
Locate 2 , 5 : Lcd Gf
End If

W1 = 0
W2 = W2 + 1
Gf = Gf + 1
Out 8200 , W2

If Gf = 16581375 Then
W1 = 0 : W2 = 0 : W3 = 0 : W4 = 0 : Gf = 0
Out 8200 , 0 : Out 8201 , 0 : Out 8202 , 0
End If

End If

If W2 = 255 Then
W1 = 0 : W2 = 0
W3 = W3 + 1
Out 8201 , W3
End If

If W3 = 255 Then
W1 = 0 : W2 = 0 : W3 = 0
W4 = W4 + 1
Out 8202 , W4
End If

If W4 = 255 Then
W1 = 0 : W2 = 0 : W3 = 0 : W4 = 0 : Gf = 0
Out 8200 , 0 : Out 8201 , 0 : Out 8202 , 0
End If

End If

Rx = Inkey

If Rx = 102 Then
Print ":" ; Gf ; " fL-m3"
End If

If Rx = 59 Then
Print : Print ":Flow Meter V1.2"
Print ":Copyright (c) Autlec Perth Aust. 1998"

file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas (3 of 10) [16-7-2000 19:52:20]


file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas

End If

If Rx = 91 Then
Goto Sendtime
End If

If Rx = 92 Then
Cls : Locate 1 , 3 : Lcd "PC Download"
Locate 2 , 3 : Lcd "Add. "
Print ":Start Download" : Print : Print ":";
Adc = 0

For W5 = 8300 To 15020


Adc = Inp(w5)
Print Adc ; "~";
Locate 2 , 8 : Lcd W5
Next W5

Print : Print ":End Download"


W5 = 0 : Adc = 0
Waitms 100
Goto Start
End If

If P4.7 = 0 Then
If Ck = 0 Then
Ck = 1
Waitms 250
End If
End If

If P4.7 = 0 Then
If Ck = 100 Then
Ck = 2
Waitms 250
End If
End If

If P4.7 = 0 Then
If Ck = 101 Then
Ck = 3
Waitms 250
End If
End If

If P4.7 = 0 Then
If Ck = 102 Then
Ck = 4
Waitms 250
End If
End If

If P4.7 = 0 Then
If Ck = 103 Then
Ck = 5
Waitms 250
End If
End If

If P4.7 = 0 Then
If Ck = 104 Then

file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas (4 of 10) [16-7-2000 19:52:20]


file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas

Ck = 6
Waitms 250
End If
End If

If P4.7 = 0 Then
If Ck = 105 Then
Ck = 7
Waitms 250
End If
End If

If P4.7 = 0 Then
If Ck = 107 Then
Ck = 0
Waitms 250
Goto Start
End If
End If

If Ck = 1 Then
Cls : Locate 1 , 1 : Lcd "V1.2 Copyright"
Locate 2 , 1 : Lcd "Autlec Perth1998"
Print : Print ":Flow Meter V1.2"
Print ":Copyright (c) Autlec Perth Aust. 1998"
Ck = 100
Waitms 250
End If

If Ck = 2 Then
Cls : Locate 1 , 1 : Lcd "Dn * 100 +"
Locate 2 , 1 : Lcd "Rb-Up Lb-Dn_Set"
Print ""
Print ":Changing reading m3"
Print ":Right Button Up - Left Button Dn + Down Button * 100"
Ck = 101
Waitms 250
End If

If Ck = 3 Then
Cls : Locate 1 , 1 : Lcd "fL will be ZERO"
Locate 2 , 1 : Lcd "Rb-Do it"
Print : Print ":Flow will be Zeroed"
Print ":Right Button Do it"
Ck = 102
Waitms 250
End If

If Ck = 4 Then
Cls : Locate 1 , 1 : Lcd " Calibrate"
Locate 2 , 1 : Lcd Cal
Print ":Calibrate"
Print ":" ; Cal
Ck = 103
Waitms 250
End If

If Ck = 5 Then
Cls : Locate 1 , 1 : Lcd " Line Pressure"
Locate 2 , 7 : Lcd "kPa"
Print ":Line Pressure"

file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas (5 of 10) [16-7-2000 19:52:20]


file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas

Print ":k - display"


Ck = 104
Waitms 250
End If

If Ck = 6 Then
Cls : Locate 1 , 1 : Lcd "Line Temperature"
Locate 2 , 6 : Lcd "C"
Print ":Line Temperature"
Print ":c - display"
Ck = 105
Waitms 250
End If

If Ck = 7 Then
Cls : Locate 1 , 1 : Lcd "Time"
Locate 2 , 1 : Lcd "Date"
Print ":Time and Date"
Print ":t - display"
Ck = 107
Waitms 250
End If

If P4.4 = 0 Then
If Gf < 160000099 Then
If Ck = 101 Then
Cls : Locate 1 , 1 : Lcd "Changing Reading"
Print ":Changing Reading"
Gf = Gf + 1
W2 = W2 + 1
Locate 2 , 1 : Lcd Gf
Print ":" ; Gf
Waitms 80
End If
End If
End If

If P4.5 = 0 Then
If Gf > 0 Then
If Ck = 101 Then
Cls : Locate 1 , 1 : Lcd "Changing Reading"
Print ":Changing Reading"
Gf = Gf - 1
W2 = W2 - 1
Locate 2 , 1 : Lcd Gf
Print ":" ; Gf
Waitms 80
End If
End If
End If

If P4.6 = 0 Then
If P4.4 = 0 Then
If Gf < 160000099 Then
If Ck = 101 Then
Cls : Locate 1 , 1 : Lcd "Changing Reading"
Print ":Changing Reading"
Gf = Gf + 100
W2 = W2 + 100
Locate 2 , 1 : Lcd Gf
Print ":" ; Gf

file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas (6 of 10) [16-7-2000 19:52:20]


file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas

Waitms 10
End If
End If
End If
End If

If P4.6 = 0 Then
If P4.5 = 0 Then
If Gf > 100 Then
If Ck = 101 Then
Cls : Locate 1 , 1 : Lcd "Changing Reading"
Print ":Changing Reading"
Gf = Gf - 100
W2 = W2 - 100
Locate 2 , 1 : Lcd Gf
Print ":" ; Gf
Waitms 10
End If
End If
End If
End If

If P4.4 = 0 Then
If Ck = 102 Then
Goto Zero
End If
End If

If P4.4 = 0 Then
If Ck = 103 Then
Locate 2 , 1 : Lcd " "

If Cal < 500 Then


Cal = Cal + 1
Out 8194 , Cal
End If

Locate 2 , 2 : Lcd Cal


Waitms 100
End If
End If

If P4.5 = 0 Then
If Ck = 103 Then
Locate 2 , 1 : Lcd " "

If Cal > 1 Then


Cal = Cal - 1
Out 8194 , Cal
End If

Locate 2 , 2 : Lcd Cal


Waitms 100
End If
End If

If Ck = 104 Then
Adc = 0
Gosub Adconvert
Adc = Inp(16192)
Adc = Adc - 55

file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas (7 of 10) [16-7-2000 19:52:20]


file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas

Adc = Adc - 100

If Adc => 0 Then


Locate 2 , 1 : Lcd " "
Locate 2 , 2 : Lcd Adc

If Rx = 107 Then
Print ":" ; Adc ; "kPa"
End If

End If

Waitms 50
End If

If Ck = 105 Then
Adc = 0
Gosub Adconvert
Adc = Inp(16193)
Locate 2 , 1 : Lcd " "
Locate 2 , 2 : Lcd Adc

If Rx = 99 Then
Print ":" ; Adc ; "C"
End If

Waitms 50
End If

If Ck = 107 Then

Sendtime:

Rtc = 0 : Locate 1 , 6 : Lcd " " : Locate 1 , 6


Rtc = Inp(16379) : Lcd Bcd(rtc) ; ":" ;

If Rx = 116 Then
Print ":Time " ; Bcd(rtc) ; ":";
End If

Rtc = 0 : Rtc = Inp(16378) : Lcd Bcd(rtc) ; ":" ;

If Rx = 116 Then
Print Bcd(rtc) ; ":";
End If

Rtc = 0 : Rtc = Inp(16377) : Lcd Bcd(rtc)

If Rx = 116 Then
Print Bcd(rtc)
End If

Rtc = 0 : Locate 2 , 6 : Lcd " " : Locate 2 , 6


Rtc = Inp(16381) : Lcd Bcd(rtc) ; "/" ;

If Rx = 116 Then
Print ":Date " ; Bcd(rtc) ; "/";
End If

Rtc = 0 : Rtc = Inp(16382) : Lcd Bcd(rtc) ; "/" ;

file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas (8 of 10) [16-7-2000 19:52:20]


file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas

If Rx = 116 Then
Print Bcd(rtc) ; "/";
End If

Rtc = 0 : Rtc = Inp(16383) : Lcd Bcd(rtc)

If Rx = 116 Then
Print Bcd(rtc)
Rx = 0 : Ck = 0
Goto Start
End If

Waitms 20
End If

If P4.7 = 0 Then
If P4.4 = 0 Then
Ck = 0
Waitms 250
Goto Start
End If
End If

P4.4 = 1 : P4.5 = 1 : P4.6 = 1 : P4.7 = 1


Loop

End

Zero:

Out 8200 , 0 : Out 8201 , 0 : Out 8202 , 0 : Gf = 0

If Ck = 102 Then
Ck = 0 : Goto Startone
End If

Return

Saveit:

Ck = 200

If Ad > 15020 Then 'Allow for 28 days of .5


hour records
Ad = 8300
End If

Ad = Ad + 1 : Out Ad , Min
Min = Inp(16379)
Ad = Ad + 1 : Out Ad , Min
Ad = Ad + 1 : Out Ad , W2
Ad = Ad + 1 : Out Ad , W3
Ad = Ad + 1 : Out Ad , W4
Return

Adconvert:

MOV DPTR,#16192
MOV R1,#0
!Loopit:
MOV A,R1

file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas (9 of 10) [16-7-2000 19:52:20]


file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas

MOV ADCON,A
ADD A,#40
MOV ADCON,A
!ADC1:
MOV A,ADCON
JNB ACC.4,ADC1
MOV A,ADCH
MOVX @DPTR,A
PUSH ACC
!SWAP A
POP ACC
INC R1
INC DPTR
CJNE R1,#8,Loopit
Return

End

file:///F|/FrontPage Webs/Content/server/download/appnotes/flm.bas (10 of 10) [16-7-2000 19:52:20]


file:///F|/FrontPage Webs/Content/server/download/appnotes/an09.bas

'-----------------------------------------------------------------
' Copyright 1997 MCS Electronics
' this example uses library version 1.08 [14 sept 1997]
'-----------------------------------------------------------------
'Application Note 3 : controlling the X9CMME
'The X9CMME is a digital potentiometer chip From Xicor http://www.xicor.com
'
'Chip pin Function
'1 /INC increment input
'2 U/D up/down input
'3 VH potmeter high terminal
'4 VSS Ground
'5 VW potmeter wiper terminal
'6 VL potmeter low terminal
'7 /CS chip select/enable
'8 VCC power (+5V)
'The chip used is the X9C103
'The chip can be used to dim a lights or a VCO or ....
'-----------------------------------------------------------------

Dim Pulse As Byte 'byte to hold number of pulses


Dim Up As Bit 'counter direction flag

Cls 'clear lcd


' ----- define aliases -----
Incr Alias P1.1 'pin 1 of IC
Ud Alias P1.0 'pin 2 of IC
Cs Alias P3.2 'pin 7 of IC

'-------now init the chip to make sure it's value is 0


Set Cs 'disable chip
Set Incr 'ready for clock pulse
Reset Ud 'count down
Reset Up 'count down

Pulse = 100 : Gosub Sendpulse 'make sure value is 0

Do
Set Ud 'count up
Set Up 'set flag too
Pulse = 100 '100 pulses maximum
Gosub Sendpulse 'send pulses

Wait 1 'wait 1 second

Reset Ud 'count down


Reset Up 'counting up flag
Pulse = 100 '100 pulses
Gosub Sendpulse 'send pulses

Wait 1 'wait 1 second


Loop
End

'-------- subroutine to send pulse to chip


'Input : pulse holds the number of pulse to generate
'Otput : none
Sendpulse:
Dim Count As Byte 'varianle for counter
Reset Cs 'enable chip
Cls 'clear lcd

file:///F|/FrontPage Webs/Content/server/download/appnotes/an09.bas (1 of 2) [16-7-2000 19:52:36]


file:///F|/FrontPage Webs/Content/server/download/appnotes/an09.bas

'we must use a bit variable to test the direction since we can only examine
'the state of the Px.x flag if it is used as an input and we are using it as an output.
If Up = 0 Then
Lcd "Counting down" 'display direction
Else
Lcd "Counting Up"
End If

For Count = 1 To Pulse 'for all pulses


Home Lowerline 'set cursor home at line 2
Reset Incr 'generate pulse
Delay 'wait a little
Set Incr 'high again
Lcd "Value : " ; Count 'display value
Next
Set Cs 'disable chip and store value
Return

file:///F|/FrontPage Webs/Content/server/download/appnotes/an09.bas (2 of 2) [16-7-2000 19:52:36]


file:///F|/FrontPage Webs/Content/server/download/appnotes/bigdigit.bas

' BIG DIGIT THERMOMETER USING DALLAS DS1820 1WIRE SENSOR


' LCD-DISPLAY SHOWS TEMPERATURE WITH A RESOLUTION FROM 1/10 C
' UP TO 5 DIGITS CAN BE USED ON THE DISPLAY. IDEAL FOR CLOCKS,ETC...
'
' 1WIRE : P1.0 ...4K7 to VCC
'
' CODE BY RETI/BELGIUM : CONTACT ME ... rETi@nettaxi.com

$crystal = 11059200
$iramstart = &H60
$ramstart = 0
$ramsize = &H7FFF
$default Xram
$large

Config 1wire = P1.0


1wreset
Config Lcd = 20 * 4
Config Lcdbus = 4

Cursor Off
Display On
Cls

Deflcdchar 1 , 224 , 224 , 224 , 240 , 248 , 252 , 254 , 255 ' \ B
Deflcdchar 2 , 224 , 224 , 224 , 255 , 255 , 255 , 255 , 255 ' = O
Deflcdchar 3 , 255 , 255 , 255 , 255 , 254 , 252 , 248 , 240 ' !/ O
Deflcdchar 4 , 255 , 255 , 255 , 255 , 239 , 231 , 227 , 225 ' !\ O
Deflcdchar 5 , 224 , 224 , 224 , 225 , 227 , 231 , 239 , 255 ' / B
Deflcdchar 6 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ' ! N

' SYMBOL ARRAYS : INCLUDE DATA TO DISPLAY BIG DIGITS USING 6 CUSTOM LCD SYMBOLS

Dim L1(17) As String * 4 , L2(17) As String * 4 , L3(17) As String * 4 , L4(17) As String


* 4

' EACH DIGIT EXISTS OF 12 BYTES DISPLAYING EACH ONE OF THE ABOVE DEFLCDCHAR'S

' NUMBER 1
L1(1) = " " + Chr(5) + Chr(2) + " "
L2(1) = " " + " " + Chr(7) + " "
L3(1) = " " + " " + Chr(7) + " "
L4(1) = " " + " " + Chr(7) + " "
' NUMBER 2
L1(2) = Chr(5) + Chr(2) + Chr(1) + " "
L2(2) = Chr(5) + Chr(2) + Chr(3) + " "
L3(2) = Chr(6) + " " + " " + " "
L4(2) = Chr(6) + Chr(2) + Chr(2) + " "
' NUMBER 3
L1(3) = Chr(5) + Chr(2) + Chr(1) + " "
L2(3) = " " + Chr(2) + Chr(6) + " "
L3(3) = Chr(2) + " " + Chr(6) + " "
L4(3) = Chr(4) + Chr(2) + Chr(3) + " "
' NUMBER 4
L1(4) = Chr(5) + " " + Chr(2) + " "
L2(4) = Chr(6) + Chr(2) + Chr(6) + " "
L3(4) = " " + " " + Chr(6) + " "
L4(4) = " " + " " + Chr(6) + " "
' NUMBER 5
L1(5) = Chr(2) + Chr(2) + Chr(2) + " "

file:///F|/FrontPage Webs/Content/server/download/appnotes/bigdigit.bas (1 of 4) [16-7-2000 19:52:43]


file:///F|/FrontPage Webs/Content/server/download/appnotes/bigdigit.bas

L2(5) = Chr(6) + Chr(2) + Chr(1) + " "


L3(5) = Chr(2) + " " + Chr(6) + " "
L4(5) = Chr(4) + Chr(2) + Chr(3) + " "
' NUMBER 6
L1(6) = Chr(5) + Chr(2) + Chr(2) + " "
L2(6) = Chr(6) + Chr(2) + Chr(1) + " "
L3(6) = Chr(6) + " " + Chr(6) + " "
L4(6) = Chr(4) + Chr(2) + Chr(3) + " "
' NUMBER 7
L1(7) = Chr(2) + Chr(2) + Chr(2) + " "
L2(7) = " " + Chr(5) + Chr(3) + " "
L3(7) = " " + Chr(6) + " " + " "
L4(7) = " " + Chr(6) + " " + " "
' NUMBER 8
L1(8) = Chr(5) + Chr(2) + Chr(1) + " "
L2(8) = Chr(4) + Chr(2) + Chr(3) + " "
L3(8) = Chr(6) + " " + Chr(6) + " "
L4(8) = Chr(4) + Chr(2) + Chr(3) + " "
' NUMBER 9
L1(9) = Chr(5) + Chr(2) + Chr(1) + " "
L2(9) = Chr(4) + Chr(2) + Chr(6) + " "
L3(9) = " " + " " + Chr(6) + " "
L4(9) = Chr(4) + Chr(2) + Chr(3) + " "
' NUMBER 0
L1(10) = Chr(5) + Chr(2) + Chr(1) + " "
L2(10) = Chr(6) + " " + Chr(6) + " "
L3(10) = Chr(6) + " " + Chr(6) + " "
L4(10) = Chr(4) + Chr(2) + Chr(3) + " "
' DEGREE SYMBOL
L1(11) = Chr(5) + Chr(2) + Chr(1) + " "
L2(11) = Chr(4) + Chr(2) + Chr(3) + " "
L3(11) = " " + " " + " " + " "
L4(11) = " " + " " + " " + " "
' LETTER C
L1(12) = Chr(5) + Chr(2) + Chr(2) + " "
L2(12) = Chr(6) + " " + " " + " "
L3(12) = Chr(6) + " " + " " + " "
L4(12) = Chr(4) + Chr(2) + Chr(2) + " "
' LETTER F
L1(13) = Chr(5) + Chr(2) + Chr(2) + " "
L2(13) = Chr(6) + Chr(2) + Chr(2) + " "
L3(13) = Chr(6) + " " + " " + " "
L4(13) = Chr(6) + " " + " " + " "
' LETTER H
L1(14) = Chr(2) + " " + " " + " "
L2(14) = Chr(6) + Chr(5) + Chr(2) + " "
L3(14) = Chr(6) + " " + Chr(6) + " "
L4(14) = Chr(6) + " " + Chr(6) + " "
' SYMBOL :
L1(15) = " " + " " + " " + " "
L2(15) = " " + Chr(2) + " " + " "
L3(15) = " " + Chr(2) + " " + " "
L4(15) = " " + " " + " " + " "
' SYMBOL .
L1(16) = " " + " "
L2(16) = " " + " "
L3(16) = " " + " "
L4(16) = Chr(3) + " "
' UNKNOW
L1(17) = "?" + " "
L2(17) = "?" + " "

file:///F|/FrontPage Webs/Content/server/download/appnotes/bigdigit.bas (2 of 4) [16-7-2000 19:52:43]


file:///F|/FrontPage Webs/Content/server/download/appnotes/bigdigit.bas

L3(17) = "?" + " "


L4(17) = "?" + " "

Declare Sub Showstring(stri As String * 5)


Dim Stri As String * 5

Declare Sub Rd1820(valu As Single)


Dim Valu As Single

Dim E1 As String * 5
Dim E2 As String * 5
Dim E3 As String * 5

' /**** MAIN LOOP ****/


Do

Call Rd1820(valu)
E1 = Str(valu)
E2 = Left(e1 , 4)
Print E2
E3 = E2 + ""
Call Showstring(e3)

Loop
' /**** END LOOP ****/

Sub Rd1820(valu As Single)


Dim T1 As Byte , T11 As Single , T2 As Single , T3 As Single , T4 As Single , T7 As
Single , T8 As Single
Dim Ar(9) As Byte , I As Byte
Dim X1 As Const 0.25
1wreset
1wwrite &HCC ' Skip ROM command , only
one DS1820
1wwrite &H44 ' Convert Temp
1wreset
1wwrite &HCC ' Skip ROM Command
1wwrite &HBE ' Read Scratchpad command
For I = 1 To 9
Ar(i) = 1wread ' Read out 9 registers
(Bytes)
Next I
T1 = Ar(1) / 2
T11 = T1 ' Conversion of Byte to
Single
T7 = Ar(7) ' Count Remain
T8 = Ar(8) ' Counts per C
T2 = T8 - T7 ' Calculate High resolution
T3 = T2 / T8
T4 = T11 - X1
Valu = T4 + T3 ' Return Value to the Main
Program
1wreset
End Sub

Sub Showstring(stri As String * 5)


If Len(stri) > 5 Then Stri = Left(stri , 5)
Dim A1 As Byte

file:///F|/FrontPage Webs/Content/server/download/appnotes/bigdigit.bas (3 of 4) [16-7-2000 19:52:43]


file:///F|/FrontPage Webs/Content/server/download/appnotes/bigdigit.bas

Dim A2 As String * 1
Dim A3 As Byte
Dim A4 As Byte
Dim B1 As String * 20
Dim B2 As String * 20
Dim B3 As String * 20
Dim B4 As String * 20

B1 = "" : B2 = "" : B3 = "" : B4 = ""


A4 = Len(stri)
For A1 = 1 To A4
A2 = Mid(stri , A1 , 1)

Select Case A2
Case Is = "1" : A3 = 1
Case Is = "2" : A3 = 2
Case Is = "3" : A3 = 3
Case Is = "4" : A3 = 4
Case Is = "5" : A3 = 5
Case Is = "6" : A3 = 6
Case Is = "7" : A3 = 7
Case Is = "8" : A3 = 8
Case Is = "9" : A3 = 9
Case Is = "0" : A3 = 10
Case Is = "" : A3 = 11
Case Is = "C" : A3 = 12
Case Is = "c" : A3 = 12
Case Is = "F" : A3 = 13
Case Is = "f" : A3 = 13
Case Is = "H" : A3 = 14
Case Is = "h" : A3 = 14
Case Is = "X" : A3 = 15
Case Is = "." : A3 = 16
Case Else : A3 = 17
End Select

B1 = B1 + L1(a3)
B2 = B2 + L2(a3)
B3 = B3 + L3(a3)
B4 = B4 + L4(a3)

Next A1

Upperline
Lcd B1
Lowerline
Lcd B2
Thirdline
Lcd B3
Fourthline
Lcd B4

End Sub

file:///F|/FrontPage Webs/Content/server/download/appnotes/bigdigit.bas (4 of 4) [16-7-2000 19:52:43]


file:///F|/FrontPage Webs/Content/server/download/appnotes/1820.bas

' ----------------------------------------------------------------
'Author : Bojan Ivancic
' Email : nicrodesign@siol.net
' Example measuring temperature using Dallas DS1820,
' with calculated for 0.1 C resolution and with 8-bit CRC!
' ----------------------------------------------------------------

$CRYSTAL = 12000000 ' we are using this frequency

declare sub Read1820


declare sub CRCit
declare sub Temperature

dim bd(9) as byte


dim i as byte , tmp as byte
dim CRC as byte
dim T as integer , T1 as integer
dim v as byte

Config 1wire = P1.0 ' DS1820 on pin 12 (pull up)


cursor off noblink
cls

locate 1 , 1 : lcd "DEMO for DS1820"


locate 2 , 1 : lcd "T="

do
Temperature
waitms 250
loop

End

'//////////////////////////////////////////////////////////////////////////////
sub Temperature ' actual measuring

1wwrite &hcc : 1wwrite &h44 ' start measure


waitms 300 ' wait for end of conversion
Read1820 ' read 9 bytes

if Err = 1 then ' if there is no sensor


locate 2 , 4 : lcd "-- " ' we put "-- " on LCD
else
if CRC = 0 then ' sensor present, check CRC
locate 2 , 4 : lcd T ' CRC OK, print T*10 on LCD
else
locate 2 , 4 : lcd "** " ' CRC NOT OK, "** " on LCD
end if
end if
end sub

'//////////////////////////////////////////////////////////////////////////////
sub Read1820 ' reads sensor ans calculate
' T for 0.1 C
1wreset ' reset the bus
1wwrite &hcc ' read internal RAM
1wwrite &Hbe ' read 9 data bytest
bd(1) = 1wread(9) ' read bytes in array
1wreset ' reset the bus

file:///F|/FrontPage Webs/Content/server/download/appnotes/1820.bas (1 of 2) [16-7-2000 19:52:47]


file:///F|/FrontPage Webs/Content/server/download/appnotes/1820.bas

CRCit ' ckeck CRC


if CRC = 0 then ' if is OK, calculate for
tmp = bd(1) and 1 ' 0.1C precision
if tmp = 1 then decr bd(1)
T = makeint(bd(1) , bd(2))
T = T * 50 : T = T - 25 : T1 = bd(8) - bd(7) : T1 = T1 * 100
T1 = T1 / bd(8) : T = T + T1 : T = T / 10
end if
end sub

'//////////////////////////////////////////////////////////////////////////////
sub CRCit ' calculate 8 bit CRC
' bigger but faster
CRC = 0 ' needs a 256 elements table
for i = 1 to 9
tmp = CRC xor bd(i)
CRC = lookup(tmp , crc8)
next
end sub

'//////////////////////////////////////////////////////////////////////////////
crc8:
data 0 , 94 , 188 , 226 , 97 , 63 , 221 , 131 , 194 , 156
data 126 , 32 , 163 , 253 , 31 , 65 , 157 , 195 , 33 , 127
data 252 , 162 , 64 , 30 , 95 , 1 , 227 , 189 , 62 , 96
data 130 , 220 , 35 , 125 , 159 , 193 , 66 , 28 , 254 , 160
data 225 , 191 , 93 , 3 , 128 , 222 , 60 , 98 , 190 , 224
data 2 , 92 , 223 , 129 , 99 , 61 , 124 , 34 , 192 , 158
data 29 , 67 , 161 , 255 , 70 , 24 , 250 , 164 , 39 , 121
data 155 , 197 , 132 , 218 , 56 , 102 , 229 , 187 , 89 , 7
data 219 , 133 , 103 , 57 , 186 , 228 , 6 , 88 , 25 , 71
data 165 , 251 , 120 , 38 , 196 , 154 , 101 , 59 , 217 , 135
data 4 , 90 , 184 , 230 , 167 , 249 , 27 , 69 , 198 , 152
data 122 , 36 , 248 , 166 , 68 , 26 , 153 , 199 , 37 , 123
data 58 , 100 , 134 , 216 , 91 , 5 , 231 , 185 , 140 , 210
data 48 , 110 , 237 , 179 , 81 , 15 , 78 , 16 , 242 , 172
data 47 , 113 , 147 , 205 , 17 , 79 , 173 , 243 , 112 , 46
data 204 , 146 , 211 , 141 , 111 , 49 , 178 , 236 , 14 , 80
data 175 , 241 , 19 , 77 , 206 , 144 , 114 , 44 , 109 , 51
data 209 , 143 , 12 , 82 , 176 , 238 , 50 , 108 , 142 , 208
data 83 , 13 , 239 , 177 , 240 , 174 , 76 , 18 , 145 , 207
data 45 , 115 , 202 , 148 , 118 , 40 , 171 , 245 , 23 , 73
data 8 , 86 , 180 , 234 , 105 , 55 , 213 , 139 , 87 , 9
data 235 , 181 , 54 , 104 , 138 , 212 , 149 , 203 , 41 , 119
data 244 , 170 , 72 , 22 , 233 , 183 , 85 , 11 , 136 , 214
data 52 , 106 , 43 , 117 , 151 , 201 , 74 , 20 , 246 , 168
data 116 , 42 , 200 , 150 , 21 , 75 , 169 , 247 , 182 , 232
data 10 , 84 , 215 , 137 , 107 , 53

file:///F|/FrontPage Webs/Content/server/download/appnotes/1820.bas (2 of 2) [16-7-2000 19:52:47]

You might also like