You are on page 1of 7

Microprocessors

Laboratory Session Guideline: Session 2

V 0.2
Luc BIENSTMAN, ZHANG Lin, Supinya PIAMPONGSANT

October 16, 2011


1

Chapter 5 Peripherals in C
PIC18F2550 is equipped with a number of peripheral modules, including the Timer Modules, the Capture/ Compare/PWM (CCP) Module, the Comparator Module, the Master Synchronous Serial Port (MSSP) Module, and the Analog-to-Digital Converter (ADC) Module. This chapter serves as an introduction to, and a guide for, using two of these modules: the ADC and the PWM. By configuring the PIC to perform ADC and DAC functions, you will learn to initialize the PIC for peripheral module usage and handling of interrupts.

1. Initialization
Before using the peripheral modules, you need to initialize the PIC. Initialization is the process of resetting variables or special function registers in order to prevent calculating errors or unpredictable behavior due to leftover values in these registers. The initialization will force the device to a ready-to-start state regardless of how many times the program has been looped. In template.c, initialization is done in the function initChip(), take a look at this function.

/************************************************* Initialize the CHIP **************************************************/ void initChip(){ PORTA = 0x00; TRISA = 0x00; ADCON1 = 0x0f; //Turn off ADcon CMCON = 0x07; //Turn off Comparator PORTB = 0x00; TRISB = 0xFF; PORTC = 0x00; TRISC = 0x00; INTCONbits.GIE = 0; // Turn Off global interrupt } To understand what this function does, consult the datasheet. For example, to understand what ADCON1 = 0x0f does, search for information on register ADCON1 in the datasheet. You should come across this page:

Luc BIENSTMAN, ZHANG Lin, Supinya PIAMPONGSANT

This page gives the name of the register, the name of each bit, and the significance of each bit in special function register ADCON1. The row of boxes under the register name gives the name of each bit. For example, bit0 is PCFG0, bit1 is PCFG1, bit5 is VCFG1, etc. If you wish to set only bit0 without affecting other bits, you can code in the following way: ADCON1bits.PCFG0 = 1; Or you can assign value to the whole register. For example, if you wish to use Vdd and Vss as reference voltages and to set AN0 as the only analog pin, you should type the following: ADCON1 = 0x0E;

Page 254 on datasheet

Luc BIENSTMAN, ZHANG Lin, Supinya PIAMPONGSANT

2. A/D via Converter Module


Goal: With the aid of the datasheet, configure the PIC to read an analog signal (between 0V and 5V!) on channel AN0. Display the higher bits on PORTB. The PIC18F2550 has a built-in analog to digital converter that can perform 10-bit A/D conversions on 10 input channels. To use the module, the A/D hardware should first be initialized. There are three special function registers involved in the configuration of the A/D converter module: ADCON0: enables A/D module, select the input channel ADCON1: configures pins as digital or analog ADCON2: configures acquisition time and conversion clock. In this lab, you will control the conversion rate of the A/D converter module using TMR1. The PIC18F has dedicated hardware that connects the TMR1 functionality to the A/D convertor. This requires the use of the Capture/Compare CCP2 logic. Read section 21.8 in the datasheet and understand this special cooperation between TMR1 and the A/D.

Figure 1 (Figure 15-2 in datasheet) shows how the comparator module works with Timers 1 and 3 to generate a Special Event Trigger

To start the A/D conversion, the Special Event Trigger of the CCP2 module should be activated. This requires the CCP2CON register to be set to value 0x0B. This setup will cause the A/D to execute a non-stop periodic conversion. The start of the A/D should not be controlled by the GO bit. The functionality of the CCP2 module will activate the GO bit periodically as the TMR1 value equals to the compare preset value in CCPR2H:CCPR2L. The output of the comparator between TMR1 and the preset value CCPR2H:CCPR2L will generate an interrupt flag CCP2IF which will automatically restart the A/D conversion. No interrupt routine is needed to deal with this CCP2 interrupt. (See Fig. 15.2 on the datasheet) Thus the CCP2IF should not be enabled to generate an interrupt, because we dont need it. When the A/D conversion is finished, an interrupt will be generated. This interrupt should be enabled. The A/D conversion results are stored in special function registers ADRESH and ADRESL. To use these values, configure the interrupt routine to copy them to a different memory location. Summary: automatic A/D conversion can be configured using registers associated with PORTA, A/D, Luc BIENSTMAN, ZHANG Lin, Supinya PIAMPONGSANT 4

TMR2, CCP2 as well as an interrupt routine. Once initialized, A/D conversion is executed repeatedly and automatically without software intervention. Overall software execution suffers from one overhead: when a conversion is finished, the A/D result should be copied to a register. This is done via the A/D interrupt routine. Assignment: Read in an analog signal via AN0 and display the most significant bits on PORTB using LEDs. Test your program with a potentiometer (any value between 1k - 100k) connected between power supply and ground. The sliders pin should be connected to analog input AN0. Adjust the voltage on the slider. You should observe changes on PORTB values.

3. D/A via the PWM generator


The PIC18F2550 has a built-in PWM generator. The PWM is based on the TMR2 and one of the CCP modules (the user can normally select either CCP1 or CCP2). For this lab, use CCP2 and set up the PIC so that pin RB3 is the PWM output.

Figure 2 PWM cycle and period

Apply an RC filter after the pulsed PWM output will generate a smooth signal. Goal: learn to generate analog signals from a PIC using PWM. Optional warm up: Create a simple PWM of a square wave at 10kHz. Check your result on an oscilloscope. Assignment: You should have been assigned a team number. Please generate a function accordingly. Team 1 2 3 4 5 6 7 8 9 10 Waveform Triangular 20kHz Sinusoidal 10kHz Sawtooth 30kHz Triangular 30kHz Sinusoidal 5kHz Sawtooth 20kHz Triangular 15kHz Sinusoidal 8kHz Sawtooth 15kHz Sinusoidal 2kHz 5

Luc BIENSTMAN, ZHANG Lin, Supinya PIAMPONGSANT

For the triangular waveforms, the PWM duty cycle should change automatically and smoothly from 100% to 0% and back to 100%. For the sinusoidal waveforms, the PWM duty cycles can be stored in advance in a lookup table. These values should then be fed to the PWM module at the appropriate time.

For the sawtooth waveforms, the PWM duty cycle should change automatically and smoothly from 100% to 0% then go abruptly back to 100%. Optional bonus: Combine your A/D and D/A programs so that the PIC reads in an analog signal via ADC and generates the same signal back on a different pin by PWM. If you finish this, also turn it in for extra points.

4. Reminder: simulating with interrupts


The PICs memory contains a bootloader as well as the program to be executed. The bootloader resides at address 0x000 0x7FF. The executable program begins at address 0x800 (reset vector) while high and low priority interrupt vectors are situated at addresses 0x808 and 0x818 respectively. When the program starts, the program counter points to the reset vector and executes the program line-by-line. When an interrupt occurs, the counter jumps to an interrupt vector address, which then points it to the interrupt routine. This is what happens on your PIC and the program template has been written to be compatible with this behavior.

MPLABs simulation tool, however, is not aware of the bootloaders presence and assumes that program memory begins at address 0x000 and that high and low interrupt vectors are at 0x008 and 0x018. When an interrupt event occurs in simulation, the counter thus jumps to the wrong place. To correct this, you can change the template so that it ignores the presence of a bootloader in simulation. Follow the steps below. Notice the following lines in the program.
#pragma code _HIGH_INTERRUPT_VECTOR = 0x000808 #pragma code _LOW_INTERRUPT_VECTOR = 0x000818 Luc BIENSTMAN, ZHANG Lin, Supinya PIAMPONGSANT

While simulating, change vector values to:


#pragma code _HIGH_INTERRUPT_VECTOR = 0x000008 #pragma code _LOW_INTERRUPT_VECTOR = 0x000018

Run your program, then simulate an interrupt event using Stimulus tool. Use the Step Into tool to observe your program pointer go into the correct interrupt routine. Once you are satisfied with the program and want to load it onto the board, change the addresses back to:
#pragma code _HIGH_INTERRUPT_VECTOR = 0x000808 #pragma code _LOW_INTERRUPT_VECTOR = 0x000818

Luc BIENSTMAN, ZHANG Lin, Supinya PIAMPONGSANT

You might also like