Top Banner
2/27/2019 1 Programming PIC with C Spring 2019 EE3954: Microprocessors and Microcontrollers Avinash Karanth Professor, Electrical Engineering and Computer Science Ohio University E-mail: [email protected] Acknowledgment: Harsha Chenji, Jim Goble, Maarten Uijt de Haag 1 Course Administration Lab 3 this week! Homework 3 to be posted by end of week – due next Friday March 8 th No lab next week! 2 1 2
20

Programming PIC with C - ace.cs.ohio.edu

Oct 16, 2021

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

1

Programming PIC with C

Spring 2019EE3954: Microprocessors and Microcontrollers

Avinash Karanth

Professor, Electrical Engineering and Computer Science

Ohio University

E-mail: [email protected]: Harsha Chenji, Jim Goble, Maarten Uijt de Haag

1

Course Administration

• Lab 3 this week!

• Homework 3 to be posted by end of week – due next Friday March 8th

• No lab next week!

2

1

2

Page 2: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

2

Reference Sections

• MPLAB® XC8 C Compiler User’s Guide

3

C vs Assembler

4

Assembly Code

MachineCode

EEPROM

CCode

MachineCode

EEPROM

Assembly Code

High-level language

Low-level language/Native language

Machine code words

Hardware

3

4

Page 3: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

3

Embedded C

5

• Myth Busting –

• C is not as portable between architectures or compilers as everyone claims• ANSI language features ARE portable• Processor specific libraries are NOT portable• Processor specific code (peripherals, I/O,

interrupts, special features) are NOT portable

• C is NOT as efficient as assembly• A good assembly programmer can usually do

better than the compiler, no matter the optimization employed - C WILL use more memory

Source Code to Silicon

6

5

6

Page 4: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

4

A Simple C Program

7

• The line numbers are just for reference.

• Lines 1 and 3 are preprocessor directives.

• Just like any other C program, we must have only one main function.

• This is a very simple program, but it demonstrates how much easier it is to program the PIC in C than Assembly. There is no defined way to do floating point or even multiplication in assembly. You have to write those routines yourself. In C, they are just part of the normal include files.

A Simple C Program

8

• Variables have to be defined before we use them. Harder than MatLab, much easier than assembly.

• Note that float is a data type. PIC C supports all of the normal data types.

• Unlike most PCs we will program, we should keep track of the bytes we are using with our data. Floats are 4 bytes, chars 1 byte, ints 2 bytes, etc. Why you say? Because we only have 8 KB of program memory and 1 KB of data memory.

7

8

Page 5: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

5

A Simple C Program

9

• The identifiers for our variables follow the normal C convention. They must be composed of combinations of the letters of the alphabet, the numbers 0-9 and the underscore. They are case sensitive.

• The identifiers cannot use any of the normal ANSI C keywords or any of the 12 additional keywords used by the PIC compiler. These will give you compiler errors at best.

Literal Constants

10

• A literal constant or simply a literal is a value, such as a number, character, or string that may be assigned to a variable or symbolic constant, used as an operand in an arithmetic or logical operation, or as a parameter to a function.

• Literals are "hard coded" values such as the number 5, the character 'A', or the string, "Hello, world!".

• Numeric literals may be represented in a variety of formats (decimal, hexadecimal, binary, floating point, etc.)

• A literal always represents the same value (5 always represents the quantity of five)

9

10

Page 6: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

6

Literal vs. Constants

11

• Although most of the C programming world uses the terms constant and literal interchangeably, those with assembly language background will understand them to describe two distinctly different, though related concepts.

• The numbers 32767 and -32768 are literals. They are actual values and the symbols we use to represent them cannot ever mean anything other than the values they represent.

• The words MAXINT and MININT are constants. They are symbols used to represent the values we assigned to them (32767 and -32768 respectively), but the symbols could mean anything we want.

Operators

12

• We won’t be covering many of the operators, since you already have covered them in previous classes. The memory addressing operators take the place of the FSR and INDF assembly commands and do a few things extra. The cost is always memory space.

11

12

Page 7: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

7

Statements

13

• Statements behave exactly the same way they do in any other C compiler. Unlike C on our lab workstations, you have to be aware of memory limitations. Especially since we are using Microchip’s free compiler. The free version is not vey efficient at unpacking. A while statement may use far more memory than you expect, especially compared to the bit test statements used in the assembler.

Functions

14

• Again, functions behave exactly the same way they do in any other C compiler. Again, you have to be aware of memory limitations. A simple looking expression like the one below could use far more memory than you expect.

13

14

Page 8: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

8

Labs

• Lab 1 introduced you to the MPLabdevelopment environment.

• Other than the warnings concerning memory, developing in C will make your life much easier.

• Use of the following configuration slides in setting up your programs will make life easier still.

15

MPLab XC8 C Compiler

• The MPLAB XC8 C Compiler is a free-standing, optimizing ISO C90 (popularly known as ANSI C) compiler. It supports all 8-bit PIC® microcontrollers: PIC10, PIC12, PIC16 and PIC18 series devices.

• It comes in free, standard, and Pro versions. The free version is installed in the labs. You may download this from MicroChip for the PC, Linux, or Mac.

16

15

16

Page 9: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

9

MPLab XC8 C Compiler

• The C language implemented on MPLAB XC8 C Compiler can diverge from the ANSI C Standard in several areas.

• One divergence is due to limited device memory and no hardware implementation of a data stack. For this reason, recursion is not supported.

• Another divergence from the Standard is that you cannot reliably use the C sizeof operator with pointer types; however, this operator may be used with pointer variable identifiers.

17

Main Template

18

/* * File: newmain.c* Author: Maarten Uijt de Haag** Created on January 3, 2017*/

// Insert CONFIG bits

#define _XTAL_FREQ 4000000 // oscillator frequency definition

#include <xc.h>#include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <stdbool.h>

// Global variables

// Functions

int main(int argc, char** argv) {

return (EXIT_SUCCESS);}

Can be replaced by void main(void) as well

17

18

Page 10: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

10

Configuration Bits

• Assembly:

• C (in a separate header files: config.h):

; Include the PIC16F18875 header file that defines all special purpose registers and core registers#include "p16F18875.inc”

; Set PIC16F18875 Configuration Bit Settings __CONFIG _CONFIG1, _FEXTOSC_ECH & _RSTOSC_EXT1X & _CLKOUTEN_OFF & _CSWEN_ON & _FCMEN_ON __CONFIG _CONFIG2, _MCLRE_ON & _PWRTE_OFF & _LPBOREN_OFF & _BOREN_ON & _BORV_LO & _ZCD_OFF & _PPS1WAY_ON & _STVREN_ON __CONFIG _CONFIG3, _WDTCPS_WDTCPS_31 & _WDTE_OFF & _WDTCWS_WDTCWS_7 & _WDTCCS_SC __CONFIG _CONFIG4, _WRT_OFF & _SCANE_available & _LVP_ON __CONFIG _CONFIG5, _CP_OFF & _CPD_OFF

// CONFIG1#pragma config FEXTOSC = LP // External Oscillator mode selection bits (EC above 8MHz; PFM set to high power)#pragma config RSTOSC = HFINT1 // Power-up default value for COSC bits (HFINTOSC (1MHz))#pragma config CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)#pragma config CSWEN = ON // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable bit (FSCM timer enabled)// CONFIG2#pragma config MCLRE = ON // Master Clear Enable bit (MCLR pin is Master Clear function)#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)#pragma config LPBOREN = OFF // Low-Power BOR enable bit (ULPBOR disabled)#pragma config BOREN = ON // Brown-out reset enable bits (Brown-out Reset Enabled, SBOREN bit is ignored)#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices)#pragma config ZCD = OFF // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)#pragma config PPS1WAY = ON // Peripheral Pin Select one-way control (The PPSLOCK bit can be cleared and set only once in software)#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a reset)// CONFIG3#pragma config WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)#pragma config WDTE = OFF // WDT operating mode (WDT enabled regardless of sleep; SWDTEN ignored)#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)#pragma config WDTCCS = SC // WDT input clock selector (Software Control)// CONFIG4#pragma config WRT = OFF // UserNVM self-write protection bits (Write protection off)#pragma config SCANE = available// Scanner Enable bit (Scanner module is available for use)#pragma config LVP = ON // Low Voltage Programming Enable bit (Low Voltage programming enabled. MCLR/Vpp pin function is MCLR.)// CONFIG5#pragma config CP = OFF // UserNVM Program memory code protection bit (Program Memory code protection disabled)#pragma config CPD = OFF // DataNVM code protection bit (Data EEPROM code protection disabled)

How to Access SFRs and Pins

20

void main(void) {

// Configure the I/O portsTRISB = 0b11100001; TRISD = 0b00000000;

}

For example: PORTA, TRISA, RA0, RA1, RCIF, TXSTA, TXIF, GIE, PEIE, SYNC, TXEN, etc. etc.

NO BANK SELECTION REQUIRED

Most Special Function Registers (SFRs) and pins are defined in “xc.h” by their official name as specified in the reference manual and datasheet.

19

20

Page 11: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

11

How to Access Pins

21

void main(void) {

// Configure the I/O portsTRISA = 0x00; TRISB = 0xFF;

RA1 = 1;PORTAbits.RA2 = 1;

if(RB3 == 1) RA3 = 1;else RA3 = 0;

}

Multiple options are available to access a PORT pin:

Example PORTA pin 1: RA1

PORTAbits.RA1

Outputs

OutputsInput

Register Usage

22

The assembly code generated from the C source code will use certain registers in the PIC MCU register set and assumes that nothing other than code it generates

can alter the contents of these registers.

21

22

Page 12: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

12

Variables

23

Non-s

tandard

types

Only integerarithmetic

Variable – Use <stdint.h>

24

C type<stdint.h>

typeBits Sign Range

char uint8_t 8 Unsigned 0 .. 255

signed char int8_t 8 Signed -128 .. 127

unsigned short or unsigned int

uint16_t 16 Unsigned 0 .. 65,535

short or int int16_t 16 Signed -32,768 .. 32,767

unsigned int uint32_t 32 Unsigned 0 .. 4,294,967,295

int int32_t 32 Signed -2,147,483,648 .. 2,147,483,647

unsigned long long

uint64_t 64 Unsigned 0 .. 18,446,744,073,709,551,615

long long int64_t 64 Signed -9,223,372,036,854,775,808 .. 9,223,372,036,854,775,807

23

24

Page 13: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

13

Variables

25

char a;int8_t a;

(_a) 0x75 (for example)

short b;int16_t b;

(_b+1) 0x76 (for example)(_b) 0x75 (for example)(2 bytes)

short long c;int24_t c: (_c+2) 0x77 (for example)

(_c+1) 0x76 (for example)(3 bytes)

(_c) 0x75 (for example)

long d;int32_t d;

(_d+3) 0x78 (for example)(_d+2) 0x77 (for example)(4 bytes)

(_d+1) 0x76 (for example)(_d) 0x75 (for example)

Type Ranges

26

216-1

27-1

Unsigned

Signed

-27

25

26

Page 14: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

14

Use of Functions

27

// Functionschar AddTwoNumbersReturnLowByte(int a, int b);

// Main Program

void main(void) {

TRISA = 0x00;PORTA = AddTwoNumbersReturnLowByte(23456, 12456);

}

char AddTwoNumbersReturnLowByte(int a, int b);{

char ret;int c;

c = a + b;ret = (char)(0x00FF & c);

return(ret);}

16 bits = 2 bytes

Mask most significant byte

Logic AND operation

Use of Functions – Pass by Value

28

char AddTwoNumbersReturnLowByte(int a, int b);{

char ret;int c;

c = a + b;ret = (char)(0x00FF & c);

return(ret);}

Arguments are values:Inputs (two bytes each)Output (byte)

Return the output (byte)

“When passing arguments by value, the only way to return a value back to the caller is via the function’s return value”

Alternative:“Pass by reference” and

“Pass by address”

27

28

Page 15: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

15

‘bit’

29

bit flag; holds the values 0 or 1

bit func(void) {

return(RA0);}

The 1 or 0 value will be returned in the carry flag in the STATUS

register

Eight bit objects are packed into each byte of memory storage, so they don’t consume large amounts of internal RAM.

Operations on bit objects are performed using the single bit instructions (bsf and bcf) wherever possible, thus the generated code to access bit objects is very efficient.

Arithmetic Operations

30

Operator Description Example

+ Addition a = b + c;

- Subtraction a = b – c;

+= Addition and assignment a += 16;

-= Subtraction and assignment b -= 32;

<< Shift left by ‘n’ bits a << 4;

>> Shift right by ‘n’ bits c >> 2;

& Logical AND a = b & c;

| Logical OR c = a | b;

29

30

Page 16: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

16

Computed Goto

31

• Remember the Notes #3, lookup table (LUT) of a Square function:

SQR: brwretlw d’0’ retlw d’1’ retlw d’4’retlw d’9’retlw d’16’retlw d’25’retlw d’36’retlw d’49’retlw d’64’retlw d’81’retlw d’100’

Computed Goto’s

32

• In C we use a ‘switch’ statement;

• So, the following function/subroutine would return the square for each number (0,…,10)

unsigned char Square(char num) {

switch(num) {

case 0: return(0);case 1: return(1);case 2: return(4);case 3: return(9);case 4: return(16);case 5: return(25);case 6: return(36);case 7: return(49);case 8: return(64);case 9: return(81);default: return(100);

}}

With the full version of the XC8 compiler (not free), this code will be optimized to a computed goto.

31

32

Page 17: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

17

Timing Loops

33

• Remember the 1-second delay loop:

• Now is:

DELAY: movlw d'167' ; this is the OUT_CNT starting value.movwf out_cnt ; store it in OUT_CNT register.

mid_agn movlw d'176' ; this is the MID_CNT starting value.movwf mid_cnt ; store it in MID_CNT register.

in_agn movlw d'10' ; this is the IN_CNT starting value.movwf in_cnt ; store it in IN_CNT location.

in_nxt decfsz in_cnt,f ; decrement the inner counter value.goto in_nxt ; if not zero, go decrement again.decfsz mid_cnt,f ; decrement the middle counter.goto in_agn ; if middle cntr is not zero, do inner again.decfsz out_cnt,f ; decrement the outer counter.goto mid_agn ; if outer cntr is not zero, do middle again.return ; if outer counter = 0 then done

// Delay for 1000ms = 1second__delay_ms(1000);

// oscillator frequency for delay#define _XTAL_FREQ 10000000

Must define the correct oscillator frequency:

two underscores, not one

Interrupts

34

• Can be easily enabled by using enable interrupt function: ei()

• Can be easily disabled by using diableinterrupt function: di()

ADIE = 1; // A/D interrupts will be usedPEIE = 1; // peripheral interrupts are enabledei(); // enable interrupts………di(); // disable interrupts

Like setting GIE = 0;

33

34

Page 18: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

18

Interrupts

35

// Interrupt-on-change example

void interrupt my_isr(void){

if(IOCIE && IOCBFbits.IOCBF4) {

// perform task required

IOCBFbits.IOCBF4 = 0;}

}

clear the flag

Use:

‘interrupt’ qualifier

Use of Mixed Code

36

• Various methods exist for mixing assembly code in with the C source code.

Use #asm and #endasm directives

unsigned int var;

void main(void){

var = 1;#asm

banksel (_var)rlf (_var), 1rlf (_var+1), 1

#endasm}

Selects the correct data memory bank for the variable

Suppose variable ‘var’ is at data memory location 0x74 (chosen by C compiler)

(_var) = memory location 0x74, (_var+1) is memory location 0x75

35

36

Page 19: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

19

Loops

37

int16_t ii;int8_t array[10];

for(ii=0;ii<10;ii++){

array[ii] = ii;……

}

Check MPLAB X IDE -> Window -> Output-> Disassembly Listing File

10-byte character array

When defining an array of characters, integers, etc., remember the size limitations of the data memory.

For example, int16_t array[100] represents 200 bytes, and will be filing up a large portion of your data memory.

Loops

38

bit flag;

flag = determineFlag()

while(flag){

………flag = determineFlag();…

}

bit flag;

do{

………flag = determineFlag();…

} while(flag);

37

38

Page 20: Programming PIC with C - ace.cs.ohio.edu

2/27/2019

20

Infinite Loop

39

while(1){

……………

}

Condition is always true, program within loops keeps getting executed.

39