Demonstrating 8-bit PIC® MCU Direct Memory Access (DMA)
Contents
Objective
This tutorial shows how to configure the PIC18F57Q43 Direct Memory Access (DMA) feature using Microchip’s MPLAB® Code Configurator (MCC). MCC is used to configure Core Independent Peripherals (CIPs) such as the DMA, Universal Asynchronous Receiver Transmitter (UART), Analog-to-Digital Converter (ADC), Timer, and Pulse Width Modulator (PWM).
A video version of this training is available on Microchip Technology's YouTube™ Channel "How to use DMA on 8 bit PIC® MCUs".
Overview
This tutorial makes use of Microchip’s Curiosity Nano Evaluation Boards and Microchip’s Curiosity Nano Adapter Boards to simplify hardware integration.
It showcases the capability of the PIC18F57Q43 DMA to transfer data between CIPs without using any CPU bandwidth.
The PIC18F57Q43 DMA is designed to service data transfers between different memory regions directly, without intervention from the CPU. By eliminating the need for CPU-intensive management of handling interrupts intended for data transfers, the CPU now can spend more time on other tasks.
The DMA modules can be independently programmed to transfer data between different memory locations, move different data sizes and use a wide range of hardware triggers to initiate transfers. The DMA modules can even be programmed to work together to carry out more complex data transfers without CPU overhead.
For more details about the features of the PIC1827/47/57Q43 device family, refer to the PIC18F27/47/57Q43 Datasheet.
MCC is a free graphical programming environment that generates seamless, easy-to-understand C code that is inserted into your project. It enables and configures a rich set of CIPs and functions using an intuitive interface. It is integrated into MPLAB X IDE to provide a powerful and easy-to-use development platform.
This training uses two PIC18F57Q43 Curiosity Nano Evaluation Kits (DM164150) and two Curiosity Nano Adapter Boards (AC164162), which are available from Microchip Purchasing and Client Services.
The application is based on two sets of software. The first performs regular ADC conversions on the potentiometer every 50 ms. When the DMA determines the UART transmit buffer is empty, it loads the ADC result to send the information via the UART. The second set of software moves the data from its UART receiver buffer, when it is full, to the PWM duty cycle register to modify the LED brightness.
The potentiometer varies the input voltage to MCU1’s ADC input. The LED connected to MCU2’s digital output changes according to the potentiometer position.
This application utilizes:
- Timer0 to regularly trigger ADC conversions
- ADC to read the potentiometer voltage
- UART to send/receive data between MCUs
- PWM to control LED brightness
- DMA to transfer data between CIPs
- General Purpose I/O (GPIO) to drive the LED
Two Ways to Use This Tutorial
- Create the project from scratch:
- Follow the step-by-step instructions to create the required software
- Use the solution project as an example:
- Build the solution projects and program them to the PIC18F57Q43 Curiosity Boards to observe the expected behavior
Lab Objectives
- Create an MPLAB X IDE MCC project for a PIC18F57Q43 microcontroller from scratch
- Use MCC to configure and generate peripheral libraries (PLIB) code for the following CIPs:
- Timer0
- ADC
- UART
- PWM
- DMA
- GPIO
Reference Materials
Apart from the hardware tools listed above, the following items are required:
- 2 USB Type-A male to Micro-B male cable for programming and debugging
- Potentiometer
- 3 jumper wires to connect the potentiometer
- 1 jumper wire for UART communication
- 4 28-pin 100 mil male header strips
- Breadboard
Hardware Connection Setup
Connection Diagram
The application has the potentiometer connected to the ADC, LED connected to GPIO, and the host UART connected to the client UART.
Lab Solutions
This ZIP file contains the completed solution projects for this lab. The contents of this ZIP file contains two files and they can be placed in a folder of your choice. Both files are stored in a single GitHub repository. You will need to create a free account to download the files.
PIC18F57Q43 Curiosity Nano Evaluation Board Connections
Connect PIC18F57Q43 Curiosity Nano Board and Curiosity Nano Adapter Board using 100 mil header strip.
Here’s how the setup should look after all connections have been made:
Create and Set Up an MPLAB® X IDE Project for MCU1
Create an MPLAB X IDE project for the PIC18F57Q43 using the MPLAB XC8 compiler.
If needed, install MPLAB Code Configurator (MCC). We will use it to graphically create peripheral drivers for this tutorial (if you didn't download the whole project).
Configure MCU1 Resources with MCC
Launch MCC - Open MPLAB® Code Configurator (MCC) by clicking the MCC logo in the MPLAB X Integrated Development Environment (IDE) toolbar.
Configure System Module - Click on System Module in the Project Resources window.
- For System Module, we will use the HFINTOSC Oscillator for the clock source.
Configure TImer 0 - Add Timer0 by opening the Timer folder under Device Resources window and clicking the + icon for TMR0.
- Select the TMR0 CIP in the Project Resources window to configure its settings:
- In the TMR0 configuration window, select FOSC/4 for the Clock Source and 1:64 for the Clock prescaler. This will configure Timer0 for a 50 ms rollover.
Configure ADC - Add ADC by opening the ADCC folder in the Device Resources window and clicking the + icon for ADCC.
- Now select the ADCC CIP in the Project Resources window.
- Update the ADCC configuration window to match the following:
Configure UART - Add UART3 by opening the UART folder in the Device Resources window and clicking the + icon for UART3.
- Select UART3 in the Project Resources window.
- Update the UART3 configuration window to match the following:
Configure GPIO - Select Pin Manager: Grid View in the bottom right window. Click each pin with a green lock as either an input or output as shown in the accompanying figure:
Configure DMA - Select DMA Manager from the Project Resources window
Update the DMA configuration window as follows:
- Check the DMA Channel 1 box
- Set Source Module to ADCC
- Set Source Region to SFR
- Set Source SFR to ADRESL
- Set Source Mode to Incremented
- Set Source Message Size to 2
Continue to update the DMA configuration window as follows:
- Set the Destination Module to UART3
- Set the Destination Region to SFR
- Set the Destination SFR to U3TXB
- Set the Destination Mode to Unchanged
- Set the Destination Message Size to 1
- Set the Start Trigger to U3TX
Generate MCC Code - Press the Generate button.
- Verify the MCC code generation is successful.
Build Application for MCU1
Build Application - Right-click on the project and select Build.
- The project will successfully build.
Program MCU1 - Click the Make and Program Device icon to program the MCU.
- On the PIC18F57Q43 Curiosity Nano tab, you will be able to see a “Programming complete” message.
Create and Set Up MPLAB® X IDE Project for MCU2
Create an MPLAB X IDE project for the PIC18F57Q43 using the MPLAB XC8 compiler.
Configure MCU2 Resources with MCC
Launch MCC - Open MPLAB® Code Configurator (MCC) by clicking the MCC logo in the MPLAB X Integrated Development Environment (IDE) toolbar.
Configure System Module - Now you can start configuring the settings for MCU2.
Click on System Module in the Project Resources window.
As before, we will use the HFINTOSC Oscillator for the clock source.
Configure PWM - Now we will add the Core Independent Peripherals (CIPs) needed to the project and configure them. The PWM is used to control the LED brightness with its duty cycle value.
Add PWM by opening the PWM folder under Device Resources window and clicking the + icon for PWM1_16BIT.
Select the PWM1_16BIT CIP in the Project Resources window to configure its settings:
Make necessary changes to the PWM configuration window to match the following settings:
- Enable PWM: Check
- Clock Selection: FOSC
- Clock Prescaler: 0
- Mode: Left aligned mode
- Requested Frequency: 1 kHz
- Output1 Duty Cycle (%): 50
- Output2 Duty Cycle (%): 50
Configure UART - The UART is used to receive the ADC results.
Open the UART folder in the Device Resources window and click on the + icon for UART3.
Open the UART3 setting by clicking UART3 in the Project Resources window.
Configure UART3 for the following settings:
- Mode: Asynchronous 8-bit mode
- Enable UART: Check
- Enable Transmit: Check
- Enable Receive: Check
- Baud Rate: 9600
- Transmit Polarity: not inverted
- Receive Polarity: not inverted
Configure GPIO - GPIO will be configured to output the PWM waveform and to receive UART data.
Select Pin Manager: Grid View in the bottom right window. Click each pin with a green lock as either an input or output as shown in the accompanying figure:
Configure DMA - The DMA is used to transfer the UART receive buffer contents to the PWM duty cycle register
Select DMA Manager from the Project Resources window.
Update the DMA configuration window as follows:
- DMA Channel 1 Box: Check
- Source Module: UART3
- Source Region: SFR
- Source SFR: U3RXB
- Source Mode: unchanged
- Source Message Size: 1
Continue to update the DMA configuration window as follows:
- Destination Module: PWM1_16BIT
- Destination Region: SFR
- Destination SFR: PWM1S1P1L
- Destination Mode: incremented
- Destination Message Size: 2
- Start Trigger: U3RX
Update PWM Settings - The PWM needs to be assigned to DMA Channel 1.
Select the PWM1_16BIT CIP from the Project Resources window again.
Open the UART3 setting by clicking UART3 in the Project Resources window.
Generate MCC Code - Press the Generate button.
Verify the MCC code generation is successful.
Build Application for MCU2
Right-click on the project and select Build.
The project will successfully build.
Program MCU2 - Click the Make and Program Device icon to program the MCU.
On the PIC18F57Q43 Curiosity Nano tab, you will be able to see a "Programming complete" message.
Verify Correct Operation
With the USB cables still connected supplying power, both MCUs will run. When the potentiometer is turned, the LED on the MCU2 demonstration board will adjust its brightness accordingly.
Results
The application reads the potentiometer voltage and adjusts the LED brightness in relation to its position.
Analysis
You have successfully demonstrated DMA functionality using the MPLAB® Code Configurator (MCC). Your project used fundamental DMA elements to move data between peripherals that can benefit almost any application. This demonstration continuously reads the potentiometer voltage, moves data to the UART peripheral for transmission, moves data from another UART after reception, and updates the PWM duty cycle without using a single line of code in the execution loop.
You used MCC to configure the system clock, Timer0 to create a continuous 50 ms trigger, ADC to read the potentiometer voltage, UART to send and transmit data, GPIO for analog and digital modes and input and output operations, PWM to control LED brightness and DMA to move data between peripherals.
Conclusion
This tutorial provided you with training for configuring the PIC18F57Q43 DMA using MPLAB X IDE and MCC. As a next step, you can create your own application to suit your needs. Ultimately, if you use another MCU with a DMA, you can explore a similar solution. Note that the configuration would change since the MCU resources will be different.