Programming the Finite State Machine (Extract)

Page 1

Programming the Finite State Machine

Programming the Finite State Machine

Andrew Pratt served for 25 years in the Royal Air Force as an Aircraft Technician. He holds a Higher National Certificate in electrical and electronic engineering and an Honours Degree from the Open University. He continued his career working in industrial controls.

ISBN 978-1-907920-92-9

Elektor International Media BV

www.elektor.com

Andrew Pratt provides a detailed introduction to programming PIC microcontrollers, as well as a thorough overview of the Finite State Machine (FSM) approach to programming. Most of the book uses assembly programming, but do not be deterred. The FSM gives a structure to a program, making it easy to plan, write, and modify. The last two chapters introduce programming in C, so you can make a direct comparison between the two techniques. The book references the relevant parts of the Microchip datasheet as familiarity with it is the best way to discover detailed information. This book is aimed at Microsoft Windows and Linux users. To keep your costs to a minimum and to simplify the toolchain, specific applications are provided as a free download to enable you to use an FTDI serial lead as the programmer. The assembler used is the open-source "gpasm". All programming can be done in a text editor. There are detailed instructions on how to perform the necessary installations on Windows, Linux Debian, and derivatives such as Ubuntu and Fedora. For programming in C, Microchip's XC8 compiler is used from the command line. In addition to the programming applications, two serial read and serial write applications can be used for communicating with the PICs from a computer. A voltmeter project including practical instructions on building a circuit board from scratch is included. All theory is covered beforehand, including how to do integer arithmetic in assembly. Two PICs are covered: the PIC12F1822 and the PIC16F1823. Both can run at 32 MHz with an internal oscillator. You do not need to buy a factory-made development board and programmer. With relatively inexpensive parts including a serial lead, microcontroller, a few resistors, and LEDs, you can get started exploring embedded programming.

LEARN DESIGN SHARE

Programming the Finite State Machine ● Andrew Pratt

Andrew Pratt

with 8-Bit PICs in Assembly and C

with 8-Bit PICs in Assembly and C

Enhanced 2nd Edition ;-----------Machine States. S0 MOVLW 3 SUBWF TICK_COUNTER, W BTFSS STATUS, C GOTO S0 BCF PORTA, 2 CLRF TICK_COUNTER INCF PULSE_COUNTER, F S1

S2

S3

MOVLW 10 SUBWF PULSE_COUNTER, W BTFSS STATUS, C GOTO $+3 CLRF PULSE_COUNTER GOTO S3 MOVLW 9 SUBWF TICK_COUNTER, W BTFSS STATUS, C GOTO S1 CLRF TICK_COUNTER BSF PORTA, 2 GOTO S0 MOVLW 31 SUBWF TICK_COUNTER, W BTFSS STATUS, C GOTO S2 BCF PORTA, 2 CLRF TICK_COUNTER INCF PULSE_COUNTER, F

MOVLW 3 SUBWF PULSE_COUNTER, W BTFSS STATUS, C GOTO $+3 CLRF PULSE_COUNTER GOTO S1 MOVLW 91 SUBWF TICK_COUNTER, W BTFSS STATUS, C GOTO S3 CLRF TICK_COUNTER BSF PORTA, 2 GOTO S2

; LED on. Fast cycle. ; ; ; ; ; ; ;

C in STATUS is set when TICK_COUNTER >= to 3. Skip the next instruction if C in STATUS is found set. C in STATUS found not set. Stay in this state. Turn LED off Reset the tick counter. Add 1 to PULSE_COUNTER and put the result in PULSE_COUNTER. Continue to S1

; LED off. Fast cycle. ; ; ; ; ; ; ; ; ;

C in STATUS is set when PULSE_COUNTER >= to 10. Skip the next instruction if C in STATUS is found set. Have not reached 10 pulses jump to ticks check. 10 Pulses have been counted, reset PULSE_COUNTER. Transition to S3. Load W with 9 for ticks check. C in STATUS is set when TICK_COUNTER >= to 9. Skip the next instruction if C in STATUS is found set. C in STATUS found set, 9 ticks counted.

; Turn LED on.

; ; ; ; ; ; ;

C in STATUS is set when TICK_COUNTER >= to 3. Skip the next instruction if C in STATUS is found set. C in STATUS found not set. Turn LED off Reset the tick counter. Add 1 to PULSE_COUNTER and put the result in PULSE_COUNTER. Continue to S3

; LED on. Slow cycle. ; ; ; ; ;

C in STATUS is set when PULSE_COUNTER >= to 3. Skip the next instruction if C in STATUS is found set. ave not reached 3 pulses jump to ticks check. Reset PULSE_COUNTER. Transition to S1.

; C in STATUS is set when TICK_COUNTER >= to 9. ; Skip the next instruction if C in STATUS is found set. ; C in STATUS found set. ; Turn LED on.

Andrew Pratt LEARN DESIGN SHARE

LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHAR ESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHA COVER EN template pratt.indd All Pages

28/05/2020 12:06:56



Programming the Finite State Machine with 8-Bit PICs in Assembly and C

â—? Andrew Pratt

an Elektor Publication

LEARN DESIGN SHARE

AndrewPratt.indd 3

28/05/2020 12:26:22


This is an Elektor Publication. Elektor is the media brand of

Elektor International Media B.V. 78 York Street London W1H 1DP, UK Phone: (+44) (0)20 7692 8344 © Elektor International Media BV 2020 First published in the United Kingdom 2020

All rights reserved. No part of this book may be reproduced in any material form, including

photocopying, or storing in any medium by electronic means and whether or not transiently or incidentally to some other use of this publication, without the written permission of the copyright holder except in accordance with the provisions of the Copyright, Designs and Patents Act 1988 or under the terms of a licence issued by the Copyright Licensing Agency Ltd, 90 Tottenham Court Road, London, England W1P 9HE. Applications for the copyright holder’s written permission to reproduce any part of this publication should be addressed to the publishers. The publishers have used their best efforts in ensuring the correctness of the information contained in this book. They do not assume, and hereby disclaim, any liability to any party for any loss or damage caused by errors or omissions in this book, whether such errors or omissions result from negligence, accident or any other cause.

British Library Cataloguing in Publication Data

ISBN: 978-1-907920-92-9

Catalogue record for this book is available from the British Library

Prepress production: DMC ¦ dave@daverid.com Printed in the Netherlands by Wilco

Elektor is part of EIM, the world’s leading source of essential technical information and electronics products for pro engineers, electronics designers, and the companies seeking to engage them. Each day, our international team develops and delivers high-quality content - via a variety of media channels (e.g., magazines, video, digital media, and social media) in several languages - relating to electronics design and DIY electronics. www.elektor.com

LEARN DESIGN SHARE

AndrewPratt.indd 4

28/05/2020 12:26:22


● Table Of Contents

Table of Contents • Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

Chapter 1 • Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.1 • Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.2 • Practical Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.2.1 • Choice of Operating System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.2.2 • Machine Language and Assembly Source Files . . . . . . . . . . . . . . . . . . . . . 11 1.2.3 • Using the Applications on Microsoft Windows . . . . . . . . . . . . . . . . . . . . . 13 1.2.4 ● Installing the Applications on Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.2.5 • The FTDI Lead and Testing the Programming Chain . . . . . . . . . . . . . . . . . 15 1.3 • Some Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1.3.1 • Bits and Bytes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1.3.2 • The Hexadecimal Numbering System . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 1.3.3 • Boolean Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 1.3.4 • Bitwise logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 1.3.5 • PIC Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 1.3.6 • Data Memory Organization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 1.3.7 • An Assembly Program Snippet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 1.4 • Program Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 1.5 • Hello World . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 1.5.1 • Some Key Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 1.5.2 • Assembling the Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 Chapter 2 • The Assembly Program as a Finite State Machine . . . . . . . . . . . . . . . . . . 32 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9

• • • • • • • • •

Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A State Machine Framework for Assembly Language . . . . . . Timer0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A More Complicated LED Flasher . . . . . . . . . . . . . . . . . . . Running More Than One Machine in a Program . . . . . . . . . . Driving a Seven Segment LED Display . . . . . . . . . . . . . . . . The Differences Between the PIC 12F1822 and the 16F1823 . Interrupts and State Diagrams . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

32 32 33 35 41 43 45 51 52

Chapter 3 • Macros, Subroutines and Bank Switching . . . . . . . . . . . . . . . . . . . . . . . 53 3.1 • Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 3.2 • Create Your Own Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

●5

AndrewPratt.indd 5

28/05/2020 12:26:23


Programming the Finite State Machine with 8-Bit PICs in Assembly and C 3.2.1 • Use an Include File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 3.2.2 • More Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 3.2.3 • Conditional Assembly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 3.3 • Subroutines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 3.3.1 • An Example of a Subroutine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 3.3.2 • Return Address and the Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 3.3.3 • Calculating the Delay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 3.3.4 • Calling Subroutines from Subroutines . . . . . . . . . . . . . . . . . . . . . . . . . . 64 3.4 • Bank Switching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Chapter 4 • Inputs and Outputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 4.1 • Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 4.2 • Serial Output to a Computer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 4.2.1 • TTL Level Serial Communications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 4.2.2 • Configuring the EUSART to Transmit a Byte . . . . . . . . . . . . . . . . . . . . . . 68 4.2.3 • Serial Output Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 4.3 • Serial Input from a Computer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 4.3.1 • Configuring the EUSART to Receive Bytes . . . . . . . . . . . . . . . . . . . . . . . . 73 4.3.2 • Interrupt Service Routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 4.3.3 • Serial Input Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 4.4 • Analog Inputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 4.4.1 ● Setting ADCON0 and ADCON1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 4.4.2 ● Circuit and State Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 4.5 ● Pulse with modulated outputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 4.5.1 ● LED with Pulsing Brightness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 4.6 ● Digital Inputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 4.6.1 ● Counting Input Pulses From a Switch . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 4.6.2 ● First method eliminating the effect of switch bounce . . . . . . . . . . . . . . . . 88 4.6.3 ● A Better Method of Eliminating the Effect of Switch Bounce . . . . . . . . . . . . 90 Chapter 5 • Project Hardware Construction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 5.1 5.2 5.3 5.4 5.5

• • • • •

Introduction . . . . . . . . . . . . . . . . Overview of the Suggested Method . Cutting and Drilling the board . . . . Populating and Wiring the Board . The Circuit Board Test Program . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

93 93 94 96 97

5.5.1 • Analog Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

●6

AndrewPratt.indd 6

28/05/2020 12:26:23


● Table Of Contents Chapter 6 • Binary Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 6.1 • Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 6.2 • Binary Addition of Unsigned Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 6.2.1 • Adding Two Eight Bit Positive Integers . . . . . . . . . . . . . . . . . . . . . . . . . 104 6.2.2 • Serial Read Program Command Line Arguments . . . . . . . . . . . . . . . . . . 107 6.2.3 • Adding Two Sixteen Bit Positive Numbers . . . . . . . . . . . . . . . . . . . . . . . 108 6.3 6.4 6.5 6.6

• • • •

Binary Subtraction of unsigned integers . Binary Subtraction with Negative Results . Negative numbers in binary . . . . . . . . . . Binary Multiplication . . . . . . . . . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

111 113 114 116

6.7 • Binary Division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 Chapter 7 • Digital Voltmeter Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 7.1 7.2 7.3 7.4 7.5 7.6

• • • • • •

Introduction . . . . . . . . . . . . . . . . The State Diagrams . . . . . . . . . . . Scaling the Raw Analog Value . . . . Extracting the individual figures for Detecting No Input Voltage . . . . . . Recalibration . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . the display . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

126 126 133 135 135 135

Chapter 8 • Troubleshooting and Planning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 8.1 • Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 8.2 • Have an Overview of the Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 8.2.1 • State Diagrams and Flow Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 8.3 8.4 8.5 8.6

• • • •

Break Big Problems Down Into Smaller Ones . . . . . . . Read Through Your Code in Detail and Add Comments . Debugging a Running Program . . . . . . . . . . . . . . . . . Traffic Lights . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

137 137 137 138

8.6.1 • A Circuit Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 8.6.2 • Separate Different Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 8.6.3 • Producing the Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 8.7 • Using Debug Macro on the Voltmeter Programmable . . . . . . . . . . . . . . . . . . . 148 8.8 • A List of Things to Remember . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 Chapter 9 • A Comparison with C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 9.1 • Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 9.2 • The Microchip XC8 Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 9.2.1 • XC8 for Microsoft Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 9.2.2 • XC8 for 32 Bit Debian-Based Distributions . . . . . . . . . . . . . . . . . . . . . . 151 9.2.3 • XC8 for 64 Bit Debian-Based Distributions . . . . . . . . . . . . . . . . . . . . . . 152 9.2.4 • XC8 for 64-Bit Fedora . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 9.3 • Introduction to C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153

●7

AndrewPratt.indd 7

28/05/2020 12:26:23


Programming the Finite State Machine with 8-Bit PICs in Assembly and C 9.3.1 • Hello World in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 9.3.2 • Using the XC8 Compiler in Microsoft Windows . . . . . . . . . . . . . . . . . . . . 156 9.3.3 • Using the XC8 Compiler in Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 9.3.4 • Emitted Code Assembly vs C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 9.3.5 • Interrupts in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 9.3.6 • The __delay() functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 9.3.7 • Extending the If Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 9.3.8 • The Switch Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 9.3.9 • An Experiment to Measure Code Speed . . . . . . . . . . . . . . . . . . . . . . . . 167 9.4 • Serial Communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 9.4.1 • Serial Byte Transmission . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 9.4.2 • Serial Byte Reception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 Chapter 10 • Further C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 10.1 10.2 10.3 10.4

• • • •

Introduction . . . . . Data Types . . . . . . More on Functions . Integer Arithmetic .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

171 171 172 173

10.4.1 • Transmitting a Four-Byte Integer . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 10.4.2 • The "for" loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 10.5 • The Voltmeter in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 10.5.1 • Turning Bits On and Off Using Bit Type . . . . . . . . . . . . . . . . . . . . . . . . 179 10.5.2 • Turning Bits On and Off Using Bitwise Operators . . . . . . . . . . . . . . . . . 183 10.5.3 • Turning Bits On and Off Using Bitfields . . . . . . . . . . . . . . . . . . . . . . . . 183 10.6 • Summary of Assembly, C, and Finite State Machines . . . . . . . . . . . . . . . . . . 184 • Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185

●8

AndrewPratt.indd 8

28/05/2020 12:26:23


● Preface

Preface

This practical guide is aimed at electronics students and hobbyists. It is intended to be a valuable aid in writing programs using Finite State Machines (FSMs) in assembly language using 8-bit PIC microcontrollers. The last two chapters introduce the use of the C programming language and make a direct comparison with development in Assembly. An FSM is a way of writing a program to make it easier to produce and modify. The machine is abstract in that it is just the structure of the program. This abstract machine can be represented by drawing a diagram on paper. The diagram is independent of the programming language used. The FSM chart gives a complete description of what the program does. It can then be implemented as source code. The book should appeal to those with an interest in the combination of electronics and software and have an interest in how things work. The book will describe writing code for two particular microcontrollers: The 12F1822 and 16F1823. Both are mid-range and inexpensive. To read and write the programs to and from the PICs, all that is required is an FTDI TTL level USB lead (TTL-232R-5V-WE) in addition to two programs that are both available for free download as executable files and source code from Elektor. Microsoft Windows or Linux can be used. The PIC programs are written in assembly language. This goes against the conventional wisdom of using a higher-level language such as C. One reason for this is that assembly is a good way of learning what is happening at the lowest level. This is important as microcontroller programming requires an understanding of the chip. Another reason for using the finite state machine approach is that it makes assembly programs surprisingly easy to follow. One of the main obstacles in the way of getting started with embedded programming is the installation and learning of new software tools. The emphasis of this book is on making things straightforward with as little complication as possible. Therefore you can concentrate on understanding the code. Real projects aren’t just about coding: our software has to do something real. As a consequence, a chapter deals with a method of circuit board construction. All coding is done in a text editor of your choosing. The command line is used for running programs. If you are a Windows user, you might look at this as old fashioned. This is actually an efficient way of doing things: simple scripts for repetitive tasks save lots of mouse clicks. The last two chapters give an introduction to programming in C using the XC8 compiler. Again this is done using a text editor and the command line. The intention has been to achieve results using an inexpensive microcontroller with simple command line tools. Much emphasis is placed on using Microchip’s datasheet as this is the best place to get correct detailed information.

●9

AndrewPratt.indd 9

28/05/2020 12:26:23


Programming the Finite State Machine with 8-Bit PICs in Assembly and C

Chapter 1

Getting Started

1.1 • Introduction

Don’t be put off by the technical-sounding words ‘Finite State Machine’ (FSM). The principle of how they work is really easy to understand. Firstly, the machine is not an actual machine that you have to build. It is merely a structure your program has. The idea is that the program is broken down into a set number of states. When the program is in one of these states, it can respond to a set of inputs or events resulting in the program jumping to a different state. The outputs from the program depend only on the state (Moore machine) or on the state and the inputs (Mealy machine). Let’s start with the basic ‘Hello World’ microcontroller program to flash an LED as an example of a state machine with two states, LED ON and OFF.

Figure 1-1 A two-state machine

Figure 1-1 displays what the program does and how to write it. What the program does is: After power up, the initial conditions are the LED is ON and the timer is reset and started. After the timer expires, the LED turns OFF and the timer is reset and started. After the timer expires again, the LED turns ON and the timer is reset and started. This continues until the microcontroller is powered down In this example, there is only one event that triggers a change of state: This being the expiry of the timer. The effect of the expiry depends on the current state - it might jump to the LED ON state or the LED OFF state. The fact that an input or event is only used by the current state helps to make a more complicated program robust and easier to follow. This example is a Mealy machine, where outputs or actions are determined by the current state and inputs. On the state diagrams, the transitions between states are shown by arrows. Alongside these are the input conditions that trigger transitions and the resulting outputs. In a Moore machine, the outputs depend only on the current state of the machine. The outputs would be shown on the diagram inside the states. This book is specifically about practical programs. I will not try to adhere to strict definitions. As for how

● 10

AndrewPratt.indd 10

28/05/2020 12:26:23


Chapter 1 ● Getting Started

to write the program, you have already done the important bit by planning. All that has to be done now is to implement the diagram as code and this will be less prone to error as you can concentrate on local detail. The book will mostly use the Mealy type machine. Inputs causing a transition will be separated by a forward slash from the outputs. This will be written next to the transition between two states. With regards to the FSM, inputs and outputs (I/O) are not restricted to electrical I/O. They also include other types of change. An input could be the timer timing out or an output could be the writing of a value to a register in the CPU. FSMs can be written in just about any programming language. 1.2 • Practical Implementation

Microcontroller projects do not need to be expensive. The two PICs that are going to be used throughout the book are the 12F1822 and 16F1823 variants. Both are cheap midrange devices, costing less than one pound in the UK at the time of writing. They are available in the dual in-line package (DIP) form that is easy to solder or can be plugged into a holder. The programs will be written in a text editor and assembled with the gpasm open-source assembler. To load your programs into the PIC, you could use a programmer such as PICKIT 3, but there is no need to buy one. Two programs have been written for this book that can read and write using an FTDI USB lead TTL-232R-5V-WE. This same lead can also be used for reading and writing data from PICs in later projects. 1.2.1 • Choice of Operating System

Microsoft Windows or Linux can be used for assembling and loading programs to the PICs. There are two archive files available by way of a free download from the Elektor website: One is for Windows and the other for Linux. These files contain all the source files for the examples in the book and applications mentioned above. As described in the preface, the command line method is used throughout the book for both Linux and Windows. The use of the terminal with typed commands might seem like a throwback to the last century for those who remember using DOS. It is, however, a very easy way of doing things, especially for repetitive tasks like running assembler programs or loading the PIC with its program. Tasks can be simplified with scripts to save typing and recent commands can be recalled using the up and down keys. If you are using Linux, typing history will give a numbered list of the previous commands you have used. They can be run again by using the exclamation mark followed by the number. Auto-completion allows you to use the tab key to list possible files. You never have to type the complete name. If you are happy writing source code for an electronic device using text files then using the command line should be the logical choice. Graphic User Interfaces (GUIs) have their advantages. However, if you are doing something repetitive, a lot of mouse clicking or even using keyboard shortcuts is tedious compared with running a script or recalling a previous command and its options. 1.2.2 • Machine Language and Assembly Source Files

The PIC microcontroller has to be programmed by loading the machine code into its flash memory. The word ‘programmed’ in the last sentence means transferring machine code from a file on a computer to the PIC as opposed to writing the code. The machine code is

● 11

AndrewPratt.indd 11

28/05/2020 12:26:23


Programming the Finite State Machine with 8-Bit PICs in Assembly and C

the raw byte values that it processes when running. This machine code is first assembled into a file called a hex on your computer. It gets its name from the Intel Hex Format which is a file standard for this purpose. The hex file is then written to the PIC using a combination of a program on your computer and a hardware interface called a programmer. When referring to machine code, this is not the finite state machine but the processor itself being referred to as a machine. It is possible to write your program by typing a hex file directly into a text editor. Manually assembling machine instructions is too time-consuming to be considered a realistic task. To make it easier, code is written in assembly language where short acronyms for machine instructions are used to produce more readable code. The file that you type this way is the source code and usually has the file suffix .asm. This file is then read by the assembler application and written to the hex file as raw machine code. It is generally accepted that it is better to write your programs in a higher-level language. If you want to get things done quicker and with less chance of error, then this is absolutely true. C language was invented to get away from the problems of programming in assembly language. This book is about finite state machines implemented on simpler PICs. To write code for a microcontroller, you have to understand what is going on at the level where software meets hardware. Where C makes coding faster and easier, it also makes things more complicated. You don’t, however, see this extra complication: it’s taken care of by the compiler and linker. All of this gets in the way of understanding what your code is doing. For the PICs used in this book, there are 49 available instructions. The ones commonly used are quickly learnable. The beauty of assembly language is that you can see what’s going on. The code you write is exactly the machine code that goes into the PIC. Once the source code file is finished, it is converted to machine language by the assembler application: in our case the program gpasm. The assembler reads your source code and outputs the hex file. The hex file is then read by another application that writes to the PIC using some form of hardware interface. Figure 1-2 below depicts this programming chain.

● 12

AndrewPratt.indd 12

28/05/2020 12:26:23


Chapter 1 ● Getting Started

Figure 1-2 Programming Chain

You can if you prefer, use MPLABX and PICKET 3 or 4 from Microchip. You may already have these and be familiar with them. The next two paragraphs describe an alternative using the applications provided in the download. 1.2.3 • Using the Applications on Microsoft Windows

First, you need to download and install gputils for Windows from here: https://sourceforge.net/projects/gputils/files/gputils-win32/ The version used at the time of writing was 1.4.0. Although not the latest version, it was chosen to be the same as used by the current Debian and Ubuntu. You can use the latest version if like. You will need the FTDI driver for your USB interface lead, and the installation of the file FTD2XX.DLL. The best way to do this is to download the executable setup for Windows from: http://www.ftdichip.com/Drivers/D2XX.htm At the time of writing, it is named CDM2128_Setup.zip. Inside the zip file is CDM2128_ Setup.exe that will install the driver and the required DLL file. Install it before plugging in the lead. You need to unzip the file from the Elektor website into a convenient directory on your computer. Please make sure that you download the correct file. The Linux version won’t work on Windows and vice versa. It’s not just executables that are not compatible. Text files have different line endings: Linux files have a new line character while Windows files

● 13

AndrewPratt.indd 13

28/05/2020 12:26:23


Programming the Finite State Machine with 8-Bit PICs in Assembly and C

have a carriage return and new line character at the end of each line. The file unzips several directories. The working directory contains a batch file called terminal_here. Clicking on this will open a virtual terminal. If you type dir and press return, the contents of the directory will be displayed. Initially, the files in the working directory are executable. These executables will be run from the command line. This only involves typing a couple of words and pressing return. Later in this chapter, instructions will be given on how to use these applications. For reading and writing PIC source files, you can use Windows’ text editor, notepad, but any text editor will do, including notepad++. 1.2.4 ● Installing the Applications on Linux

The archive file for Linux is a tar file. This can be extracted by typing on the command line tar -xvf <file name>.tar. There are many variants of Linux. I won’t try to cover the instructions in detail for all of them. I will give instructions for two: Debian and Fedora. The details for Debian are also applicable to Ubuntu and other Debian derivatives. The assembler program gpasm is part of the GNU PIC Utilities (gputils) package. This can be installed on Debian based Linux by opening a terminal window and typing: sudo apt-get install gputils. Of course, you have to be connected to the Internet. On Fedora, the command is sudo dnf install gputils.

Figure 1-3a Installing gputils on Debian (Ubuntu etc)

For Fedora:

Figure 1-3b Installing gputils on Fedora

To load the hex file contents into the PIC microcontroller and read back the loaded bytes, the two programs that have been written especially for this book are called program_ writer_xx and program_reader_xx, where xx is 32 or 64. Both versions are provided: one for 32-bit and one for 64-bit operating systems. These programs need to have the package libftdi1-dev installed to work. This can be installed on Debian by opening a terminal window and typing sudo apt-get install libftdi1-dev .

Figure 1-4a Installing libftdi1-dev on Debian

● 14

AndrewPratt.indd 14

28/05/2020 12:26:23


Chapter 1 ● Getting Started

For Fedora:

Figure 1-4b Installing libftdi on Fedora

These two applications have only been tested with these two PICs. Figure 1-5 shows the directory trees for the Linux and Windows downloads.

Figure 1-5 Download directory tree for Linux and Windows

Once you have all the software installed, the next thing is to try it out using the hardware. 1.2.5 • The FTDI Lead and Testing the Programming Chain

All that is required is an FTDI TTL-232R-5V-WE USB wire end lead. They are readily available from suppliers such as Farnell, RS Components, and Digi-Key. 1k resistors to pins 4, 6, and 7 are recommended for protection. The one connected to pin 5 is to limit the current flowing through the LED.

● 15

AndrewPratt.indd 15

28/05/2020 12:26:23


Programming the Finite State Machine with 8-Bit PICs in Assembly and C

Figure 1-6 In-Circuit Programming Diagram

The above circuit can quickly be connected to a plugin breadboard: see Figure 1-9. The LED is not part of the programming circuit. It is there for the test program to demonstrate that it is all correctly working. The test program test.hex is included in the Chap01_progs folder of the archive file. It makes the LED flash on for a quarter of a second and off for threequarters of a second. You need to copy it to the working directory to use it. If you are using Windows, click on the terminal_here batch file in the working directory to open the terminal window. Type in the following and press return. See the upper pane in Figure 1-7.

program_writer.exe test.hex

If you are using Linux, open a virtual terminal and navigate to the working directory. Type the following and press return. See the lower pane in Figure 1-7.

sudo ./program_writer_64

test.hex

Note that in Linux you must prefix the executable file with ./ .This is the path to the present directory. The sudo command will be required to acquire the privilege of opening the USB port. Once the code is loaded into the PIC, the LED should start flashing. The code can be verified by reading it back using the program program_reader: refer Figure 1-8. Only a few lines of the output from these programs is shown in the screen dumps. Take care to correctly connect the wires and get the LED the correct way round. The PIC has pin 1 marked with a dimple on the top surface.

â—? 16

AndrewPratt.indd 16

28/05/2020 12:26:23


Chapter 1 ● Getting Started

Figure 1-7 Writing the Hex File to the PIC: Windows and Linux 64 bit

Figure 1-8 Reading Back PIC Code: Windows and Linux

● 17

AndrewPratt.indd 17

28/05/2020 12:26:24


Programming the Finite State Machine with 8-Bit PICs in Assembly and C

Figure 1-9 Plugin breadboard

1.3 • Some Fundamentals

Assuming that everything has so far worked, you can move on in the next chapter to writing a first PIC program with confidence that it can be written to the controller. The rest of this chapter is of benefit to those who are not familiar with PIC programming in assembly language. All that is required to write the code is a text editor. You should also have open a copy of the datasheet for the 12F1822 and 16F1823 which can be downloaded free as a PDF file from Microchip. The name of the document is DS40001413E. To get you on your way, I will present a program that flashes an LED at about 5Hz. This is not the same program as test. hex that was used to prove the programming chain above. Writing code for a microcontroller requires knowledge of the inner workings of a device. The controller is part of an electronic circuit. The code is an extension of the circuit that you are building. If you browse through the datasheet, you’ll see that there are more than four hundred pages. Trying to read a document like this can be overwhelming as it has not been written as a teaching aid and is packed with information. We will start slowly with just enough detail to start-off. We will add more as the projects get more advanced. Once you start to become familiar with the layout of this manual, it is quite easy to find what you want to know as you progress. I’m assuming that all of this is new to you and will try to explain all you need to know to understand this first program. 1.3.1 • Bits and Bytes

Let’s start with the bit. The word bit is the contraction of binary digit. A bit is a basic unit of

● 18

AndrewPratt.indd 18

28/05/2020 12:26:24


Chapter 1 ● Getting Started

information: it has only two states commonly referred to as 0 or 1. Physically these states can be represented by say a voltage of 0V or +5V. Any physical quantity that can have two distinct values could be used. Now if two bits are placed next to each other, there are now four permutations that bits can be in, 00, 01, 10, 11. If three bits are used, there are eight permutations, 000, 001, 010, 011, 100, 101, 110, 111. Whenever a bit is added to the group, the number of permutations double. A byte is normally a group of eight bits and these have 256 permutations. Each arrangement of bits can be used to represent an integer. To start with we’ll look at positive integers and zero. Negative integers can also be expressed but that’s for later. Bits that are 1 are sometimes referred to as being on, and off when they are 0. Each bit in a byte not only has a value of 0 or 1 but has a position in the byte. We give weight to the positions so that the bit on the right end is worth 1 when it is on and 0 when it is off. The next position has a weight of 2 so that bit is worth 2 when it is on and 0 when it is off. Continuing this binary weighting to all eight bits in a byte, all the values from 0 to 255 can be allocated to bit states.

128

64

32

16

8

4

2

1

0

0

0

0

0

0

0

0

0

1

0

0

0

0

0

0

0

1

2

0

0

0

0

0

0

1

0

3

0

0

0

0

0

0

1

1

4

0

0

0

0

0

1

0

0

5

0

0

0

0

0

1

0

1

6

0

0

0

0

0

1

1

0

7

0

0

0

0

0

1

1

1

8

0

0

0

0

1

0

0

0

9

0

0

0

0

1

0

0

1

10

0

0

0

0

1

0

1

0

11

0

0

0

0

1

0

1

1

12

0

0

0

0

1

1

0

0

13

0

0

0

0

1

1

0

1

14

0

0

0

0

1

1

1

0

15

0

0

0

0

1

1

1

1

16

0

0

0

1

0

0

0

0

-

-

-

-

-

-

-

-

-

255

1

1

1

1

1

1

1

1

Table 1-1 Binary Weighting

● 19

AndrewPratt.indd 19

28/05/2020 12:26:24


Programming the Finite State Machine with 8-Bit PICs in Assembly and C

For example, eleven is expressed by the bits with the weights of 8, 2 and 1 being set on. This is no different to the way we count in tens. The number 364 is four lots of units plus six lots of tens plus three lots of hundreds. Each place is weighted by a factor of ten. If we add 6 to 364 it becomes 370. The units position has overflowed and the value of ten has been carried and added to the tens position. The same happens with binary addition. Here are three separate examples:

Figure 1-10 Additions with Carry

When an addition results in the overflow of a byte, a carry is generated that adds to the next higher byte. If the first byte counts up to 255, the next will count the number of 256s and so on with the next higher byte counting the number of 65536s and so on. 1.3.2 • The Hexadecimal Numbering System

In everyday life, we use the decimal numbering system. Microcontrollers and computers operate using the binary system as described above using bits and bytes. Converting the expression of a value backward and forwards to a binary bit pattern is not very convenient. There is an alternative to the decimal system that uses 16 characters instead of the ten. What makes this convenient is that a group of four bits has sixteen different permutations. To have 16 characters representing the values from 0 - 15, the letters A to F are used for 10, 11, 12, 13, 14, and 15. This means that a byte’s value can be represented by two hexadecimal digits. Figure 1-11 shows an example of the decimal number 44 which is 00101100 as eight bits displayed as hexadecimal 0x2C. Two ways of indicating that a number is being expressed in hexadecimal notation, are to prefix it with ‘0x’ or suffix it with ‘h’. Hexadecimal offers a way of writing binary numbers in a way that is easier than long strings of ones and noughts in a way that can be converted to individual bits easily.

● 20

AndrewPratt.indd 20

28/05/2020 12:26:24


Chapter 1 ● Getting Started

Figure 1-11 Example of a Hexadecimal Number (0x2C)

1.3.3 • Boolean Logic

In programming, bits are often operated on by logic operations to give a binary result either true or false. The operations used are AND, OR, NOT, and XOR. A good way to see how this works is the truth table. Figure 1-12 shows these. In the tables, only two input bits called the operands are shown for the AND, OR, and XOR operators. The NOT simply inverts the value of one bit. XOR stands for exclusive OR.

Figure 1-12 Boolean Logic Truth Tables 1.3.4 • Bitwise logic

If we carry out boolean logic with corresponding bits in two or more words, the result will be another word. Here is an example to demonstrate this. Taking two words with the values 0x1234 and 0xABCD and then performing the bitwise AND operation the result is 0x0204. This sort of operation is frequently used in low-level programming.

● 21

AndrewPratt.indd 21

28/05/2020 12:26:24


Programming the Finite State Machine with 8-Bit PICs in Assembly and C

Figure 1-13 Bitwise Logic

1.3.5 • PIC Architecture

Inside the PIC is a central processing unit connected to a set of peripheral devices, memory and inputs and outputs. Refer to pages 9 and 16 of the datasheet. You get a lot for your money! Throughout the book and in comments to the source code files, I will refer to pages to supplement information. These are the pages in the Microchip DS40001413E datasheet unless stated otherwise. There are three areas of memory: Program Memory Non-volatile: it retains information when the power is off. It is flash memory. This is where your program (the hex file) is loaded to. Data Memory Volatile: it does not retain information when the power is off. It is a random access memory (RAM), made up of banks of eight-bit registers also referred to as files in this context. Electrically Erasable Programmable Read-Only Memory (EEPROM) Non-volatile: this can be used to store data when the power is off. This is called the Harvard architecture where the program and the data are in separate memory areas. 1.3.6 • Data Memory Organization

Data memory is made up of 32 banks. Each bank has 128 locations although not every location is implemented. Each location is one byte or eight bits wide. Some of the implemented memory can be used to store variables. Other locations are registers that have predefined use and are called special function registers. Pages 22 to 25 of the datasheet shows a map of data memory. Of these special registers, 12 are core registers. These are repeated in every bank in the first 12 locations. I’ll start by mentioning only three of these registers:

● 22

AndrewPratt.indd 22

28/05/2020 12:26:24


Chapter 1 ● Getting Started

W Working Register: temporary storage used by logic and arithmetic operations. STATUS A register containing the status of the arithmetic, logic unit of the CPU and reset status. BSR Bank Select Register: This register has to be set to the bank that you want to access. Bank selection is a feature of this type of PIC. It comes about because of the format of machine instructions. They are 14 bits wide. For some instructions, 7 bits are used to point to the address of a register. Note that the word file is used, meaning register. Here is an example of one of the instructions, BCF (bit clear file). This sets a particular bit in a file to zero. If you wanted to turn bit 5 in the PORTA register off, the assembly code would be BCF PORTA, 5.

0

1

0

Operation code

0

b

b

b

Bit in the file e.g bit 5 = 1 0 1

f

f

f

f

f

f

f

File in the bank e.g PORTA is 0x0c in bank 0. 0x0C = 0 0 0 1 1 0 0

Table 1-2 Bit Clear File (BCF) Instruction

There are only 7 bits in the instruction for the file address, which limits the range to 128 one bank. If you are in the wrong bank, for example, bank 1 instead of bank 0, and think you are going to access PORTA you would get TRISA - not what you wanted. The bank is set in BSR. There is an MOVLB instruction (move literal to bank select register) that is used to load BSR directly. To use it you have to remember or look up the bank number for each file you want to access. To make it easier, there is an assembly directive provided called BANKSEL that generates the correct code. For example, BANKSEL PORTA will generate MOVLB 0. Please note it is the gpasm assembler’s job to generate the instructions like the one in Table 1-2 using the operation code (opcode) and the operands from each line of code. Page 308 onwards describes all the detail you need to manually assemble the instructions. You would however, then have to format the Intel hex file. I will revisit the topic of bank selection in Chapter 3. In assembly programming, the term ‘move from one location to another’ means to copy the value to a destination. It does not delete the value from the source location.  1.3.7 • An Assembly Program Snippet

From an electronic point of view, a microcontroller is a programmable integrated circuit or chip. It has several electrical connections or pins that can be used as inputs or outputs. The PIC can be programmed to perform many different functions. To get an idea, I will describe part of a program to make a 12F1822 into an AND gate. This is a trivial use of a PIC and only part of the code will be shown to demonstrate what you can expect when assembly

● 23

AndrewPratt.indd 23

28/05/2020 12:26:24


Programming the Finite State Machine with 8-Bit PICs in Assembly and C

programming.

Figure 1-14 PIC 12F1822 as an AND gate

When you write a program for a computer, there is an operating system such as Windows, Linux, BSD or macOS that deals with hardware interfacing by way of a kernel. The PIC has no operating system. You have to deal with the details of hardware such as configuring inputs and outputs, oscillator frequency or perhaps configuration of the serial port (if you want to communicate with a PC). Figure 1-14 shows how the PIC would appear if programmed to be an AND gate. You might want to argue that what I have drawn is a ‘NOT OR’ gate. As the switches pull the inputs down to 0V when they are closed, from the point of view of the voltages on the inputs, they all have to be high for the output to go high. Therefore, it is an AND gate. Each input has an internal high-value resistor that pulls it up to 5V when the pin is open circuit. This is called a weak pull-up and is configured in the code. This saves on external components as all that is needed is a switch to pull the voltage on the pin-down. Something that I should mention is that the programming method used by my programs, program_writer, and program_reader use low voltage programming with the FTDI lead as opposed to high voltage programming that would require pin 5 MCLR/Vpp/ RA3 to have between 8 and 9V applied to it to enter the programming mode. Low voltage programming can be performed with just a 5V supply and special train of bits applied to the ICPDAT pin to enter programming mode. The downside of this is pin 4 can only be used as MCLR (not master clear reset). This means that 0V applied to this pin resets the PIC. Pin 4 must therefore always have 5V applied to it. The weak pull-up does this. It is enabled by default in low voltage programming mode. This means we have lost the use of RA3 as an input pin. It is never an output anyway. Don’t concern yourself with all this detail about programming methods for now. If you want more information about the details of this then

● 24

AndrewPratt.indd 24

28/05/2020 12:26:24


Chapter 1 ● Getting Started

take a look at page 1, note 2 of the datasheet on in circuit DS41390C programming. This datasheet explains everything about the in circuit programming of these PICs. One last point: the line drawn over MCLR means ‘NOT MCLR’. If the voltage is 5V, it is not resetting the PIC. It resets on 0V. Now for a look at some assembly language code. The code once written to the PIC is a list of machine instructions. Generally, one instruction is executed for every four clock cycles. Clock cycles are produced by the oscillator. Everything in this book will use the internal oscillator. No external components are required for the oscillator. Each instruction is located at a memory address in the flash memory of the PIC. As the program runs, the current instruction is pointed to by the program counter. This counter increments by one as each instruction is executed. Some of the instructions can cause the program counter to jump forwards or backward. These jumps can be decided on by the outcome of logical or mathematical operations. If you have programmed in another language such as C/C++, Java, Python, etc, you will be familiar with the if...else statement used frequently to execute one piece of code or another based on whether an expression is true or false. Consider this example in pseudo-code.

if

bit Z in the STATUS register is high then turn the output on;

else

turn the output off;

end_if;

Figure 1-15 shows how to implement this in PIC assembly language. Before the code that is shown here, a subtraction calculation is carried out. If the result is zero, bit Z in STATUS will be set on. BTFSS (bit test file skip on set) tests a bit in a file. If the bit is high, the next instruction will be skipped. If low, the next instruction will be executed. In typing your assembly program, the opcode mnemonics are indented. The words on the extreme left are labels that you invent to mark places in the code. These labels can be used as the destination for GOTO opcode.

● 25

AndrewPratt.indd 25

28/05/2020 12:26:24


Programming the Finite State Machine with 8-Bit PICs in Assembly and C

Figure 1-15 Part of an Assembly Language Program Implementing ‘if ...else’

PORTA is the register holding the state of the pins for port A. In this example bit 5 was configured as an output. Therefore, writing to bit 5 sets the electrical state of the pin. The BTFSS STATUS, Z decides whether to skip the next instruction. If Z is high, the program jumps to the line BSF PORTA, 5 (bit set file) and turns on bit 5 in PORTA. If Z is low the next instruction GOTO ELSE is executed. The program then jumps to BCF PORTA, 5 (bit clear file) turning off bit 5. 1.4 • Program Memory

The program is held in flash memory. Each location is 14 bits wide and holds a machine instruction. The next instruction to be executed is held in the program counter that is 15 bits wide making it capable of addressing 32k locations. The 12F1822 and 16F1823 PICS have only 2048 locations implemented. The rate at which instructions are executed is determined by oscillator frequency. It takes four clock cycles for every instruction cycle. Program memory is divided up into pages that are 2048 locations long. The program counter PC that points to the current location in the program is 15 bits wide. It can point to a range of 0 to 32767 or 32568 locations. The PC is loaded from two registers: PCL and PCLATH. This occurs under five circumstances that are described on page 38 of the datasheet. PCL is one of the special function registers and appears in all banks. It provides the lower 8 bits of PC, PCL (standing for Program Counter Lower). PCLATH (standing for Program Counter Latch Higher) provides the higher 7 bits. If you are using a PIC that has more than 2048 program memory locations, you have to be aware that your program will cross page boundaries. Fortunately, we don’t have to worry

● 26

AndrewPratt.indd 26

28/05/2020 12:26:24


● Index

Index

A addition 9, 20, 103, 104, 105, 106, 110, 116, 162, 176 analog input 76, 77, 79, 98, 99, 135 AND 21, 23, 24, 28, 174, 175 apt-get 14, 152 arguments 54, 59, 72, 107, 155, 157, 159, 172 assembler 11, 12, 14, 23, 27, 28, 30, 55, 60, 61, 136 assembly 9, 12, 18, 23, 25, 26, 27, 28, 30, 31, 32, 41, 53, 60, 154, 156, 157, 159, 162, 163, 164, 168, 170, 171, 172, 173,

61, 103, 111, 151, 153,

174, 176, 179, 184

B bank select 23, 28, 65 Baud rate 67 binary arithmetic 93, 103, 126 bits 19, 20, 21, 22, 23, 24, 26, 27, 28, 29, 30, 34, 35, 36, 37, 48, 57, 64, 65, 68, 73, 77, 78, 79, 80, 83, 84, 96, 97, 99, 100, 103, 104, 108, 114, 115, 116, 122, 128, 133, 134, 135, 148, 155, 156, 168, 171, 175 bitwise 21, 28, 174, 175 Boolean 21 bytes 14, 20, 67, 68, 73, 77, 105, 107, 108, 110, 111, 113, 114, 116, 119, 124, 162, 167, 168, 173, 174, 175

C chmod 151 clock 25, 26, 33, 34, 35, 61, 63, 68, 69, 73, 74, 77, 78, 80, 88, 100, 101, 103, 128, 134, 161, 162, 169, 170, 176, 177 command-line 72, 80, 107, 155 compiler 9, 12, 30, 66, 103, 116, 151, 152, 153, 154, 155, 156, 157, 159, 162, 168, 171, 173, 176, 179, 184 C programming 9, 30, 153

D Debian 13, 14, 61, 151, 152 debug 136, 138, 141, 148 digital input 74, 88, 91, 101, digital output 167 dnf 14, 152

126, 170

E EUSART

67, 68, 72, 73, 74, 76, 106, 109, 110, 112, 113, 118, 119, 121, 122, 123, 124,

143

● 185

AndrewPratt.indd 185

28/05/2020 12:26:35


Programming the Finite State Machine with 8-Bit PICs in Assembly and C

F Fedora 14, 15, 152, 153 finite state machine 9, 12, 31, 47, flow charts 136 FSM 9, 10, 11, 32, 43, 67, 136, 184

58, 105, 117, 151, 184

G gpasm gputils

11, 12, 14, 23, 29, 30, 38, 40, 41, 56, 61, 66 13, 14, 27

H hexadecimal 20, 28, 29, 34, 37, 38, 65 hex file 12, 14, 17, 22, 23, 29, 61, 151, 156,

157, 167, 176

I include file 28, 51, 156 instructions 12, 14, 23, 25, 26, 48, 63, 65, 66, 88, 104, 157, 161, 184 integer 19, 107, 108, 114, 116, 119, 120, 134, 135, 154, 155, 162, 163, 173, 174, 175, 178 interrupt service routine 36, 37, 74, 75, 76, 142, 159, 170 interrupt vector 36, 142

164, 171, 172,

M macros

49, 54, 55, 56, 57, 58, 59, 60, 61, 62, 65, 66, 70, 75, 76, 80, 84, 88, 91, 101,

106, 109, 112, 118, 121, 123, 128, 137, 142, 145, 146, 147, 162, 172

Mealy 10, 11, 32, 120, 139, 140, 143, 164, 184 Microchip 9, 13, 18, 22, 30, 32, 137, 151, 153, 156 Microsoft Windows 9, 11, 13, 41, 107, 151, 156 Mint 151 Moore 10, 32, 136, 139, 140, 143, 164, 184 multiplication 103, 116, 117, 131

N negative numbers nested 62, 140, 156, NOT 21

114, 115, 171

159, 167, 170

O one’s complement Operating System OR 23

115, 116

11, 107

P

â—? 186

AndrewPratt.indd 186

28/05/2020 12:26:36


● Index

PATH 41 polling 35 program_reader 14, 16, 24 program_writer 14, 16, 24, 29, pulse width modulation 81

30, 40, 41, 151, 154, 156

R register 64,

11, 23, 25, 26, 27, 28, 29, 33, 34, 35, 36, 38, 39, 44, 48, 49, 53, 54, 55, 57, 59,

65, 68, 69, 73, 83, 85, 91, 99, 101, 103, 104, 111, 113, 117, 129, 142, 143, 149,

157, 168, 171, 175 return address 36

S serial_reader 67, 71, 72, 80, 107, serial_writer 169 seven-segment 58, 70, 98, 126 shift 116, 143, 175 signed 107, 114, 116, 171 sleep 126, 149, 150 stack 36, 63, 64 state diagram 32, 33, 41, 42, 50, 144, 170, 179 sub-states 140, 141, 146, 150

108, 138, 168, 177, 178

60, 69, 73, 79, 82, 86, 90, 117, 120, 132, 136, 141,

T timer0 33, 36, 37, 56, 57, 73, 74, 75, 140, 141, 142, timer1 33 timer2 33 transitions 10, 41, 47, 79, 86, 120, 139, 143, 170 TTL 9, 11, 15, 67, 71 TTL-232R-5V-WE 9, 11, 15 two’s complement 115, 116

159, 160, 170

U Ubuntu USB 9,

13, 14, 151, 152

11, 13, 15, 16, 71, 97

W working register

29, 34, 35, 39, 49, 53, 57, 59, 91, 101, 104, 111, 117, 129, 149, 157

X XC8 XOR

9, 30, 151, 152, 153, 155, 156, 157, 161, 171 21

● 187

AndrewPratt.indd 187

28/05/2020 12:26:36


Programming the Finite State Machine

Programming the Finite State Machine

Andrew Pratt served for 25 years in the Royal Air Force as an Aircraft Technician. He holds a Higher National Certificate in electrical and electronic engineering and an Honours Degree from the Open University. He continued his career working in industrial controls.

ISBN 978-1-907920-92-9

Elektor International Media BV

www.elektor.com

Andrew Pratt provides a detailed introduction to programming PIC microcontrollers, as well as a thorough overview of the Finite State Machine (FSM) approach to programming. Most of the book uses assembly programming, but do not be deterred. The FSM gives a structure to a program, making it easy to plan, write, and modify. The last two chapters introduce programming in C, so you can make a direct comparison between the two techniques. The book references the relevant parts of the Microchip datasheet as familiarity with it is the best way to discover detailed information. This book is aimed at Microsoft Windows and Linux users. To keep your costs to a minimum and to simplify the toolchain, specific applications are provided as a free download to enable you to use an FTDI serial lead as the programmer. The assembler used is the open-source "gpasm". All programming can be done in a text editor. There are detailed instructions on how to perform the necessary installations on Windows, Linux Debian, and derivatives such as Ubuntu and Fedora. For programming in C, Microchip's XC8 compiler is used from the command line. In addition to the programming applications, two serial read and serial write applications can be used for communicating with the PICs from a computer. A voltmeter project including practical instructions on building a circuit board from scratch is included. All theory is covered beforehand, including how to do integer arithmetic in assembly. Two PICs are covered: the PIC12F1822 and the PIC16F1823. Both can run at 32 MHz with an internal oscillator. You do not need to buy a factory-made development board and programmer. With relatively inexpensive parts including a serial lead, microcontroller, a few resistors, and LEDs, you can get started exploring embedded programming.

LEARN DESIGN SHARE

Programming the Finite State Machine ● Andrew Pratt

Andrew Pratt

with 8-Bit PICs in Assembly and C

with 8-Bit PICs in Assembly and C

Enhanced 2nd Edition ;-----------Machine States. S0 MOVLW 3 SUBWF TICK_COUNTER, W BTFSS STATUS, C GOTO S0 BCF PORTA, 2 CLRF TICK_COUNTER INCF PULSE_COUNTER, F S1

S2

S3

MOVLW 10 SUBWF PULSE_COUNTER, W BTFSS STATUS, C GOTO $+3 CLRF PULSE_COUNTER GOTO S3 MOVLW 9 SUBWF TICK_COUNTER, W BTFSS STATUS, C GOTO S1 CLRF TICK_COUNTER BSF PORTA, 2 GOTO S0 MOVLW 31 SUBWF TICK_COUNTER, W BTFSS STATUS, C GOTO S2 BCF PORTA, 2 CLRF TICK_COUNTER INCF PULSE_COUNTER, F

MOVLW 3 SUBWF PULSE_COUNTER, W BTFSS STATUS, C GOTO $+3 CLRF PULSE_COUNTER GOTO S1 MOVLW 91 SUBWF TICK_COUNTER, W BTFSS STATUS, C GOTO S3 CLRF TICK_COUNTER BSF PORTA, 2 GOTO S2

; LED on. Fast cycle. ; ; ; ; ; ; ;

C in STATUS is set when TICK_COUNTER >= to 3. Skip the next instruction if C in STATUS is found set. C in STATUS found not set. Stay in this state. Turn LED off Reset the tick counter. Add 1 to PULSE_COUNTER and put the result in PULSE_COUNTER. Continue to S1

; LED off. Fast cycle. ; ; ; ; ; ; ; ; ;

C in STATUS is set when PULSE_COUNTER >= to 10. Skip the next instruction if C in STATUS is found set. Have not reached 10 pulses jump to ticks check. 10 Pulses have been counted, reset PULSE_COUNTER. Transition to S3. Load W with 9 for ticks check. C in STATUS is set when TICK_COUNTER >= to 9. Skip the next instruction if C in STATUS is found set. C in STATUS found set, 9 ticks counted.

; Turn LED on.

; ; ; ; ; ; ;

C in STATUS is set when TICK_COUNTER >= to 3. Skip the next instruction if C in STATUS is found set. C in STATUS found not set. Turn LED off Reset the tick counter. Add 1 to PULSE_COUNTER and put the result in PULSE_COUNTER. Continue to S3

; LED on. Slow cycle. ; ; ; ; ;

C in STATUS is set when PULSE_COUNTER >= to 3. Skip the next instruction if C in STATUS is found set. ave not reached 3 pulses jump to ticks check. Reset PULSE_COUNTER. Transition to S1.

; C in STATUS is set when TICK_COUNTER >= to 9. ; Skip the next instruction if C in STATUS is found set. ; C in STATUS found set. ; Turn LED on.

Andrew Pratt LEARN DESIGN SHARE

LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHAR ESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHARE ● LEARN ● DESIGN ● SHA COVER EN template pratt.indd All Pages

28/05/2020 12:06:56


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.