Conditional branching and working with bits One of the most important features of any microprocessor or microcontroller program is its ability to make ‘decisions’, i.e. to act differently according to the state of logical variables. Microprocessors generally have within their instruction sets a number of instructions which allow them to test a particular bit, and either continue program execution if a condition is not met or branch to another part of the program if it is. This is illustrated in Figure 5.3. These variables are often bit values in condition code or Status registers. ThePIC16Seriesmicrocontrollersarealittleunusualwhenitcomestoconditionalbranching as they do not have branch instructions as such. They have instead four conditional ‘skip’ instructions.Thesetestforacertaincondition,skippingjustoneinstructioniftheconditionis met and continuing normal program execution if it is not. The most versatile and general- purpose of these are the instructions:
Branching on Status register bits
Aswedevelopbiggerprograms,wequicklyfindthatthereareprogramsectionsthataresouseful thatwewouldliketousethemindifferentplaces.Yetitistedious,andspace-andmemory- consuming,towriteouttheprogramsectionwheneveritisneeded.Enterthesubroutine. The subroutine is a program section structured in such a way that it can be called from anywhere in the program. Once it has been executed the program continues to execute from wherever it was before. The idea is illustrated in Figure 5.4. At some point in the main program there is an instruction ‘Call SR1’. Program execution then switches to Subroutine 1, identified by its label. The subroutine must end with a ‘Return from Subroutine’ instruction. Program execution then continues from the instruction after the Call instruction. A little later in the program another subroutine is called, followed a little later by another call to the first routine. TheactionoftheCallinstructionistwo-fold.ItsavesthecontentsoftheProgramCounteronto theStacksothattheCPUwillknowwheretocomebacktoafterithasfinishedthesubroutine. It then loads the subroutine start address into the Program Counter. Program execution thus continuesatthesubroutine.ThereturninstructioncomplementstheactionoftheCall.Itloads theProgramCounterwiththedataheldatthetopoftheStack,whichwillbetheaddressofthe instruction following the Call instruction. Program execution then continues at this address. SubroutineCallandReturninstructionsmustalwaysworkinpairs.GothroughProgramming Exercise 5.3 to find out what happens if they don’t.