GC Basic
GC Basic
GCB team
Table of Contents
Introducing Great Cow BASIC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Using GCBASIC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Command Line Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Frequently Asked Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Microcontroller Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Inputs/Outputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Lookup Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Miscellaneous . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
ReadTable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Subroutines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Converters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Command References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Analog/Digital conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
ADFormat (Deprecated - Do not use) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
ADOff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
ReadAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
ReadAD10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
EEPROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
EPRead . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
EPWrite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
ProgramErase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
ProgramRead . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
ProgramWrite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
HEFM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
HEFM Overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
HEFreadBlock. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
HEFRead . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
HEFwriteBlock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
HEFWrite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Flow control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Do . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
End . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Exit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
For . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Gosub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Goto. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
If . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
IndCall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Pause . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Repeat. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Wait . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Interrupts. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Interrupts overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
IntOff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
IntOn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
On Interrupt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
On Interrupt: The default handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Keypad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Keypad Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
KeypadData. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
KeypadRaw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Graphical LCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
GLCD Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
ILI9340 Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
KS0108 Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
PCD8544 Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
SDD1289 Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
SSD1306 Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
ST7735 Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
ST7920 Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
ST7920GLCDClearGraphics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
ST7920GLCDDisableGraphics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
ST7920GLCDEnableGraphics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
ST7920GraphicTest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
ST7920LineHs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
ST7920Locate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
ST7920Tile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
ST7920cTile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
ST7920gLocate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
ST7920gTile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
ST7920lineh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
ST7920linev . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
ST7920GLCDReadByte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
ST7920WriteByte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
ST7920WriteCommand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
ST7920WriteData . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
ST7920gReaddata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Circle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
FilledBox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
FilledCircle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
GLCDCLS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
GLCDDrawChar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
GLCDDrawString . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
GLCDPrint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
GLCDReadByte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
GLCDTimeDelay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
GLCDWriteByte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
InitGLCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Pset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Liquid Crystal Display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
LCD Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
LCD_IO 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
LCD_IO 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
LCD_IO 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
LCD_IO 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
LCD_IO 10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
LCD_IO 10 Port Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
LCD_IO 12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
LCD_IO 12 Port Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
LCD_SPEED . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
CLS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Get . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
LCDBacklight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
LCDCreateChar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
LCDCreateGraph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
LCDCmd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
LCDCursor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
LCDHex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
LCDHome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
LCDDisplayOn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
LCDDisplayOff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
LCDSpace. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
LCDWriteChar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Locate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Print . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Put . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Two Wire LCD Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Four Wire LCD Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
Eight Wire LCD Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
LCD_IO 10 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Pulse with modulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
PWM Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
PWMOut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
PWMOff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
PWMOn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
HPWM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Random Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Random . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Randomize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
7-Segment Displays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
7 Segment Displays Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Common Cathode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Common Anode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
DisplayValue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
DisplayChar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
One Wire Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
DS18B20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
ReadDigitalTemp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
ReadTemp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
ReadTemp12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
Serial Communications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
RS232 (software) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
RS232 Software Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
InitSer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
SerSend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
SerReceive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
SerPrint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
RS232 (hardware) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
RS232 Hardware Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
HSerPrint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
HSerReceive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
HSerSend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
HserPrintByteCRLF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
HserPrintCRLF. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
PS/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
PS/2 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
InKey . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
PS2SetKBLeds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
PS2ReadByte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
PS2WriteByte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
SPI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
SPIMode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
SPITransfer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
I2C Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
I2C Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
I2CAckPollState . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
I2CAckpoll . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
I2CReceive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
I2CReset. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
I2CRestart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
I2CSend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
I2CStart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
I2CStop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
I2C/TWI Hardware Module. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
HI2C Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
HI2CAckPollState . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
HI2CReceive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
HI2CRestart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
HI2CSend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
HI2CStart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
HI2CStartOccurred . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
HI2CMode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
HI2CSetAddress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
HI2CStop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
HI2CStopped . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Sound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Sound Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Tone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
ShortTone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
Timers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
Timer Overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
ClearTimer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
InitTimer0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
InitTimer1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
InitTimer2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
InitTimer3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
InitTimer4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
InitTimer6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
Settimer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
StartTimer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
StopTimer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
Reading Timers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
Variables Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
Using Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
More on setting Variables and Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
Setting Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
Dim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
BcdToDec_GCB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
DecToBcd_GCB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
Rotate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
SWAP4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
SWAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
String Manipulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
Asc. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
ByteToBin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
Chr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
Hex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
Instr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
LCase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
Left . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
Len . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
Ltrim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
Mid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
Pad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
Right . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
Rtrim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
Str . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
Trim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
UCase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
Val . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
WordToBin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
Concatenation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
Miscellaneous Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
Dir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
Pot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
PulseOutInv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
PulseIn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
PulseOut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
Peek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
Poke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
Weak Pullups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
Maths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Abs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Average . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Logarithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
Log2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
Loge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
Log10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
Power . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
Sqrt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
Trigonometry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
Compiler Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
#chip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
#config . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
#define . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
#if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
#ifdef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
#ifndef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
#include . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
#script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
#startup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
#mem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
Other directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
Compiler Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
#option bootloader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
#option NoContextSave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
#option nolatch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
Using Assembler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
Assembler Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
Macros Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
Example Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
Measuring a Pulse Width . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
Implementing a method with a Pin name as a parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
Example Programs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
Flashing LEDs and an Interrupt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
Flashing LED with timing parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
Generate Accurate Pulses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
Graphical LCD Demonstration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
InfraRed Remote . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
SonyRemote.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
Midpoint Circle Algorithm. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
IC2 Master Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
I2C Slave Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
RGB LED Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
Serial/RS232 Buffer Ring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
Sine Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
Trigonometry Circle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
Great Cow Graphical Basic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
Code Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
Windows .NET Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
GCBasic for Linux. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
Introducing Great Cow BASIC
Hello, and welcome to Great Cow BASIC help. This help file is intended to act as a backup to several
other documents - to clarify topics which may not be made clear adequately in other places.
For information on installing GCBASIC and several other programs that may be helpful, please see
Getting Started with Great Cow BASIC.
If you’re new to programming, you should try the Great Cow BASIC tutorial. This explains everything
in a step-by-step manner, and assumes no prior knowledge.
If you’ve programmed in another language, then the demonstration files and command reference may
be the best place to turn.
If there’s anything else that you need help on, please visit the Great Cow BASIC forum.
Using GCBASIC
About GCBASIC
Need to compile a program with Great Cow BASIC, but don’t know where to begin? Try these
instructions:
1. First, download and install GCBASIC. It’s best if you let everything install to its default directory
(folder).
2. Open up the folder that contains GCBASIC. This is generally C:\Program Files\GCBASIC.
3. Open the folder that contains the program you want to compile. Make sure that you open it in a
new window.
4. Drag the icon of the file you want to compile onto gcbasic.exe. The compiler will open, compile the
file, and then close again.
(1)
5. A file called compiled.hex will have been created. Download this to your microcontroller , and
you’re set to go!
Additional, more detailed instructions are available on the Getting Started with GCBASIC page.
(1)
You need a suitable programmer to do this, and instructions should be included with the
programmer on how to download to the microcontroller.
Changes
Formal Release of GBASIC.EXE 0.941 31.07.2015
• Added information on how to set address on mjkdz I2C LCD 1602 Modules
• Added new command set for second hardware I2C port. The HI2C2 command set
• Added new sub-section Compiler Options, moved options from Compiler Directives
Release 0.94b
• Added HEFM support
Release v0.91
• Added USART_TX_BLOCKING
• Added LCD_SPEED
• Improved LCD section
Release v0.9ho
• Updated parameter passing to Sub routines
• LAT has been deprecated. The compiler will redirect all I/O pin writes from PORTx to LATx
registers on PIC 16F1/18F.
Release v0.9hm
• Correct errors in PWM section and improved examples.
Release v0.9hn
• Changes to Arrays. Number of elements is now limited to 10,000 for 12F and 16F devices, or, the
available RAM.
3. constants and calculations within the single line data table entries are permitted
• New Pad command. The Pad method is used to create string to a specific length that is extended
with a specific character
v0.9hm
• Updated I2C - software and hardware. Demonstration code now uses Chipino demonstration
board. Changed to Serial I2C section with these new examples.
v0.9hl
• HSERPRINTCLRF - Added parameter to repeat the number of CRLF sent.
• Hardware I2C command set added. This is revised functionality to provide support the MSSP
module.
@0.9hk
• Help file updated to correct Power entry, it was in the incorrect section. Moved to Maths section
and other minors typos.
• Correct Timer0 information. Revised to show constants and the timer code was corrected.
@v0.9hj
• This information relates to the Hot Release 11 May 2014. Where functionality is not supported
by earlier versions of GCB please upgrade. Some functions will not work in the earlier releases
of Great Cow Basic.
@ v0.9hk
• Documented method for GCGB documentation.
Added MATHS.H
Added SQRT function.
@ v0.9hi
• Support for ST7735 documented. Functionality added to GLCD.h
• Revised GLCD section to include the one new and one undocumented device.
• Trigonometry Circles
@v0.9hg
• Corrected GLCD Common Anode display pages
@v0.9hf
• Revised 7 Segment section to support Common Cathode. Split 7 Segment entry to show the two
options available.
@v0.9he
• New commands. Required post March 2014 LCD.h:
LCDHOME, LCDSPACE, LCDCreateGraph, LCDCursor, `LCDCmd
• Added Concatenation
• Updated DisplayValue to show the support for HEX values. Required post March 2014
7Segment.h
• Updated GLCD example code to ensure the example compiled without external files.
• Updated the LCD Overview to include the LATx support for higher clock speed. Required post
March 2014 LCD.h
@v0.9hd
• Revised Rotate to clarify type supported byte types.
• Revised TABLE to show the limitation with respect to using WORDS when placing TABLES in
EEPROM
Jan 14
• New item(s):
Len, Asc, Chr, Trim, Ltrim, Rtrim, Swap4, Swap, Abs, Average, Trim, Ltrim, Rtrim, Wordtobin, Bytetobin,
GLCD, DectoBCD, BCDtoDec
Using variables
More on constants and variables
Acknowledgements
• Changes to:
Str, Hex, Poke, Else, Readtable, Exit (was exitsub)
Command line parameters Frequently asked questions
• Fixed typos.
@v0.9hg
• Corrected GLCD Common Anode display pages
@v0.9hf
• Revised 7 Segment section to support Common Cathode. Split 7 Segment entry to show the two
options available.
@v0.9he
• New commands. Required post March 2014 LCD.h:
LCDHOME, LCDSPACE, LCDCreateGraph, LCDCursor, LCDCmd
• Added Concatenation
• Updated DisplayValue to show the support for HEX values. Required post March 2014
7Segment.h
• Updated GLCD example code to ensure the example compiled without external files.
• Updated the LCD Overview to include the LATx support for higher clock speed. Required post
March 2014 LCD.h
@v0.9hd
• Revised Rotate to clarify type supported byte types.
• Revised TABLE to show the limitation with respect to using WORDS when placing TABLES in
EEPROM
• I2CRestart
Jan 14
• New item(s):
Len, sc, Chr, Trim, Ltrim, Rtrim, Swap4, Swap, Abs, Average, Trim, Ltrim, Rtrim, Wordtobin, Bytetobin,
GLCD, DectoBCD, BCDtoDec
Using variables
More on constants and variables
Acknowledgements
• Changes to:
Str, Hex, Poke, Else, Readtable, Exit (was exitsub)
Command line parameters Frequently asked questions
• Fixed typos.
/O:filename Sets the name of the assembly Same name as the input file, but
file generated to filename. with a .asm extension.
/NP Do not pause on errors. Use with Pause when an error occurs, and
IDEs. wait for the user to press a key.
(1)
For the /A: and /P: switches, there are special options available. If %FILENAME% is present, it will be
replaced by the name of the .asm file. %FN_NOEXT% will be replaced by the name of the .asm file but
without an extension, and %CHIPMODEL% will be replaced with the name of the chip. The name of the chip
will be the same as that on the chip data file.
A batch to to load the ASM from GCBASIC into MPASM. I think that your m.bat should be like this:
@ECHO OFF
echo C:\progra~1\microc~1\mpasms~1\MPASMWIN /c- /o- /q+ /l- /x- /w1 %code%.asm
C:\progra~1\microc~1\mpasms~1\MPASMWIN /c- /o- /q+ /l- /x- /w1 %code%.asm
Great Cow BASIC is a command line compiler. To compile a file, you can drag and drop it onto the
gcbasic.exe icon. There are also several Integrated Development Environments, or IDEs, available for
GCBASIC. These will give you an area where you can edit your program and a button to send the
program to the chip. Several are listed on the GCBASIC website.
Hopefully, all 8 bit PIC chips (those in the PIC10, PIC12, PIC16 and PIC18 families). If you find one that
GCBASIC does not work with properly, please post about it in the Compiler Problems section of the
GCBASIC forum. Support for Atmel AVR chips has been added.
No! For example, Set, SET, set, SeT, etc are all treated exactly the same way by GCBASIC.
No. Set variable.other variable. This does not work. GCBasic may not generate an error, but it will not
act as expected.
Because it hasn’t been thought of, or no-one has been able to implement it! If there are any features
that you would like to see in Great Cow BASIC, please post them in the "Open Discussion" section of the
GCBASIC forum. Or, if you can, have a go at adding the feature yourself!
When using include files, in this instance the <ds3231.h> include, if you are not using all the functions
of the include file, does GCB know not to include the non used functions within the include file when
compiling, or does everything get included anyway. For instance, if I am not using the hardware I2C,
does all the code related to hardware I2C still get compiled in the code?
GCBASIC only compiles functions and subroutines if they are called. GCBASIC starts by compiling the
main routine, then anything called from there. Each time it finds a new subroutine that is called, it
compiles it and anything that it calls. If a subroutine is not needed, it does not get compiled.
Acknowledgements
Developers and Contributors:
Evan Venn - Utilities, revised I2C routines and the update to this help file
Translation Contributors:
Other Contributors:
Chuck Hellebuyck - His documentation for the GLCD and other pieces, see here.
Frank Steinberg - GCB@SYN IDE for Great Cow Basic, see here.
Thomas Henry for the Select Case and the Sine Table examples, see here and here respectively.
Microcontroller Fundamentals
Inputs/Outputs
About Inputs and Outputs
Most general purpose pins on a microcontroller can function in one of two modes: input mode, or
output mode.
When acting as an input, the pin will be placed in high impedance state. The microcontroller will then
sense the pin, and the program can read the state of the pin and make decisions based on it.
When in output mode, the microcontroller will connect the pin to either Vcc (the positive supply), or
Vss (ground, or the negative supply). The program can then set the state of the pin.
GCBASIC will attempt to determine the direction of each pin, and set it appropriately. However, if the
pin is read from and written to, then then pin must be configured to input / output mode by the
program, using the appropriate Dir commands.
Configuration
About Configuration
(Note: This section does not apply to AVR microcontrollers. AVR chips do have a similar configuration
settings, but they are controlled through "Configuration Fuses". GCBASIC cannot set these - you*must*use
the programmer software.)
Every PIC chip has a CONFIG word. This is an area of memory on the chip that stores settings which
govern the operation of the chip.
The following asects of the chip are governed by the CONFIG word:
• Oscillator selection - will the chip run from an internal oscillator, or is an external one attached?
• Automatic resets - should the chip reset if the power drops too low? If it detects it is running the
same piece of code over and over?
• Code protection - what areas of memory must be kept hidden once written to?
• Pin usage - which pins are available for programming, resetting the chip, or emitting PWM signals?
The exact configuration settings vary amongst chips. To find out a list of valid settings, please consult
the datasheet for the PIC chip that you wish to use.
This can all be rather confusing - hence, GCBASIC will automatically set some config settings, unless
told otherwise:
• Low Voltage Programming (LVP) is turned off. This enables the PGM pin (usually B3 or B4) to be
used as a normal I/O pin.
• Watchdog Timer (WDT) is turned off. The WDT resets the chip if it runs the same piece of code
over and over - this can cause trouble with some of the longer delay routines in GCBASIC.
• Master Clear (MCLR) is disabled where possible. On many newer chips this allows the MCLR pin
(often PORTA.5) to be used as a standard input port. It also removes the need for a pull-up resistor
on the MCLR pin.
◦ If the PIC has an internal oscillator, and the internal oscillator is capable of generating the
speed specified in the #chip line, then the internal oscillator will be used.
◦ If the clock speed is 4 MHz or less, then the external XT oscillator mode is selected.
Note that these settings can easily be individually overridden whenever needed. For example, if the
Watchdog Timer is needed, adding the line
#config WDT = ON
This will enable the watchdog timer, without affecting any other configuration settings.
Using Configuration
Once the necessary CONFIG options have been determined, adding them to the program is easy. On a
new line type "#config" and then list the desired options separated by commas, such as in this line:
However, for upwards compatibility with 18F chips, you should use the = style config settings.
It is possible to have several #config lines in a program - for instance, one in the main program, and
one in each of several #include files. However, care must then be taken to ensure that the settings in
one file do not conflict with those in another.
Syntax
Arrays
About Arrays
An array is a special type of variable - one which can store several values at once. It is essentially a list
of numbers in which each one can be addressed individually through the use of an "index". The index
is a value in brackets immediately after the name of the array.
Array/Index Meaning
The number of elements can be number, a variable or a constant. The use of constant was
implemented at GCBASIC compiler v0.941
It is possible to set several elements of an array with a single line of code. This short example shows
how:
Dim TestVar(10)
TestVar = 1, 2, 3, 4, 5, 6, 7, 8, 9
Element 0 of TestVar will be set to the number of items in the list, which in this case is 9. Each element
of the array will then be loaded with the corresponding value in the list - so in the example, TestVar(1)
will be set to 1, TestVar(2) to 2, and so on.
If there are many items in the array, it may be better to use a Lookup Table to store the items, and then
copy some of the data items into a smaller array as needed.
Using Arrays
To use an array, its name is specified, then the index. Arrays can be used everywhere that a normal
variable can be used.
1. The 12F/16F series of chips the array limit is the physical RAM less a few bytes for array handling.
2. For the AVR or an 18F there is not limit other than free RAM.
3. However, GCBASIC limits the array size of any array to 10,000 elements.
Array RAM usage is determined by the architecture of the chip type. Getting most out of the available
memory is determined by the allocation of the array within the available banks of memory.
An example is an array of 6 or 7 bytes when there is only 24 bytes of RAM and the 24 bytes is split
across multiple memory banks. Assume in this example that 18 bytes have allocated to other variables
and there is 29 bytes total available. An array of 6 bytes will fit into the free space in one bank, but the
array of 7 will not.
GCBASIC currently cannot split an array over banks, so if there are 6 bytes free in one bank and 5 in
another, you cannot have an array of 7 bytes. This would be very hard to do efficiently on 12F/16F as
there would be a series of special function registers in the middle of the array when using a 12F or 16F.
This constraint is not the case on 16F1/18F as linear addressing makes it easy to span banks because
the SFRs are not making the problem (as with 12F/16F).
Comments
Usage:
Adding comments to your GCB program is done with an apostrophe before the comment line. You can
also comment out sections of code if you want just by placing an apostrophe, a semi-colon or use the
statement REM at the beginning of each line. The SynGCB IDE has a feature to do this automatically.
Example:
REM You can create a header using an apostrophe before each line
REM This is a great way to describe your program
REM You can also use it to describe the hardware connections.
' You can place comments above the command or on the same line
Dir PORTB Out ' Initialise PORTB to all Outputs
Conditions
About Conditions
In GCBASIC (and most other programming languages) a condition is a statement that can be either true
or false. Conditions are used when the program must make a decision. A condition is generally given as
a value or variable, a relative operator (such as = or >), and another value or variable. Several
conditions can be combined to form one condition through the use of logical operators such as AND
and OR.
GCBASIC supports these relative operators:
Symbol Meaning
= Equal
In addition, these logical operators can be used to combine several conditions into one:
NOT is slightly different to the other logical operators, in that it only needs one other condition. Other
arithmetic operators may be combined in conditions, to change values before they are compared, for
example.
GCBASIC has two built in conditions - TRUE, which is always true, and FALSE, which is always false.
These can be used to create infinite loops.
It is also possible to test individual bits in conditions. To do this, specify the bit to test, then 1 or 0 (or
ON and OFF respectively). Presently there is no way to combine bit tests with other conditions - NOT,
AND, OR and XOR will not work.
Example conditions:
Condition Comments
Mode = 1 AND Time > 10 True if Mode is 1 and Time is more than 10
Heat > 5 OR Smoke > 2 True if Heat is more than 5 or Smoke is more than
2
Condition Comments
Light >= 10 AND (NOT Time > 7) True if Light is 10 or more, and Time is 7 or less
Constants
About Defines
A define is a type of directive that tells the compiler to find a given word, and replace it with another
word or number. Defines are useful for situations where a routine needs to be easily altered. For
example, a define could be used to specify the amount of time to run an alarm for once triggered.
It is also possible to use defines to specify ports - thus defines can be used to aid in the creation of code
that can easily be adapted to run on a different PIC with different ports.
GCBASIC makes considerable use of defines internally. For instance, the LCD code uses defines to set
the ports that it must use to communicate with the LCD.
Using Defines
To create a define is a matter of using the #define directive. Here are some examples of defines:
#define Line 34
#define Light PORTB.0
#define LightOn Set PORTB.0 on
Line is a simple constant - GCBASIC will find Line in the program, and replace it with the number 34.
This could be used in a line following program, to make it easier to calibrate the program for different
lighting conditions.
Light is a port - it represents a particular pin on the PIC chip. This would be of use if the program had
many lines of code that controlled the light, and there was a possibility that the port the light was
attached to would need to change in the future.
LightOn is a define used to make the program more readable. Rather than typing Set PORTB.0 on over
and over, it would then be made possible to type LightOn, and have the compiler do the hard work.
Functions
About Functions
Functions are a special type of subroutine that can return a value. This means that when the name of
the function is used in the place of a variable, GCBASIC will call the function, get a value from it, and
then put the value into the line of code in the place of the variable.
Functions may also have parameters - these are treated in exactly the same way as parameters for
subroutines. The only exception is that brackets are required around any parameters when calling a
function.
Using Functions
This program uses a function called AverageAD to take two analog readings, and then make a decision
based on the average:
'Select chip
#chip 16F88, 20
'Define ports
#define LED PORTB.0
#define Sensor AN0
'Main code
Do
Set PORTB.0 Off
If AverageAD > 128 Then Set PORTB.0 On
wait 10 ms
Loop
Function AverageAD
'Get 2 readings, divide by 2, store in AverageAD
'Note the cast, the result of ReadAD needs to be converted to
'a word before adding, or the result may overflow.
AverageAD = ([word]ReadAD(Sensor) + ReadAD(Sensor)) / 2
end function
Labels
About Labels
Labels are used as markers throughout the program. Labels are used to mark a position in the program
to ‘jump to’ from another position using a goto, gosub or other command.
Labels can be any word (that is not already a reserved keyword) and may contain digits and the
underscore character. Labels must start with a letter or underscore (not digit), and are followed
directly by a colon (:) at the marker position. The colon is not required within the actual commands.
The compiler is not case sensitive. Lower and/or upper case may be used at any time.
Example:
'This program will flash the light until the button is pressed
'off. Notice the label named SWITCH_OFF.
#chip 16F628A, 4
Do
PulseOut LIGHT, 500 ms
If BUTTON = 1 Then Goto SWITCH_OFF
Wait 500 ms
If BUTTON = 1 Then Goto SWITCH_OFF
Loop
SWITCH_OFF:
Set LIGHT Off
'Chip will enter low power mode when program ends
Lookup Tables
About Lookup Tables
A lookup table is a list of values that are stored in the program memory of the chip, which can be
accessed using the ReadTable command.
The advantage of lookup tables is that they are memory efficient, compared to an equivalent set of IF
statements.
3. constants and calculations within the single line data table entries are permitted
Defining Tables
#define calculation_constant 2
Data tables can now be loaded directly from a file. The source file will be read as a hexidecimal raw
file.
First, the table must be created. The code to create a lookup table is simple - a line that has Table and
then the name of the table, a list of numbers (up to 10,000 elements), and then End Table.
For tables with more than 255 elements it is mandated to used a WORD variable to read the size of the
table. See below.
Once the table is created, the ReadTable command is used to read data from it. The ReadTable command
requires the name of the table it is to read, the location of the item to retrieve, and a variable to store
the retrieved number in.
Lookup tables can store byte, word, longs and integer values. GCBASIC will automatically detect the
type of the table depending on the values in it. GCBASIC can be explicitly instructed to cast the table to
a variable type, as follows:
Item 0 of a lookup table stores the size of the table. If the ReadTable command attempts to read beyond
the end of the table, the value 0 will be returned.
For tables with more than 255 elements it is mandatory to use a WORD variable to read the size of the
table. See below.
table TestDataSource
'a table with more than 255 elements
end table
For tables that are defined using an external file the table data will be read into the TestDataSource
table from the external file.
for nn = 1 to 10
ReadTable TestDataSource, nn, inc
HSerPrint inc
next
You can use the Table statement to store the data table in EEPROM. If the compiler is told to store a data
table in "Data" memory, it will store it in the EEPROM.
The limitation of of using EPPROM tables is that you can only store BYTEs. You cannot
NOTE
store WORD values in the EEPROM tables.
TableLoc = 2
ReadTable TestDataSource, TableLoc, SomeVar
Miscellaneous
Combining multiple instructions
It is possible to combine multiple instructions on a single line, by separating them with a colon. For
example, this code:
Set PORTB.0 On
Set PORTB.1 On
Wait 1 sec
Set PORTB.0 Off
Set PORTB.0 Off
In most cases, it will make no difference if commands share a line or not. However, special care should
be taken with If commands, as this code:
Also, the commands used to start and end subroutines, data tables and functions must be alone on a
line. For example, this is WRONG:
ReadTable
Syntax:
Command Availability:
Available on all microcontrollers.
Explanation:
The ReadTable command is used to read information from lookup tables. TableName is the name of the
table that is to be read, Item is the line of the table to read, and Output is the variable to write the
retrieved value in to.
Item is 1 for the first line of the table, 2 for the second, and so on. Item 0 gives the size of the table. Care
must be taken to ensure that the program is not told to read beyond the end of the table, or strange
effects will be observed.
The type of Output should match the type of data stored in the table. For example, if the table contains
Word values then Output should be a Word variable. If the type does not match, GCBASIC will attempt
to convert the value.
Example:
'Chip Settings
#chip 16F88, 20
'Hardware Settings
#define LED PORTB.0
Dir LED Out
'Main Routine
ReadTable TimesTwelve, 4, Temp
Set LED Off
If Temp = 48 Then Set LED On
Scripts
About Scripts
A script is a small section of code that Great Cow BASIC runs when it starts to compile a program. Their
main use is to perform calculations that are required to adjust the program for different speed chips.
Scripts are not compiled and downloaded to the microcontroller - GCBASIC reads them, runs them,
removes them from the program and then allows any results they have calculated to be used as
constants in the program.
Inside a script, constants are treated like variables. Scripts can read the values of constants, and set
them to contain new values.
Scripts start with #script and end with #endscript. Inside, they can consist of 3 commands:
If
Assignment (=)
Error
If is similar to the If command in normal GCBASIC code, except that it doesn’t have an Else clause. It is
used to compare the values of constants.
The = sign is identical to that in GCBASIC programs. The constant that is to be set goes on the left side of
the =, and the new value goes on the right.
Error is used to display an error message. Anything after the Error command is displayed at the end of
compilation, and is saved in the error log for the program.
Example Script
This script is used in the pwm.h file. It takes the values of the constants PWM_Freq, PWM_Duty and
ChipMHz, and uses the equations shown in the PIC datasheets to calculate the correct values for the
relevant system variables.
#script
PR2Temp = int((1/PWM_Freq)/(4*(1/(ChipMHz*1000))))
T2PR = 1
If PR2Temp > 255 Then
PR2Temp = Int((1 / PWM_Freq) / (16 * (1 / (ChipMHz * 1000))))
T2PR = 4
If PR2Temp > 255 Then
PR2Temp = Int(( 1 / PWM_Freq) / (64 * (1 / (ChipMHz * 1000))))
T2PR = 16
If PR2Temp > 255 Then
Error Invalid PWM Frequency value
End If
End If
End If
After this script has run, the values PR2Temp, DutyCycleH and DutyCycleL are used as constants to set up
the required variables.
Subroutines
About Subroutines
A subroutine is a small program inside of the main program. Subroutines are typically used when a
task needs to be repeated several times in different parts of the main program.
When the PIC comes to a subroutine it saves its location in the current program before jumping to the
start of, or calling, the subroutine. Once it reaches the end of the subroutine it returns to the main
program, and continues to run the code where it left off previously.
Normally, it is possible for subroutines to call other subroutines. There are limits to the number of
times that a subroutine can call another sub, which vary from chip to chip:
18F*, 18C* 16 31
These limits are due to the amount of memory on the PIC which saves its location before it jumps to a
new subroutine. Some GCBASIC commands are subroutines, so you should always allow for 2 or 3
subroutine calls more than your program has.
AVR microcontrollers have no fixed limit on how many subroutines can be called at a time, but if too
many are called then some variables on the chip may be corrupted. To check if there are too many
subroutines, work out the most that will be called at once, then multiply that number by 2 and create
an array of that size. If an out of memory error message comes up, there are too many calls.
Another feature of subroutines is that they are able to accept parameters. These are values that are
passed from the main program to the subroutine when it is called, and then passed back when the
subroutine ends.
Using Subroutines
To call a subroutine is very simple - all that is needed is the name of the sub, and then a list of
parameters. This code will call a subroutine named "Buzz" that has no parameters:
Buzz
If the sub has parameters, then they should be listed after the name of the subroutine. This would be
the command to call a subroutine named "MoveArm" that has three parameters:
If a subroutine has parameters, you may choose to put brackets around them, like so:
All that this does is change the appearance of the code - it doesn’t make any difference to what the code
does. Decide which one meets your own personal preference, and then stick with it.
Creating subroutines
To create a subroutine is almost as simple as using one. There must be a line at the start which has sub,
and then the name of the subroutine. Also, there needs to be a line at the end of the subroutine which
reads end sub. To create a subroutine called Buzz, this is the required code:
sub Buzz
end sub
If the subroutine has parameters, then they need to be listed after the name. For example, to define the
MoveArm sub used above, use this code:
end sub
In the above sub, ArmX, ArmY and ArmZ are all variables. If the call from above is used, the variables will
have these values at the start of the subroutine:
ArmX = NewX
ArmY = NewY
ArmZ = 10
When the subroutine has finished running, GCBASIC will copy the values back where possible. NewX
will be assigned to ArmX, and NewY will be assigned to ArmY. GCBASIC will not attempt to set the number
10 to ArmZ.
It is possible to instruct GCBASIC not to copy the value back after the subroutine is called. If a
subroutine is defined like this:
end sub
Then GCBASIC will copy the values to the subroutine, but will not copy them back.
GCBASIC can also be prevented from copying the values back, by adding Out before the parameter
name. This is used in the EEPROM reading routines - there is no point copying a data value into the
read subroutine, so Out has been used to avoid wasting time and memory. The EPRead routine is
defined as Sub EPRead(In Address, Out Data).
Many older sections of code use #NR at the end of the line where the parameters are specified. The #NR
means "No Return", and when used has the same effect as adding In before every parameter. Use of #NR
is not recommended, as it does not give the same level of control.
It is possible to use any type of variable a as parameter for a subroutine. Just add As and then the data
type to the end of the parameter name. For example, to make all of the parameters for the MoveArm
subroutine word variables, use this code:
Optional parameters
Sometimes, the same value may be used over and over again for a parameter, except in a particular
case. If this occurs, a default value may be specified for the parameter, and then a value for that
parameter only needs to be given in a call if it is different to the default.
For example, suppose a subroutine to create an error beep is required. Normally it emits ! 440 Hz tone,
but sometimes a different tone is required. To create the sub, this code would be use:
Note the Optional before the parameter, and the = 440 after it. This tells GCBASIC that if no parameter
is supplied, then set the OutTone parameter to 440.
ErrorBeep
ErrorBeep 1000
When using several parameters, it is possible to make any number of them optional. If the optional
parameter/s are at the end of the call, then no value needs to be specified. If they are at the start or in
the middle, then you must insert commas to allow GCBASIC to tell where the optional parameters are.
Overloading
It is possible to have 2 subroutines with the same name, but different parameters. This is known as
overloading, and GCBASIC will automatically select the most appropriate subroutine for each call.
An example of this is the Print routine in the LCD routines. There are actually several Print
subroutines; for example, one has a byte parameter, one a word parameter, and one a string
parameter. If this command is used:
Print 100
Then the Print (byte) subroutine will be called. However, if this command is used:
Print 30112
Then the Print (word) subroutine will be called. If there is no exact match for a particular call,
GCBASIC will use the option that requires the least conversion of variable types. For example, if this
command is used:
Print PORTB.0
The byte print will be used. This is because byte is the closest type to the single bit parameter.
Variables
About Variables
A variable is an area of memory on the microcontroller that can be used to store a number or a series
of letters. This is useful for many purposes, such as taking a sensor reading and acting on it, or
counting the number of times the robot has performed a particular task.
Each variable must be given a name, such as "MyVariable" or "PieCounter". Choosing a name for a
variable is easy - just don’t include spaces or any symbols (other than _), and make sure that the name
is at least 2 characters (letters and/or numbers) long.
Variable Types
There are several different types of variable, and each type can store a different sort of information.
These are the variable types that Great Cow BASIC can currently use:
Variable type Information that this variable Example uses for this type of
can store variable
Long A whole number between 0 and Storing very, very big numbers
32
2 (4.29 billion)
Using Variables
Byte variables do not need any special commands to set them up - just put the name of the variable in
to the command where the variable is needed.
Other types of variable can be used in a very similar way, except that they must be "dimensioned" first.
This involves using the DIM command, to tell Great Cow BASIC that it is dealing with something other
than a byte variable.
A key feature of variables is that it is possible the have the microcontroller check a variable, and only
run a section of code if it is a given value. This can be done with the IF command.
String Variables
String variables default to the following rules and the RAM constraints of a specific chip.
Defining a length for the string is the best way to limit memory usage. It is good practice if you need a
string of a certain size to set the length of a strings, since the default length for a string variable
changes depending on the amount of memory in the microcontroller (see above).
Variable Aliases
Some variables are aliases, which are used to refer to memory locations used by other variables. These
are useful for joining predefined byte variable together to form word variables.
Alias are not like pointers in many languages - they must always refer to the same variable or variables
and cannot be changed.
Casting
Casting changes the type of a variable or value. Placing the type that the value should be converted to
in square brackets will tell the compiler to convert it. For example, this will cause two byte variables to
be treated as word variables by the addition code:
Why do this? If there are no casts, then GCBASIC will add the two values using the byte addition code,
and then convert the result to a word to store in MyWord. Suppose that ByteVar is 150, and AnotherByteVar
is 231. When added, this will come to 381 - which will overflow, leaving 125 in the result. However,
when the cast is added, GCBASIC will treat ByteVar as if it were a word, and so will use the word
addition code. This will cause the correct result to be calculated.
For more help, see: Declaring variables with DIM, Setting Variables
Checking variables and doing different things based on their value, see If, Do, For, Conditions
Converters
About Converters
Converters allow GCBasic to read files that have been created by other programs. A converter can
convert these files into GCBASIC libraries or any GCBASIC instruction or a GCBasic dataset.
The use case for using a converters can be where you have a data source file another computer system.
This files could be databases, graphical, reference data or music files. The converter will read these
source files and convert into a format the can be processed by GCBasic. The conversion process is
completed by external application which can written by the developer or you can use one of the
converters provided with the GCBasic release.
The GCBasic release includes the converter for BMP files, EZ CAD files and standard Text files.
With an appropriate Converter is installed, and an associated #include to these non-GCBASIC files,
GCBasic will detect that the file extension and hand the processing to the external converting program.
When the external converting program had complete GCBasic will then continue to with the converted
source file as a GCBasic source file.
An example of an converters is to read an existing picture file, to convert the picture file to a GCB table,
then to refer to the picture file table to display the picture file on a GLCD.
Conversion is achieved by including a command within the source program to transform external
data. The command used is the instruction #include followed by the data source. An example:
#include <..\converters\ManLooking.BMP>
The inclusion of the #include line within a GCBASIC program will enable the commencement of the
following process:
1. GCBASIC will examine the ..\converters folder structure for a configuration file that will handle
the file extension specified in the include statement.
2. GCBASIC will examine the configuration file(s) *.INI for command line instructions.
3. GCBASIC will at stage examine the folder structure for the source file and the target transformed
file. If the source file is older than the transformed file the next step will not be executed, goto step
6.
4. GCBASIC will execute the command as specified within the configuration file to transform the
source file to the target file.
The Conversion program must create the output file extension as specified in the configuration file.
If the include statement as an extension of .TXT and the configuration files states the input file
extension as .TXT and the output as .GCB the converted file must have the extension of .GCB.
#include <..\converters\ManLooking.BMP>
Init file is input file as BMP and output as GCB, then the file expected is
..\converters\ManLooking.GCB
5. GCBASIC will attempt to include the transformed target file (with the file extension as specified in
the configuration file) within the GCBASIC program.
6. GCBASIC will resume normal processing of the GCBASIC program including the transformed target
file, therefore, with normal compiling and errors handling.
The configuration file MUST have the extension of .INI. No leading spaces are permitted in the
configuration file. Specification of the configuration file. The file has four items: desc, in, out and
exe. Where:
You can have multiple configuration files within the ..\converters folder structure.
GCBASIC will examine all configuration file to match the extension as specified in the #include
command.
Example 1 :
ezCircuit Designer Projects conversion configuration file is called ezcd2GCBasic.ini. The
source extension is .ezproj, the transformed file extension is .h, and the executable is called
ezcd2GCBasic.exe
Example 2 :
Example 3 :
BMP (Black and White) conversion configuration file is called BMP2GCBasic.ini. The source
extension is .bmp, the transformed file extension is .GCB, and the executable is called
BMP2GCBASIC.exe.
An example :
#include <..\converters\ManLooking.BMP>
Example 4 :
Data file conversion configuration file is called TXT2GCB.ini. The source extension is .TXT, the
transformed file extension is .GCB, and the command line called AWKRUN.BAT .
An example :
#include <..\converters\InfraRedPatterns.TXT>
The example would require a supporting batch file and a script process to complete the
transformation.
2. Conversion Executable
The conversion executable MUST create the converted file with the correct file extension as
specified in the configuration file.
The conversion executable will be passed one parameter - the source file name. Using example #3
the conversion executable would be passed ..\converters\ManLooking.BMP
The conversion executable MUST create a GCBASIC compatible source file. Any valid
commands/instruction are permitted.
3. Installation
The INI file, the source file and the conversion executable MUST be located in the ..\converters
folder. The converters folder is relative to the GCBASIC.EXE compiler folder.
#chip16f877a, 16
#include <..\converters\InfraRedPatterns.TXT>
Do Forever
For TableReadPosition = 1 to TableLen step 2
ReadTable DataSource, TableReadPosition, TransmissionPattern
ReadTable DataSource, TableReadPosition+1 , PulseDelay
portb = TransmissionPattern
wait PulseDelay ms
next
Loop
Command References
Analog/Digital conversion
ADFormat (Deprecated - Do not use)
Syntax:
Command Availability:
Left justified means 8 bits in the high byte, 2 in the low. Right justified means 2 in the high byte, and
the remaining 8 in the low byte. It’s only supported on PIC.
ADOff
This command is obsolete. There should be no need to call it. GCBASIC will automatically disable the
A/D converter and set all pins to digital mode when starting the program, and after every use of the
ReadAD function.
ReadAD
Syntax:
Command Availability:
Available on all PIC and AVR chips with an analog to digital converter module built in.
Explanation:
ReadAD is a function that can be used to read the built-in analog to digital converter that many
microcontroller chips include. port should be AN0, AN1, AN2, etc., up to the number of analog inputs
available on the chip that is in use. Those familiar with AVR microcontrollers can also refer to the ports
as ADC0, ADC1, etc. Refer to the datasheet for the microcontroller chip to find the number of ports
available. (Note: it’s perfectly acceptable to use ANx on AVR, or ADCx on PIC.)
Another function, ReadAD10, is almost identical to ReadAD. The only difference is that it returns a full 10
bit value in a word variable.
AD_Delay controls is the acquisition delay. The default value is 20 us. This can be changed by adding the
following constant.
ADSpeed controls the source of the clock for the ADC module. It varies from one chip to another.
InternalClock is a PIC only option that will drive the ADC from an internal RC oscillator. The default
value is 128.
'default value
#define ADSpeed MediumSpeed
'pre-defined constants
#define HighSpeed 255
#define MediumSpeed 128
#define LowSpeed 0
AD_VREF_DELAY controls the charging time for VRef capacitor on AVR microprocessors only. This
therefore controls the charge from internal VRef. ReadAD will not be accurate for internal reference
without this.
When selecting the reference source for ADC on ATmega328 GCBASIC will overwrite anything that you
put into te ADMUX register - but this option allow you change the ADC reference source on AVR
microprocessors. You can set the AD_REF_SOURCE constant to whatever you want to use. It defaults to
the VCC pin, as example you can set the AVR to use the 1.1V reference with this:
#define AD_REF_SOURCE AD_REF_256 ' 256 refers to the 2.56V reference on some older AVRs,
but the same code will select the 1.1V reference on an ATmega328p
Example 1:
The example above sets the AD_REF_SOURCE to a variable, and then changes the value of the variable
to select the source. With this approach, we also need to allow time to charge the reference capacitor
to the correct voltage. This capability is available from GCBASIC version 9.41.
Example 2:
This example reads the ADC port and writes the output to the EEPROM.
#chip 16F819, 8
#config osc = int
ReadAD10
Syntax:
Command Availability:
Available on all PIC and AVR chips with an analog to digital converter module built in.
Explanation:
ReadAD10 is a function that can be used to read the built-in analog to digital converter that many
microcontroller chips include. port should be AN0, AN1, AN2, etc., up to the number of analog inputs
available on the chip that is in use. Those familiar with AVR microcontrollers can also refer to the ports
as ADC0, ADC1, etc. Refer to the datasheet for the microcontroller chip to find the number of ports
available. (Note: it’s perfectly acceptable to use ANx on AVR, or ADCx on PIC.)
Another function, ReadAD is almost identical to ReadAD10. The only difference is that it returns a byte
variable.
AD_Delay controls is the acquisition delay. The default value is 20 us. This can be changed by adding the
following constant.
'default value
#define ADSpeed MediumSpeed
'pre-defined constants
#define HighSpeed 255
#define MediumSpeed 128
#define LowSpeed 0
Example:
#chip 16F819, 8
#config osc = int
EEPROM
EPRead
Syntax:
Command Availability:
Available on all PIC and AVR chips with EEPROM data memory.
Explanation:
EPRead is used to read information from the EEPROM data storage that many microcontroller chips are
equipped with. location represents the location to read data from, and varies from one chip to
another. store is the variable in which to store the data after it has been read from EEPROM.
Example:
#chip tiny2313, 1
#define Button PORTB.0
#define Light PORTB.1
Dir Button In
Dir Light Out
If LightStatus = 0 Then
Set Light Off
Else
Set Light On
End If
Do
'Wait for the button to be pressed
Wait While Button = On
Wait While Button = Off
'Toggle value, record
LightStatus = !LightStatus
EPWrite 0, LightStatus
'Update light
If LightStatus = 0 Then
Set Light Off
Else
Set Light On
End If
Loop
EPWrite
Syntax:
EPWrite location, data
Command Availability:
Available on all PIC and AVR chips with EEPROM data memory.
Explanation:
EPWrite is used to write information to the EEPROM data storage, so that it can be accessed later by a
programmer on the PC, or by the EPRead command. location represents the location to read data from,
and varies from one chip to another. data is the data that is to be written to the EEPROM, and can be a
value or a variable.
Example:
#chip 16F819, 8
#config osc = int
ProgramErase
Syntax:
ProgramErase(location)
Command Availability:
Available on all PIC chips with self write capability. Not available on AVR at present.
Explanation:
ProgramErase erases information from the program memory on chips that support this feature. The
largest value possible for location depends on the amount of program memory on the PIC, which is
given on the datasheet.
This command must be called before writing to a block of memory. It is slow in comparison to other
GCBASIC commands. Note that is erases memory in 32-byte blocks - see the relevant PIC datasheet for
more information.
This is an advanced command which should only be used by advanced developers. Care must be taken
with this command, as it can easily erase the program that is running on the PIC.
ProgramRead
Syntax:
Command Availability:
Available on all PIC chips with self write capability. Not available on AVR at present.
Explanation:
ProgramRead reads information from the program memory on chips that support this feature. location
and store are both word variables, meaning that they can store values over 255.
The largest value possible for location depends on the amount of program memory on the PIC, which
is given on the datasheet. store is 14 bits wide, and thus can store values up to 16383.
Example:
ProgramWrite
Syntax:
Command Availability:
Available on all PIC chips with self write capability. Not available on AVR at present.
Explanation:
ProgramWrite writes information to the program memory on chips that support this feature. location
and value are both word variables.
The largest value possible for location depends on the amount of program memory on the PIC, which
is given on the datasheet. value is 14 bits wide, and thus can store values up to 16383.
This is an advanced command which should only be used by advanced developers. ProgramErase must
be used to clear a block of memory BEFORE ProgramWrite is called.
Example:
HEFM
HEFM Overview
Introduction:
This section of the Help file assumes you have a release of Great Cow Basic June 2015 or later. Several
members of the PIC family, including the PIC16F14xx, PIC16F15xx and PIC16F17xx have replaced the
data EEPROM present on older models with a block of Flash memory that is designed to provide the
same high endurance (100K erase/write cycles). This high endurance flash memory (HEFM) is a block
of 128 locations found at the top of the Flash program memory. Each location can only be used to hold
a byte variable (whereas the standard Flash memory for a mid-range PIC MCU will typically hold 14
bits of information). The main difference between EEPROM and HEFM is that the former does allow
byte-by-byte erase whereas the latter does not. With HEFM data must be erased before a write and this
can only be performed in blocks (also referred as rows) of a fixed size associated with the chip design.
The heflash.h library uses as an input the following variables which are available from the chips *.dat
files supporting HEFM.
HEFreadBlock
Syntax:
Command availability:
Explanation:
HEFreadBlock reads information from the HEFM on chips that support this feature. buffer is a byte
array of length equal to count. Reading starts at the beginning of given row number
Example
#chip 16F1509, 8
; The following example reads a byte vector
; from row 0 of the HEFM of the 16F1509
dim data(32)
HEFreadBlock(data,0,HEFLASH_ROWSIZE)
HEFRead
Syntax:
HEFRead(HEFaddress, HEFDataValue)
• HEFaddress is the HEFM relative location in the whole HEFM area (i.e. a number generally
comprised between 0 and 127)
• HEFDataValue is the byte data being retrieved
Command availability:
Explanation:
This subroutine reads information from the HEFM given its relative number in the whole HEFM area.
It is the equivalent of the EPRead subroutine for EEPROM. The subroutine will compute the row
number and the offset in the row from HEFaddress and HEFLASH_ROWSIZE. It will then call the
HEFreadBlock subroutine to retrieve the byte data.
Example:
#chip 16F1509, 8
; The following example stores in the byte variable “value” the
; HEFM byte variable located in row 1 at offset 2
HEFRead(34,value)
HEFwriteBlock
Syntax:
Command availability:
Explanation:
HEFwriteBlock writes information to the HEFM on chips that support this feature. buffer is a byte
array of length equal to count. Writing starts at the beginning of the given row number.
Be aware that this subroutine will first erase whatever data are present on the
WARNING
destination row. If you want to preserve them check the HEFwrite subroutine.
Example:
#chip 16F1509, 8
; The following example generates a byte vector and stores it
; in row 0 of the HEFM of the 16F1509
dim data(32)
for index = 1 to 32
data(index)=index
next
HEFwriteBlock(0,data,HEFLASH_ROWSIZE)
;
; Now we store a string in row 1
Dim Hello as String
Hello="Hello GCB World!"
HEFwriteBlock(1,Hello,len(Hello))
HEFWrite
Syntax:
HEFWrite(HEFaddress, HEFDataValue)
• HEFaddress is the HEFM relative location in the whole HEFM area (i.e. a number generally
comprised between 0 and 127)
Command availability:
Explanation:
This subroutine writes information to the HEFM given its relative number in the whole HEFM area. It
is the equivalent of the EPWrite subroutine for EEPROM. The subroutine will compute the row number
and the offset in the row from HEFaddress and HEFLASH_ROWSIZE. It will then call the
HEFWriteBlock subroutine to store the byte data.
Example:
#chip 16F1509, 8
; The following example stores in the byte variable “value” the
; HEFM byte variable located in row 1 at offset 2
HEFWrite(34,value)
Flow control
Do
Syntax:
Command Availability:
Explanation:
The Do command will cause the code between the Do and the Loop to run repeatedly while condition is
true or until condition is true, depending on whether While or Until has been specified.
Note that the While or Until and the condition can only be specified once, or not at all. If they are not
specified, then the code will repeat endlessly.
Example 1:
Dir BUTTON In
Dir LIGHT Out
Do Until BUTTON = 1
PulseOut LIGHT, 1 s
Wait 1 s
Loop
Example 2:
This code will also flash a light until the button is pressed. This example uses EXIT DO within a
continuous loop.
#chip 12F629, 4
#config osc = int
Dir BUTTON In
Dir LIGHT Out
Do
PulseOut LIGHT, 1 s
Wait 1 s
if BUTTON = 1 then EXIT DO
Loop
End
Syntax:
End
Command Availability:
Explanation:
When the End command is used, the program will immediately stop running. There are very few cases
where this command is needed - generally, the program should be an endless loop.
Example:
'This program will turn on the red light, but not the green light
Set RED On
End
Set GREEN On
Exit
Syntax options:
Command Availability:
Explanation:
This command will make the program exit the routine it is currently in, as it would if it came to the end
of the routine.
Applies to Subroutines, Functions, For-Next loops, Do-Loop loops and Repeat loops.
Example:
#chip tiny13, 1
Do
Burglar
Loop
Syntax:
Command Availability:
Explanation:
The For command is ideal for situations where a piece of code needs to be run a set number of times,
and where it is necessary to keep track of how many times the code has run. When the For command is
first executed, counter is set to start. Then, each successive time the program loops, increment is added
to counter, until counter is equal to end. Then, the program continues beyond the Next.
Step and increment are optionals. If Step is not specified, GCBASIC will increment counter by 1 each time
the code is run.
The Exit For is optional and can used to exit the loop upon a specific condition.
Example 1:
Example 2:
'This code will flash alternate LEDS until the switch is pressed.
+
#chip 16F88, 8
#config Osc = Int
Gosub
Syntax:
Gosub label
Command Availability:
Explanation:
The Gosub command is used to jump to a label as a subroutine, in a similar way to Goto. The difference
is that Return can then be used to return to the line of code after the Goto.
Gosub should not be used if it can be avoided. It is not required to call a subroutine that
NOTE
has been defined using Sub, just write the name of the subroutine.
Example:
'This program will flash an LED on portb bit 0 and play a beep on
'porta bit 4. until the robot is turned off.
Do
'Flash Light
PulseOut LIGHT, 1 s
Wait 1 s
'Beep
Gosub PlayBeep
Loop
PlayBeep:
Tone 200, 10
Tone 100, 10
Return
Goto
Syntax:
Goto label
Command Availability:
Explanation:
The Goto command will make the robot jump to the line specified, and continue running the program
from there. The Goto command is mainly useful for exiting out of loops - if you need to create an
infinite loop, use the Do command instead.
Be careful how you use Goto. If used too much, it can make programs very hard to read.
To define a label, put the name of the label alone on a line, with just a colon (:) after it.
Example:
'This program will flash the light until the button is pressed
'off. Notice the label named SWITCH_OFF.
Do
PulseOut LIGHT, 500 ms
If BUTTON = 1 Then Goto SWITCH_OFF
Wait 500 ms
If BUTTON = 1 Then Goto SWITCH_OFF
Loop
SWITCH_OFF:
Set LIGHT Off
'Chip will enter low power mode when program ends
If
Syntax:
Short form:
If condition Then command
Long form:
If condition Then
...
program code
...
End If
Using Else:
If condition Then
code to run if true
Else
code to run if false
End If
Command Availability:
Available on all microcontrollers.
Explanation:
The If command is the most common command used to make decisions. If condition is true, then
command (short) or program code (long) will be run. If it is false, then the robot will skip to the code
located on the next line (short) or after the End If (long form).
If Else is used, then the condition between If and Else will run if the condition is true, and the code
between Else and End If will run if the condition is false.
Supported:
<instruction>
Else
<instruction>
<instruction> Else
<instruction>
Example:
'Turn a light on or off depending on a light sensor
#chip 12F683, 8
#config osc = int
Do
If ReadAD(SENSOR) > 128 Then
Set LIGHT Off
Else
Set LIGHT On
End If
Loop
IndCall
Syntax:
IndCall Address
Command Availability:
Explanation:
IndCall provides a basic implementation of function pointers. Address is the program memory location
of the subroutine that is to be called. There are two ways to specify this - either by providing a direct
reference to the subroutine using the @ operator, or by specifying a word variable that contains the
address.
This command is useful for callbacks. For example, a particular subroutine might read bytes from a
serial connection, but different actions may need to be taken at different times. A different subroutine
could be created for each action, and then the subroutine for the appropriate action could be passed to
the serial connection reading routine each time it is called.
Calling subroutines that have parameters using IndCall is not supported. Errors
WARNING
may occur. If data needs to be passed, use a variable instead.
Example:
'Main loop
Do
'Indirect call to subroutine at location FlashingSub
IndCall FlashingSub
Loop
Pause
Syntax:
Command Availability:
Explanation:
The Pause command will cause the program to wait for either a specified amount of time in
milliseconds.
Repeat
Syntax:
Repeat times
...
program code
...
<condition> Exit Repeat
...
End Repeat
Command Availability:
Explanation:
The Repeat command is ideal for situations where a piece of code needs to be run a set number of
times. It uses less memory and runs faster than the For command, and should be used wherever it is
not necessary to count how many times the code has run.
Example:
#chip 16F88, 20
Repeat 6
PulseOut LED, 1 s
Wait 1 s
End Repeat
Select
Syntax:
Select Case var
Case value1
code1
Case value2
code2
Case Else
code3
End Select
Command Availability:
Explanation:
The Select Case control structure is used to select and run a particular section of code, based on the
value of var. If var equals value1 then code1 will be run. Once code1 has run, the chip will jump to the
End Select command and continue running the program. If none of the other conditions are true, then
the code under the Case Else section will be run.
Case Else is optional, and the program will function correctly without it.
If there is only one line of code after the Case, the code may look neater if the line is placed after the
Case. This is shown below in the example, for cases 3, 4 and 5.
It is important to note that only one section of code will be run when using Select Case.
Example 1:
'Program to read a value from a potentiometer, and display a
'different word based on the result
#chip 18F4550, 20
DIR PORTA.0 IN
Do
Temp = ReadAD(AN0) / 20
CLS
Select Case Temp
Case 0
Print "None!"
Case 1
Print "One"
Case 2
Print "Two"
Case 3: Print "Three"
Case 4: Print "Four"
Case 5: Print "Five"
Case Else
Print "A lot!"
End Select
Wait 250 ms
Loop
Example 2:
This code demonstrates how to receive codes from a handheld remote control unit. This has been
tested and supports a Sony TV remote and also a universal remote set to Sony TV mode.
The program gets both the device number and the key number, and also translates the key number to
English. The received results are displayed on an LCD.
The circuit for the IR receiver and the chip is shown below.
;----- Constants
;----- Variables
;----- Program
do
getIR, cmd ;wait for IR signal
printCmd ;show device and command
printKey ;show key label
wait 10 mS ;ignore any repeats
loop ;repeat forever
;----- Subroutines
sub getIR
tarry1:
count = 0 ;wait for start bit
do while IR = 0 ;measure width (active low)
wait 100 uS ;24 X 100 uS = 2.4 mS
count += 1
loop
if count < 20 then goto tarry1 ;less than this so wait
Wait
Syntax:
Conditional Delay:
Wait {While | Until} condition
Command Availability:
Explanation:
The Wait command will cause the program to wait for either a specified amount of time (such as 1
second), or while/until a condition is true.
When using the fixed-length delay, there is a variety of units that are available:
Unit Length of unit Delay range
us 1 microsecond 1 us - 65535 us
ms 1 millisecond 1 ms - 65535 ms
s 1 second 1 s - 255 s
At one stage, GCBASIC variables could not hold more than 255. The 10us and 10ms units were added as a
way to work around this limit. There is now no such limit (Wait 1000 ms will work for example), so
these are not really needed. However, you may see them in some older examples or programs, and the
10us units are sometimes the shortest delay that will work accurately.
Example:
'This code will wait until a button is pressed, then it will flash
'a light every half a second and produce a 440 Hz tone.
#chip 16F819, 8
#config osc = int
Do
'Flash the light
Set LIGHT On
Wait 500 ms
Set LIGHT Off
Interrupts
Interrupts overview
Introduction
Interrupts are a feature of many microcontrollers. They allow the microcontroller to temporarily
pause (interrupt) the code it is running and then start running another piece of code when some event
occurs. Once it has dealt with the event, it will return to where it was and continue running the
program.
Many events can trigger an interrupt, such as a timer reaching its limit, a serial message being
received, or a special pin on the microcontroller receiving a signal.
Using Interrupts
There are two ways to use interrupts in GCBASIC. The first way is to use the On Interrupt command.
This will automatically enable a given interrupt, and run a particular subroutine when the interrupt
occurs.
The other way to deal with interrupts is to create a subroutine called Interrupt. GCBASIC will call this
subroutine whenever an interrupt occurs, and then your code can check the "flag" bits to determine
which interrupt has occured, and what should be done about it. If you use this approach, then you’ll
need to enable the desired interrupts manually. It is also essential that your code clears the flag bits, or
else the interrupt routine will be called repeatedly.
Some combination of these two methods is also possible - the code generated by On Interrupt with
check to see if the interrupt is one it recognises. If the interrupt is recognised, On Interrupt will deal
with it - if not, the Interrupt subroutine will be called to deal with the interrupt.
The recommended way is to use On Interrupt, as it is both more efficient and easier to set up.
During some sections of code, it is desirable not to have any interrupts occur. If this is the case, then
use the IntOff command to disable interrupts at the start of the section, and IntOn to re-enable them at
the end. If any interrupt events occur while interrupts are disabled, then they will be processed as
soon as interrupts are re-enabled. If the program does not use interrupts, IntOn and IntOff will be
removed automatically by GCBASIC.
IntOff
Syntax:
IntOff
Command Availability:
Available on PIC and AVR microcontrollers with interrupt support. Will be automatically removed on
chips without interrupts.
Explanation:
IntOff is used to disable interrupts on the microcontroller. It should be used at the start of code which
is timing-sensitive, and which would not function correctly if paused and restarted.
It is essential that IntOn is used to turn interrupts on again after the timing-sensitive code has finished
running. If not, no interrupts will be handled.
IntOff will be removed from the program if no interrupts are used. It is recommended that IntOff be
placed before all code that is timing sensitive, in case interrupts are implemented later.
IntOn
Syntax:
IntOn
Command Availability:
Available on PIC and AVR microcontrollers with interrupt support. Will be automatically removed on
chips without interrupts.
Explanation:
IntOn is used to enable interrupts on the microcontroller after IntOff has disabled them. It should be
used at the end of code which is timing-sensitive.
On Interrupt
Syntax:
Command Availability:
Explanation:
On Interrupt will add code to call the subroutine handler whenever the interrupt event occurs. When
Call is specified, GCBASIC will enable the interrupt, and call the interrupt handler when it occurs.
When Ignore is specified, GCBASIC will disable the interrupt handler and prevent it from being called
when the event occurs. If the event occurs while the handler is disabled, then the handler will be
called as soon as it is re-enabled. The only way to prevent this from happening is to manually clear the
flag bit for the interrupt.
There are many possible interrupt events that can occur, and the events vary greatly from chip to chip.
GCBASIC will display an error if a given chip cannot support the specified event.
In some cases, On Interrupt will not be able to set or clear the interrupt flag and/or enable bits. If this is
the case, GCBASIC will display a warning. You will need to consult the chip datasheet and use the Set
command to manually set/clear the flag and enable bits, both at the start of the program and inside the
interrupt handler subroutine. If On Interrupt is used to handle an event, then the Interrupt subroutine
will not be called for that event. However, it will still be called for any events not dealt with by On
Interrupt.
Events:
GCBASIC supports the events shown on the table below. Some events are only implemented on a few
specialised chips. Events in grey are supported by PICs and AVRs, events in blue are only supported by
some PICs, and events in red are only supported by AVRs.
Note that GCBASIC doesn’t fully support all of the hardware which can generate interrupts - some work
may be required with various system variables to control the unsupported peripherals.
PWMTimeBase The PWM time base matches the PWM Time Base
Period register (PTPER)
Example:
'This program increments a counter every time Timer1 overflows
#chip 16F877A, 20
Wait 100 ms
Print "Int Test"
Do
CLS
Print CounterValue
Wait 100 ms
Loop
Sub IncCounter
CounterValue ++
End Sub
For more help, see InitTimer0 article contains an example of using Timer 0 and On Interrupt to
generate a Pulse Width Modulation signal to control a motor.
Introduction
1. You can define the interrupt flags and the default handler (a sub routine) will executed
2. You can define an On Interrupt event Call handler where the handler is executed that matches the
event and where all other define/valid events are handled by the default handler (a sub routine),
The easiest way to write an interrupt handler is to write it in GCBasic in conjunction with the On
Interrupt statement. On Interrupt tells microprocessor to activate its internal interrupt handling
and to jump to a predetermined interrupt handler (a sub routine that has been defined) when the
interrupt handler (the sub routine) has completed processing returns to correct address in the
program. See On Interrupt.
This method of supports the handling interrupts by enabling a default interrupt subroutine.
Example 1
Basically if an event occurs the microprocessor will be program to jump to the interrupt vector and the
compiler does not know why, it will simple execute the Interrupt subroutine. This code is not intended
as a meaningful solution.
#chip 16f877a, 4
Set PORTB.0 On
Sub Interrupt
Set PORTB.1 On
TMR1IF = 0
End Sub
Example 2
Any events that are not dealt with by On Interrupt will result in the code in the Interrupt subroutine
executing. This example shows the operation of two interrupt handlers - is not intended as a
meaningful solution.
#chip 16f877a, 4
On Interrupt Timer1Overflow call Overflowed
Set PORTB.0 On
Sub Interrupt
Set PORTB.2 On
TMR2IF = 0
End Sub
Sub Overflowed
Set PORTB.1 On
TMR1IF = 0
End Sub
Keypad
Keypad Overview
Introduction
The keypad routines allow for a program to read from a 4 x 4 matrix keypad.
There are two ways that the keypad routines can be set up. One option is to connect the wires from the
keypad in a particular order, and then to set the KeypadPort constant. The other option is to connect
the keypad in whatever way is easiest, and then set the KEYPAD_ROW_x and KEYPAD_COL_x constants. The
first option (setting KeypadPort) will generate slightly more efficient code.
When setting up the keypad code using the KeypadPort constant, only KeypadPort needs to be set.
Pull-ups or pull-downs go on the columns only, and are typically 4.7k to 10k in value.
The keypad routine has a feature when using pull-down resistors, simply add the constant to your
program and the and the scan logic will be inverted appropriately.
Constant Name Controls Default Value
0 Row 1
1 Row 2
2 Row 3
3 Row 4
4 Column 1
5 Column 2
6 Column 3
7 Column 4
Note: To use a 3 x 3 keypad in this mode, the pins on the microcontroller for any unused columns must
be pulled up.
KeypadData
Syntax:
var = KeypadData
Command Availability:
Explanation:
This function will return a value corresponding to the key that is pressed on the keypad. Note that if
two or more keys are pressed, then only one value will be returned. var can have one of the following
values:
0 0
1 1
2 2
Value Constant Name Key Pressed
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 KEY_A A
11 KEY_B B
12 KEY_C C
13 KEY_D D
Example:
'Program to show the value of the last pressed key on the LCD
#chip 18F4550, 20
'Main loop
Do
'Get key
Temp = KeypadData
KeypadRaw
Syntax:
largevar = KeypadRaw
Command Availability:
Explanation:
This function will return a 16 bit value, in which each bit corresponds to a key on the keypad. If the key
is pressed its bit will hold 1, and if it is released its bit will contain a 0.
This table shows the key that each bit corresponds to:
15 1,1 1
14 1,2 2
13 1,3 3
12 1,4 A
11 2,1 4
10 2,2 5
9 2,3 6
8 2,4 B
7 3,1 7
6 3,2 8
5 3,3 9
4 3,4 C
3 4,1 *
2 4,2 0
1 4,3 #
0 4,4 D
Example:
'Program to show the keypad status using LEDs
#chip 16F877A, 20
'LEDs
#define LED1 PORTC
#define LED2 PORTD
Dir LED1 Out
Dir LED2 Out
'Main loop
Do
'Get key
KeyStatus = KeypadRaw
'Display
LED1 = KeyStatus_H 'High Byte
LED2 = KeyStatus 'Low Byte
Loop
Graphical LCD
GLCD Overview
The GLCD commands are used to control a graphical Liquid Crystal Display based on the three GLCD
chipset. These are often 128x64 pixel displays. They can draw graphical elements by enabling or
disabling pixels.
The GLCD with back-lit pixels. These GLCD are a graphical upgrade to the popular 16x2 LCDs (see
Liquid Crystal Display Overview ) but the GLCD allows full graphical control of the display. Typical
displays are
KS0108 controllers, see KS0108 Controllers. ST7735 controllers, see ST7735 Controllers. ST7920
controllers, see ST7920 Controllers.
Great Cow Basic makes this type of device easier to control with the commands for the GLCD.
Setup:
You must include the glcd.h file at the top of your program. The file needs to be in brackets as shown
below.
#include <GLCD.h>
Defines:
There are several connections that must be defined to use the GLCD commands with a KS0108 display.
The I/O pin is the pin on the PIC Microcontroller that is connected to that specific pin on the graphic
LCD.
For more help, see KS 0108 controllers, ST7735 Controllers and ST7920 Controllers
This example shows how to drive a KS0108 based Graphic LCD module with the built in commands of
Great Cow Basic. See Graphic LCD for details, this is an external web site.
;Chip Settings
#chip 16F886,16
'#config MCLRE = on 'enable reset switch on CHIPINO
#include <GLCD.h>
;Defines (Constants)
#define GLCD_RW PORTB.1 'D9 to pin 5 of LCD
#define GLCD_RESET PORTB.5 'D13 to pin 17 of LCD
#define GLCD_CS1 PORTB.3 'D12 to actually since CS1, CS2 are backward
#define GLCD_CS2 PORTB.4 'D11 to actually since CS1, CS2 are backward
#define GLCD_RS PORTB.0 'D8 to pin 4 D/I pin on LCD
#define GLCD_ENABLE PORTB.2 'D10 to Pin 6 on LCD
#define GLCD_DB0 PORTC.7 'D0 to pin 7 on LCD
#define GLCD_DB1 PORTC.6 'D1 to pin 8 on LCD
#define GLCD_DB2 PORTC.5 'D2 to pin 9 on LCD
#define GLCD_DB3 PORTC.4 'D3 to pin 10 on LCD
#define GLCD_DB4 PORTC.3 'D4 to pin 11 on LCD
#define GLCD_DB5 PORTC.2 'D5 to pin 12 on LCD
#define GLCD_DB6 PORTC.1 'D6 to pin 13 on LCD
#define GLCD_DB7 PORTC.0 'D7 to pin 14 on LCD
InitGLCD
Start:
GLCDCLS
GLCDPrint 0,10,"Hello" 'Print Hello
wait 5 s
GLCDPrint 0,10, "ASCII #:" 'Print ASCII #:
Box 18,30,28,40 'Draw Box Around ASCII Character
for char = 15 to 129 'Print 0 through 9
GLCDPrint 17, 20 , Str(char)+" "
GLCDdrawCHAR 20,30, char
wait 125 ms
next
line 0,50,127,50 'Draw Line using line command
for xvar = 0 to 80 'draw line using Pset command
pset xvar,63,on '
next '
Wait 1 s
GLCDPrint 0,10,"End " 'Print Hello
wait 1 s
Goto Start
For more help, see Graphical LCD Demonstration, InitGLCD, GLCDCLS, GLCDDrawChar, GLCDPrint,
GLCDReadByte, GLCDWriteByte, Pset
ILI9340 Controllers
See below for an example of using the ILI9340 GLCD. This section contains the relevant information for
this type of device.
The Great Cow Basic constants for control of the connectivity are shown in the table below. The only
connectivity option the serial mode where connection between the microcomputer and the GLCD to
control the data bus is managed the data in and data out lines.
#include <glcd.h>
#DEFINE GLCD_TYPE GLCD_TYPE_ILI9340
GLCD_TYPE GLCD_TYPE_ILI9340
The Great Cow Basic constants for control display characteristics are shown in the table below.
The Great Cow Basic commands supported for this GLCD are shown in the table below.
GLCDDrawChar Print character on GLCD using GCB font GLCDDrawChar( Xposition, Yposition,
set CharCode )
This example shows how to drive a ILI9340 based Graphic LCD module with the built in commands of
Great Cow Basic.
Example:
;Chip Settings
#chip 16F1937,32
#config Osc = INT, VCAPEN_OFF, MCLRE_ON, PLLEN_ON, CLKOUTEN_OFF
#include <glcd.h>
For more help, see Graphical LCD Demonstration, InitGLCD, GLCDCLS, GLCDDrawChar, GLCDPrint,
GLCDReadByte, GLCDWriteByte, Pset
Supported in <GLCD.H>
KS0108 Controllers
See below for an example of using the KS0108 GLCD. This section contains the relevant information for
this type of device.
The Great Cow Basic constants for control of the connectivity are shown in the table below. The only
connectivity option the 8-bit mode where 8 pins are connected between the microcomputer and the
GLCD to control the data bus.
#include <glcd.h>
#DEFINE GLCD_TYPE GLCD_TYPE_KS0108
GLCD_RW Specifies the output pin that is Must be set (unless R/W is disabled)
connected to Read/Write on the GLCD. see GLCD_NO_RW
The R/W pin can be disabled.
GLCD_NO_RW Disables read/write inspection of the Optional, but recommend NOT to set.
device during read/write operations The R/W pin can be disabled by setting
the GLCD_NO_RW constant. If this is done,
there is no need for the R/W to be
connected to the chip, and no need for
the LCD_RW constant to be set. Ensure
that the R/W line on the LCD is
connected to ground if not used.
The Great Cow Basic constants for control display characteristics are shown in the table below.
Constants Controls Default
The Great Cow Basic commands supported for this GLCD are shown in the table below.
;Chip Settings
#chip 16F886,16
'#config MCLRE = on 'enable reset switch on CHIPINO
#include <GLCD.h>
;Defines (Constants)
#define GLCD_RW PORTB.1 'D9 to pin 5 of LCD
#define GLCD_RESET PORTB.5 'D13 to pin 17 of LCD
#define GLCD_CS1 PORTB.3 'D12 to actually since CS1, CS2 can be reversed on some devices
#define GLCD_CS2 PORTB.4 'D11 to actually since CS1, CS2 can be reversed on some devices
#define GLCD_RS PORTB.0 'D8 to pin 4 D/I pin on LCD
#define GLCD_ENABLE PORTB.2 'D10 to Pin 6 on LCD
#define GLCD_DB0 PORTC.7 'D0 to pin 7 on LCD
#define GLCD_DB1 PORTC.6 'D1 to pin 8 on LCD
#define GLCD_DB2 PORTC.5 'D2 to pin 9 on LCD
#define GLCD_DB3 PORTC.4 'D3 to pin 10 on LCD
#define GLCD_DB4 PORTC.3 'D4 to pin 11 on LCD
#define GLCD_DB5 PORTC.2 'D5 to pin 12 on LCD
#define GLCD_DB6 PORTC.1 'D6 to pin 13 on LCD
#define GLCD_DB7 PORTC.0 'D7 to pin 14 on LCD
InitGLCD
Start:
GLCDCLS
GLCDPrint 0,10,"Hello" 'Print Hello
wait 5 s
GLCDPrint 0,10, "ASCII #:" 'Print ASCII #:
Box 18,30,28,40 'Draw Box Around ASCII Character
for char = 15 to 129 'Print 0 through 9
GLCDPrint 17, 20 , Str(char)+" "
GLCDdrawCHAR 20,30, char
wait 125 ms
next
line 0,50,127,50 'Draw Line using line command
for xvar = 0 to 80 'draw line using Pset command
pset xvar,63,on '
next '
Wait 1 s
GLCDPrint 0,10,"End " 'Print Hello
wait 1 s
Goto Start
For more help, see Graphical LCD Demonstration, InitGLCD, GLCDCLS, GLCDDrawChar, GLCDPrint,
GLCDReadByte, GLCDWriteByte, Pset
Supported in <GLCD.H>
PCD8544 Controllers
See below for an example of using the PCD844 GLCD display device. This section contains the relevant
information for this type of device.
The Great Cow Basic constants for control of the connectivity are shown in the table below. The only
connectivity option the serial mode where connection between the microcomputer and the GLCD to
control the data bus is managed the data in and data out lines.
#include <glcd.h>
#DEFINE GLCD_TYPE GLCD_TYPE_PCD8544
GLCD_TYPE GLCD_TYPE_PCD8544
GLCD_DATA_PORT Not Available for this controller Not applicable
The Great Cow Basic constants for control display characteristics are shown in the table below.
The Great Cow Basic commands supported for this GLCD are shown in the table below.
This example shows how to drive a PCD8544 based Graphic LCD module with the built in commands of
Great Cow Basic.
Example:
#chip 16lf1939,32
#config Osc = INT, MCLRE_ON, PLLEN_Off, CLKOUTEN_OFF
#include <glcd.h>
GLCDCLS
DO forever
for CCount = 31 to 127
GLCDPrint (0, 0, "PrintStr")
GLCDDrawString (0, 9, "DrawStr")
GLCDPrint ( 44 , 21, " ")
GLCDPrint ( 44 , 29, " ") ' word value
GLCDPrint ( 44 , 37, " ") ' Byte value
box 46,9,57,19
GLCDDrawChar(48, 9, CCount )
outString = str( CCount )
' draw a box to overwrite existing strings
FilledBox(58,9,GLCD_WIDTH-1,17,GLCDBackground )
GLCDDrawString(58, 9, outString )
longNumber = longNumber + 7
wordNumber = wordNumber + 3
byteNumber++
NEXT
LOOP
end
SDD1289 Controllers
See below for an example of using the SDD1289 GLCD. This section contains the relevant information
for this type of device.
The Great Cow Basic constants for control of the connectivity are shown in the table below. The only
connectivity option the serial mode where connection between the microcomputer and the GLCD to
control the data bus is managed the data in and data out lines.
GLCD_TYPE GLCD_TYPE_SDD1289
The Great Cow Basic constants for control display characteristics are shown in the table below.
The Great Cow Basic commands supported for this GLCD are shown in the table below.
GLCDDrawChar Print character on GLCD using GCB font GLCDDrawChar( Xposition, Yposition,
set CharCode )
This example shows how to drive a SDD1289 based Graphic LCD module with the built in commands of
Great Cow Basic.
Example:
;Chip Settings
#chip 16F1937,32
#config Osc = INT, VCAPEN_OFF, MCLRE_ON, PLLEN_ON, CLKOUTEN_OFF
#include <glcd.h>
For more help, see Graphical LCD Demonstration, InitGLCD, GLCDCLS, GLCDDrawChar, GLCDPrint,
GLCDReadByte, GLCDWriteByte, Pset
Supported in <GLCD.H>
SSD1306 Controllers
See below for an example of using the SSD1306 GLCD. This section contains the relevant information
for this type of device.
The Great Cow Basic constants for control of the connectivity are shown in the table below. The only
connectivity option is I2C BUS. I2C is the connectivity between the microcomputer and the GLCD to
control the data bus.
To use the SSD1306 drivers simply include the following. The I2C setup/configuration commands must
be included.
#include <glcd.h>
The Great Cow Basic constants for control display characteristics are shown in the table below.
The Great Cow Basic specific commands for this GLCD are shown in the table below.
Command Purpose
Startscrollright_SSD1306 ( start , stop Activate a right handed scroll for rows start
[,scrollspeed] ) through stop Hint, the display is 16 rows tall. To
scroll the whole display, execute:
startscrollright_SSD1306(0x00, 0x0F)
Parameters are Start row, End row, optionally
Scrollspeed
Command Purpose
Startscrollleft_SSD1306 ( start , stop Activate a left handed scroll for rows start
[,scrollspeed] ) through stop Hint, the display is 16 rows tall. To
scroll the whole display, execute:
startscrollleft_SSD1306(0x00, 0x0F)
Parameters are Start row, End row, optionally
Scrollspeed
Startscrolldiagright_SSD1306 ( start , stop Activate a diagright handed scroll for rows start
[,scrollspeed] ) through stop Hint, the display is 16 rows tall. To
scroll the whole display, execute:
startscrolldiagright_SSD1306(0x00, 0x0F)
Parameters are Start row, End row, optionally
Scrollspeed
Startscrolldiagleft_SSD1306 ( start , stop Activate a diagleft handed scroll for rows start
[,scrollspeed] ) through stop Hint, the display is 16 rows tall. To
scroll the whole display, execute:
startscrolldiagleft_SSD1306(0x00, 0x0F)
Parameters are Start row,End row, optionally
Scrollspeed
SetContrast_SSD1306 ( in dim_state ) Sets the constrast to select 1 out of 256 contrast
steps. Contrast increases as the value increases.
Parameter is dim value
This example shows how to drive a SSD1306 based Graphic LCD module with the built in commands of
Great Cow Basic.
; ----- Configuration
#chip mega328p,16
#include <glcd.h>
GLCDCLS
GLCDPrint 0, 0, "Great Cow Basic"
GLCDPrint (0, 16, "Anobium 2015")
wait 3 s
GLCDCLS
DO forever
for CCount = 31 to 127
GLCDPrint ( 64 , 36, hex(longNumber_E ) ) ; Print a HEX string
GLCDPrint ( 76 , 36, hex(longNumber_U ) ) ; Print a HEX string
GLCDPrint ( 88 , 36, hex(longNumber_H ) ) ; Print a HEX string
GLCDPrint ( 100 , 36, hex(longNumber ) ) ; Print a HEX string
GLCDPrint ( 112 , 36, "h" ) ; Print a HEX string
Supported in <GLCD.H>
ST7735 Controllers
See below for an example of using the ST7735 GLCD. This section contains the relevant information for
this type of device.
The Great Cow Basic constants for control of the connectivity are shown in the table below. The only
connectivity option the serial mode where connection between the microcomputer and the GLCD to
control the data bus is managed the data in and data out lines.
#include <glcd.h>
#DEFINE GLCD_TYPE GLCD_TYPE_ST7735
GLCD_TYPE GLCD_TYPE_ST7735
GLCD_DATA_PORT Not Available for this controller. Not applicable.
The Great Cow Basic constants for control display characteristics are shown in the table below.
The Great Cow Basic commands supported for this GLCD are shown in the table below.
#include <lowlevel\glcd.h>
For more help, see LCD_IO 0, LCD_IO 2 LCD_IO 4, LCD_IO 8, LCD_IO 10 or LCD_IO 12
Supported in <GLCD.H>
ST7920 Controllers
The ST7920 GLCD is Graphic and character mixed display mode display. ST7920 LCD controller/driver
IC can display alphabets, numbers, Chinese fonts and self-defined characters. It supports 3 kinds of bus
interface, namely 8-bit, 4-bit and serial. Great Cow Basic is currently supports 8-bit only. For LCD only
operations (text characters only) you can use the Great Cow Basic LCD routines.
All functions, including display RAM, Character Generation ROM, LCD display drivers and control
circuits are all in a one-chip solution. With a minimum system configuration, a Chinese character
display system can be easily achieved.
The ST7920 includes character ROM with 8192 16x16 dots Chinese fonts and 126 16x8 dots half-width
alphanumerical fonts. It supports 64x256 dots graphic display area for graphic display (GDRAM). Mix-
mode display with both character and graphic data is possible. ST7920 has built-in CGRAM and provide
4 sets software programmable 16x16 fonts.
See below for an example of using the ST7920 GLCD. This section contains the relevant information for
this type of device.
The Great Cow Basic constants for control of the connectivity are shown in the table below. The only
connectivity option the 8-bit mode where 8 pins are connected between the microcomputer and the
GLCD to control the data bus.
To use the ST7920 drivers simply include the following:
#include <glcd.h>
#DEFINE GLCD_TYPE GLCD_TYPE_ST7920
GLCD_RW Specifies the output pin that is Must be set unless R/W is
connected to Read/Write on the disabled), see GLCD_NO_RW
GLCD. The R/W pin can be
disabled*.
ST7920WriteDelay Set the time delay between data Required, set to 20 us for 32Mhz
transmissions. support. Can be reduced for
slower chip speeds.
The Great Cow Basic constants for control display characteristics are shown in the table below.
The Great Cow Basic commands supported for this GLCD are shown in the table below. For device
specific see the commands with the prefix of ST7920*.
This example shows how to drive a KS0108 based Graphic LCD module with the built in commands of
Great Cow Basic. See Graphic LCD for details, this is an external web site.
Example 1:
;Chip Settings
#chip 16F1937,32
#config Osc = INT, VCAPEN_OFF, MCLRE_ON, PLLEN_ON, CLKOUTEN_OFF
#include <glcd.h>
' read delay of 25 is required at 32mhz, this can be reduced to 0 for slower clock speeds
#define ST7920ReadDelay 25
' write delay of 2 is required at 32mhz. this can be reduced to 1 for slower clock
speeds
#define ST7920WriteDelay 2
ST7920GLCDEnableGraphics
ST7920GLCDClearGraphics
GLCDPrint 0, 1, "Great Cow Basic "
wait 1 s
GLCDCLS
ST7920GLCDClearGraphics
rrun = 0
dim msg1 as string * 16
Do forever
GLCDCLS
ST7920GLCDClearGraphics ;clear screen
GLCDDrawString 30,0,"ChipMhz@" ;print string
GLCDDrawString 78,0, str(ChipMhz) ;print string
GLCDCircle(10,10,10,0) ;upper left
GLCDCircle(117,10,10,0) ;upper right
GLCDCircle(63,31,10,0) ;center
GLCDCircle(63,31,20,0) ;center
GLCDCircle(10,53,10,0) ;lower left
GLCDCircle(117,53,10,0) ;lower right
GLCDDrawString 30,54,"PIC16F1937" ;print string
wait 1 s ;wait
FilledBox( 0,0,128,63) ;create box
for ypos = 0 to 63 ;draw row by row
ST7920lineh 0,ypos,128, 0 ;draw line
next
wait 1 s ;wait
ST7920GLCDClearGraphics ;clear
loop
'radiusErr = 1 - xradius
radiusErr = -(xradius/2)
Do While xradius >= yordinate
Pset ((xoffset + xradius), (yoffset + yordinate), on)
Pset ((xoffset + yordinate), (yoffset + xradius), on)
Pset ((xoffset - xradius), (yoffset + yordinate), on)
Pset ((xoffset - yordinate), (yoffset + xradius), on)
Pset ((xoffset - xradius), (yoffset - yordinate), on)
Pset ((xoffset - yordinate), (yoffset - xradius), on)
Pset ((xoffset + xradius), (yoffset - yordinate), on)
Pset ((xoffset + yordinate), (yoffset - xradius), on)
yordinate ++
If radiusErr < 0 Then
radiusErr = radiusErr + 2 * yordinate + 1
else
xradius --
radiusErr = radiusErr + 2 * (yordinate - xradius + 1)
end if
Loop
end sub
Example 2:
;Chip Settings
#chip 16F1937,32
#config Osc = INT, VCAPEN_OFF, MCLRE_ON, PLLEN_ON, CLKOUTEN_OFF
#include <lowlevel\glcd.h>
#define GLCD_TYPE GLCD_TYPE_ST7920
#define GLCD_IO 8
#define GLCD_WIDTH 128
#define GLCD_HEIGHT 160
#define GLCDFontWidth 6
' read delay of 25 is required at 32mhz, this can be reduced to 0 for slower clock speeds
#define ST7920ReadDelay 25
' write delay of 2 is required at 32mhz. this can be reduced to 1 for slower clock
speeds
#define ST7920WriteDelay 2
WAIT 1 S
ST7920GLCDEnableGraphics
ST7920GLCDClearGraphics
ST7920Tile "A"
GLCDPrint 0, 1, "Great Cow Basic "
GLCDCLS
rrun = 0
dim msg1 as string * 16
do forever
ST7920GLCDEnableGraphics
ST7920GLCDClearGraphics
ST7920gTile 0x55, 0x55
wait 1 s
ST7920GLCDClearGraphics
ST7920Lineh(0, 0, GLCD_WIDTH)
ST7920Lineh(0, GLCD_HEIGHT - 1, GLCD_WIDTH)
ST7920LineV(0, 0, GLCD_HEIGHT)
ST7920LineV(GLCD_WIDTH - 1, 0, GLCD_HEIGHT)
Box 18,30,28,40
WAIT 2 S
FilledBox 18,30,28,40
ST7920GLCDClearGraphics
Start:
workingGLCDDrawChar:
ST7920GLCDEnableGraphics
dim gtext as string
gtext = "ST7920 @QC12864B"
ST7920GLCDClearGraphics
ST7920GLCDDisableGraphics
GLCDCLS
msg1 = "Run = " +str(rrun)
rrun++
GLCDPrint 0, 0, "ST7920 @QC12864B"
GLCDPrint 0, 1, "Great Cow Basic "
GLCDPrint 0, 2, "GLCD 128*64"
GLCDPrint 0, 3, msg1
wait 5 s
GLCDCLS
ST7920Tile ( 0xa9 )
wait 1 s
GLCDCLS
'ST7920 can display half-width HCGROM fonts, user- defined CGRAM fonts and full 16x16
CGROM fonts. The
'character codes in 0000H~0006H will use user- defined fonts in CGRAM. The character
codes in 02H~7FH will use
'half-width alpha numeric fonts. The character code larger than A1H will be treated as
16x16 fonts and will be
'combined with the next byte automatically. The 16x16 BIG5 fonts are stored in
A140H~D75FH while the 16x16 GB
'fonts are stored in A1A0H~F7FFH. In short:
'1. To display HCGROM fonts:
'Write 2 bytes of data into DDRAM to display two 8x16 fonts. Each byte represents 1
character.
'The data is among 02H~7FH.
'2. To display CGRAM fonts:
'Write 2 bytes of data into DDRAM to display one 16x16 font.
'Only 0000H, 0002H, 0004H and 0006H are acceptable.
'3. To display CGROM fonts:
'Write 2 bytes of data into DDRAM to display one 16x16 font.
'A140H~D75FH are BIG5 code, A1A0H~F7FFH are GB code.
linetest1:
ST7920GLCDEnableGraphics
ST7920gTile(0x55, 0x55)
wait 1 s
ST7920GLCDClearGraphics
'linehtest:
'
ST7920LineH(0, 0, GLCD_WIDTH)
ST7920LineH(0, GLCD_HEIGHT - 1, GLCD_WIDTH)
ST7920LineV(0, 0, GLCD_HEIGHT)
ST7920LineV(GLCD_WIDTH - 1, 0, GLCD_HEIGHT)
box test
ST7920LineH(10 ,0 , 118 )
ST7920LineH(0 ,8 , 128)
ST7920LineH(16 ,16 , 96 )
ST7920LineH(10 ,32 , 108 )
ST7920LineH(0, 16, GLCD_WIDTH)
ST7920LineH(0, 24, GLCD_WIDTH)
ST7920LineH(0, 32, GLCD_WIDTH)
ST7920LineH(0, 40, GLCD_WIDTH)
ST7920LineH(0, 48, GLCD_WIDTH)
ST7920LineH(0, 56, GLCD_WIDTH)
ST7920LineH(0, 63, GLCD_WIDTH)
ST7920LineV(16, 0, GLCD_HEIGHT)
ST7920LineV(17, 0, GLCD_HEIGHT)
ST7920LineV(15, 0, GLCD_HEIGHT)
ST7920LineV(46, 0, GLCD_HEIGHT)
ST7920LineV(47, 0, GLCD_HEIGHT)
ST7920LineV(48, 0, GLCD_HEIGHT)
ST7920LineV(46, 0, GLCD_HEIGHT)
ST7920LineV(47, 0, GLCD_HEIGHT)
ST7920LineV(48, 0, GLCD_HEIGHT)
ST7920LineV(96, 0, GLCD_HEIGHT)
ST7920LineV(97, 0, GLCD_HEIGHT)
ST7920LineV(98, 0, GLCD_HEIGHT
GraphicTestPlace:
ST7920GLCDClearGraphics
ST7920GraphicTest
ST7920GLCDClearGraphics
ST7920GLCDClearGraphics
ST7920GLCDDisableGraphics
GLCDCLS
ST7920SetIcon( 1, 0x55 )
loop
sub ST7920CallBuiltinChar
' 0xA140 ~ 0xA15F
for ii = 0 to 31
ST7920WriteData( 0xA1)
ST7920WriteData( 0x40 + ii)
next
wait 1 s
GLCDCLS
ST7920WriteData( 0xA1)
ST7920WriteData( 0xb0 + ii)
next
wait 1 s
GLCDCLS
ST7920WriteData( 0xA4)
ST7920WriteData( 0x40 + ii)
next
wait 1 s
GLCDCLS
end sub
For more help, see LCD_IO 0, LCD_IO 2 LCD_IO 4, LCD_IO 8, LCD_IO 10 or LCD_IO 12
Supported in <GLCD.H>
ST7920GLCDClearGraphics
Syntax:
ST7920GLCDClearGraphics
Explanation:
Example usage:
ST7920GLCDDisableGraphics
Syntax:
ST7920GLCDDisableGraphics
Explanation:
Example usage:
ST7920GLCDDisableGraphics 'Set to text mode
ST7920GLCDEnableGraphics
Syntax:
ST7920GLCDEnableGraphics
Explanation:
Example usage:
ST7920GraphicTest
Syntax:
ST7920GraphicTest
Explanation:
Example usage:
ST7920LineHs
Syntax:
Explanation:
This command draws a line with a specific style. The style is based on the bits value of the byte passed
to the routine.
Example usage:
ST7920LineHs ( 0, 31,128 , 0x55) ‘will draw a dashed line
ST7920Locate
Syntax:
Explanation:
This command locates the pixel at the specific X and Y location of the text screen. Subsequent printing
to the GLCD will place a character to the GLCD controller on the specified row and column. Due to the
design of the ST7920 controller (to accomodate Mandarin and Cyrillic), you must place the text on the
column according to the numbers above the diagram below. The addressing is handle by the
command.
|--0--|--1--|--2--|... ...|--7--|
+--+--+--+--+--+---------------------+
+--+--+--+--+--+---------------------+
+--+--+--+--+--+---------------------+
|' |' |' |' |' |' ... | <- row 2 (address 0x88)
+--+--+--+--+--+---------------------+
+--+--+--+--+--+---------------------+
+--+--+--+--+--+---------------------+
+--+--+--+--+--+---------------------+
+--+--+--+--+--+---------------------+
+--+--+--+--+--+---------------------+
+--+--+--+--+--+---------------------+
Example usage:
ST7920Tile
Syntax:
Explanation:
This command tiles the screen with the word value provided.
Example usage:
ST7920cTile
Syntax:
ST7920cTile ( word variable )
Explanation:
This required 2 bytes of data into DDRAM to display one 16x16 font from memory location
A140H~D75FH are BIG5 code, A1A0H~F7FFH are GB code.
Example usage:
ST7920gLocate
Syntax:
Explanation:
This command locates the pixel at the specific X and Y location of the graphical screen.
Example usage:
ST7920gTile
Syntax:
Explanation:
Example usage:
ST7920gTile (0x55, 0x85) ‘tile the screen with an odd cross hatch
ST7920lineh
Syntax:
Explanation:
This command draws a horizontal line with the specific style. The style can be ON or OFF. Default is
ON.
Example usage:
ST7920linev
Syntax:
Explanation:
This command draws a vertical line with the specific style. The style can be ON or OFF. Default is ON
Example usage:
ST7920GLCDReadByte
Syntax:
byte_variable = ST7920GLCDReadByte
Explanation:
This function return the word value (16 bits) of the GLCD display for the current XY position.
Example usage:
ST7920WriteByte( SysCalcPositionY )
ST7920WriteByte( SysCalcPositionX )
' read data
GLCDDataTempWord = ST7920GLCDReadByte
GLCDDataTempWord = ST7920GLCDReadByte
GLCDDataTempWord = (GLCDDataTempWord*256) + ST7920GLCDReadByte
ST7920WriteByte
Syntax:
ST7920GLCDWriteByte
Explanation:
This command write to the appropriate location as specified by the current XY position.
Example usage:
...
ST7920WriteByte( SysCalcPositionY )
ST7920WriteByte( SysCalcPositionX )
' read data
GLCDDataTempWord = ST7920GLCDReadByte
GLCDDataTempWord = ST7920GLCDReadByte
GLCDDataTempWord = (GLCDDataTempWord*256) + ST7920GLCDReadByte
...
ST7920WriteCommand
Syntax:
ST7920GWriteCommand ( byte_variable)
Explanation:
Example usage:
...
ST7920WriteCommand(0x36) ' set the graphics mode on
GLCD_TYPE_ST7920_GRAPHICS_MODE = true
...
ST7920WriteData
Syntax:
ST7920GWriteData ( byte_variable)
Explanation:
Example usage:
...
for yy = 0 to ( GLCD_HEIGHT - 1 )
ST7920gLocate(0, yy)
for xx = 0 to ( GLCD_COLS -1 )
ST7920WriteData( 0x55 )
T7920WriteData( 0x55 )
next
next
...
ST7920gReaddata
Syntax:
byte_variable = ST7920gReaddata
Explanation:
This function return the word value (16 bits) of the GLCD display for the current XY position.
Example usage:
...
' Read a word from the display device.
word_variable = ST7920GLCDReadData
Box
Syntax:
Explanation:
Draws a box on a graphic LCD from the upper corner of X1, Y1 location to X2,Y2 location.
Circle
Circle:
Explanation:
The constant GLCD_PROTECTOVERRUN can be added to prevent circles from re-drawing at the screen edges.
Ensure the GLCD_Width and GLCD_HEIGHT constants are set correctly when using this additional constant.
Example:
#include <glcd.h>
Versions of GCB prior to May 2014 does not support circle drawing. You can install
WARNING
the latest glcd.h file to enable this functionality.
FilledBox
Syntax:
Explanation:
Draws a filled box on a graphic LCD from the upper corner of X1, Y1 location to X2,Y2 location.
FilledCircle
Circle:
Example:
#include <glcd.h>
Versions of GCB prior to May 2014 does not support filled circle drawing. You can
WARNING
install the latest glcd.h file to enable this functionality.
GLCDCLS
Syntax:
GLCDCLS
Explanation:
This command supports both the text and graphics mode of the ST7920 GLCD devices.
GLCDDrawChar
Syntax:
GLCDDrawChar(CharLocX, CharLocY, CharCode [, Optional Colour] )
Colour can be ON or OFF. For the ST7735 devices this an be any word value that represents the color
palette.
Explanation:
X = 1 to 128
Y = 1 to 64
GLCDDrawString
Syntax:
Explanation:
GLCDPrint
Syntax:
Explanation:
GLCDReadByte
Syntax:
byte_variable = GLCDReadByte
Explanation:
GLCDTimeDelay
Syntax:
GLCDTime
Explanation:
This will call the delay routine that delays data transmissions. By default this is set to 20, which equate
to 20 us. GLCDTimeDelay default of 20us is for 32Mhz support. The can be reduced for slower chip speeds
by change the constant ST7920WriteDelay.
Example usage:
GLCDWriteByte
Syntax:
GLCDWriteByte (LCDByte)
Explanation:
InitGLCD
Syntax:
InitGLCD
Explanation:
This initializes the Graphical LCD for operation. Here are the steps it takes:
Example:
'Set pin directions
'Reset
Set GLCD_CS1 On
Set GLCD_CS2 On
'Set on
'Set Z to 0
GLCDWriteByte 192
'Deselect chips
'Clear screen
GLCDCLS
Line
Syntax:
Example:
#include <glcd.h>
line 0,0,127,63
line 0,63,127,0
line 40,0,87,63
line 40,63,87,0
Versions of GCB prior to May 2014 only supports lines in the vertical or horizontal
WARNING
axis.
The following addition to a Great Cow Basic program will tell the compiler to use the old line drawing
routines.
Pset
Syntax:
Explanation:
Sets or Clears a Pixel at the specified X, Y location. A one for GLCDState sets the pixel and a zero clears
the pixel.
Liquid Crystal Display
LCD Overview
Introduction:
This section of the Help file assumes you have a release of GCBasic Feb 2015 or later.
The LCD routines in this section allow GCBASIC programs to control an alphanumeric Liquid Crystal
Displays based on the HD44780 IC. This covers most 16 x 2, 20 x 4 and similar LCD displays.
These methods allow the displays to be connected to the microcontroller in many different ways:
8 R/W, RS, Enable and all 8 data lines. The data lines
must all be connected to the same I/O port, in
sequential order. For example, DB0 to PORTB.0, DB1
to PORTB.1 and so on, with`DB7` going to PORTB.7.
This a common method to connect a
microprocessor to an LCD. This requires 11 data
ports on the microprocessor.
See the separate sections of the Help file for the specifics of each Connection Mode.
For more help, see LCD_IO 0, LCD_IO 2 LCD_IO 4, LCD_IO 8, LCD_IO 10 or LCD_IO 12
LCD_IO 0
To use 0-bit connection mode, a subroutine to write a byte to the LCD must be provided.
Optionally, another subroutine to read a byte from the LCD can also be given. If there is no way to read
from the LCD, then the LCD_NO_RW constant must be set.
In 0-bit mode, the LCD_RS constant will be set automatically to a spare bit variable. The higher level LCD
commands (such as Print and Locate) will set it, and the code responsible for writing to the LCD should
read it and then set the RS pin on the LCD appropriately.
Relevant Constants:
These constants are used to control settings for the Liquid Crystal Display routines included with
GCBASIC. To set them, place a line in the main program file that uses #define to assign a value to the
particular constant.
When using 2-bit mode only three constants must be set - all others can be ignored.
This code is an example of how to use 0-bit mode. It sends messages to another microcontroller, which
has been programmed to read the messages and toggle the pins of an LCD appropriately:
# #define LCD_IO 0
#define LCD_NO_RW
#define LCDWriteByte MySendToLCD
; ----- Variables
' No Variables specified in this example. All byte variables are defined upon use.
[todo]
end
'Uses I2C
'Sends an address byte (128)
'Then a control byte, where bit 4 is the state of the RS pin
'Then a data byte, which is sent to the LCD data pins.
ControlByte = 0
If LCD_RS = On Then ControlByte.4 = On
I2CStart
I2CSend 128
I2CSend ControlByte
I2CSend MyLCDByte
I2CStop
End Sub
See the separate sections of the Help file for the specifics of each Connection Mode.
For more help, see LCD_IO 0, LCD_IO 2, LCD_IO 4, LCD_IO 8, LCD_IO 10 or LCD_IO 12
LCD_IO 2
Data and Clock lines. This mode is used when the LCD is connected through a 74LS174 shift register IC,
as detailed at the Internet way back engine
Relevant Constants:
These constants are used to control settings for the Liquid Crystal Display routines included with
GCBASIC. To set them, place a line in the main program file that uses #define to assign a value to the
particular constant.
When using 2-bit mode only three constants must be set - all others can be ignored.
Example
'LCD connection settings
#define LCD_IO 2
#define LCD_NO_RW
CLS
End
See for further code examples see Two Wire LCD Examples
See the separate sections of the Help file for the specifics of each Connection Mode.
For more help, see LCD_IO 0, LCD_IO 2 LCD_IO 4, LCD_IO 8, LCD_IO 10 or LCD_IO 12
LCD_IO 4
To use 4-bit connection mode the R/W, RS, Enable and the highest 4 data lines (DB4 through DB7) must be
connect to the microprocessor.
Relevant Constants:
These constants are used to control settings for the Liquid Crystal Display routines included with
GCBASIC. To set them, place a line in the main program file that uses #define to assign a value to the
particular constant.
LCD_IO Must be 4 4
LCD_RW Specifies the output pin that is Must be set (unless R/W is
connected to Read/Write on the disabled)
LCD. The R/W pin can be
disabled*.
The R/W pin can be disabled by setting the LCD_NO_RW constant. If this is done, there is no need for the R/W
to be connected to the chip, and no need for the LCD_RW constant to be set. Ensure that the R/W line on
the LCD is connected to ground if not used!
Example :
'LCD connection settings
#define LCD_IO 4
#define LCD_NO_RW
CLS
End
See for further code examples see Four Wire LCD Examples
See the separate sections of the Help file for the specifics of each Connection Mode.
For more help, see LCD_IO 0, LCD_IO 2 LCD_IO 4, LCD_IO 8, LCD_IO 10 or LCD_IO 12
LCD_IO 8
Using 8-bit connection mode will require R/W, RS, Enable and all 8 data lines.
The data lines must all be connected to the same I/O port, in sequential order. For example, DB0 to
PORTB.0, DB1 to PORTB.1 and so on, with DB7 going to PORTB.7.
Relevant Constants:
These constants are used to control settings for the Liquid Crystal Display routines included with
GCBASIC. To set them, place a line in the main program file that uses #define to assign a value to the
particular constant.
LCD_RW Specifies the output pin that is Must be set (unless R/W is
connected to Read/Write on the disabled)
LCD. The R/W pin can be
disabled*.
The R/W pin can be disabled by setting the LCD_NO_RW constant. If this is done, there is no need for the R/W
to be connected to the chip, and no need for the LCD_RW constant to be set. Ensure that the R/W line on
the LCD is connected to ground if not used!
Example
'LCD connection settings
#define LCD_IO 8
#define LCD_NO_RW
CLS
END
See the separate sections of the Help file for the specifics of each Connection Mode.
For more help, see LCD_IO 0, LCD_IO 2, LCD_IO 4, LCD_IO 8, LCD_IO 10 or LCD_IO 12
LCD_IO 10
The LCD is controlled via I2C. A type 10 LCD 12C adapter. Set LCD_10 to 10 for the YwRobot LCD1602
IIC V1 or the Sainsmart LCD_PIC I2C adapter To use mode 10 you must define the I2C ports as normal
in your GCB code. Then, define the LCD type, set the I2C_address of the LCD adapter and the LCD speed,
if required. Then set the backlight control, if required. As follows:
; ----- Define I2C settings – Change Ports. This configuration is for Software I2C.
#define I2C_MODE Master
#define I2C_DATA PORTC.4
#define I2C_CLOCK PORTC.5
#define I2C_DISABLE_INTERRUPTS ON
‘#define I2C_BIT_DELAY 0 us ;Optional
‘#define I2C_CLOCK_DELAY 1 us ;Optional
‘#define I2C_END_DELAY 0 us ;Optional
; ----- Constants
'''Set up LCD
'''Set LCD_10 to 10 for the YwRobot LCD1602 IIC V1 or the Sainsmart LCD_PIC I2C adapter
Then, you can use all the normal LCD commands like: CLS Print Locate Cursor etc. etc.
Relevant Constants:
These constants are used to control settings for the Liquid Crystal Display routines included with
GCBASIC. To set them, place a line in the main program file that uses #define to assign a value to the
particular constant.
When using 2-bit mode only three constants must be set - all others can be ignored.
See the separate sections of the Help file for the specifics of each Connection Mode.
For more help, see LCD_IO 0, LCD_IO 2, LCD_IO 4, LCD_IO 8, LCD_IO 10 or LCD_IO 12
LCD_IO 10 Port Configuration
Using mode 10
When using I2C LCD mode 10 the target I2C device address is setup as shown below. Each bit of the the
variable i2c_lcd_byte is defined to address the correct LCD display port.
i2c_lcd_e = i2c_lcd_byte.2
i2c_lcd_rw = i2c_lcd_byte.1
i2c_lcd_rs = i2c_lcd_byte.0
i2c_lcd_bl = i2c_lcd_byte.3
i2c_lcd_d4 = i2c_lcd_byte.4
i2c_lcd_d5 = i2c_lcd_byte.5
i2c_lcd_d6 = i2c_lcd_byte.6
i2c_lcd_d7 = i2c_lcd_byte.7
If you have an I2C LCD display adapter with a different set of connection of the adapter then change
this configuration to suit the specific of the adapter as follows. This should be done in the your main
program code.
LCD_IO 12
The LCD is controlled via I2C. A type 12 is the Ywmjkdz I2C adapter with pot bent over top of chip. To
use mode 12 you must define the I2C ports as normal in your GCB code. Then, define the LCD type, set
the I2C_address of the LCD adapter and the LCD speed, if required. Then set the backlight control, if
required. As follows:
; ----- Define I2C settings – Change Ports. This configuration is for
Software I2C.
#define I2C_MODE Master
#define I2C_DATA PORTC.4
#define I2C_CLOCK PORTC.5
#define I2C_DISABLE_INTERRUPTS ON
‘#define I2C_BIT_DELAY 0 us ;Optional
‘#define I2C_CLOCK_DELAY 1 us ;Optional
‘#define I2C_END_DELAY 0 us ;Optional
; ----- Constants
'''Set up LCD
'''Set LCD_12 to for the Ywmjkdz I2C adapter with pot bent over top of chip.
Then, you can use all the normal LCD commands like:
CLS
Print
Locate
Cursor commands etc. etc.
Relevant Constants:
These constants are used to control settings for the Liquid Crystal Display routines included with
GCBASIC. To set them, place a line in the main program file that uses #define to assign a value to the
particular constant.
When using 2-bit mode only three constants must be set - all others can be ignored.
See the separate sections of the Help file for the specifics of each Connection Mode.
For more help, see LCD_IO 0, LCD_IO 2, LCD_IO 4, LCD_IO 8, LCD_IO 10 or LCD_IO 12
Using mode 12
When using I2C LCD mode 12 the target I2C device address is setup as shown below. Each bit of the the
variable i2c_lcd_byte is defined to address the correct LCD display port.
i2c_lcd_e = i2c_lcd_byte.4
i2c_lcd_rw = i2c_lcd_byte.5
i2c_lcd_rs = i2c_lcd_byte.6
i2c_lcd_bl = i2c_lcd_byte.7
i2c_lcd_d4 = i2c_lcd_byte.0
i2c_lcd_d5 = i2c_lcd_byte.1
i2c_lcd_d6 = i2c_lcd_byte.2
i2c_lcd_d7 = i2c_lcd_byte.3
If you have an I2C LCD display adapter with a different set of connection of the adapter then change
this configuration to suit the specific of the adapter as follows. This should be done in the your main
program code.
LCD_SPEED
Using LCD_SPEED:
To use the IO connection mode 0, a subroutine to support the LCD write operations must be provided.
The communication performance of a LCD display can be controlled via a #DEFINE. This method allow
the displays to be connected to the microcontroller and the timing to be optimised.
Example
CLS
Syntax:
CLS
Command Availability:
Explanation:
The CLS command clears the contents of the LCD, and returns the cursor to the top left corner of the
screen
Example :
'Main routine
Do
Print "Hello World"
Wait 1 sec
CLS
Wait 1 sec
Loop
For more help, see LCD Overview
Supported in <LCD.H>
Get
Syntax:
Command Availability:
Available on all microcontrollers with the LCD R/W line (pin 5) connected and if the following constant
definition is used; #define LCD_RW. Not available if the LCD is connected using the 0 or 2 bit mode or if
the constant definition #define LCD_NO_RW is used.
Explanation:
The Get function reads the ASCII character code at a given location on the LCD.
Supported in <LCD.H>
LCDBacklight
Syntax:
LCDBacklight ( On | Off )
Command Availability:
Explanation:
Do not connect the LCD backlight to the microprocessor! Always refer to the datasheet for the correct
method to drive the LCD backlight.
The diagram below shows a method to connect the LCD backlight to a microcomputer.
The
diagram above was provided by William Roth, January 2015.
Supported in <LCD.H>
LCDCreateChar
Syntax:
Command Availability:
Explanation:
Each character on the LCD is made up from an 8 row by 5 column (5x8) matrix of pixels. The data to be
sent to the LCD is composed of an 8 element array, where each element corresponds to a row. Inside
each element, the 5 lowest bits make up the data for the corresponding row. When a bit is set a dot will
be drawn at the matching location; when it is cleared, no dot will appear.
An array of more than 8 elements may be used, but only the first 8 will be read.
char is the ASCII value of the character to create. ASCII codes 0 through 7 are usually used to store
custom characters.
Example:
Supported in <LCD.H>
LCDCreateGraph
Syntax:
LCDCreateGraph value
Command Availability:
Explanation:
The LCDCreateGraph command will create a graph like character which can then be displayed on the
LCD
Example :
;Chip Settings
#chip 16F88,8
#config osc = intrc
;Defines (Constants)
#define LCD_IO 4
#define LCD_RS PORTA.6
#define LCD_NO_RW
#define LCD_Enable PORTA.7
#define LCD_DB4 PORTB.4
#define LCD_DB5 PORTB.5
#define LCD_DB6 PORTB.6
#define LCD_DB7 PORTB.7
Locate 0,0
Print "Reset"
wait 1 s
cls
Graph_Tests:
cls
'Draw the custom character - fill the LCD
repeat 64
LCDWriteChar 0
end Repeat
LCDCmd
Syntax:
LCDCreateGraph value
Command Availability:
Explanation:
This command set LCD specific instructions to the LCD display. As shown in the table below.
Clear Screen 1 01
;Chip Settings
#chip 16F88,8
#config osc = intrc
;Defines (Constants)
#define LCD_IO 4
#define LCD_RS PORTA.6
#define LCD_NO_RW
#define LCD_Enable PORTA.7
#define LCD_DB4 PORTB.4
#define LCD_DB5 PORTB.5
#define LCD_DB6 PORTB.6
#define LCD_DB7 PORTB.7
Locate 0,0
Print "Reset"
wait 1 s
cls
LCD_Command_Tests:
locate 0,8
print "123456"
'Scroll display one character right (all lines) 28
'
lcdcmd 28
wait 1 s
lcdcmd 28
wait 1 s
lcdcmd 28
wait 1 s
lcdcmd 28
wait 1 s
lcdcmd 16
wait 1 s
lcdcmd 16
wait 1 s
lcdcmd 16
wait 1 s
lcdcmd 16
wait 1 s
Supported in <LCD.H>
LCDCursor
Syntax:
LCDCursor value
Command Availability:
Explanation:
FLASH, and ON/OFF have been retained for backward compatibility with older releases of GCB)
Example :
#config osc = intrc
;Defines (Constants)
#define LCD_IO 4
#define LCD_RS PORTA.6
#define LCD_NO_RW
#define LCD_Enable PORTA.7
#define LCD_DB4 PORTB.4
#define LCD_DB5 PORTB.5
#define LCD_DB6 PORTB.6
#define LCD_DB7 PORTB.7
Start:
CLS
WAIT 3 s
PRINT "START DEMO"
locate 1,0
PRINT "DISPLAY ON"
wait 3 s
CLS
Locate 0,0
Print "Cursor ON"
Locate 1,0
LCDcursor CursorOn
wait 3 S
CLS
LCDcursor CursorOFF
locate 0,0
Print "Cursor OFF"
wait 3 s
CLS
Locate 0,0
Print "FLASH ON"
Locate 1,0
LCDcursor FLASHON
wait 3 s
CLS
locate 0,0
Print "FLASH OFF"
LCDCURSOR FLASHOFF
wait 3 sec
Locate 0,0
Print "CURSOR&FLASH ON" 'Both are on at the same time
locate 1,0
LCDCURSOR CURSORON
LCDCURSOR FLASHON
Wait 3 sec
Locate 0,0
Print "CURSOR FLASH OFF"
locate 1,0
LCDCURSOR CursorOFF
LCDCURSOR FLASHOFF
Wait 3 sec
CLS
Locate 0,4
PRINT "Flashing"
Locate 1,4
Print "Display"
wait 500 ms
repeat 5
LCDCURSOR LCDOFF
wait 500 ms
LCDCURSOR LCDON
wait 500 ms
end repeat
CLS
Locate 0,0
Print "DISPLAY OFF"
Locate 1,0
Print "FOR 5 SEC"
Wait 2 SEC
LCDCURSOR LCDOFF
WAIT 5 s
CLS
Locate 0,0
LCDCURSOR LCDON
Print "END DEMO"
wait 3 s
goto start
Supported in <LCD.H>
LCDHex
Syntax:
LCDHex value
Where value is a byte value from 0 to 255. Where LeadingZeroActive is a constant or byte value of 2.
Command Availability:
Explanation:
The LCDHex will display the byte value as a 1 or 2 character HEX string.
Example :
;Set chip model required:
#chip mega328p, 16
;Setup LCD Parameters
#define LCD_IO 4
#define LCD_NO_RW
#define LCD_Speed MEDIUM 'FAST IS OK ON ARDUINO UNO R3
'Change as necessary
#define LCD_RS PortC.0
#define LCD_Enable PortC.1
#define LCD_DB4 PortC.2
#define LCD_DB5 PortC.3
#define LCD_DB6 PortC.4
#define LCD_DB7 PortC.5
'Program Start
DO Forever
CLS
WAIT 2 s
PRINT "Test LCDHex "
wait 3 s
CLS
wait 1 s
for bv = 0 to 255
locate 0,0
Print "DEC " : Print BV
locate 1,0
Print "HEX "
LCDHex BV, LeadingZeroActive ; dislay leading Zero
' LCDHex BV ; do not display leading zero
wait 1 s
next
CLS
wait 1 s
Print "END TEST"
LOOP
LCDHome
Syntax:
LCDHome
Command Availability:
Explanation:
The LCDHome command will return the cursor to home position. The current contents of the LCD screen
will be retained.
Example:
;Chip Settings
#chip 16F88,8
#config osc = intrc
;Defines (Constants)
#define LCD_IO 4
#define LCD_RS PORTA.6
#define LCD_NO_RW
#define LCD_Enable PORTA.7
#define LCD_DB4 PORTB.4
#define LCD_DB5 PORTB.5
#define LCD_DB6 PORTB.6
#define LCD_DB7 PORTB.7
Locate 0,0
Print "Reset"
wait 1 s
ClS
Cursor_Home_Tests:
cls
lcdcursor flash
print "Test Home Cmd"
LCDHome
wait 3 s
Supported in <LCD.H>
LCDDisplayOn
Explanationv:
Supported in <LCD.H>
LCDDisplayOff
Explanation:
LCDSpace
Syntax:
LCDSpace value
Command Availability:
Explanation:
The LCDSpace command will print the required number of spaces on the LCD display
Example :
;Chip Settings
#chip 16F88,8
#config osc = intrc
;Defines (Constants)
#define LCD_IO 4
#define LCD_RS PORTA.6
#define LCD_NO_RW
#define LCD_Enable PORTA.7
#define LCD_DB4 PORTB.4
#define LCD_DB5 PORTB.5
#define LCD_DB6 PORTB.6
#define LCD_DB7 PORTB.7
Locate 0,0
Print "Reset"
wait 1 s
cls
LCD_Space_Tests:
lcdcursor flash
lcdspace 12
print "*"
Supported in <LCD.H>
LCDWriteChar
Syntax:
LCDWriteChar char
Command Availability:
Explanation:
The LCDWriteChar command will show the specified character on the LCD, at the current cursor
position.
char is the ASCII value of the character to show. On most LCDs, characters 0 through 7 are user defined,
and can be set using the LCDCreateChar command.
Example :
'This program draws a smiling face character
Supported in <LCD.H>
Locate
Syntax:
Command Availability:
The Locate command is used to move the cursor on the LCD to the given location.
Example :
'Main routine
Print "Hello"
Locate 1, 5
Print "World"
Supported in <LCD.H>
Syntax:
Print string
Print byte
Print word
Print long
Print integer
Command Availability:
Explanation:
The Print command will show the contents of a variable on the LCD. It can display string, word, byte,
long or integer variables.
Example:
CLS
Print "Light Meter"
Locate 1,2
Print "A GCBASIC Demo"
Wait 2 s
Do
CLS
Print "Light Level: "
Print ReadAD(LightSensor)
Wait 250 ms
Loop
Supported in <LCD.H>
Put
Syntax:
Command Availability:
Explanation:
The Put command writes the given ASCII character code to the location on the LCD.
Example :
'Misc Settings
#define SCROLL_DELAY 250 ms
'Main routine
For StarPos = 0 To 16
If StarPos = 0 Then
Put 0, 16, 32
Put 0, 0, 42
Else
Put 0, StarPos - 1, 32
Put 0, StarPos, 42
End If
Wait SCROLL_DELAY
Next
Supported in <LCD.H>
Examples
#chip 16F877A,20
#define LCD_IO 2
#define LCD_DB portb.2
#define LCD_CB portb.0
#define LCD_NO_RW
;Here are various LCD commands which can be used.
;These are the LCD commands for the HD44780 controller
do forever
printMsg(0) ;print first message
wait 3 S ;pause 3 seconds
printMsg(2) ;print next message
wait 3 S ;pause 3 seconds
repeat 5 ;blink it five times
LCDCmd(lcdOff) ;display off
wait 500 mS ;pause
LCDCmd(lcdOn) ;display on
wait 500 mS ;pause
end repeat
wait 1 S ;pause before next demo
;demonstrate panning
printMsg(4) ;print next message
wait 3 S ;pause 3 seconds
repeat 16
LCDCmd(panL) ;pan left a step at a time
wait 300 mS ;slow down to avoid blur
end repeat
repeat 16
LCDCmd(panR) ;then pan right
wait 300 mS
end repeat
wait 1 S ;pause before next demo
;demonstrate moving the cursor
printMsg(6) ;print next message
wait 3 S ;pause 3 seconds
doHome ;home cursor
LCDCmd(under) ;choose underline cursor
for ii = 0 to 15 ;move cursor across first line
LCDCmd(line1+i)
wait 200 mS
next i
for ii = 0 to 15 ;move cursor across second line
LCDCmd(line2+i)
wait 200 mS
next i
for ii = 15 to 0 step -1 ;move cursor back over second line
LCDCmd(line2+i)
wait 200 mS
next i
for ii = 15 to 0 step -1 ;move cursor back over first line
LCDCmd(line1+i)
wait 200 mS
next i
wait 3 S
;demonstrate blinking block cursor
printMsg(8) ;print next message
doHome ;home the cursor
LCDCmd(block) ;choose blinking block cursor
wait 4 S ;pause 4 seconds
LCDCmd(mode1) ;change to one long line mode
doHome ;home the cursor again
LCDCmd(curOff) ;and disable it
end
for ii = 0 to StringLength
index = row*16+ii
EPread index, char ;fetch next character and
print chr(char) ;transmit to the LCD
next
LCDCmd(line2) ;get set for second line
for ii = 0 to StringLength
index = (row+1)*16+ii
EPread index, char ;fetch next character and
print chr(char) ;transmit to the LCD
next
end sub
sub loadEeprom
' Strings for EEPROM, Strings should be limited to 16 characters for the
first 13 sstrings, then a long string to fill eeprom
location = 0
WriteEeprom "First we'll show"
WriteEeprom "this message. "
WriteEeprom "Then we'll blink"
WriteEeprom "five times. "
WriteEeprom "Now lets pan "
WriteEeprom "left and right. "
WriteEeprom "Watch the line "
WriteEeprom "cursor move. "
WriteEeprom "A block cursor "
WriteEeprom "is available. "
WriteEeprom "Characters: "
WriteEeprom "Bye! "
WriteEeprom "in one line mode"
WriteEeprom "Next well scroll this long message as a marquee"
end sub
end sub
#chip 16F877A,20
do forever
printMsg(0) ;print first message
wait 3 S ;pause 3 seconds
printMsg(2) ;print next message
wait 3 S ;pause 3 seconds
repeat 5 ;blink it five times
LCDCmd(lcdOff) ;display off
wait 500 mS ;pause
LCDCmd(lcdOn) ;display on
wait 500 mS ;pause
end repeat
wait 1 S ;pause before next demo
;demonstrate panning
printMsg(4) ;print next message
wait 3 S ;pause 3 seconds
repeat 16
LCDCmd(panL) ;pan left a step at a time
wait 300 mS ;slow down to avoid blur
end repeat
repeat 16
LCDCmd(panR) ;then pan right
wait 300 mS
end repeat
wait 1 S ;pause before next demo
;demonstrate moving the cursor
printMsg(6) ;print next message
wait 3 S ;pause 3 seconds
doHome ;home cursor
LCDCmd(under) ;choose underline cursor
for ii = 0 to 15 ;move cursor across first line
LCDCmd(line1+i)
wait 200 mS
next i
for ii = 0 to 15 ;move cursor across second line
LCDCmd(line2+i)
wait 200 mS
next i
for ii = 15 to 0 step -1 ;move cursor back over second line
LCDCmd(line2+i)
wait 200 mS
next i
for ii = 15 to 0 step -1 ;move cursor back over first line
LCDCmd(line1+i)
wait 200 mS
next i
wait 3 S
;demonstrate blinking block cursor
printMsg(8) ;print next message
doHome ;home the cursor
LCDCmd(block) ;choose blinking block cursor
wait 4 S ;pause 4 seconds
LCDCmd(mode1) ;change to one long line mode
doHome ;home the cursor again
LCDCmd(curOff) ;and disable it
end
for ii = 0 to StringLength
index = row*16+ii
EPread index, char ;fetch next character and
print chr(char) ;transmit to the LCD
next
LCDCmd(line2) ;get set for second line
for ii = 0 to StringLength
index = (row+1)*16+ii
EPread index, char ;fetch next character and
print chr(char) ;transmit to the LCD
next
end sub
sub loadEeprom
' Strings for EEPROM, Strings should be limited to 16 characters for the
first 13 sstrings, then a long string to fill eeprom
location = 0
WriteEeprom "First we'll show"
WriteEeprom "this message. "
WriteEeprom "Then we'll blink"
WriteEeprom "five times. "
WriteEeprom "Now lets pan "
WriteEeprom "left and right. "
WriteEeprom "Watch the line "
WriteEeprom "cursor move. "
WriteEeprom "A block cursor "
WriteEeprom "is available. "
WriteEeprom "Characters: "
WriteEeprom "Bye! "
WriteEeprom "in one line mode"
WriteEeprom "Next well scroll this long message as a marquee"
end sub
end sub
#chip 16F877A,20
do forever
printMsg(0) ;print first message
wait 3 S ;pause 3 seconds
printMsg(2) ;print next message
wait 3 S ;pause 3 seconds
repeat 5 ;blink it five times
LCDCmd(lcdOff) ;display off
wait 500 mS ;pause
LCDCmd(lcdOn) ;display on
wait 500 mS ;pause
end repeat
wait 1 S ;pause before next demo
;demonstrate panning
printMsg(4) ;print next message
wait 3 S ;pause 3 seconds
repeat 16
LCDCmd(panL) ;pan left a step at a time
wait 300 mS ;slow down to avoid blur
end repeat
repeat 16
LCDCmd(panR) ;then pan right
wait 300 mS
end repeat
wait 1 S ;pause before next demo
;demonstrate moving the cursor
printMsg(6) ;print next message
wait 3 S ;pause 3 seconds
doHome ;home cursor
LCDCmd(under) ;choose underline cursor
for ii = 0 to 15 ;move cursor across first line
LCDCmd(line1+i)
wait 200 mS
next i
for ii = 0 to 15 ;move cursor across second line
LCDCmd(line2+i)
wait 200 mS
next i
for ii = 15 to 0 step -1 ;move cursor back over second line
LCDCmd(line2+i)
wait 200 mS
next i
for ii = 15 to 0 step -1 ;move cursor back over first line
LCDCmd(line1+i)
wait 200 mS
next i
wait 3 S
;demonstrate blinking block cursor
printMsg(8) ;print next message
doHome ;home the cursor
LCDCmd(block) ;choose blinking block cursor
wait 4 S ;pause 4 seconds
LCDCmd(mode1) ;change to one long line mode
doHome ;home the cursor again
LCDCmd(curOff) ;and disable it
end
for ii = 0 to StringLength
index = row*16+ii
EPread index, char ;fetch next character and
print chr(char) ;transmit to the LCD
next
LCDCmd(line2) ;get set for second line
for ii = 0 to StringLength
index = (row+1)*16+ii
EPread index, char ;fetch next character and
print chr(char) ;transmit to the LCD
next
end sub
sub loadEeprom
' Strings for EEPROM, Strings should be limited to 16 characters for the
first 13 sstrings, then a long string to fill eeprom
location = 0
WriteEeprom "First we'll show"
WriteEeprom "this message. "
WriteEeprom "Then we'll blink"
WriteEeprom "five times. "
WriteEeprom "Now lets pan "
WriteEeprom "left and right. "
WriteEeprom "Watch the line "
WriteEeprom "cursor move. "
WriteEeprom "A block cursor "
WriteEeprom "is available. "
WriteEeprom "Characters: "
WriteEeprom "Bye! "
WriteEeprom "in one line mode"
WriteEeprom "Next well scroll this long message as a marquee"
end sub
end sub
LCD_IO 10 Example
'''Set up LCD
#define LCD_IO 10
#define LCD_I2C_Address_1 0x4E ; LCD 1
#define LCD_I2C_Address_2 0x4C ; LCD 2
; ----- Constants
' DS18B20 port settings - this is required
#define DQ PortC.3
'''Set LCD_10 to 10 for the YwRobot LCD1602 IIC V1 or the Sainsmart LCD_PIC I2C adapter
'''Set LCD_10 to 12 for the Ywmjkdz I2C adapter with pot bent over top of chip
; ----- Variables
dim TempC_100 as word ' a variabler to handle the temperature calculations
dim DSdataRaw as Integer
ccount = 0
Do forever
' The function readtemp12 returns the raw value of the sensor.
' The sensor is read as a 12 bit value therefore each unit equates to 0.0625 of a
degree
DSdataRaw = readtemp12 ; save to this variable to prevent the delay bewtween
screen up dates
' The function readtemp returns the integer value of the sensor
DSdata = readtemp
ccount++
wait 1 s
loop
End
Case 1
CLS
print "GCBasic 2015"
locate 1,0
print "DS18B20 Demo"
Case 2
' Display the integer value of the sensor on the LCD
locate 0,0
print hex(ccount)
print " Ceil"
locate 0,8
print DSdata
print chr(223)+"C"+" "
Case 3
' Display the integer and decimal value of the sensor on the LCD
' Convert value * 0.0625. Mulitple value by 6 then add result to multiplication of
the value with 25 then divide result by 100.
TempC_100 = DSdata * 6
DSdata = ( DSdata * 25 ) / 100
TempC_100 = TempC_100 + DSdata
DisplayTemp:
locate 1,0
print hex(ccount)
print " Real"
locate 1,8
print str(Whole)
print "."
' To ensure the decimal part is two digits
Dig = Fract / 10
print Dig
Dig = Fract % 10
print Dig
print chr(223)
print "C"+" "
End Select
end sub
Introduction:
The routines described in this chapter allow the generation of Pulse Width Modulation signals. These
allow for the microcontroller to control the speed of a motor, or the brightness of a light. The routines
can also be used to generate the appropriate frequency signal to drive an infrared LED for remote
control applications.
The PWMOn, PWMOff and HPWM routines use the PWM generation module on the microcontroller. They will
only work on some microcontrollers - see the article on each command for details. PWMOn and HPWM will
cause the PWM module on the microcontroller to start generating the PWM signal, which will then
continue to be generated until the PWMOff instruction is run.
PWMOut does not make use of any special hardware. However, a signal is only generated while the
PWMOut command is running - when the program moves on to the next command, the signal will stop.
Relevant Constants:
These constants are used to control settings for the Pulse Width Modulation module of the PIC chip. To
set them, place a line in the main program file that uses #define to assign a value to the particular
constant.
Note that there are two sets of constants: one for Hardware PWM, and one for Software PWM.
Hardware PWM requires a CCP module on the PIC chip - Software PWM has no requirements
regarding the PIC.
Hardware PWM
These constants are only required for PWMOn. HPWM and PWMOff do not require any constants to
operate.
Hardware PWM is only available through the "CCP1" or "CCP" pin. This is a hardware limitation of PIC
microcontrollers.
Software PWM
More than 4 channels are possible, but for this the PWMOut routine in include\lowlevel\stdbasic.h must
be altered.
PWMOut
Syntax:
Command Availability:
Explanation :
This command uses a software PWM routine included in GCBASIC to produce a PWM signal on the
selected port of the chip. This routine does NOT require a PWM module on the chip.
channel sets the channel that the PWM is to be generated on. This must have been defined previously
by setting the constants PWM_Out1, PWM_Out2, PWM_Out3 or PWM_Out4. The maximum number of channels
available is 4.
duty cycle specifies the PWM duty cycle, and ranges from 0 to 255. 255 corresponds to 100%, 127 to
50%, 63 to 25%, and so on.
cycles is used to set the amount of PWM pulses to supply. This is useful for situations in which a pulse
of a specific length is required. The formula for calculating the time taken for one cycle is:
where C is the number of channels used and TOSC is the length of time taken to execute 1 instruction on
the chip (0.2 us on a 20 MHz chip, 1 us on a 4 Mhz chip). PWM_Delay is a length of time specified using
the PWM_Delay constant.
Example 1 :
'This program controls the brightness of an LED on PORTB.0
'using the software PWM routine and a potentiometer.
#chip 16f877a, 4
; ----- Constants
'PWM constant. This is a required constant.
#define PWM_Out1 portb.0
; ----- Variables
' No Variables specified in this example.
end
Example 2 :
'This program controls the brightness of an LED on gpio.1
'using the software PWM routine and a potentiometer.
#chip 12f675, 4
; ----- Constants
'PWM constant. This is a required constant.
#define PWM_Out1 gpio.1
; ----- Variables
' No Variables specified in this example.
PWMOff
Syntax:
PWMOff
Command Availability:
Explanation:
This command will disable the output of the PWM module on the PIC chip.
Example:
'This program will enable a 76 Khz PWM signal, with a duty cycle
'of 80%. It will emit the signal for 10 seconds, then stop.
#define PWM_Freq 76 'Set frequency in KHz
#define PWM_Duty 80 'Set duty cycle to 80 %
PWMOn 'Turn on the PWM
WAIT 10 s 'Wait 10 seconds
PWMOff 'Turn off the PWM
PWMOn
Syntax:
PWMOn
Command Availability:
Explanation:
This command will enable the output of the PWM module on the PIC chip.
Example:
'This program will enable a 76 Khz PWM signal, with a duty cycle
'of 80%. It will emit the signal for 10 seconds, then stop.
#define PWM_Freq 76 'Set frequency in KHz
#define PWM_Duty 80 'Set duty cycle to 80 %
PWMOn 'Turn on the PWM
WAIT 10 s 'Wait 10 seconds
PWMOff 'Turn off the PWM
HPWM
Syntax:
Command Availability:
Only available on PIC microcontrollers with Capture/Compare/PWM (CCP) module.
Explanation:
This command sets up the hardware PWM module of the PIC chip to generate a PWM waveform of the
given frequency and duty cycle. Once this command is called, the PWM will be emitted until PWMOff is
called. If you only need one particular frequency and duty cycle, you should use PWMOn and the
constants PWM_Freq and PWM_Duty instead.
channel is 1 or 2, and corresponds to the pins CCP1 and CCP2 respectively. On chips with only one CCP
port, pin CCP or CCP1 is always used, and channel is ignored. (It should be set to 1 anyway to allow for
future upgrades to more powerful PIC chips.)
frequency sets the frequency of the PWM output. It is measured in KHz. The maximum value allowed is
255 KHz. The minimum value varies depending on the clock speed. 1 KHz is the minimum on chips 16
MHz or under and 2 Khz is the lowest possible on 20 MHz chips. In situations that do not require a
specific PWM frequency, the PWM frequency should equal approximately 1 five-hundredth the clock
speed of the PIC (ie 40 Khz on a 20 MHz chip, 16 KHz on an 8 MHz chip). This gives the best duty cycle
resolution possible.
duty cycle specifies the desired duty cycle of the PWM signal, and ranges from 0 to 255 where 255 is
100% duty cycle.
The optional constant HPWM_FAST can be defined to enable the recalculation of the timer prescaler when
needed. This will provide faster operation, but uses extra byte of RAM and may cause problems if HPWM
and PWMOn are used together in a program. This will not cause any issue when using HPWM and PWMOff in
the same program with HPWM_FAST.
Example:
'This program will alter the brightness of an LED using
'hardware PWM.
'Main code
do
'Turn up brightness over 2.5 seconds
For Bright = 1 to 255
HPWM 1, 40, Bright
wait 10 ms
next
'Turn down brightness over 2.5 seconds
For Bright = 255 to 1
HPWM 1, 40, Bright
wait 10 ms
next
loop
Random Numbers
Overview
Introduction:
The generator uses a 16 bit linear feedback shift register to produce pseudo-random numbers. The
most significant 8 bits of the LFSR are used to provide an 8 bit random number.
When compiling a program, GCBASIC will generate an initial seed for the generator. However, this
seed will be the same every time the program runs, so the sequence of numbers produced by a given
program will always be the same. To work around this, there is a Randomize subroutine. It can be
provided with a new seed for the generator (which will cause the generator to move to a different
point in the sequence). Alternatively, Randomize can be set to obtain a seed from some other source
such as a timer every time it is run.
Relevant Constants:
These constants are used to control settings for the tone generation routines. To set them, place a line
in the main program file that uses #define to assign a value to the particular constant.
Random
Syntax:
var = Random
Command Availability:
Explanation:
The Random function will generate a pseudo-random number between 0 and 255 inclusive.
The numbers generated by Random will follow the same sequence every time, until Randomize is used.
Example:
Randomize
Syntax:
Randomize
Randomize seed
Command Availability:
Explanation:
Randomize is used to seed the pseudo random number generator, so that it will produce a different
sequence of numbers each time it is used.
If no seed is specified, then the RANDOMIZE_SEED constant will be used as the seed. If seed is specified,
then it will be used to seed the generator.
It is important that the seed is different every time that Randomize is used. If the seed is always the
same, then the sequence of numbers will always be the same. It is best to use a running timer, an input
port, or the analog to digital converter as the source of the seed, since these will normally provide a
different value each time the program runs.
Example:
7-Segment Displays
7 Segment Displays Overview
Introduction
The 7 segment display routines make it easier for GCBASIC programs to display numbers and letters on
7 segment LED displays.
There are two ways that the 7 segment display routines can be set up. One option is to connect the
wires from the display/s in a particular order, and then to set the DisplayPort_n_ and DispSelect_n_
constants. The other option is to connect the display/s in whatever way is easiest, and then set the
DISP_SEG_x and DISP_SEL_x constants. The first option (setting DisplayPortx and DispSelectn) will
generate slightly more efficient code.
The default for 7 segment displays is to be connected to a common parallel bus with a Common
Cathode, see the section Common Cathode for an example of the GCB code to control this configuration,
and, see the section Common Anode for an example of the GCB code to control this configuration.
DISP_SEL_x The command used to select None - needs to be set, see note
display n. Used to control below.
addressing pins when several
displays are multiplexed.
Note: Instead of setting DISP_SEL_x, it is possible to set DispSelectn and use these in conjunction with
DISP_SEG_x.
To set the 7-Segment display routines supplied with GCBASIC using DisplayPortn, it is necessary to set
these constants:
To set up the routines in this way, the displays must be connected as follows:
Microcontroller port pin Display Segment
0 A
1 B
2 C
3 D
4 E
5 F
6 G
Common Cathode
Example:
'Chip model
#chip 16f1783,8
Main:
For count = 0 to 999
number = count
Num2 = 0
Num3 = 0
If number >= 100 Then
Num3 = number / 100
number = SysCalcTempX
End if
If number >= 10 Then
Num2 = number / 10
number = SysCalcTempX
end if
Num1 = number
Repeat 10
DisplayValue 1, Num1
wait 5 ms
DisplayValue 2, Num2
wait 5 ms
DisplayValue 3, Num3
Set PortC.7 On 'A manually inserted dp (SEG_DOT), like in a voltage reading
wait 5 ms
Set PortC.7 Off
end Repeat
Next
Goto Main
Common Anode
When setting up the 7 segment Common Anode display you MUST use the 7Seg_CommonAnode constant.
You can optionally use the 7Seg_HighSide constant to support PFET or PNP high side driving of the
Common Anode display
Example:
Main:
For count = 0 to 999
number = count
Num2 = 0
Num3 = 0
If number >= 100 Then
Num3 = number / 100
number = SysCalcTempX
End if
If number >= 10 Then
Num2 = number / 10
number = SysCalcTempX
end if
Num1 = number
Repeat 10
DisplayValue 1, Num1
wait 5 ms
DisplayValue 2, Num2
wait 5 ms
DisplayValue 3, Num3
Set PortC.7 Off 'CA manually inserted dp, like in a voltage reading
wait 5 ms
Set PortC.7 On
end Repeat
Next
Goto Main
DisplayValue
Syntax:
Command Availability:
Explanation:
This command will display the given value on a seven segment LED display. display is the number of
the display to use, and data is the value between 0 and 9 to show.
The command also support HEX characters in the range between 0x00 and 0x0F (0 to 15). See example
two below for usage.
Example 1:
'This program will count from 0 to 99 on two LED displays
#chip 16F819, 8
#config osc = int
Do
For Counter = 0 To 99
Example 2:
'This program will count from 0 to 0xff on two LED displays
#chip 16F819, 8
#config osc = int
Do
For Counter = 0 To 0xff
Syntax:
Command Availability:
Explanation:
This command will display the given ASCII character on a seven segment LED display. display is the
number of the display to use, and character is the ASCII character to show.
Example:
#chip 16F877A, 20
#define DisplayPortA PORTB
The DS18B20 is a 1-Wire digital temperature sensor from Maxim IC. The sensor reports degrees C with
9 to 12-bit precision from -55C to 125C (+/- 0.5C).
Each sensor has a unique 64-Bit Serial number etched into it. This allows for a number of sensors to be
used on one data bus. This sensor is used in many data-logging and temperature control projects.
#include <DS18B20.h>
Note the GCBASIC commands do not work with the older DS1820 or DS18S20 as they have a different
internal resolution. These commands are not designed to be used with parasitically powered DS18B20
sensors, the 5V pin of the sensor must
ReadDigitalTemp
Syntax:
ReadDigitalTemp
Command Availability:
Explanation:
Return the value of the sensor. The following two lines must be included in the GCBASIC source file.
#include <DS18B20.h>
#define DQ PortC.3 ; change port configuration as required
The method returns whole part of the sensor value in the byte variable DSint, the method also returns
decimal part of the sensor value in the byte variable DSdec.
Example:
'Chip Settings. Assumes the development board with with a 16F877A
#chip 16F877A,1
*#include <DS18B20.h>*
ReadDigitalTemp
ReadTemp
Syntax:
byte_var = ReadTemp
Command Availability:
Explanation:
A function that returns the value of the sensor. The following two lines must be included in the
GCBASIC source file.
#include <DS18B20.h>
#define DQ PortC.3 ; change port configuration as required
Reads sensor and stores in output variable. The conversion takes up to 750ms. Readtemp carries out a
full 12 bit conversion and then rounds the result to the nearest full degree Celsius (byte_value). For the
full 12 bit value use the readtemp12 command.
The temperature is read back in whole degree steps, and the sensor operates from -55 to + 125 degrees
Celsius. Note that bit 7 is 0 for positive temperature values and 1 for negative values (ie negative values
will appear as 128 + numeric value).
Note the Readtemp command does not work with the older DS1820 or DS18S20 as they have a different
internal resolution. This command is not designed to be used with parasitically powered DS18B20
sensors, the 5V pin of the sensor must be connected.
Example:
'Chip Settings. Assumes the development board with with a 16F877A
#chip 16F877A,1
#include <DS18B20.h>
ccount = 0
CLS
do forever
' The function readtemp returns the integer value of the sensor
DSdata = readtemp
wait 2 s
ccount++
loop
ReadTemp12
Syntax:
byte_var = ReadTemp12
Command Availability:
Available on all microcontrollers.
Explanation:
A function that returns the raw value of the sensor. The following two lines must be included in the
GCBASIC source file.
#include <DS18B20.h>
#define DQ PortC.3 ; change port configuration as required
Reads sensor and stores in output variable. The conversion takes up to 750ms. Readtemp12 carries out
a full 12 bit conversion.
This command is for advanced users only. For standard ‘whole degree’ data use the readtemp
command.
The temperature is read back as the raw 12 bit data into a word variable (0.0625 degree resolution).
The user must interpret the data through mathematical manipulation. See the DS18B20 datasheet for
more information on the 12 bit temperature/data information construct.
Note the readtemp12 command does not work with the older DS1820 or DS18S20 as they have a
different internal resolution. This command is not designed to be used with parasitically powered
DS18B20 sensors, the 5V pin of the sensor must be connected.
Example:
#include <DS18B20.h>
do forever
'Display the integer and decimal value of the sensor on the LCD
' The function readtemp12 returns the raw value of the sensor.
' The sensor is read as a 12 bit value. Each unit equates to 0.0625 of a degree
DSdata = readtemp12
SignBit = DSdata / 256 / 128
If SignBit = 0 Then goto Positive
' its negative!
DSdata = ( DSdata # 0xffff ) + 1 ' take twos comp
Positive:
' Convert value * 0.0625. Mulitple value by 6 then add result to multiplication of the
value with 25 then divide result by 100.
TempC_100 = DSdata * 6
DSdata = ( DSdata * 25 ) / 100
TempC_100 = TempC_100 + DSdata
DisplayTemp:
locate 1,0
print hex(ccount)
print " Real"
locate 1,8
print str(Whole)
print "."
' To ensure the decimal part is two digits
Dig = Fract / 10
print Dig
Dig = Fract % 10
print Dig
print chr(223)
print "C"
wait 2 s
ccount++
loop
Serial Communications
RS232 (software)
Introduction:
These routines allow the microcontroller to send and receive RS232 data.
All functions are implemented using software, so no special hardware is required on the
microcontroller. However, if the microcontroller has a hardware serial module (usually referred to as
UART or USART), and the serial data lines are connected to the appropriate pins, the hardware routines
should be used for smaller code, improved reliability and higher baud rates.
Relevant Constants:
These constants are used to control settings for the RS232 serial communication routines. To set them,
place a line in the main program file that uses #define to assign a value to the particular constant.
RecALow, RecBLow, RecCLow The condition that is true when Sys232Temp.0 OFF
a low bit is being received (must be set)
InitSer
Syntax:
Command Availability:
This command will set up the serial communications. The parameters are as follows:
• channel is 1, 2 or 3, and refers to the I/O ports that are used for communication.
• rate is the bit rate, which is given by the letter r and then the desiredrate in bps. Acceptable units
are r300, r600, r1200, r2400, r4800, r9600 and r19200.
• start gives the number of start bits, which is usually 1. To make the PIC wait for the start bit before
proceeding with the receive, add 128 to start. (Note: it may be desirable to use the WaitForStart
constant here.)
• data tells the program how many data bits are to be sent or received. In most situations t his is 8,
but it can range between 1 and 8, inclusive.
• stop is the number of stop bits. If start bit 7 is on, then this number will be ignored.
• parity refers to a system of error checking used by many devices. It can be odd (in which there
must always be an odd number of high bits), even (where the number of high bits must always be
even), or none (for systems that do not use parity).
• invert can be either "normal" or "invert". If it in "invert", then high bits will be changed to low, and
low to high.
Example:
SerSend
Syntax:
Command Availability:
Explanation:
This command will send a byte given by data using the RS232 channel referred to as channel according
to the rules set using InitSer.
Example:
'This program will send a byte using PORTB.2, the value of which
'depends on whether a button is pressed. This can be used with the example for
SerReceive.
#chip 16F819, 8
#config Osc = Int
Dir Button In
Dir PORTB.2 Out
SerReceive
Syntax:
Command Availability:
Explanation:
This command will read a byte from the RS232 channel given by channel according to the rules set
using InitSer, and store the received byte in the variable output.
Example:
'This program will read a byte from PORTB.2, and set the LED on if
'the byte is more than 50. This can be used with the SerSend
'example program.
#chip 16F88, 8
#config Osc = Int
SerPrint
Syntax:
Command Availability:
Explanation:
SerPrint is used to send a value over the serial connection. value can be a string, integer, word or byte -
SerPrint is very similar to Print. channel is the serial connection to send data through. SerPrint will not
send any new line characters. If the chip is sending to a terminal, these commands should follow every
SerPrint:
SerSend channel, 13
SerSend channel, 10
Example:
'This program will display any values received over the serial
'connection. If "pot" is received, the value of the analog sensor
'will be sent.
'Chip settings
#chip 18F2525, 8
#config Osc = Int
'LCD settings
#define LCD_IO 4
#define LCD_RS PORTC.7
#define LCD_RW PORTC.6
#define LCD_Enable PORTC.5
#define LCD_DB4 PORTC.4
#define LCD_DB5 PORTC.3
#define LCD_DB6 PORTC.2
#define LCD_DB7 PORTC.1
'Serial settings
#define SerInPort PORTB.6
#define SerOutPort PORTB.7
'Potentiometer
#define POT_PORT PORTA.0
#define POT_AN AN0
'Main loop
Do
'Get a byte from the terminal
SerReceive 1, Temp
BufferSize = 0
End If
'Backspace code, delete last character in buffer
If Temp = 8 Then
If BufferSize > 0 Then BufferSize -= 1
End If
'Received ASCII code between 32 and 127, add to buffer
If Temp >= 32 And Temp <= 127 Then
BufferSize += 1
Buffer(BufferSize) = Temp
End If
Loop
RS232 (hardware)
Introduction
These subroutines allow GCBASIC programs to communicate more easily using RS232.
These hardware-based routines are intended for use on microcontrollers with built in RS232 modules -
normally referred to in datasheets as USART or UART modules. To use these, the RS232 data lines must
be connected to the pins on the microcontroller used by the serial module. If the RS232 lines are
connected elsewhere, or the microcontroller has no RS232 module, then the software based routines
must be used.
Relevant Constants
An additional delay may be required in programs to ensure the usart buffer is empty
NOTE before the end of the program. If you do not include a delay, typcally 100 ms, you may
lose a few characters as the microcomputer goes to sleep at the end of the program.
HSerPrint
Syntax:
HSerPrint value
Command Availability:
Explanation:
HSerPrint is used to send a value over the serial connection. value can be a string, integers, long, word
or byte. HSerPrint is very similar to Print. The channel used will be the hardware serial connection.
HSerPrint will not send any new line characters. If the chip is sending to a terminal, these commands
should follow every HSerPrint :
HSerPrint 13
HSerPrint 10
Example:
'This program will display any values received over the serial
'connection. If "pot" is received, the value of the analog sensor
'will be sent.
'Note: This has been adapted from the SerPrint example.
'Chip settings
#chip 18F2525, 8
#config Osc = Int
'LCD settings
#define LCD_IO 4
#define LCD_RS PORTC.7
#define LCD_RW PORTC.6
#define LCD_Enable PORTC.5
#define LCD_DB4 PORTC.4
#define LCD_DB5 PORTC.3
#define LCD_DB6 PORTC.2
#define LCD_DB7 PORTC.1
'USART settings
#define USART_BAUD_RATE 9600
'Potentiometer
#define POT_PORT PORTA.0
#define POT_AN AN0
'Main loop
Do
'Get a byte from the terminal
HSerReceive Temp
BufferSize = 0
End If
'Backspace code, delete last character in buffer
If Temp = 8 Then
If BufferSize > 0 Then BufferSize -= 1
End If
'Received ASCII code between 32 and 127, add to buffer
If Temp >= 32 And Temp <= 127 Then
BufferSize += 1
Buffer(BufferSize) = Temp
End If
Loop
HserPrintByteCRLF
HserPrintCRLF
HSerReceive
Syntax:
Used as subroutine:
HSerReceive output
Used as function:
output = HSerReceive
Command Availability:
Explanation:
This command will read a byte from the hardware RS232 module. It can be used either as a subroutine
or as a function. If used as a subroutine, a variable must be supplied to store the received value in. If
used as a function, it will return the received value.
Example:
'This program will read a value from the USART, and display it on PORTB.
#chip 16F877A, 20
'USART settings
#define USART_BAUD_RATE 9600
'Main loop
Do
'Get and display value
'If there is no new data, HSerReceive will return old value.
HSerReceive PORTB
'Could also write:
'PORTB = HSerReceive
Loop
HSerSend
Syntax:
HSerSend data
Command Availability:
Explanation:
This command will send a byte given by data using the hardware RS232 module.
Example:
'This program will send the status of PORTB through the hardware
'serial module.
#chip 16F877A, 20
'USART settings
#define USART_BAUD_RATE 9600
'Main loop
Do
'Send PORTB value through USART
HSerSend PORTB
'Short delay for receiver to process message
Wait 10 ms
Loop
HserPrintByteCRLF
Syntax:
HserPrintByteCRLF data
Command Availability:
Explanation:
This command will send a byte given by _data_using the hardware RS232 module and then send the
ASCII codes 13 and 10. ASCII codes 13 and 10 equate to a carriage return and line feed.
Example:
'This program will send the status of PORTB through the hardware serial module.
HserPrintCRLF
Syntax:
Command Availability:
Explanation:
This command will send ASCII codes 13 and 10 only using the hardware RS232 module. ASCII codes 13
and 10 equate to a carriage return and line feed.
Optionally, you can add a parameter. The number will determine the number of ASCII codes 13 and 10
set to the hardware RS232 module.
Example:
'This program will send the status of PORTB through the hardware serial module.
PS/2
PS/2 Overview
Introduction
These routines make it easier to communicate with a PS/2 device, particularly a keyboard.
Relevant Constants
InKey
Syntax:
output = InKey
Command Availability:
Explanation:
The InKey function will read the last pressed key from a PS/2 keyboard, and return an ASCII value
corresponding to the key. If no key is pressed, then InKey will return 0.
It will also monitor Caps Lock, Num Lock and Scroll Lock keys, and update the status LEDs as
appropriate.
Example:
'Hardware settings
#chip 18F4620, 20
Main:
'Read the last pressed key
KeyIn = INKEY
'If no key pressed, try reading again
If KeyIn = 0 Then Goto Main
DisplayData:
'Display key buffer
'LCDWriteChar is used instead of Print for greater control
CLS
For DataPos = 1 to DataCount
If DataPos = 17 then Locate 1, 0
LCDWriteChar KeyLog(DataPos)
Next
Goto Main
PS2SetKBLeds
Syntax:
PS2SetKBLeds (LedStatus)
Command Availability:
Explanation:
This routine will turn the status LEDs on a keyboard on or off. LedStatus is a variable, of which the
lower 3 bits correspond to the 3 LEDs. Bit 0 is for Scroll Lock, bit 1 controls Num Lock and bit 2 controls
Caps Lock.
Note that this routine does not alter the status variables within the INKEY routine - so even if the Caps
Lock LED is turned on, Caps Lock will stay off.
Example:
'A spinning LED program for a keyboard
'Will flash Num Lock, then Caps Lock, then Scroll Lock.
'Hardware settings
#chip 16F88, 8
'Main Loop
Do
Loop
PS2ReadByte
Syntax:
output = PS2ReadByte
Command Availability:
Explanation:
PS2ReadByte will read a byte from the PS/2 bus. It will return the byte, or 0 if no data was returned by
the PS/2 device.
The PS/2 bus will normally be held in the inhibit state. PS2ReadByte will uninhibit the bus for 25 ms. If a
response is received, it will be read. Then, the bus will be placed back in the inhibit state.
Example:
For an example, please refer to the InKey function in the ps2.h file.
PS2WriteByte
Syntax:
PS2WriteByte data
Command Availability:
Explanation:
PS2WriteByte will send a byte to a PS/2 device. Once the byte has been written, the PS/2 bus will be
placed in the inhibit state.
Example:
For an example, please refer to the PS2SetKBLeds function in the ps2.h file.
SPI
SPIMode
Syntax:
SPIMode Mode
Command Availability:
Explanation:
SPIMode sets the mode of the SPI module within the PIC chip. These are the possible SPI Modes:
SPITransfer
Syntax:
SPITransfer tx, rx
Command Availability:
Explanation:
This command simultaneously sends and receives a byte of data using the SPI protocol. It behaves
differently depending on whether the PIC has been set to act as a master or a slave. When operating as
a master, SPITransfer will initiate a transfer. The data in tx will be sent to the slave, whilst the byte that
is buffered in the slave will be read into rx. In slave mode, the SPITransfer command will pause the
program until a transfer is initiated by the master. At this point, it will send the data in tx whilst
reading the transmission from the master into the rx variable.
Example:
There are two example programs for this command - one to run on the slave PIC, and one on the
master. A reading is taken from a sensor on the slave, and sent across to the master which shows the
data on its LCD screen.
Slave Program:
'Select chip model and configuration
#chip 16F88, 20
#config MCLR_OFF
Master Program:
'General hardware configuration
#chip 16F877A, 20
'Main Loop
do
'Read a byte from the slave
'No data to send, so tx is 0
SPITransfer 0, Temp
'Display data
if Temp > 0 then
CLS
Print "Light: "
LCDInt Temp
Temp = 0
end if
'Wait to allow time for the LCD to show the given value
wait 100 ms
loop
I2C Software
I2C Overview
Introduction:
These software routines allow GCBASIC programs to send and receive I2C messages. They can be
configured to act as master or slave, and the speed can also be altered.
No hardware I2C module is required for these routines - all communication is handled in software.
However, these routines will not work on 12-bit instruction PICs (10F, 12F5xx and 16F5xx chips).
Relevant Constants:
Example: This example examines the IC2 devices and displays on a terminal. This code will require
adaption but the code shows an approach to discover the IC2 devices.
' I2C Overview - using the ChipIno board, see here for information
#chip 16F886, 8
#config MCLRE_ON
HSerPrintCRLF 2
HSerPrint "I2C Discover using the ChipIno"
HSerPrintCRLF 2
wait 100 ms
dim DeviceID as byte
for DeviceID = 0 to 255
I2CStart
I2CSend ( deviceID )
I2CSend ( 0 )
I2CSend ( 0 )
i2cstop
HSerPrint "__"
HSerPrint "ID: 0x"
HSerPrint hex(deviceID)
HSerPrint " (d"
HSerPrint Str(deviceID)
HSerPrint ")"
HSerPrintCRLF
end if
next
HSerPrint "End of Device Search": HSerPrintCRLF 2
End
Supported in <I2C.H>
I2CAckPollState
Syntax:
Command Availability:
Only available in GCB I2C.h with release after 1/2014 Available on all microcontrollers except 12 bit
instruction PICs (10F, 12F5xx, 16F5xx chips)
Explanation:
Should only be used when I2C routines are operating in Master mode, this command will return the
last state of the acknowledge response from a specific I2C device on the I2C bus.
I2CACKPOLL sets the state of variable I2CAckPollState. I2CAckPollState can only read - it cannot be set.
Example:
...
' ACK polling removes the need to for the 24xxxxx device to have a 5ms
write time
I2CACKPOLL( eeprom_device )
' You check the exit state,
' Use I2CAckPollState to check the state of a target device
...
Supported in <I2C.H>
I2CAckpoll
Syntax:
I2CAckpoll ( I2C_device_address )
Command Availability:
Only available in GCB I2C.h with release after 1/2014 Available on all microcontrollers except 12 bit
instruction PICs (10F, 12F5xx, 16F5xx chips)
Explanation:
Should only be used when I2C routines are operating in Master mode, this command will look for a
specific I2C device on the I2C bus.
This sets a global variable I2CAckPollState that can be inspected in your calling routine.
Example:
...
' ACK polling removes the need to for the 24xxxxx device to have a 5ms write time
I2CACKPOLL( eeprom_device )
' You check the exit state, use I2CAckPollState to check the state of
' the acknowledge from the target device
...
Supported in <I2C.H>
I2CReceive
Syntax:
I2CReceive data
I2CReceive data, ack
Command Availability:
Available on all microcontrollers except 12 bit instruction PICs (10F, 12F5xx, 16F5xx chips)
Explanation:
The I2CReceive command will send data through the I2C connection. If ack is TRUE, or no value is given
for ack, then I2CReceive will send an ack.
If in slave mode, I2CReceive will wait for the master to send the data before reading. When the method
I2CReceive is used in Slave mode the global variable I2CMatch will be set to true when the received
value is equal to the constant I2C_ADDRESS.
#chip 16F886, 8
#config MCLRE_ON
'I2C settings
#define I2C_MODE Master
#define I2C_DATA PORTC.4
#define I2C_CLOCK PORTC.3
'Misc settings
#define LED PORTB.5
dir LED Out
'Main loop
Do
'Send start
I2CStart
'Request value
I2CSend 83
I2CSend 1
'Read value
I2CReceive ValueIn
'Send stop
I2CStop
'Delay
Wait 20 ms
Loop
See the I2C Overview for the Master mode device to control this Slave mode device.
#chip 16F88, 8
#config INTRC_IO,MCLR_OFF
;----- Variables
;----- Program
#define LED0 porta.2 ;pin 1
#define LED1 porta.3 ;pin 2
#define LED2 porta.4 ;pin 3
do
I2CStart ;wait for Start signal
I2CReceive( addr ) ;then wait for an address
case 1:
if value then
set LED1 on
else
set LED1 off
end if
case 2:
if value then
set LED2 on
else
set LED2 off
end if
case else
;other register numbers are ignored
end select
else
I2CStop ;release bus in any event
end if
loop
Supported in <I2C.H>
I2CReset
Syntax:
I2CReset
Command Availability:
Available on all microcontrollers except 12 bit instruction PICs (10F, 12F5xx, 16F5xx chips)
Explanation:
This will attempt a reset of the I2C by changing the state of the I2C bus.
Example:
...
I2CReset
...
Supported in <I2C.H>
I2CRestart
Syntax:
I2CRestart
Command Availability:
Available on all microcontrollers except 12 bit instruction PICs (10F, 12F5xx, 16F5xx chips)
Explanation:
If the I2C routines are operating in Master mode, this command will send a start and restart condition
in a single command.
Example:
...
I2CRESTART
....
Supported in <I2C.H>
I2CSend
Syntax:
I2CSend data
I2CSend data, ack
Command Availability:
Available on all microcontrollers except 12 bit instruction PICs (10F, 12F5xx, 16F5xx chips)
Explanation:
The I2CSend command will send data through the I2C connection. If ack is TRUE, or no value is given
for ack, then I2CSend will wait for an Ack from the receiver before continuing. If in master mode,
I2CSend will send the data immediately. If in slave mode, I2CSend will wait for the master to request the
data before sending.
Example 1:
' I2CSend - using the ChipIno board, see here for information.
' This program send commands to a GCB Slave with three LEDs attached.
#chip 16F886, 8
#config MCLRE_ON
'I2C settings
#define I2C_MODE Master
#define I2C_DATA PORTC.4
#define I2C_CLOCK PORTC.3
#define I2C_BIT_DELAY 20 us
#define I2C_CLOCK_DELAY 30 us
;----- Program
do
loop
Example 2:
'This program will act as an I2C analog to digital converter
'When data is requested from address 83, registers 0 through
'3, it will return the value of AN0 through AN3.
'Chip model
#chip 16F88, 8
'I2C settings
#define I2C_MODE Slave
#define I2C_CLOCK PORTB.0
#define I2C_DATA PORTB.1
#define I2C_DISABLE_INTERRUPTS ON
'Main loop
Do
'Wait for start condition
I2CStart
'Get address
I2CReceive Address
If Address = 83 Then
'If address was this device's address, respond
I2CReceive Register
OutValue = ReadAD(Register)
I2CSend OutValue
End If
I2CStop
Wait 5 ms
Loop
Supported in <I2C.H>
I2CStart
Syntax:
I2CStart
Command Availability:
Available on all microcontrollers except 12 bit instruction PICs (10F, 12F5xx, 16F5xx chips)
Explanation:
If the I2C routines are operating in Master mode, this command will send a start condition. If routines
are in Slave mode, it will pause the program until a start condition is sent by the master. It should be
placed at the start of every I2C transmission.
Example:
Supported in <I2C.H>
I2CStop
Syntax: I2CStop
Command Availability:
Available on all microcontrollers except 12 bit instruction PICs (10F, 12F5xx, 16F5xx chips)
Explanation:
When in Master mode, this command will send an I2C stop condition, and re-enable interrupts if
I2CStart disabled them. In Slave mode, it will re- enable interrupts.
Example:
Supported in <I2C.H>
HI2C Overview
Introduction:
These methods allow GCBASIC programs to send and receive Inter- Integrated Circuit (I2C™) messages
via:
1. The Master Synchronous Serial Port (MSSP) module of the microcomputer for the Microchip
architecture
2. Or, ATMEL 2-wire Serial Interface (TWI) for the AVR microcontroller architecture.
These methods are serial interfaces that are useful for communicating with other peripheral or
microcontroller devices. These peripheral devices may be serial EEPROMs, shift registers, display
drivers, A/D converters, etc.
1. Master Mode, or
The method in I2C mode fully implements all master and slave functions (including general call
support) and provides interrupts on start and stop bits in hardware to determine a free bus (multi-
master function).
The method implements the standard mode specifications as well as 7-bit and 10-bit addressing. A
“glitch” filter is built into the SCL and SDA pins when the pin is an input. This filter operates in both
the 100 KHz and 400 KHz modes. In the 100 KHz mode, when these pins are an output, there is a slew
rate control of the pin that is independent of device frequency.
A hardware I2C module within the microcontroller is required for these methods.
The driver supports two hardware I2C ports. The second port is addressed by the suffix HI2C2. All
HI2C commands are applicable to the second HI2C2 port.
Relevant Constants:
Port Settings:
The settings of the pin direction is critical to the operation of these methods. Both pins must be set as
inputs and be pulled up with an appropriate resistor (typically 4.k @ 5.0v for 100Mkz transmissions).
Example:
This example examines the IC2 devices and displays on a serial terminal. This code will require
adaption but the code shows an approach to discover the IC2 devices.
#chip mega328p, 16
#config MCLRE_ON
'MASTER MODE
HI2CMode Master
HSerPrintCRLF 2
HSerPrint "Hardware I2C Discover using the "
HSerPrint CHipNameStr
HSerPrintCRLF 2
HI2CSend ( 0 )
HI2CSend ( 0 )
end if
HI2CStop
next
HSerPrintCRLF
HSerPrint "End of Device Search"
HSerPrintCRLF 2
Supported in <HI2C.H>
HI2CAckPollState
Syntax:
Command Availability:
Only available in GCB HI2C.h with release after 6/2014 and microcontrollers with the hardware I2C or
TWI module.
Explanation:
Should only be used when I2C routines are operating in Master mode, this command will return the
last state of the acknowledge response from a specific I2C device on the I2C bus.
Example:
This example code would display only the devices on the I2C bus.
...
for deviceID = 0 to 255
HI2CStart
HI2CSend ( deviceID )
Supported in <HI2C.H>
HI2CReceive
Syntax:
HI2CReceive data
Command Availability:
Only available for microcontrollers with the hardware I2C or TWI module.
Explanation:
The HI2CReceive command will send data through the I2C connection. If ack is TRUE, or no value is
given for ack, then I2CReceive will send an ack to the I2C bus.
If in master mode, I2CReceive will read the data immediately. If in slave mode, I2CReceive will wait for
the master to send the data before reading.
NOTE This command is also available on microcomputers with a second hardware I2C port.
Example 1:
'This program reads an I2C register and sets an LED if it is over 100.
'It will read from I2C device with an address of 83, register 1.
' Change the processor
#chip 16F1937, 32
#config Osc = intOSC, MCLRE_ON, PLLEN_ON, VCAPEN_OFF
'Misc settings
#define LED PORTB.0
'Main loop
Do
'Send start
HI2CStart
'Request value
HI2CSend 83
HI2CSend 1
'Read value
HI2CReceive ValueIn
'Send stop
HI2CStop
'Delay
Wait 20 ms
Loop
Example 2:
See the I2C Overview for the Master mode device to control this Slave mode device.
' I2CHardwareReceive_Slave.gcb - using a 16F88.
' This program receives commands from a GCB Master. This Slave has three LEDs attached.
; This Slave device responds to address 0x60 and may only be written to.
; Within it, there are three registers, 0,1 and 2 corresponding to the three LEDs.
Writing a zero
; turns the respective LED off. Writing anything else turns it on.
#chip 16F88, 4
#config INTRC_IO,MCLR_Off
#define I2C_BIT_DELAY 20 us
#define I2C_CLOCK_DELAY 10 us
#define I2C_END_DELAY 10 us
'Serial settings
#define SerInPort PORTB.6
#define SerOutPort PORTB.7
;----- Variables
do forever
if reg <> oldreg then ; only process when the reg is a new value
oldreg = reg ; retain old value
show = 1 ; its time to show the LEDS!
if value <> oldvalue then ; logic for tracking old values. You only want to
update terminal once per change
oldvalue = value
show = 1
end if
end if
SerPrint 1, "0x"+hex(addr)
SerSend 1,9
SerPrint 1, STR(reg)
SerSend 1,9
SerPrint 1, STR(value)
SerSend 1,10
SerSend 1,13
show = 0
end if
loop
Sub I2C_Interrupt
' handle interrupt
IF SSPIF=1 THEN ; its a valid interrupt
end if
IF addr = ( I2C_ADDRESS | 1 ) THEN ; its our write address
CKP = 0 ; acknowledge command
; If the SDA line was low (ACK), the
transmit data must be loaded into
; the SSPBUF register which also loads
the SSPSR
; register. Then, pin RB4/SCK/SCL should
be enabled
; by setting bit CKP.
else
if SSPSTAT.P = 1 then ' Stop bit has been detected - out of
sequence
' handle event
end if
IF SSPSTAT.S = 1 THEN ' Start bit has been detected - out of
sequence
' handle event
END IF
END IF
END IF
CKP = 1 ' acknowledge command
SSPOV = 0 ' acknowledge command
END IF
SSPIF=0
END SUB
sub UpdateLEDS
select case reg ;now turn proper LED on or off
case 0
if value = 1 then
set LED0 on
else
set LED0 off
end if
case 1
if value = 1 then
set LED1 on
else
set LED1 off
end if
case 2
if value = 1 then
set LED2 on
else
set LED2 off
end if
end select
End Sub
Supported in <HI2C.H>
HI2CRestart
Syntax:
HI2CRestart
Command Availability:
Only available for microcontrollers with the hardware I2C or TWI module.
Explanation:
If the HI2C routines are operating in Master mode, this command will send a start and restart
condition in a single command.
NOTE This command is also available on microcomputers with a second hardware I2C port.
Example:
do
HI2CReStart ;generate a start signal
HI2CSend(eepDev) ;inidcate a write
loop While HI2CAckPollState
Supported in <HI2C.H>
HI2CSend
Syntax:
HI2CSend data
Command Availability:
Explanation:
The HI2CSend command will send data through the I2C connection. If in master mode, HI2CSend will
send the data immediately. If in slave mode, HI2CSend will wait for the master to request the data
before sending.
Example:
This example code retrieves multiple bytes from an EEPROM memory device.
do
HI2CReStart ;generate a start signal
HI2CSend(eepDev) ;indicate a write
loop While HI2CAckPollState
Supported in <HI2C.H>
HI2CStart
Syntax:
HI2CStart
Command Availability:
Explanation:
If the HI2C routines are operating in Master mode, this command will send a start condition. If
routines are in Slave mode, it will pause the program until a start condition is sent by the master. It
should be placed at the start of every I2C transmission.
Example:
Supported in <HI2C.H>
HI2CStartOccurred
Syntax:
HI2CStartOccurred
Command Availability:
Only available for microcontrollers with the hardware I2C or TWI module.
Explanation:
Check if a start condition has occurred since the last run of this function
NOTE This command is also available on microcomputers with a second hardware I2C port.
Supported in <HI2C.H>
HI2CMode
Syntax:
Command Availability:
Only available for microcontrollers with the hardware I2C or TWI module.
Explanation:
NOTE This command is also available on microcomputers with a second hardware I2C port.
Supported in <HI2C.H>
HI2CSetAddress
Syntax:
HI2CSetAddress <number>
Command Availability:
Only available for microcontrollers with the hardware I2C or TWI module.
Explanation:
NOTE This command is also available on microcomputers with a second hardware I2C port.
Supported in <HI2C.H>
HI2CStop
Syntax:
HI2CStop
Command Availability:
Only available for microcontrollers with the hardware I2C or TWI module.
Explanation:
Example:
NOTE This command is also available on microcomputers with a second hardware I2C port.
Supported in <HI2C.H>
HI2CStopped
Syntax:
HI2CStopped
Command Availability:
Only available for microcontrollers with the hardware I2C or TWI module.
Explanation:
In Slave mode only. Check if start condition received since last used of HI2CStopped.
NOTE This command is also available on microcomputers with a second hardware I2C port.
Supported in <HI2C.H>
Sound
Sound Overview
Introduction:
Note: If an exact frequency is required, or a smaller program is needed, these routines should not be
used. Instead, you should use code like this:
Repeat count
PulseOut SoundOut, period us
Wait period us
End Repeat
Relevant Constants:
These constants are used to control settings for the tone generation routines. To set them, place a line
in the main program file that uses #define to assign a value to the particular constant.
Tone
Syntax:
Explanation:
This command will produce the specified tone for the specified duration. Frequency is measured in Hz,
and Duration is in 10 ms units.
Please note that this command may not produce the exact frequency specified. While it is accurate
enough for error beeps and small pieces of monophonic music, it should not be used for anything that
requires a highly precise frequency.
Example:
Do
Tone 440, 1000
Loop
ShortTone
Syntax:
Command Availability:
Explanation:
This command will produce the specified tone for the specified duration. Frequency is measured in
units of 10 Hz, and Duration is in 1 ms units. Please note that this command may not produce the exact
frequency specified. While it is accurate enough for error beeps and small pieces of monophonic
music, it should not be used for anything that requires a highly precise frequency.
Example:
'Sample program to produce a tone on PORTB bit 1, based on the
'reading of an LDR on AN0 (usually PORTA bit 0).
#chip 16F88, 20
#define SoundOut PORTB.1
Dir PORTA.0 In
Do
ShortTone ReadAD(AN0), 100
Loop
Timers
Timer Overview
Several functions are provided to read the current timer value. They are:
• Timer0
• Timer1
• Timer2
• Timer3
• Timer4
• Timer5
• Timer6
Not all of these functions are available on all chips. For example, if a chip only has 3 timers, then only
Timer0, Timer1 and Timer2 will be available. Timer0 and Timer2 return byte values, while Timer1, Timer3,
Timer4, Timer5 and Timer6 will return words.
Please refer to the datasheet for your microcontroller to determine the number and size of the timers
available.
ClearTimer
Syntax:
ClearTimer TimerNo
Command Availability:
Available on all PIC and AVR microcontrollers with built in timer modules.
Explanation:
Example:
InitTimer0
Syntax:
Command Availability:
Explanation:
InitTimer0 will set up timer 0, according to the settings given. `source can be Osc or Ext.
These correspond to a prescaler of between 1/2 and 1/256 the oscillator speed. The prescaler will apply
to either the oscillator or the external clock input.
1 PS_1 PS0_1/2 1
8 PS_8 PS0_1/4 2
64 PS_16 PS0_1/8 3
These correspond to a prescaler of between 1/1 and 1/1024 times the original input frequency. On the
AVR, the prescaler will only apply when the timer is driven from the internal oscillator - the prescaler
has no effect on the external clock pulse.
When the timer overflows from 255 to 0, a Timer0Overflow interrupt will be generated. This can be
used in conjunction with On Interrupt to run a section of code periodically.
Example:
#chip 16F88, 8
#config osc = int
'Main routine
Do
'Increase speed to full over 2.5 seconds
For Speed = 0 to 100
MotorSpeed = Speed
Wait 25 ms
Next
'Hold speed
Wait 1 s
'Decrease speed to zero over 2.5 seconds
For Speed = 100 to 0
MotorSpeed = Speed
Wait 25 ms
Next
'Hold speed
Wait 1 s
Loop
'Setup routine
Sub InitMotorControl
'Clear variables
MotorSpeed = 0
PWMCounter = 0
'PWM sub
'This will be called when Timer 0 overflows
Sub PWMHandler
If MotorSpeed > PWMCounter Then
Set MOTOR On
Else
Set MOTOR Off
End If
PWMCounter += 1
If PWMCounter = 100 Then PWMCounter = 0
End Sub
Supported in <TIMER.H>
InitTimer1
Syntax:
Command Availability:
Explanation:
InitTimer1 will set up timer 1, according to the settings given. source can be Osc , Ext or ExtOsc (ExtOsc is
only available on PIC microcontrollers). On a PIC, prescaler can be one of the following settings:
• PS1_1
• PS1_2
• PS1_4
• PS1_8
• PS_1
• PS_8
• PS_64
• PS_256
• PS_1024
Example:
'This example will measure that time that a switch stays on for
#chip 16F819, 20
#define Switch PORTA.0
Dir Switch In
DataCount = 0
InitTimer1 Osc, PS1_8
Do
ClearTimer 1
Wait Until Switch = On
StartTimer 1
Wait Until Switch = Off
StopTimer 1
Syntax:
Command Availability:
Explanation:
InitTimer2 will set up timer 2, according to the settings given. . On a PIC. prescaler can be one of the
following settings:
- PS2_1/1 0
- PS2_1/4 1
- PS2_1/16 2
- PS2_1 0
- PS2_4 1
- PS2_16 2
postscaler slows the rate of the interrupt generation (or WDT reset) from a counter/timer by dividing it
down. Postscaler values from 1:1 to 1:16
InitTimer3
Syntax:
Command Availability:
Explanation:
InitTimer3 will set up timer 3, according to the settings given. source can be Osc , Ext or ExtOsc (ExtOsc is
only available on PIC microcontrollers). On a PIC, prescaler can be one of the following settings:
· PS3_1/1 0
· PS3_1/2 16
· PS3_1/4 32
· PS3_1/8 48
· PS3_1 0
· PS3_2 16
· PS3_4 32
· PS3_8 48
· PS_1
· PS_8
· PS_64
· PS_256
· PS_1024
InitTimer4
Syntax:
Command Availability:
Explanation:
InitTimer4 will set up timer 4, according to the settings given. source can be Osc , Ext or ExtOsc (ExtOsc is
only available on PIC microcontrollers). On a PIC, prescaler can be one of the following settings:
· PS4_1/1 0
· PS4_1/4 1
· PS4_1/16 2
· PS4_1/64 3
· PS4_1 0
· PS4_4 1
· PS4_16 2
· PS4_64 3
InitTimer6
Syntax:
Command Availability:
Explanation:
InitTimer6 will set up timer 6, according to the settings given. source can be Osc , Ext or ExtOsc (ExtOsc is
only available on PIC microcontrollers). On a PIC, prescaler can be one of the following settings:
· PS6_1/1 0
· PS6_1/4 1
· PS6_1/16 2
· PS6_1/64 3
· PS6_1 0
· PS6_4 1
· PS6_16 2
· PS6_64 3
· PS_1
· PS_8
· PS_64
· PS_256
· PS_1024
Settimer
Syntax:
Settimer timernumber, value
Command Availability:
Explanation:
StartTimer
Syntax:
StartTimer TimerNo
Command Availability:
Available on all PIC and AVR microcontrollers with built in timer modules.
Explanation:
StartTimer is used to start the specified timer. Note that it cannot be used to start Timer 0 on a PIC - this
timer always runs.
Example:
StopTimer
Syntax:
StopTimer TimerNo
Command Availability:
Available on all PIC and AVR microcontrollers with built in timer modules.
Explanation:
StopTimer is used to stop the specified timer. Note that it cannot be used to stop Timer 0 on a PIC - this
timer always runs.
Example:
Please refer to the InitTimer1 article for an example.
Reading Timers
Several functions are provided to read the current timer value. They are:
· Timer0
· Timer1
· Timer2
· Timer3
· Timer4
· Timer5
· Timer6
Not all of these functions are available on all chips. For example, if a chip only has 3 timers, then only
Timer0, Timer1 and Timer2 will be available. Timer0 and Timer2 return byte values, while Timer1, Timer3,
Timer4, Timer5 and Timer6 will return words.
Please refer to the datasheet for your microcontroller to determine the number and size of the timers
available.
Variables Operations
Using Variables
Variables
Using and accessing bytes within word and long numbers etc may be required when you are creating
your solution. This can be done with some ease.
You can access the bytes within word and longs variables using the following as a guide using the
Suffixes _H, _U and _E
lowb = workvariable
highb = workvariable_H
upperb = workvariable_U
lastb = workvariable_E
To further explain, where
Dim rB as Byte
Dim sW as Word
Dim sW as Word
'To use the bits 7-0 [lower byte] in the Word variable sW
rB = sW
'For bits 15-8 [upper byte] in the Word variable sW, use sw_H
rB = sW_H
To extract the bytes from a LONG of 32 bits use the Suffixes _H, _U and _E, where
Dim rB as Byte
Dim sW as Word
Dim tL as Long
Variables
Within Great Cow Basic you can use regular variable assignments. But, you can also use C like maths
assignments.
The following methods are also supported.
GLCDPrintLoc += 6
CharCode -= 15
CharCode++
CharCode---
Within Great Cow Basic you can define constants, see Constants. Please note what is and what is not
support with respect to assigning numbers to constants. An example program examines what is
supported.
#chip 16F88, 4
#config Osc = INT, MCLRE_OFF
# Proof
dir porta Out
porta = test0
porta = test1
porta = test2
porta = test3
porta = test4
porta = test5
porta = test6
You can assigned values/numbers with all the methods shown above (for constants and variables) but
please be aware that you must Use '0' not '00'. One zero equates to zero and two zeros will give you an
unassigned variable.
Constants
A few critical constants are defined within Great Cow Basic , you can re- use this constants. They
include:
#define ON 1 ' These are defined in System.h
#define OFF 0
#define TRUE 255
#define FALSE 0
+
#define OSC = 1 ' These are defined in TIMER.H
#define EXT = 2 ' and, are used by InitTimer0 command
#define EXTOSC = 3
Setting Variables
Syntax:
Variable = data
Explanation:
Variable will be set to data. data can be either a fixed value (such as 157), another variable, or a sum.
All unknown byte variables are assigned Zero. A variable with the name of Forever is not defined by
GCBasic and therefore defaults to the value of zero.
· + (add)
· - (subtract, or negate if there is no value before it)
· * (multiply)
· / (divide)
· % (modulo)
· & (and)
· | (or)
· # (xor)
· ! (not)
· = (equal)
· <> (not equal)
· < (less than)
· > (greater than)
· <= (less than or equal)
· >= (more than or equal)
The final 6 operands are for checking conditions. They will return FALSE (0) if the condition is false, or
TRUE (255) if the condition is true.
The And, Or, Xor and Not operators function both as bitwise and logical operators.
GCBASIC understands order of operations. If multiple operands are present, they will be processed in
this order:
1. Brackets
3. Multiply/Divide/Modulo
4. Add/Subtract
5. Conditional operators
6. And/Or/Xor
There are several modes in which variables can be set. GCBASIC will automatically use a different
mode for each calculation, depending on the type of variable being set. If a byte variable is being set,
byte mode will be used; if a word variable is being set, word mode will be used. If a byte is being set
but the calculation involves numbers larger than 255, word mode can be used by adding [WORD] to
the start of one of the values in the calculation. This is known as casting - refer to the Variables article
for more information.
If you prefer, you can add Let to the start of the line. It will not alter the execution of the program, but
is included for those who are used to including it in other BASIC dialects.
Example:
Dim has two uses, both of which involve large variables. It can be used to define arrays, and to declare
variables larger than 1 byte.
Syntax:
For Arrays:
Dim array(size) [At location]
Command Availability:
Explanation:
The Dim variable command is used to inform GCBASIC of variables that are larger than 1 byte, or to
create alternate names for other variables.
The Dim array command also sets up array variables. The maximum array size is determined by the
parameter size is dynamically allocated by the compiler and depends on the specific chip used, as well
as the complexity of the program.
The limit on array size varies dependent on the chip type. The 12F/16F series of chips the array limit is
80 elements. For the AVR or an 18F there is not limit other than free RAM however Great Cow Basic
limits the array size to 10,000 elements. If a memory limit is reached, the compiler will give an error
message.
type specifies the type of variable that is to be created. Different variable types can hold values over
different ranges, and use different amounts of RAM. See the Variables article for more information.
When multiple variables are included on the one line, GCBASIC will set them all to the type that is
specified at the end of the line. If there is no type specified, then GCBASIC will make the variable a byte.
Alias creates a variable using the same memory location as one or more other variables. It is mainly
used internally in GCBASIC to treat system variables as a word. For example, this command is used to
create a word variable, made up from the two memory locations used to store the result of an A/D
conversion:
A variable can be placed at a specific location in the data memory of the chip using the At option.
location will be used whether it is a valid location or not, but a warning will be generated if GCBASIC
has already allocated the memory, or if the memory does not appear to be valid. This can be used for
peripherals that have multi byte buffers in RAM.
Example:
dim DataList(10)
dim Reading as word
Reading = 21978
DataList(1) = 15
For more help, see: the SerPrint article uses Dim to create string variables and Variables for more
details in creating and managing strings lengths.
BcdToDec_GCB
Syntax:
BcdToDec_GCB ( ByteVariable )
Command Availability:
Explanation:
But, you can easily add it with this function below. Just add this to your GCB program and then call it
when you need it.
Example:
Function BcdToDec(va) as byte
BcdToDec=(va/16)*10+va%16
End Function
DecToBcd_GCB
Syntax:
DectoBcd( ByteVariable )
Command Availability:
Explanation:
But, you can easily add it with this function below. Just add this to your GCB program and then call it
when you need it.
Example:
Rotate
Syntax:
Explanation:
The Rotate command will rotate variable one bit in a specified direction. The bit shifted will be placed
in the Carry bit of the Status register (STATUS.C). STATUS.C acts as a ninth bit of the variable that is being
rotated.
When a variable is rotated right, the bit in the STATUS.C location is placed into the MSB of the variable
being rotated, and the LSB of the variable is placed into STATUS.C location.
When rotated left the opposite occurs. The MSB of the variable is shifted to the STATUS.C bit and the
LSB of the variable will contain what was previously in the STATUS.C bit location. This table shows the
operation of the Rotate Left command
As you may notice the STATUS.C bit added a 0 to the rotation. So this will take 9 shifts left to get back to
the original value.
Simple option
Many times you want to rotate the variable around like the STATUS.C bit wasn’t there so the MSB of the
variable fills the LSB of the variable on Rotate Left or the LSB fills the MSB on Rotate Right. That is
where the SIMPLE option comes in. It adds a hidden step that shifts the STATUS.C bit twice so the bit
moves from one end of the variable to the other.
#chip 16F819, 8
#config osc = int
'Chase
Do
Rotate PORTB Right Simple
Wait 250 ms
Loop
Set
Syntax:
Command Availability:
Explanation:
The purpose of the Set command is to turn individuals bits on and off. The Set command is most useful
for controlling output ports, but can also be used to set variables.
Often when controlling output ports, Set is used in conjunction with constants. This makes it easier to
adapt the program for a new circuit later.
Example:
'Blink LED sample program for GCBASIC
'Controls an LED on PORTB bit 0.
'Main routine
Do
Set LED On
Wait 1 sec
Set LED OFF
Wait 1 sec
Loop
SWAP4
Syntax:
SWAP4( VariableA)
Command Availability:
Explanation:
A function that swaps (or exchanges) nibbles (or the 8 bits of a byte in nibbles).
Example:
dim ByteVariable as Byte
HSerPrint hex(ByteVariable)
SWAP
Syntax:
Command Availability:
Explanation:
A function that swaps (or exchanges) one byte or word for another. SWAP support the use of byte and
word variables.
String Manipulation
Asc
Syntax:
Command Availability:
Explanation:
NOTE Only available in GCB compiler post 1/2014
Returns the character code of the character at the specified position in a string.
ASC returns the character code of a particular character in the string. If the string is an ANSI string, the
returned value will be in the range of 0 to 255. This function DOES NOT support UNICODE.
The optional position parameter determines which character is to be checked. The first character is
one, the second two, etc. If the position parameter is missing, the first character is presumed.
CHR is the natural complement of ASC. CHR produces a one-character string corresponding to its ASCII.
Restrictions:
If the string passed is null (zero-length) or the position is zero or greater than the length of the string
the returned value will be 0.
Example:
ByteToBin
Syntax:
stringvar = ByteToBin(bytevar)
Command Availability:
Explanation:
The ByteToBin function creates a string of a ANSI (8-byte) characters. The function converts a number
to a string consisting of ones and zeros that represents the binary value.
WARNING Supports BYTE variables only. For WORD variables use WordToBin
Example:
Chr
Syntax:
stringvar = CHR(bytevar)
Command Availability:
Explanation:
Example:
Hex
Syntax:
stringvar = Hex(number)
Command Availability:
Available on all microcontrollers
Explanation:
The Hex function will convert a number into hexadecimal format. The input number should be a byte
variable, or a fixed number between 0 and 255 inclusive. After running the function, the string
variable stringvar will contain a 2 digit hexadecimal number.
Example:
When using the functions Hex() do not leave space between the function call and the left brace. You
will get a compiler error that is meaningless.
' use this, note this is no space between the Hex and the left brace!
Hex(number_variable)
' do not use, note the space!
Hex (number_variable)
Instr
Syntax:
location = Instr(source, find)
Command Availability:
Explanation:
The Instr function will search one string to find the location of another string within it. source is the
string to search inside, and find is the string to find. The function will return the location of find within
source, or 0 if source does not contain find.
Example:
LCase
Syntax:
output = LCase(source)
Command Availability:
Available on all microcontrollers
Explanation:
The LCase function will convert all of the letters in the string source to lower case, and return the result.
Example:
Left
Syntax:
Command Availability:
Explanation:
The Left function will extract the leftmost count characters from the input string source, and return
them in a new string.
Example:
'Set chip model
#chip 16F1936
Len
Syntax:
Command Availability:
Explanation:
The Len function returns an byte value which is the length of a phrase or a sentence, including the
empty spaces. The format is:
target_byte_variable = Len("Phrase")
or another example. This code will loop through the for-next loop 12 times as determined by the length
of the string:
' create a test string of 12 characters
teststring = "0123456789AB"
for loopthrustring = 1 to len(teststring)
hserprint mid(teststring, loopthrustring , 1)
next
Ltrim
Syntax:
stringvar = LTRIM(stringvar)
Command Availability:
Explanation:
The Ltrim function will trim the 7-bit ASCII space character (value 32) from the LEFT hand side of a
string.
Use Ltrim on text that you have received from another source that may have irregular spacing at the
left hand end of the string.
Mid
Syntax:
Command Availability:
Explanation:
The Mid function is used to extract characters from the middle of a string variable. source is the
variable to extract from, start is the position of the first character to extract, and count is the number
of characters to extract. If count is not specified, all characters from start to the end of the source
string will be returned.
Example:
Pad
Syntax:
Command Availability:
Explanation:
The Pad function is used to create string to a specific length that is extended with a specific character.
The length of the string is specified by the second parameter. The character used to pad the string is
specified by the third parameter.
'Defibe a string
Dim TestData As String * 16
TestData = "Location"
Right
Syntax:
Command Availability:
Explanation:
The Right function will extract the rightmost count characters from the input string source, and return
them in a new string.
Example:
'Set chip model
#chip 16F1936
Rtrim
Syntax:
stringvar = Rtrim(stringvar)
Explanation:
The Rtrim function will trim the 7-bit ASCII space character (value 32) from the RIGHT hand side of a
string.
Use Rtrim on text that you have received from another source that may have irregular spacing at the
right hand end of the string.
Str
Syntax:
stringvar = Str(number)
Command Availability:
Available on all microcontrollers
Explanation:
The Str function will convert a number into a string. number can be any byte or word variable, or a
fixed number between 0 and 65535 inclusive. The string variable stringvar will contain the same
number, represented as a string.
This function is especially useful if a number needs to added to the end of a string, or if a custom data
sending routine has been created but only supports the output of string variables.
Example:
'Send
HSerPrint OutVar
HSerPrintCRLF
When using the functions STR() do not leave space between the function
call and the left brace. You will get a compiler error that is
meaningless.
' use this, note this is no space between the STR and the left brace!
STR(number_variable)
' do not use, note the space!
STR (number_variable)
Trim
Syntax:
stringvar = Trim(stringvar)
Command Availability:
Explanation:
The Trim function will trim the 7-bit ASCII space character (value 32) from text.
Trim removes all spaces from text except for single spaces between words. Use Trim on text that you
have received from another source that may have irregular spacing at the left or right hand ends of the
string.
UCase
Syntax:
output = UCase(source)
Command Availability:
Explanation:
The UCase function will convert all of the letters in the string source to upper case, and return the
result.
Example:
'Set chip model
#chip 16F1936
Val
Syntax:
var = Val(string)
Command Availability:
Explanation:
The Val function will extract a number from a string variable, and store it in a word variable. One
potential use is reading numbers that are sent in ASCII format over a serial connection.
Example:
'Program for an RS232 controlled dimmer
'Set chip model
#chip 16F1936
'Main Loop
Do
'Get serial byte
Wait Until USARTHasData
HSerReceive InByte
'Output
HPWM 1, 32, OutputLevel
'Number?
If InByte >= 48 and InByte <= 57 Then
'Add to end of DataIn string
DataInCount += 1
DataIn(DataInCount) = InByte
DataIn(0) = DataInCount
End If
Loop
See Also Hex, Str
WordToBin
Syntax:
stringvar = WordToBin(bytevar)
Command Availability:
Explanation:
The WordToBin function creates a string of a ANSI (8-byte) characters. The function converts a number
to a string consisting of ones and zeros that represents the binary value.
Example:
Concatenation
Syntax:
Command Availability:
Explanation:
This method does not change the existing strings, but returns a new string containing the text of the
joined variables.
Concatenation joins the elements of a specified values using the specified separator between each
variable.
Example:
timevariable = 999
stringvar = "Time = " + timevariable ' Returns Time = 999
Miscellaneous Commands
Dir
Syntax:
Command Availability:
Available on all microcontrollers. However, some low end PIC microcontrollers (10F, 12F5x and 16F5x
chips) will only accept the entire port form.
Explanation:
The Dir command is used to set the direction of the ports of the microcontroller chip. The individual
form sets the direction of one pin at a time, whereas the entire port form will set all bits in a port.
In the individual form, specify the port and bit (ie. PORTB.4), then the direction, which is either In or
Out.
The entire port form is similiar to the TRIS instruction offered by some PIC chips. To use it, give the
name of the port (i.e. PORTA), and then a byte is to be written into the TRIS variable. This form of the
command is for those who are familiar with the PIC chip’s internal architecture.
Entire port form will work differently on AVR when a value other than IN or OUT
WARNING is used! AVR chips use 0 to indicate in and 1 to indicate out, whereas PICs use 0 for
out and 1 for in. When IN and OUT are used there are no compatibility issues.
Example:
'This program sets PORTA bits 0 and 1 to in, and the rest to out.
'It also sets all of PORTB to output, except for B1.
'Individual form is used for PORTA:
DIR PORTA.0 IN
DIR PORTA.1 IN
DIR PORTA.2 OUT
DIR PORTA.3 OUT
DIR PORTA.4 OUT
DIR PORTA.5 OUT
DIR PORTA.6 OUT
DIR PORTA.7 OUT
'Entire port form used for B:
DIR PORTB b'00000010'
Pot
Syntax:
Command Availability:
Explanation:
Pot makes it possible to measure an analog resistance with a digital port, with the addition of a small
capacitor. This is the required circuit:
The command works by using the microcontroller pin to discharge the capacitor, then measuring the
time taken for the capacitor to charge again through the resistor.
The value for the capacitor must be adjusted depending on the size of the variable resistor. The
charging time needs to be approximately 2.5 ms when the resistor is at its maximum value. For a
typical 50 k potentiometer or LDR, a 50 nf capacitor is required.
This command should be used carefully. Each time it is inserted, 20 words of program memory are
used on the chip, which as a rough guide is more than 15 times the size of the Set command.
pin is the port connected to the circuit. The direction of the pin will be dealt with by the Pot command.
output is the name of the variable that will receive the value.
Example:
'This program will beep whenever a shadow is detected
'A potentiometer is used to adjust the threshold
#chip 16F628A, 4
#config INTOSC_OSC_NOCLKOUT
Do
Pot ADJUST, Threshold
Pot LDR, LightLevel
If LightLevel > Threshold Then
Tone 1000, 100
End If
Loop
PulseOutInv
Syntax:
Command Availability:
Explanation:
The PulseOutInv command will set the specified pin low, wait for the specified amount of time, and
then set the pin high. The pin is specified in the same way as it is for the Set` command, and the time is
the same as for the Wait command.
Example:
'This program flashes an LED on GPIO.0 using PulseOutInv
#chip 12F629, 4
#config INTRC_OSC_NOCLKOUT
PulseIn
Syntax:
Command Availability:
Explanation:
The PulseIn command will monitor the specified pin when the pin is high, and then measure the high
time. It will store the time in the variable.
Example:
#chip 12F629, 4
#config INTRC_OSC_NOCLKOUT
Dir GPIO.0 In
PulseOut
Syntax:
Command Availability:
The PulseOut command will set the specified pin high, wait for the specified amount of time, and then
set the pin low again. The pin is specified in the same way as it is for the Set command, and the time is
the same as for the Wait command.
Example:
Peek
Syntax:
Command Availability:
Explanation:
The Peek function is used to read information from the on-chip RAM of the microcontroller.
location is a word variable that gives the address to read. The exact range of valid values varies from
chip to chip.
This command should not normally be used, as it will make the porting of code to another chip very
difficult.
Example #1 :
'This program will read and check a value from PORTA
'Will only work on some PICs
Temp = Peek(5)
IF Temp.2 ON THEN SET green ON
IF Temp.2 OFF THEN SET red ON
Example #2
Poke
Syntax:
Poke(location, value)
Command Availability:
Explanation:
The Poke command is used to write information to the on-chip RAM of the microcontroller.
• location is a word variable that gives the address to write. The exact range of valid values varies
from chip to chip.
This command should not normally be used, as it will make the porting of code to another chip very
difficult.
Example 1:
Example 2:
;Chip Settings
#chip 16F88
Do Forever
FlashPin @PORTB, 8
Wait 1 s
Loop
Using @ before the name of a variable (including a special function register) will give you the address
of that variable, which can then be stored in a word variable and used by Peek and Poke to indirectly
access the location.
Weak Pullups
Weak pullups provide a method to within many microcontrollers such as the Atmel AVR and
Microchip PIC parts to support internal/selectable pull-ups for convenience and reduced parts count.
If you require weak pull-ups these internal pull-ups can provide a simple solution. If you need your
weak pull-ups to exactly control current (rare for most PIC applications), then you should consider 10k
resistors (5V/10K = 500uA) Why? If you review in the microprocessor data sheet, there is no resistance
given for the weak pull-ups. That is because they are not weak pull-resistors they are weak pull-up
consisting of what appear to be high- resistance channel pFETs. Their channel resistance will vary with
temperature and between parts; not easy to characterize. The data sheet gives a current range for the
internals as 50-400uA (at 5V).
PORTs can have an individually controlled weak internal pull-up. When set, each bit of the appropriate
microchip register enables the corresponding pin pull-up. There is a master bit within a specific
register bit that enables pull- ups on all pins which also have their corresponding weak pull bit set.
Also when set, there is a weak pull register bit to disable all weak pull-ups.
The weak pull-up is automatically turned off when the port pin is configured as an output. The pull-ups
are disabled on a Power-on Reset.
Each specific microprocessor has different registers/bits for this functionality. You should review the
datasheet for the method for a specific microprocessor. The following code demonstrates how to set
the weak pull-ups available on port B of an 18F25K20.
Dir Portb in
Dir Portc out
do
portc.1 = portb.1 'in pin 22, out pin 12
portc.2 = portb.2 'in pin 23, out pin 13
portc.3 = portb.3 'in pin 24, out pin 14
portc.4 = portb.4 'in pin 25, out pin 15
Also, see I2C Slave Hardware for an example using a 16F microcomputer.
Maths
Abs
Syntax:
Command Availability:
Explanation:
The Abs function will computes the absolute value of a integer number therefore in the range of -32678
to 32768.
Example:
Average
Syntax:
Command Availability:
Explanation:
A function that returns the average of two numbers. This only supports byte variables.
Provides a very fast way to calculate the average of two 8 bit numbers.
Example:
Explanation:
Great Cow Basic support logarithmic functions through the include file <maths.h>.
These functions compute base 2, base e and base 10 logarithms accurate to 2 decimal places, +/- 0.01.
The values returned are fixed-point numbers, with two decimal places assumed on the right. Or if you
prefer, think of the values as being scaled up by 100.
The input arguments are word-sized integers, 1 to 65535. Remember, logarithms are not defined for
non-positive numbers. It is the calling program’s responsibility to avoid these. Output values are also
word- sized.
Local variables consume 9 bytes, while the function parameters consume another 4 bytes, for a grand
total of 13 bytes of RAM used. The lookup table takes 35 words of program memory.
Supported in <MATHS.H>
Log2
Syntax:
Command Availability:
Explanation:
The Log2 command will return the base-2 logarithm, to 2 decimal places.
The values returned are fixed-point numbers, with two decimal places assumed on the right. or if you
prefer, think of the values as being scaled up by 100.
Example:
Supported in <MATHS.H>
Loge
Syntax:
Command Availability:
Explanation:
The Loge command will return the base-e logarithm, to 2 decimal places.
The values returned are fixed-point numbers, with two decimal places assumed on the right. or if you
prefer, think of the values as being scaled up by 100.
Example:
Supported in <MATHS.H>
Log10
Syntax:
Command Availability:
Explanation:
The Loge command will return the base-10 logarithm, to 2 decimal places.
The values returned are fixed-point numbers, with two decimal places assumed on the right. or if you
prefer, think of the values as being scaled up by 100.
Example:
dim log_value as word
log_value = loge ( 10 ) 'return 230 equate to 2.30
Supported in <MATHS.H>
Power
Syntax:
Explanation:
This function raises a base to an exponent, i.e, power(base,exponent). Remember, powers can easily
become huge, so it is up to the calling program to make certain your numbers remain within range.
The base and exponent are Byte sized numbers in any event. The returned result is a Long.
Keep in mind that 0 raised to 0 is meaningless and should be avoided, but, any other non-zero base
raised to 0 is handled correctly.
Example:
;Thomas Henry -- 5/2/2014
;----- Configuration
;----- Constants
;----- Variables
dim i, j as byte
;----- Program
Supported in <MATHS.H>
Sqrt
Syntax:
word_variable = sqrt ( word )
Explanation:
A square root routine for Great Cow Basic. The function only involves bit shifting, addition and
subtraction, which makes it fast and efficient.
It expects a word in and a word out, and will handle arguments of up to 4294.
Command Availability:
Example:
;----- Configuration
;----- Constants
;----- Variables
;----- Program
Supported in <MATHS.H>
Trigonometry
Explanation:
Syntax:
Great Cow Basic supports the following functions, sin(x), cos(x), tan(x), where x is a signed integer
representing an angle measured in a whole number of degrees. The output values are also integers,
represented as fixed point decimal fractions.
Details:
The sine, cosine and tangent functions are available for your programs simply by including the header
file offering the precision you need. In particular,
Sine and cosine are always defined, but remember that tangent fails to exist at 90 degrees, 270 degrees
and all their coterminal angles. It is the responsibility of the calling program to avoid these special
values.
Note that the tangent function is not available to four decimal places, since its value grows so rapidly,
exceeding what the Integer data type can represent.
These routines are completely general. The input argument may be positive, negative or zero, with no
restriction on the size. Further observe that lookup tables are used, so the routines are very fast,
efficient and accurate.
Example:
;----- Configuration
;----- Constants
;----- Variables
dim i as integer
dim outStr, valStr as string
;----- Program
valStr = str(value)
length = len(valStr)
select case length
case 1:
outStr = outStr + "0.00" + valStr
case 2:
outStr = outStr + "0.0" + valStr
case 3:
outStr = outStr + "0." + valStr
case 4:
outStr = outStr + left(valStr,1) + "." + right(valStr,3)
case 5:
outStr = outStr + left(valStr,2) + "." + right(valStr,3)
end select
print outStr
end sub
Compiler Directives
#chip
Syntax:
Explanation:
The #chip directive is used to specify the chip model and speed that GCBASIC must compile for. model is
the model of the microcontroller chip - something along the lines of "16F819". speed is the speed of the
chip in MHz, and is required for the delay and PWM routines.
If no chip frequency is present, the compiler will select a frequency that should work. If the chip has
an internal oscillator, the compiler will use that and pick the highest speed it supports. If you are using
an external crystal then you must specify a chip frequency.
If speed is omitted, GCBASIC will use the highest clock speed that the internal oscillator can support. If
the chip does not have an internal oscillator, then GCBASIC will assume that the chip is being run at its
maximum possible clock speed using an external crystal.
When using an AVR, there is not need to specify "AT" before the name.
Examples:
#chip 12F509, 4
#chip 18F4550, 48
#chip 16F88, 0.125
#chip tiny2313, 1
#chip mega8, 16
Some alternative compilers allow value of the clock speed to be set with the numerical value (i.e.
24576000). This can be useful when using the clock frequencies other than standard frequencies.
You can do this, you must write the speed in MHz with decimal points. For example, if you wanted to
run a 16F1827 at 24576000 Hz, you would write the following:
#config
Syntax:
Explanation:
The #config directive is used to specify configuration options for the chip. There is a detailed
explanation of #config in the Configuration section of help.
#define
Syntax:
Explanation:
#define will search through the program for Find, and replace it with the value given for Replace.
#if
Syntax:
#if Condition
...
#endif
Explanation:
The #if directive is used to prevent a section of code from compiling unless Condition is true.
Condition has the same syntax as the condition in a normal GCBASIC if command. The only difference
is that it uses constants instead of variables.
Example:
'Initialise
Dir PORTB Out
'Main loop
Do
#if FlashPins >= 1
PulseOut PORTB.0, 250 ms
#endif
#if FlashPins >= 2
PulseOut PORTB.1, 250 ms
#endif
#if FlashPins >= 3
PulseOut PORTB.2, 250 ms
#endif
#if FlashPins >= 4
PulseOut PORTB.3, 250 ms
#endif
Loop
#ifdef
Syntax:
Explanation:
The #ifdef directive is used to selectively enable sections of code. There are several ways in which it
can be used:
The advantage of using #ifdef rather than an equivalent series of IF statements is the amount of code
that is downloaded to the chip. #ifdef controls what code is compiled and downloaded, IF controls
what is run once on the chip. #ifdef should be used whenever the value of a constant is to be checked.
GCBASIC also supports the #ifndef directive - this is the opposite of the #ifdef directive - it will remove
code that #ifdef leaves, and vice versa.
The code in the following sections will not compile, as it is missing #chip directives and
NOTE
Dir commands. It is intended to act as an example only.
#define Blink1
#ifdef Blink1
PulseOut PORTB.0, 1 sec
Wait 1 sec
#endif
#ifdef Blink2
PulseOut PORTB.1, 1 sec
Wait 1 sec
#endif
This code will pulse PORTB.0, but not PORTB.1. This is because Blink1 has been defined, but Blink2 has
not. If the line
#define Blink2
was added at the start of the program, then both pins would be pulsed. The value of the constant
defined is not important and can be left off of the #define.
This program uses a constant called PinsToFlash that controls how many lights are pulsed. PORTB.0 is
pulsed when PinsToFlash is equal to 1, 2 or 3, PORTB.1 is pulsed when PinsToFlash equals 2 or 3, and
PORTB.2 is flashed when PinsToFlash is 3.
#ifdef NoVar(ANSEL)
SET ADCON1.PCFG3 OFF
SET ADCON1.PCFG2 ON
SET ADCON1.PCFG1 ON
SET ADCON1.PCFG0 OFF
#endif
#ifdef Var(ANSEL)
ANSEL = 0
#endif
The above section of code has been copied directly from a-d.h. It is used to disable the A/D function of
pins, so that they can be used as standard digital I/O ports. If ANSEL is not declared as a system variable
for a particular chip, then the program uses ADCON1 to control the port modes. If ANSEL is defined, then
the chip is newer and its ports can be set to digital by clearing ANSEL.
Similar to above, except with Bit and NoBit in the place of Var and NoVar respectively.
#ifndef
Syntax:
#ifndef Constant | Constant Value | Var(VariableName)
...
#endif
Explanation:
The #ifndef directive is used to selectively enable sections of code. It is the opposite of the #ifdef
directive - it will delete code in cases where #ifdef would leave it, and will leave code where #ifdef
would delete it.
#include
Syntax:
#include filename
Explanation:
#include tells GCBSIC to open up another file, read all of the subroutines and constants from it, and
then copy them into the current program.
Absolute is used to refer to files in the C:\Program Files\GCBASIC\include directory. The name of the file
is specified in between < and > symbols. For instance, to include the file srf04.h, the directive is:
#include <srf04.h>
Relative is used to read files in the same folder as the currently selected program. Filenames are given
enclosed in quotation marks, such as:
#include "mycode.h"
It is not essential that the include file name ends in .h - the important thing is that the
NOTE
name given to GCBASIC is the exact name of the file to be included.
Those who are familiar with #include in assembly or C should bear in mind that
#include in GCBASIC works differently to #include in most other languages - code is
WARNING
not inserted at the location of the #include, but rather at the end of the current
program.
#script
Syntax:
#script
[scriptcommand1]
[scriptcommand2]
...
[scriptcommandn]
#endscript
Explanation:
The #script block is used to create small sections of code which GCBASIC runs during compilation. A
detail explanation and example are included in the Scripts article.
#startup
Syntax:
#startup SubName
*Explanation:
#startup is used in include files to automatically insert initialization routines. If a define or subroutine
from the file is used in the program, then the specified subroutine will be called.
There are some limitations on this directive. It may only occur once within a file, and no parameters
can be specified for the subroutine that is to be called.
#mem
This directive is obsolete. GCBASIC can now determine the amount of memory on a chip
automatically, and will ignore the #mem directive.
The directives Var(), NoVar(), Bit() and NoBit() are functions that are built in to #IFDEF. They will
return true if a variable or bit is declared/not declared in the currently selected PIC chip.
Var()
NoVar()
Bit()
NoBit()
The directive AllOf and OneOf will return true if all of or one of the listed defines is declared:
AllOf(define1, define2, …)
OneOf(define1, define2, …)
Compiler Options
#option bootloader
Syntax:
Explanation:
#option bootloader prevents the overwriting of any pre-loaded bootloader code, vectors, etc. below the
address and have all GCBASIC code start at address.
A bootloader is a program that stays in the microcontroller and communicates with the PC, typically
through the serial interface. The bootloader receives a user program from the PC and writes it in the
flash memory, then launches this program in execution. Bootloaders can only be used with those
microcontrollers that can write their flash memory through software.
The bootloader itself must be written into the flash memory with an external programmer.
In order for the bootloader to be launched after each reset, a goto bootloader instruction must exist
somewhere in the first 4 instructions; There are two types of bootloaders, some that require that the
user reallocate the code and others that by themselves reallocate the first 4 instructions of the user
program to another location and execute them when the bootloader exits.
The diagram below shows the architecture of a bootloader. The left hand is the operation of the
instructions without a bootloader. The right hand shows the initial instruction of goto the bootoader,
then, when the bootloader has initialised the execution of the start code.
Example:
#option NoContextSave
Syntax:
#option NoContextSave
Explanation:
Interrupts can occur at almost any time, and may interrupt another command as it runs. To ensure
that the interrupted command can continue properly after the interrupt, some temporary variables
(the context) must be saved. Normally GCBASIC will do this automatically, but in some cases it may be
necessary to prevent this. If porting some existing assembly code to GCBASIC, or creating a bootloader
using GCBASIC that will call another program, NoContextSave can be used to prevent the context
saving code from being added automatically.
Be very careful using this option - it is very easy to cause random corruption of variables. If creating
your own context saving code, you may need to save several variables. These are:
For PIC 12F/16F: W, STATUS, PCLATH For PIC 12F1/16F1/18F: W, STATUS, PCLATH, PCLATU, BSR For
AVR: All 32 registers
Other variables may also need to be saved, depending on what commands are used inside the
interrupt handler. Everything that is saved will also need to be restored manually when the interrupt
handler finishes.
Example:
' This shows an example that could be used by a bootloader to call some application code.
' The application code must deal with context save and restore
' Suppose that application code starts at location 0x100, with interrupt vector at 0x108
'Chip model
#chip 18F2620
Note:
#option nolatch
Syntax
#option nolatch
Introduction
The GCBasic compiler will redirect all I/O pin writes from PORTx to LATx registers on PIC 16F1/18F
Microchip microcomputers. The Microchip mid-range PIC microcontrollers use a sequence known as
Read-Modify-Write (RMW) when changing an output state (1 or 0) on a pin. This can cause
unexpected behavior under certain circumstances.
When your program changes the state on a specific pin, for example RB0 in PORTB, the PIC
microcontroller first READs all 8 bits of the PORTB register which represents the states of all 8 pins in
PORTB (RB7-RB0). The PIC microcontroller then stores this data in the MCU. The bit associated with RB
that you’ve commanded to MODIFY is changed, and then the PIC microcontroller WRITEs all 8 bits
(RB7- RB0) back to the PORTB register.
During the first reading of the PORT register, you will be reading the actual state of the physical pin.
The problem arises when an output pin is loaded in such a way that its logic state is affected by the
load. Instances of such loads are LEDs without current-limiting resistors or loads with high capacitance
or inductance.
For example, if a capacitor is attached between pin and ground, it will take a short while to charge
when the pin is set to 1. On the other hand, if the capacitor is discharged, it acts like a short circuit,
forcing the pin to '0' state, and, therefore, a read of the PORT register will return 0, even though we
wrote a 1 to it.
GCBasic resolves this issue using the LATx register when writing to ports, rather than using PORTx
registers. Writing to a LATx register is equivalent to writing to a PORTx register, but readings from
LATx registers return the data value held in the port latch, regardless of the state of the actual pin. So,
for reading use PORTx.
This redirection capability from PORTx to LATx is available from version 0.94 of GCBasic compiler.
Note
Use you can use the #option nolatch if problems occur with compiler redirection.
Using Assembler
Assembler Overview
Explanation:
You can use assembler code within your Great Cow Basic code.
You can put the assembler code inline in with your source code. The assembler code will be passed
through to the assembly file associated with your project.
The commands should be in lower case and have a space or tab in front of the command.
Even if the mnemonics are not being formatted properly, gputils/MPASM should still be capable of
assemble the source code.
Example:
btfsc STATUS,Z
bsf PORTB,1
Macros
Macros Overview
Explanation:
You can use macros within your Great Cow Basic code.
Macros are similar to subroutines. But during compilation, everything is inserted inline. This may
increase the code size slightly, but it also reduces stack usage.
Parameters are handled in a similar way to how constants are handled, so there is a lot more freedom
when passing things in to a macro. (Unlike subs or functions, where everything must be stored in a
variable.)
For example, for PulseOut, one parameter is a pin, and the other is a time length like "500 ms". Neither
of those could be stored in a variable, but passing them in as macro parameters is possible.
Example:
'PulseOut Macro
macro Pulseout (Pin, Time)
Set Pin On
Wait Time
Set Pin Off
end macro
Example Macros
Measuring a Pulse Width
Introduction
When the measurement of a pulse width to sub-microsecond resolution is required for instance
measuring the high or low pulse width of an incoming analog signal a comparator can be combined
with a timer to provide the pulse width.
Microchip has published a "Compiled Tips 'N Tricks Guide" that explains how to do certain tasks with
PIC 8-Bit Microcontrollers. This guide provides the steps that need to be taken to perform the task of
measuring a pulse width.
The guide provides guidance on measuring a pulse width using Timer 1 and the CCP module. This
guidance was used as the basis for the GCBasic port the shown below. The guidance was generic and
in this example polling the CCP flag bit was more convenient than using an interrupt. In this example,
a PIC 16F1829 microprocessor operating at 32 Mhz using the internal oscillator. The GCBasic example
code is based on a macro that uses Timer1 and CCP4. However, any of the four CCP modules could be
used, the 16F1829 microprocessor has four CCP module.
Resolution of this approach using a timer Prescaler of 1:8 and a microprocessor frequency of 32 MHz
the pulse width resolution is 1ms. With the timer Prescaler of 1:2 and the microprocessor frequency of
32MHz the resolution is 250 ns.
The accuracy is dependent upon the accuracy of the system clock, but oscilliscope measurements have
show an accuracy of +- 1us from 3us to 1000us.
• Using GCBasic a macro to ensure the generated assembler is inline to ensure the timing is
consistent and no sub routines are called.
• A 4x20 LDC module with an I2C Backpack was used to display the results. However, as an
alternative, a serial output
to a terminal program to view the data could be used
This example can be improved by adding code to poll the TIMER1 overflow flag. IF the timer overflows,
then either no pulse was detected or the pulse was longer than allowed by the prescaler/OSC settings.
In this case, return a value of zero for pulse width.
Usage:
PULSE_IN
Example Program:
#Chip 16F1829, 32
#CONFIG MCLRE = OFF
'Set up LCD
#define LCD_IO 10
#define LCD_SPEED FAST
#define LCD_Backlight_On_State 1
#define LCD_Backlight_Off_State 0
'Note: This example can be improved by adding code to poll the 'TIMER1 overflow flag. IF
the timer overflows, then either no 'pulse was detected or the pulse was longer than
allowed by the 'prescaler/OSC settings. In this case, return a value of zero 'for pulse
width.
CLS
PRINT "Pulse Width Test"
DIM PULSE_WIDTH AS WORD
DIR PORTC.6 IN
'Setup timer
'Set timer1 using PS1_2 gives 250ns resolution
InitTimer1 OSC, PS1_8
wait 1 s
CLS
A constant such as a Pin name cannot be passed to a sub routine or a function. This is a constraint of
GCBasic. A macro can be used to implement a method of passing a constant.
The example shown below implements a button press routine and takes an input port constant and
prints the result on an LCD display.
A macro will use more program memory as the macro will be compiled as inline code.
NOTE Therefore, for every use of the macro will use additional program memory - the same
amount of program memory for each call to the macro.
#chip 16F877a, 16
#define Button PORTC.1 ' Switch on PIN 14 via 10K pullup resistor
DIR Button In
wait 1 sec
'USART settings
#define USART_BAUD_RATE 9600
#define USART_BLOCKING
#define USART_TX_BLOCKING
This code implements four flashing LEDs. This is based on the Microchip Low Pin Count Demo Board..
The example program will blink the four red lights in succession. Press the Push Button Switch, labeled
SW1, and the sequence of the lights will reverse. Rotate the potentiometer, labeled RP1, and the light
sequence will blink at a different rate.
This implements an interrupt for the switch press, reads the analog port and set the LEDs.
#chip 18F14K22, 32
#config OSC = IRC, MCLRE_OFF
ccount = 8
leddir = 0
SET PORTC = 15
WAIT 1 S
SET PORTC = 0
Set IOCA.3 on
Dir porta.3 in
On Interrupt PORTABCHANGE Call Setir
setLedDirection
main:
DO
INTON
ADCreading = ReadAD10(AN0)
if ADCreading < minwait then ADCreading = minwait
end if
end if
' reset interrupt - this may be been reset so set to zero so interrupt can operate.
intstate = 0
Loop
sub Setir
end sub
sub setLedDirection
case 0
leddir = 1
ccount = 8
case 1
leddir = 0
ccount = 1
end select
End Sub
When called, this subroutine will blink an LED for the number of times and duration as determined by
the input parameters.
This is intended to demonstrate how to create and use a SUB with a useful example.
Sub Flash_LED (in numtimes, in OnTime as WORD, Optional OffTime as WORD = OnTime)
repeat numtimes
set LED on
wait OnTime ms
set LED OFF
wait OffTime ms
end repeat
End Sub
Shown below is a working example program using a PIC 18F25K22.
Sub Flash_LED (in numtimes, in OnTime as WORD, optional OffTime as word = OnTime)
repeat numtimes
set LED on
wait OnTime ms
set LED OFF
wait OffTime ms
end repeat
End Sub
Generate Accurate Pulses
Introduction:
The PulseOut Command is a reliable method for generating pulses if accuracy is not critical, the
PulseOut command uses a calculation of the clock to speed for the timing .
If you need better accuracy and resolution then an alternative approach is required.
To generate pulses in the 100 us to 2500 us range with an accuracy of +- 1us over this range is practical
using the approach shown in this example.
This example code works on a midrange PIC16F690 operating at 8Mhz. However, it should work on
any Microchip microprocessor, but may need some minor modifications.
Usage:
Pulse_Out_us ( word_value )
How It Works:
Timer1 is loaded with a preset value based upon the variable passed to the sub routine. The timer
(Timer1v) is started and the pulse pin (the output pin) is set high. When `Timer1 overflows the
Timer1 interrupt flag bit (TMR1IF) is set. This causes the program to exit a polling loop and set the pulse
Pin off. Then, Timer1 is stopped and TMRIF flag is cleared and the sub routine exits.
This method supports delays between 5 us and 65535 us and uses Timer1.
Test Results:
;**************************************
; Code: Output an accurate pulse
; Author: William Roth 03/13/2015
;**************************************
#chip 16F690,8
CLS
; ---- USART settings
#define USART_BAUD_RATE 38400
DIR PORTB.7 OUT
This demonstration code shows the full set of command supported by Great Cow Basic.
;Chip Settings
#chip 16F877a,16
#include <glcd.h>
wait 1 s
GLCDCLS
GLCDPrint 0, 1, "Great Cow Basic "
wait 1 s
GLCDCLS
'USART settings
#define USART_BAUD_RATE 9600
Dir PORTc.6 Out
#define USART_DELAY 5 ms
#define SerSendDelayms 10
wait 1 s
HSerPrint "KS0108 Test GLCD Driver":crlf(1)
USART = true
rrun = 0
dim msg1 as string * 16
do forever
GLCDCLS
Box 18,30,28,40
Line 0,0,127,63
Line 0,63,127,0
wait 1 s
FilledBox 18,30,28,40
wait 1 s
GLCDCLS
GLCDDrawString 30,0,"ChipMhz@"
GLCDDrawString 78,0, str(ChipMhz)
Circle(10,10,10,1) ;upper left
Circle(117,10,10,1) ;upper right
Circle(63,31,10,1) ;center
Circle(63,31,20,1) ;center
Circle(10,53,10,1) ;lower left
Circle(117,53,10,1) ;lower right
wait 1 s
GLCDDrawString 30,0,"ChipMhz@"
GLCDDrawString 78,0, str(ChipMhz)
FilledCircle(10,10,10,1) ;upper left
FilledCircle(117,10,10,1) ;upper right
FilledCircle(63,31,10,1) ;center
FilledCircle(63,31,20,1) ;center
FilledCircle(10,53,10,1) ;lower left
FilledCircle(117,53,10,1) ;lower right
wait 1 s
GLCDCLS
GLCDDrawString 30,0,"ChipMhz@"
GLCDDrawString 78,0, str(ChipMhz)
Circle(10,0,10,1) ;upper left
Circle(117,0,10,1) ;upper right
Circle(63,31,10,1) ;center
Circle(63,31,20,1) ;center
Circle(10,63,10,1) ;lower left
Circle(117,63,10,1) ;lower right
wait 1 s
GLCDCLS
GLCDDrawString 0,10,"Hello" 'Print Hello
wait 1 s
GLCDDrawString 0,10, "ASCII #:" 'Print ASCII #:
Box 18,30,28,40 'Draw Box Around ASCII Character
for char = 0x30 to 0x39 'Print 0 through 9
GLCDDrawString 16, 20 , Str(char)+" "
GLCDdrawCHAR 20, 30, char
wait 250 ms
next
line 0,50,127,50 'Draw Line using line command
for xvar = 0 to 80 'draw line using Pset command
pset xvar,63,on '
next
FilledBox 18,30,28,40 'Draw Box Around ASCII Character '
wait 1 s
GLCDCLS
GLCDDrawString 0,10,"End "
wait 1 s
GLCDCLS
workingGLCDDrawChar:
dim gtext as string
gtext = "KS0108"
wait 1 s
GLCDCLS
loop
For more help, see Graphical LCD Demonstration, InitGLCD, GLCDCLS, GLCDDrawChar, GLCDPrint,
GLCDReadByte, GLCDWriteByte, Pset
Versions of GCB prior to May 2014 does not support circle drawing. You can install
WARNING
the latest <glcd.h> file to enable this functionality.
InfraRed Remote
Explanation:
Great Cow Basic support interfacing with IR remote controls. The header file contains explanations, for
both hardware and software, see SonyRemote.h.
This has been tested on many different IR sensors, and different remote controls.
The example is expected to work with most any IR sensor running at a 38 kHz carrier frequency.
;This demo prints the device number and key number sent by
;a Sony compatible IR remote control unit.
;----- Constants
;----- Variables
;----- Program
do
readIR_Remote(device, button) ;wait for button press
locate 1,0
print "Button: " ;show button code
print button
;Thomas Henry
;Version 2.0 -- 4/23/2014
;This include file will let you easily read and use the
;infrared signals from a Sony compatible television remote
;control. In particular, the remote control transmits a
;pulse modulated signal, the sensor detects this, and the
;subroutine in this header file decodes the signal,
;returning two numbers: one representing the device
;(television, VCR, DVD, tuner, etc.), while the the other
;returns the key which has been depressed (VOL+, MUTE,
;channel numbers 0 through 9, etc.).
;Ground
;Vcc
;Data
;readIR_Remote(IR_rem_dev, IR_rem_key)
;Seventeen local bytes are consumed, and two bytes are used for
;the output parameters. That's a grand total of nineteen bytes
;required when invoking this subroutine.
do
IR_rem_count = 0 ;wait for start bit
do while IR_DATA_PIN = 0 ;measure width (active low)
wait 100 uS ;24 X 100 uS = 2.4 mS
IR_rem_count++
loop
loop while IR_rem_count < 20 ;less than this so wait
Great Cow Basic can draw circle using the midpoint circle algorithm. This is an algorithm used to
determine the points needed for drawing a circle. The algorithm is a variant of Bresenham’s line
algorithm, and is thus sometimes known as Bresenham’s circle algorithm, although not actually
invented by Jack E. Bresenham.
The program below show the midpoint circle algorithm within Great Cow Basic.
Example:
#include <glcd.h>
;----- Constants
;Pinout is shown for the LCM12864H-FSB-FBW
;graphical LCD available from Amazon.
;----- Variables
;----- Program
Start:
GLCDDrawString 30,0,"ChipMhz@"
GLCDDrawString 78,0, str(ChipMhz)
GLCDCircle(10,10,10,0) ;upper left
GLCDCircle(117,10,10,0) ;upper right
GLCDCircle(63,31,10,0) ;center
GLCDCircle(63,31,20,0) ;center
GLCDCircle(10,53,10,0) ;lower left
GLCDCircle(117,53,10,0) ;lower right
GLCDDrawString 30,54,"PIC16F886"
goto start
'radiusErr = 1 - xradius
radiusErr = -(xradius/2)
Do While xradius >= yordinate
Pset ((xoffset + xradius), (yoffset + yordinate), on)
Pset ((xoffset + yordinate), (yoffset + xradius), on)
Pset ((xoffset - xradius), (yoffset + yordinate), on)
Pset ((xoffset - yordinate), (yoffset + xradius), on)
Pset ((xoffset - xradius), (yoffset - yordinate), on)
Pset ((xoffset - yordinate), (yoffset - xradius), on)
Pset ((xoffset + xradius), (yoffset - yordinate), on)
Pset ((xoffset + yordinate), (yoffset - xradius), on)
yordinate ++
If radiusErr < 0 Then
radiusErr = radiusErr + 2 * yordinate + 1
else
xradius --
radiusErr = radiusErr + 2 * (yordinate - xradius + 1)
end if
Loop
end sub
This program demonstrates how to read and write data from an EEPROM device.
This program has three sections. Read a single byte from the EEPROM, write and read a page of 64
bytes to and from the EEPROM and finally display the contents of the EEPROM.
This program also has an interrupt driven serial handler to capture and manage input from a serial
terminal.
Demonstration program:
' THIS CONFIG OF THE SERIAL PORT WORKS WITH max232 THEN TO PC
' USART settings
#define USART_BAUD_RATE 9600
Dir PORTc.6 Out
Dir PORTc.7 In
#define USART_DELAY 5 ms
#define SerSendDelayms 10
#define USART_BLOCKING
wait 500 ms
'Serial Interrupt Handler
On Interrupt UsartRX1Ready Call readUSART
wait 125 ms
do
HSerPrintCRLF 2
HSerPrint "Commence Array Write and Read"
for tt = 1 to 64
outarray(tt) = tt
next
'eeprom_wr_array(device_number, page_size, address, array_name,
number_of_bytes)
eeprom_wr_array(EEpromDevice, 64, location, outarray, 64)
HSerPrintCRLF 2
for tt = 1 to 64
else
HSerPrint inarray(tt)
end if
HSerPrint ","
next
HSerPrintCRLF 2
HSerPrint bbyte
location++
HSerPrintCRLF 2
HI2CDeviceSearch
sub HI2CDeviceSearch
' assumes serial is operational
HSerPrintCRLF
HSerPrint "I2C Device Search"
HSerPrintCRLF 2
for deviceID = 0 to 255
HI2CStart
HI2CSend ( deviceID )
if HI2CAckPollState = false then
HSerPrint "ID: 0x"
HSerPrint hex(deviceID)
HSerSend 9
testid = deviceID | 1
select case testid
case 49
Hserprint "DS2482_1Channel_1Wire Master"
case 65
Hserprint "Serial_Expander_Device"
Case 73
Hserprint "Serial_Expander_Device"
case 161
Hserprint "EEProm_Device_Device"
case 163
Hserprint "EEProm_Device_Device"
case 165
Hserprint "EEProm_Device_Device"
case 167
Hserprint "EEProm_Device_Device"
case 169
Hserprint "EEProm_Device_Device"
case 171
Hserprint "EEProm_Device_Device"
case 173
Hserprint "EEProm_Device_Device"
case 175
Hserprint "EEProm_Device_Device"
case 209
Hserprint "DS1307_RTC_Device"
case 249
Hserprint "FRAM_Device"
case else
Hserprint "Unknown_Device"
end select
HI2CSend ( 0 )
HI2CSend ( 0 )
HSerPrintCRLF
end if
HI2CStop
next
sub validateEEPROM
' validation EEPROOM code
EepromAddress = 0
HSerPrintCRLF 2
HSerPrint "Hx"
HSerPrint hex(EepromAddress_h)
HSerPrint hex(EepromAddress)
HSerPrint " "
end if
if bkbhit then
syschar = bgetc
select case syschar
case 32
do while bgetc = 32
loop
case else
HSerPrintCRLF
HSerPrint "Done"
exit sub
end select
end if
next
HSerPrintCRLF
HSerPrint "Done"
end Sub
This program demonstrates how to control and display on an LCD Code for the keypad and LCD PIC on
the Microlab board v2
This program also has an interrupt driven I2C handler to manage the I2C from the Start event..
Demonstration program:
'Code for the keypad and LCD PIC on the Microlab board v2
'PIC is responsible for:
' - Reading keypad
' - Displaying data on LCD
' - communication with main PIC via I2C
' - providing 5 keypad lines to main PIC (for compatibility)
' - receiving remote control signals for button and keypad
'This code has support for two keypad layouts. This is one possible layout:
'0123
'4567
'89AB
'CDEF
'And this is the other possible layout:
'123A
'456E
'789D
'A0BC
'Select the keypad layout by uncommenting one of these lines:
'#define KEYPAD_KEYMAP KeypadMap0123
#define KEYPAD_KEYMAP KeypadMap123F
'I2C ports
#define I2C_DATA PORTC.4
#define I2C_CLOCK PORTC.3
'RS232/USART settings
'To do if/when remote support needed
'Initialise
Dir KEYOUT_A Out
Dir KEYOUT_B Out
Dir KEYOUT_C Out
Dir KEYOUT_D Out
Dir KEYOUT_DA Out
'Key buffers
'255 indicates no key, other value gives currently pressed key
RemoteKey = 255
OutKey = 255
KeyoutDisabled = False 'False if KEYOUT lines used to send key
'Main loop
Do
'Read keypad, send value
CheckPressedKeys
SendKeys
Loop
Sub CheckPressedKeys
'Subroutine to:
' - Read keypad
' - Check remote keypress
' - Decide which key to output
'Read keypad
If RemoteKey <> 255 Then
OutKey = RemoteKey
Else
EnableKeypad
OutKey = KeypadData
End If
End Sub
Sub EnableKeypad
'Disable LCD so that keypad can be activated
Set LCD_RW Off 'Write mode, don't let LCD write
'Re-init keypad
InitKeypad
End Sub
Sub I2CHandler
'Handle I2C interrupt
'SSPIF doesn't trigger for stop condition, only start!
'Sending code
If BufferSize = 0 Then
LastI2CWasRead = False
'Detect read address
If DataIn = 129 Then
LastI2CWasRead = True
HI2CSend OutKey
KeyoutDisabled = True
Dir KEYOUT_A In
Dir KEYOUT_B In
Dir KEYOUT_C In
Dir KEYOUT_D In
Dir KEYOUT_DA In
Exit Sub
End If
End If
End Sub
Sub SendKeys
KEYOUT_DA = 1
Else
'If no key pressed, clear data available line to main PIC
KEYOUT_DA = 0
End If
End Sub
Sub ProcessI2C
CmdControl = I2CBuffer(1)
'Set backlight
If CmdControl.6 = On Then
Set BACKLIGHT On
Else
Set BACKLIGHT Off
End If
End Sub
This program demonstrates how to drive an RGB LED to create 4096 different colors. Each of the three
;elements (red, green and blue) responds to 16 different levels. A value of 0 means the element never
turns on, while a value of 15 means the element never shuts off. Values in between these two extremes
vary the pulse width.
This program is an interrupt driven three channel PWM implementation. The basic carrier frequency
depends upon the microcontroller clock speed. For example, with an 8 MHz clock, the LED elements
are modulated at about 260 Hz. The interrupts are generated by Timer 0. With an 8 MHz clock they
occur about every 256 uS. The interrupt routine consumes about 20 uS.
Don’t forget the current limiting resistors to the LED elements. A value of around 470 ohms is good, but
you may want to adjust the individual values, to balance the color response.
In this demonstration, three potentiometers are used to set the color levels.
Demonstration program:
;----- Configuration
#chip 16F88, 8 ;PIC16F88 running at 8 MHz
#config mclr=off ;reset handled internally
#config osc=int ;use internal clock
;----- Constants
#define LED_R PortB.0 ;pin to red element
#define LED_G PortB.1 ;pin to green element
#define LED_B PortB.2 ;pin to blue element
;----- Variables
dim redValue, greenValue, blueValue, ticks as byte
;----- Program
dir PortA in ;three pots for inputs
dir PortB out ;the LED outputs
on interrupt Timer0Overflow call update
initTimer0 Osc, PS0_1/2
do
redValue = readAD(AN0)/16 ;red -- 0 to 15
greenValue = readAD(AN1)/16 ;green -- 0 to 15
blueValue = readAD(AN2)/16 ;blue -- 0 to 15
loop
sub update ;interrupt routine
ticks++ ;increment master timekeeper
if ticks = 15 then ;start of the count
ticks = 0
if redValue <> 0 then ;only turn on if nonzero
set LED_R on
end if
if greenValue <> 0 then
set LED_G on
end if
if blueValue <> 0 then
set LED_B on
end if
end if
if ticks = redValue then ;time to turn off red?
set LED_R off
end if
if ticks = greenValue then ;time to turn off green?
set LED_G off
end if
if ticks = blueValue then ;time to turn off blue?
set LED_B off
end if
end sub
Serial/RS232 Buffer Ring
Explanation:
;Chip Settings
#chip 16F1937,32
#config LVP=OFF, BODEN=OFF, WDT=OFF, OSC=XT
' [change to your config] This is the config for a serial terminal
' turn on the RS232 and terminal port.
' Define the USART port
#define USART_BAUD_RATE 9600
#define USART_BLOCKING true
' [[change to your config] Ensure these port addresses are correct
#define SerInPort PORTc.7
#define SerOutPort PORTc.6
'Set pin directions
Dir SerOutPort Out
Dir SerInPort In
' [[change to your config] This assumes you are using an ANSI compatible terminal. Use
PUTTY.EXE it is very easy.
'Interrupt Handlers
On Interrupt UsartRX1Ready Call readUSART
Do
' Send some info to another device
Repeat 3
HSerSend syncbyte
end Repeat
HSerprint readad(an0)
Sub readUSART
buffer(next_in) = HSerReceive
temppnt = next_in
next_in = ( next_in + 1 ) % BUFFER_SIZE
if ( next_in = next_out ) then ' buffer is full!!
next_in = temppnt
end if
End Sub
function bgetc
wait while !(bkbhit)
bgetc = buffer(next_out)
next_out=(next_out+1) % BUFFER_SIZE
end Function
Sine Tables
Explanation:
The example program will output the Sine value of numbers between -720 and 720 degrees.
;----- Configuration
;----- Constants
;----- Variables
;----- Program
;----- Subroutines
;----- Data
Trigonometry Circle
Explanation:
Great Cow Basic can draw circles using trigonometry. An example is shown below.
Example:
;----- Configuration
#chip 16F88, 8 ;PIC16F88 running at 8 MHz
#config mclr=off ;reset handled internally
#config osc=int ;use internal clock
#include <GLCD.h>
#include <Trig2Places.h>
;----- Constants
;----- Variables
;----- Program
InitGLCD
GLCDCLS
;----- Subroutines
Troubleshooting
Problem Common Causes More Assistance
Documenting is the ability to read some extra information from comments in libraries.
Some comments that start with ''' have a special meaning, and will be displayed as tooltips or as
information to the user. This helps even inexperienced users to use extra libraries.
1. A note on comments in general. GCGB uses ; to indicate comments that it has placed automatically,
and ' to indicate ones that the user has placed. When loading a program, it will not load any that
start with ;. This shouldn’t matter too much, but just something to be aware of.
2. As for code documentation comments, GCGB will load information about subroutines/functions
and any hardware settings that need to be set.
3. For subroutines, a line before the Sub or Function line that starts with ''' will be used as a tooltip
when the user hovers over the icon. A line that starts with '''@ will be interpreted differently,
depending on what comes after the @. '''@param ParamName Parameter Description will add a
description for the parameter. For a subroutine, this will show in the Icon Settings panel under the
parameter when the user has selected that icon.
4. For a function, it will show at the appropriate time in the Parameter Editor wizard. '''@return
Returned value applies to functions only. It will be displayed in the Parameter Editor wizard when
the user is asked to choose a function. An example of all this is given in srf04.h:
'''Read the distance to the nearest object
'''@param US_Sensor Sensor to read (1 to 4)
'''@return Distance in cm
Function USDistance(US_Sensor) As Word
5. If a subroutine or command is used internally in the library, but GCGB users shouldn’t see it, it can
be hidden by placing '''@hide before the Sub or Function line. Another example from srf04.h:
'''@hide
Sub InitUSSensor
These should hopefully be pretty easy to add. For anyone more motivated, it’s also possible to add
Hardware Settings. A particular setting can be defined anywhere in the file, using this syntax:
'''@hardware condition, display name, constant, value type condition tells GCGB when to show the
setting. Normally, this is All, but sometimes it can include a constant, a space and then a comma
separated list of values. display name is a friendly name for the setting to display. constant is the
constant that must be set, and value type is the type that will be accepted for that constant’s value.
To allow for multiple value types, enter a list of types with a | between them.
Allowed types are:
free - Allows anything
label - Allows any label
condition - Allows a condition
table - Allows a data table
bit - Allows any bit from variable, or bit variable
io_pin - Allows an IO pin
io_port - Allows an entire IO port
number - Allows any fixed number or variable
rangex:y - Allows any number between x and y
var - Allows any variable
var_byte - Allows any byte variable
var_word - Allows any word variable
var_integer - Allows any integer variable
var_string - Allows any string variable
const - Allows any fixed number
const_byte - Allows any byte sized fixed number
const_word - Allows any word sized fixed number
const_integer - Allows any integer sized fixed number
const_string - Allows any fixed string
byte - Allows any byte (fixed number or variable)
word - Allows any word
integer - Allows any integer
string - Allows any string
array - Allows any array
6. When the library is added the program, GCGB will show a new device with the name of the library
file on the Hardware Settings window. The user can then set the relevant constants without
necessarily needing to see any code.
adding a GCBASIC library to GCGB won’t result in any changes to the library. GCGB
NOTE uses the information it reads to help edit the user’s program, but then the user’s
program is passed to the compiler along with the unchanged library.
7. Hardware Settings are a bit more involved to add, but hopefully the bit of extra documentation for
subroutines will be straight forward.
This instructions are not distribution specific. This has bee tested and proven for Ubuntu.
Instructions:
2. Download the GreatCowBasic package with source code from SourceForge. The latest version can
be found here.
3. Unzip the GreatCowBasic distribution into a folder for example in the folder /usr/share/GCBasic
cd /usr/share/GCBasic
6. If no error occurs, you’re now ready to run the GCBasic compiler with the command:
gcbasic
gcbasic -version