Differences

This shows you the differences between two versions of the page.

Link to this comparison view

eap:laboratoare:03 [2024/07/19 17:38]
jan.vaduva [ADC]
eap:laboratoare:03 [2024/07/19 19:52] (current)
jan.vaduva [PIO]
Line 93: Line 93:
  
 A **photoresistor** (or photocell) is a sensor that measures the intensity of light around it. Its internal resistance varies depending on the light hitting its surface; therefore, the more light there is, the lower the resistance will be. A **photoresistor** (or photocell) is a sensor that measures the intensity of light around it. Its internal resistance varies depending on the light hitting its surface; therefore, the more light there is, the lower the resistance will be.
 +
 +The RP2040 microcontroller integrates a 12-bit ADC for converting analog voltage signals from external sensors or circuits into digital values usable by your program, meaning it can represent analog voltages with 4096 (2^12) discrete values. Each input channel can measure voltages between 0V (ground) and the ADC reference voltage (typically the RP2040'​s internal 3.3V supply, but you can use an external reference for higher accuracy). ​
 +
 +By configuring the input mux, you can select the desired channel (external sensor or internal temperature) for conversion. The ADC offers a multiplexer (mux) that allows selecting one of five available input channels: ​
 +  * Four External Inputs are shared with GPIO pins 26 to 29. You can connect external sensors (e.g., photoresistors,​ voltage dividers) to these pins for measurement.
 +  * One internal dedicated Temperature Sensor accessible through the ADC. This allows you to monitor the chip's temperature within your program.
 +
 +In order to setup the ADC you need to follow the next steps:
 +  * Include the libraries:
 +<​code>​
 +#include <​hardware/​adc.h>​
 +</​code>​
 +  * Configure the ADC pin:
 +<​code>​
 +    adc_init();
 +
 +    // Make sure GPIO is high-impedance,​ no pullups etc
 +    adc_gpio_init(26);​
 +    // Select ADC input 0 (GPIO26)
 +    adc_select_input(0);​
 +</​code>​
 +  * Read the ADC values:
 +<​code>​
 +    // 12-bit conversion, assume max value == ADC_VREF == 3.3 V
 +    const float conversion_factor = 3.3f / (1 << 12);
 +    uint16_t result = adc_read();
 +</​code>​
 +
 +For the internal temperature sensor able to read the MCU temperature you can have a look over the following example: [[https://​github.com/​raspberrypi/​pico-examples/​blob/​master/​adc/​onboard_temperature/​onboard_temperature.c|onboard_temperature]]
 +
  
  
 ==== PIO ==== ==== PIO ====
  
 +The RP2040 goes beyond traditional microcontrollers by offering two Programmable I/O (PIO) blocks. These PIOs are essentially mini-state machines that can execute custom instructions,​ allowing you to precisely control hardware interactions without relying solely on the main CPU.
 +
 +Some of the benefits for PIOs include:
 +  * Offload Work: PIOs free up the main CPU for other tasks while handling repetitive or time-critical operations related to hardware interaction.
 +  * Fine-grained Control: PIO instructions offer precise control over GPIO pins, enabling features like custom bit manipulation,​ pulse generation, and protocol implementation.
 +  * Efficiency: PIOs operate independently with dedicated hardware, resulting in potentially lower power consumption compared to CPU-driven I/O.
 +
 +PIO is programmable in the same sense as a processor. There are two PIO blocks with four state machines each, that can independently execute sequential programs to manipulate GPIOs and transfer data. Unlike a general purpose processor, PIO state machines are highly specialized for IO, with a focus on determinism,​ precise timing, and close integration with fixed-function hardware. Each state machine is equipped with:
 +  * Two 32-bit shift registers – either direction, any shift count
 +  * Two 32-bit scratch registers
 +  * 4×32-bit bus FIFO in each direction (TX/RX), reconfigurable as 8×32 in a single direction ​
 +  * Fractional clock divider (16 integer, 8 fractional bits)
 +  * Flexible GPIO mapping
 +  * DMA interface, sustained throughput up to 1 word per clock from system DMA 
 +  * IRQ flag set/​clear/​status
 +
 +It can be used for multiple purposes such as: generate a precise square wave at a specific frequency on a GPIO pin, ideal for driving LEDs or communication protocols, manipulating data bits in and out of GPIO pins, a PIO can emulate a shift register for interfacing with serial devices or  handle complex communication protocols like SPI (Serial Peripheral Interface) or I2C (Inter-Integrated Circuit) by generating the necessary control signals for data transfer.
 +
 +The four state machines execute from a shared instruction memory. System software loads programs into this memory, configures the state machines and IO mapping, and then sets the state machines running. PIO programs come from various sources: assembled directly by the user, drawn from the PIO library, or generated programmatically by user software.
 +
 +From this point on, state machines are generally autonomous, and system software interacts through DMA, interrupts and control registers, as with other peripherals on RP2040. For more complex interfaces, PIO provides a small but flexible set of primitives which allow system software to be more hands-on with state machine control flow.
 +
 +
 +PIO state machines execute short, binary programs. Programs for common interfaces, such as UART, SPI, or I2C, are available in the PIO library, so in many cases, it is not necessary to write PIO programs. However, the PIO is much more flexible when programmed directly, supporting a wide variety of interfaces which may not have been foreseen by its designers.
 +
 +The PIO has a total of nine instructions:​ JMP, WAIT, IN, OUT, PUSH, PULL, MOV, IRQ, and SET. Though the PIO only has a total of nine instructions,​ it would be difficult to edit PIO program binaries by hand. The PIO assembler is included with the SDK, and is called pioasm. This program processes a PIO assembly input text file, which may contain multiple programs, and writes out the assembled programs ready for use. For the SDK these assembled programs are emitted in form of C headers, containing constant arrays.
 +
 +The following directives control the assembly of PIO programs:
 +  * .define ( PUBLIC ) <​symbol>​ <​value>:​ Define an integer symbol named <​symbol>​ with the value <​value>​. If this .define appears before the first program in the input file, then the define is global to all programs, otherwise it is local to the program in which it occurs. If PUBLIC is specified the symbol will be emitted into the assembled output for use by user code.
 +  * .program <​name>:​ Start a new program with the name <​name>​. Note that that name is used in code so should be alphanumeric/​underscore not starting with a digit. The program lasts until another .program directive or the end of the source file. PIO instructions are only allowed within a program
 +  * .origin <​offset>: ​ Optional directive to specify the PIO instruction memory offset at which the program must load. Most commonly this is used for programs that must load at offset 0, because they use data based JMPs with the (absolute) jmp target being stored in only a few bits.
 +  * .side_set <​count>​ (opt) (pindirs): If this directive is present, <​count>​ indicates the number of side-set bits to be used. Additionally opt may be specified to indicate that a side <​value>​ is optional for instructions (note this requires stealing an extra bit — in addition to the <​count>​ bits — from those available for the instruction delay). Finally, pindirs may be specified to indicate that the side set values should be applied to the PINDIRs and not the PINs.
 +  * .wrap_target:​ Place prior to an instruction,​ this directive specifies the instruction where execution continues due to program wrapping. ​
 +  * .wrap: Placed after an instruction,​ this directive specifies the instruction after which, in normal control flow (i.e. jmp with false condition, or no jmp), the program wraps (to .wrap_target instruction).
 +  * .lang_opt <​lang>​ <​name>​ <​option>:​ Specifies an option for the program related to a particular language generator.
 +  * .word <​value>:​ Stores a raw 16-bit value as an instruction in the program.
 +
 +For more information on values, expressions,​ labels and instructions supported by PIO please consult the datasheet at chapter 3.3. For example on how to use PIO consult the [[https://​github.com/​raspberrypi/​pico-examples/​tree/​master/​pio|pico pio examples]].
  
 ==== Exercises ==== ==== Exercises ====
eap/laboratoare/03.1721399882.txt.gz · Last modified: 2024/07/19 17:38 by jan.vaduva
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0