microchip-pic-avr-examples / pic18f57q43-dma-adc-to-uart-part1

This example [part1] shows how to set up Direct Memory Access (DMA) using the Microchip Code Configurator (MCC) on a PIC18F57Q43 microcontroller to transfer an ADC result to the UART transmit buffer, where the transfer is triggered directly by a TMR.
Other
3 stars 5 forks source link
dma low-power uart

MCHP

Direct Memory Access (DMA) on PIC MCUs [Part one]:

This is the first part an example showing how to set up Direct Memory Access (DMA) using the Microchip Code Configurator (MCC) on the PIC18F57Q43 Curiosity Nano to transfer an Analog to Digital (ADC) conversion to a UART TX buffer with zero lines of code and zero CPU utilization using DMA.

Part 2 covers how to set up the second device that utilizes DMA to transfer the contents of the received message in the UART RX buffer to a PWM module that will vary the brightness of an LED.

Table of Contents

This example is extendable to the entire PIC18 Q43 family, and other 8-bit PIC devices with the DMA feature, like PIC18F K42.

The Timer (TMR0), Analog to Digital Converter with Computation (ADCC), and Universal Asynchronous Receiver Transmitter (UART3) and DMA on-chip peripherals are all used in this project (part1).

This example is covered in a video format linked here.

Related Documentation and Resouces

Software Used

Hardware Used

Setup

The hardware is setup as shown in this video. All the specific pins are present in the diagram below. The Curiosity Nano Baseboard for clicks are no present in the diagram, since they were only used as breadboard-alternatives.

Connections

Potentiometer Q43 (part 1) Q43 (part 2)
+ 3.3V
gnd gnd
output RA0 (Yellow Wire)
RA3 (UART3 TX) -----------> RA4 (UART3 RX)

Operation

Summary

As noted before - this is part 1 of 2 of an example showing how to set up Direct Memory Access (DMA) using the Microchip Code Configurator (MCC) on the PIC18F57Q43 Curiosity Nano to transfer an Analog to Digital (ADC) conversion to a UART TX buffer without writing any lines of code and zero CPU utilization using DMA.

More generally, the technique detailed below shows the process of how one can:

The goal here is to exemplify the usage of the GUI provided by MCC that will generate all the code we need. This means that any device that has the DMA peripheral and is supported in MCC can be similarly configured through the same methods. The section below details how to do this.

Walkthrough

Back to Table of Contents

Create New MPLAB X Project and Open MCC

  1. Open the MPLAB X IDE
  2. Create new project by clicking the icon:
    1. Alternatively: file >> New Project
  3. In the Choose Project window:
    1. Select Microchip Embedded category
    2. Select Standalone Project
    3. Click Next>
  4. In the Select Device window:
    1. Select PIC18F57Q43 as your device
    2. Pro-tip: Input the last three or four characters of the device, then select the device from the drop-down list (e.g. Q43).
    3. Click Next>
  5. In the Select Tool window (Optional):
    1. If device is connected, select PIC18F57Q43 Curiosity Nano (PKOB nano)
    2. If not, The Curiosity Nano can be selected later on.
    3. Click Next>
  6. In the Select Compiler window:
    1. Select XC8 (v2.45)
    2. Click Finish
  7. Open MCC by clicking the icon in the toolbar

Configure MCC

  1. In the project resources window: check the dropdown box for System => click clock control.

  1. In the clock control window: go to the easy view tab, and set Clock Settings to HFINTOSC

  1. Under Device Resources in left-hand pane:
    1. Open the Drivers drop-down
    2. Click the green plus sign next to ADCC, DMA, TMR0 and UART3 peripherals to add them your project.

After adding drivers for ADCC, DMA1, TMR0, and UART3. The project resources window will look like below.

  1. In the TMR0 window:
    1. Select FOSC/4 for Clock Source
    2. Set Clock pre-scaler to 1:64
    3. Set Requested Period to 50 ms
    4. The TMR0 was configured to overflow every ~50 ms. The user can reconfigure the clock source, system clock, and pre/post-scalars to change the error rate or the range of acceptable inputs for the timer period.

  1. In the ADCC window:
    1. Set Clock Source to ADCRC
    2. Set Auto-Conversion Trigger to TMR0
    3. The default setting is changed for the clock source to the internal ADC RC oscillator circuit (i.e. FRC), and set up the ADC to get a conversion every time a rising edge is detected from TMR0.

  1. In the UART window:
    1. Set Baud Rate to 9600.

  1. In the Pin Manager: Grid View window:
    1. UART3 TX3 --> A3
    2. UAR3 RX3 --> A4 (not required for transmitting)
    3. ADCC ANx --> A0

  1. In the DMA Manager window:


Module Region SFR VarName VarSize Address Mode Message Size Start Trigger Abort Trigger
Src ADCC SFR ADRESL - - - increment 2 U3TX None
Dst UART3 SFR U3TXB - - - unchanged 1 U3TX None
  1. Enable DMA Channel1
    1. ADCC is the source module of the DMA channel
    2. ADRESL is the SFR region that we want data to be sourced from
    3. Mode must be incremented to get the value from ADRESH, which is directly above ADRESL according to the SFR Memory Map.
    4. Message size is basically how many bytes are coming from the source module. The ADC result register is a 16-bit register, so the message size is 2-bytes.
    5. Similarly, the UART TX Buffer is 1-byte, so we need to indicate that it can only handle one byte at a time. (i.e. message size = 1)
    6. Set the DMA start trigger to fire every time TX Buffer is empty (U3TXB). At this point you might wonder – why don’t I just set the trigger for every time there is an ADC conversion? You are certainly given the flexibility to do so by setting Start Trigger to AD. I encourage you to try and see what happens.
      1. Note! In many cases you will find that there is garbage data being transmitted from the UART. The reason for this is that depending on the relative speed of the UART, the DMA might be overwriting the buffer before the bits are shifting out. The DMA has no knowledge of this information, it’s a messenger.
  2. Click Generate Project and
  3. Click Program the device

Conclusion:

After finishing part 1, the user can either check out the results by using a logic analyzer, oscilloscope, or even a serial terminal like the Data Visualizer plugin or standalone application. Next, check out part 2 to complete the application.

Back to Table of Contents