8-Bit ADC Auto Update using Timer 6

 Objective

The Core Independent Peripherals (CIPs) within the latest PIC® 8-bit microcontrollers offer the opportunity to perform hardware functions without the Central Processing Unit (CPU) core running any code. This can be extremely useful for embedded projects that need to perform certain tasks without interruption from the main application. This simple example shows how to set up and use the Analog-to-Digital Converter (ADC) peripheral and Timer6 control to independently control an analog to digital conversion. The separate hardware then notifies the main application of an updated value through an ADC Interrupt. The image shows the block diagram of the project. As you can see, the control runs completely independently from the CPU.

figure1adc.png

 Materials

Hardware Tools (Optional)

Tool About Purchase
Curiosity-50px.png
Curiosity
Development Board

Software Tools

Tool About Installers
Installation
Instructions
Windows Linux Mac OSX
MPLAB® X
Integrated Development Environment
swtool-28px.png
MPLAB® Code Configurator
Dynamic Code Generation
MPLAB® XC8
C Compiler

Exercise Files

File Download
Installation
Instructions
Windows Linux Mac OSX
Project and Source Files
Curiosity Board User Guide/Schematic

 Connection Diagram

The Curiosity Development Board has four Light Emitting Diodes (LEDs) prewired to the I/O pins shown below. This project controls all four LEDs.

Hardware Function Pin Setting
IO_LED_D4 RA5 (2) Output
IO_LED_D5 RA1 (18) Output
IO_LED_D6 RA2 (17) Output
IO_LED_D7 RC5 (5) Output
figure1.png

 Procedure

1

Create a Project

Create a new project and select the PIC16F1619 along with the Curiosity Board and MPLAB® XC8 compiler. If this is your first time creating a project, click on the link below to expand the directions.

2

Launch MPLAB Code Configurator (MCC)

Open MCC under the Tools > Embedded menu of MPLAB X IDE.

mcclaunch.png

3

System Setup

From Project resources, choose System Module to open the System Setup window within MCC.

  1. In the Oscillator settings, make sure you select INTOSC.
  2. Select the System Clock FOSC.
  3. Set Internal Clock to 4MHz_HF.
  4. Check the PLL Enabled box.
  5. The Curiosity Development Board uses a Programmer/Debugger On Board (PKOB) and uses a Low-Voltage Program method to program the MCU, therefore we must enable low-voltage programming by checking the Low-voltage programming Enable box.
figure1cip.png

4

Timer6 Setup

Add the TMR6 peripheral to the project from the Device Resources area of MCC. To do that, scroll down to the Timer entry and expand the list by clicking on the arrow. Now, double click on the TMR6 entry to add it to the Project Resources list. Then, click on the TMR6 to open the Timer6 configuration setup screen.

figure2jk.png
  1. Check the Enable Timer box.
  2. Select Clock Source LFINTOSC, Postscaler 1:1, Prescaler 1:32.
  3. Set Timer period value to 100.129 ms.
  4. Set External Reset Source to T6IN, and Control mode setting to Roll over pulse.
  5. Set Start/Reset Option to Software Control (this will inhibit hardware reset of timer).
  6. Leave the Enable Timer Interrupt box unchecked.

5

ADC Setup

Add the ADC peripheral to the Project Resources from the Device Resources area.
Scroll down to the ADC entry and expand the list.
Now, double click on the ADC entry to add it to the Project Resources list.

Click on the ADC and the setup window will show up. Follow the steps below:

  1. Check the Enable ADC box.
  2. Select Clock Source: FRC.
  3. Set Result Alignment: right.
  4. Set Postitive Vref is VDD.
  5. Set Auto-conversion Trigger to TMR6_postscaled.
  6. Check the Enable ADC Interrupt box.
figure5adc.png

6

Pin Manager Setup

The potentiometer labeled POT1 and LEDs labeled D4-D7 on the Curiosity Development Board need to be connected to the proper pins in software to match the hardware. This is easily done in the Pin Manager by clicking on the blue lock to change it to green.

  1. Click on RC0 in ADC row.
  2. Click on RA1, RA2, RA5, and RC5 in the GPIO Output row.
figure6adc.png

Assign Custom Names
Click on the Pin Module in the project resources area.

  1. Uncheck WPU (Weak Pull-up) box for all pins.
  2. Uncheck Analog box for all but RC0.
  3. Rename RC0 Custom Name to "POT1_AN4".
  4. Rename RA1 Custom Name to "D5_RA1".
  5. Rename RA2 Custom Name to "D6_RA2".
  6. Rename RA5 Custom Name to "D4_RA5".
  7. Rename RC5 Custom Name to "D7_RC5".
figure7adc.png

7

Generate Driver Code

Click on the Generate button in the Project Resources area of MCC screen to have MCC create the drivers and a base main.c file for the project.

8

adc.c

To control the LEDs based on the Analog-to-Digital conversion, the Interrupt Service Routine (ISR) needs to be updated in the adc.c file. The Timer6 overflow starts the ADC conversion and then, when the conversion is complete, the ADC interrupt will run the adc.c file ISR.

These lines need to be added to the ADC_ISR function in the adc.c file. This will store the ADC result in a variable adval then light the LEDs based on that value.

adc_result_t adval = ADC_GetConversionResult();
D4_RA5_LAT = (adval > (1024*1)/5); // LEDD4 on if adval>204
D5_RA1_LAT = (adval > (1024*2)/5); // LEDD5 on if adval>409
D6_RA2_LAT = (adval > (1024*3)/5); // LEDD6 on if adval>614
D7_RC5_LAT = (adval > (1024*4)/5); // LEDD7 on if adval>819

The code is added to the adc.c file ADC_ISR function as shown below.

void ADC_ISR(void)
{
    adc_result_t adval = ADC_GetConversionResult();
    D4_RA5_LAT = (adval > (1024*1)/5); // LEDD4 on if adval>204
    D5_RA1_LAT = (adval > (1024*2)/5); // LEDD5 on if adval>409
    D6_RA2_LAT = (adval > (1024*3)/5); // LEDD6 on if adval>614
    D7_RC5_LAT = (adval > (1024*4)/5); // LEDD7 on if adval>819

    // Clear the ADC interrupt flag
    PIR1bits.ADIF = 0;
}

9

main.c

The generated main.c file needs two lines uncommented and one added for this project.
First, the Global Interrupt and Peripheral Interrupt Enable lines need to be uncommented by removing the // in front of these lines to enable interrupts.

// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();

// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();

   SYSTEM_Initialize();

    // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
    // Use the following macros to:

    // Enable the Global Interrupts
    INTERRUPT_GlobalInterruptEnable();

    // Enable the Peripheral Interrupts
    INTERRUPT_PeripheralInterruptEnable();

    // Disable the Global Interrupts
    //INTERRUPT_GlobalInterruptDisable();

    // Disable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptDisable();

The ADC conversion command line; ADC_StartConversion(POT1_AN4) is added to main.c before the continuous while(1) loop. This starts the ADC and then does nothing while looping yet the ADC runs in the background updating the LEDs based on the position of the potentiometer.

    ADC_StartConversion(POT1_AN4);
    while (1)
    {
        // Add your application code
    }

/**
 End of File
*/

10

Build Project

Click on the Build Project icon (the hammer) to compile the code and you will see a BUILD SUCCESSFUL message in the output window of MPLAB X within several seconds of processing time.

Main_Build_Project.png
BUILD SUCCESSFUL (total time: 7s)

11

Make sure your Curiosity Development Board is connected to the USB port. Then click on the Make and Program Device icon. This will build the project again and launch the programmer built into the Curiosity Development Board. In the output window, you should see a series of messages and when successful it will end with a Programming and Verify Successful message.

Main_Program_Target_Project.png

Output Window:

Connecting to MPLAB Starter Kit on Board...

Currently loaded firmware on Starter Kit on Board
Firmware Suite Version.....01.41.07
Firmware type..............Enhanced Midrange

Target detected
Device ID Revision = 2004

The following memory area(s) will be programmed:
program memory: start address = 0x0, end address = 0x7ff
configuration memory

Programming...
Programming/Verify complete

If it's the first time the programmer is connected to the board, the programming tool may need to download the proper operating firmware for the exact device. You may see a series of messages if this occurs. This should only happen once.

Downloading Firmware…
Downloading bootloader
Bootloader download complete
Programming download…
Downloading RS…
RS download complete
Programming download…
Downloading AP…
AP download complete
Programming download…
Firmware Suite Version…..01.34.11
Firmware type…………..Enhanced Midrange

 Results

Depending on the position of POT1, the LEDs may be lit. As the POT1 is turned to the right or clockwise, more LEDs should be lit. As the POT1 is turned counterclockwise the LEDs should go out in order. The whole time the main.c while(1) loop continues to run without any action.

figure8adc.jpg

 Conclusions

Setting up an automatic ADC measurement can be extremely useful especially when there are actions that the main loop does need to perform. Especially when the main loop uses the ADC data. This example is simple but does show how to use a timer to control the ADC and then how the ADC can perform the measurements independently. This project can be expanded to control any I/O pin on the Curiosity Development Board pin instead of the LEDs. This can make this a useful base program for applications that need to control a digital device based on an analog input signal.

© 2024 Microchip Technology, Inc.
Notice: ARM and Cortex are the registered trademarks of ARM Limited in the EU and other countries.
Information contained on this site regarding device applications and the like is provided only for your convenience and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO THE INFORMATION, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE, MERCHANTABILITY OR FITNESS FOR PURPOSE. Microchip disclaims all liability arising from this information and its use. Use of Microchip devices in life support and/or safety applications is entirely at the buyer's risk, and the buyer agrees to defend, indemnify and hold harmless Microchip from any and all damages, claims, suits, or expenses resulting from such use. No licenses are conveyed, implicitly or otherwise, under any Microchip intellectual property rights.