自学内容网 自学内容网

RP2040 CXX SDK PIO应用例程

RP2040 CXX SDK PIO应用例程


  • 📍DS18B20 PIO参考项目例程:https://github.com/jondurrant/RP2040PIO-DS18B20
  • 📍DHT11 PIO 参考项目例程:https://github.com/vmilea/pico_dht
    在官方的SDK pico-examples中有关PIO的例程有20个:https://github.com/raspberrypi/pico-examples
    在这里插入图片描述

📗RP2040 PIO功能介绍

📝RP2040中有2个相同的PIO块。每个PIO模块都有到总线结构、GPIO和中断控制器的专用连接。单个PIO模块的示意图如图38所示:
在这里插入图片描述

  • ✨使用PIO功能模拟外设,需要使用PIO专门的汇编指令集进行编程。
  • 📑PIO指令集:
    在这里插入图片描述

不懂得汇编的,只能先拿现有PIO开发出来的模拟驱动外设模块,直接使用。我们不需要了解驱动模块内部是如何实现的。RP2040只集成了2路PIO资源,一般只能用来模拟单线或双线的信号。

📘DS18B20 PIO驱动例程

  • 📍例程项目:https://github.com/jondurrant/RP2040PIO-DS18B20
  • DS1820.PIO引脚7。
  • 工程结构:
    在这里插入图片描述
  • 🔖CMakeLists.txt相关内容:
set(PICO_CXX_ENABLE_EXCEPTIONS 1) # Enable C++ exceptions
add_executable(RP2040_PIO_DS18B20
                                  RP2040_PIO_DS18B20.cpp
                                  DS18B20.h
                                  DS18B20.cpp)
# Add any user requested libraries
pico_generate_pio_header(RP2040_PIO_DS18B20 ${CMAKE_CURRENT_LIST_DIR}/DS1820.pio)
  • 程序
/*
 CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program RP2040_PIO_DS18B20.elf verify reset exit"

 jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_PIO_DS18B20.elf verify reset exit"
*/

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "hardware/clocks.h"
#include "DS1820.pio.h"
#include "pico/time.h"
#include "DS18B20.h"
#include "hardware/adc.h"//读取内部温度需要

#define BUILTIN_LED PICO_DEFAULT_LED_PIN // LED is on the same pin as the default LED 25
#define DS18B20_PIN 7
#define DS18B20_PIO pio0
//芯片内部温度读取函数
float getTemp(){
const float conversion_factor = 3.3f / (1 << 12);
adc_select_input(4);

float v = (float)adc_read() * conversion_factor;
float t = 27.0 - ((v - 0.706)/0.001721);

return t;
}

int main()
{
    uint32_t time;
float temp;

DS18B20 ds = DS18B20(DS18B20_PIO, DS18B20_PIN);

    stdio_init_all();
    //setup_default_uart();
    gpio_init(BUILTIN_LED);
  gpio_set_dir(BUILTIN_LED, GPIO_OUT);
  gpio_pull_up(BUILTIN_LED);
    adc_init();
adc_set_temp_sensor_enabled(true);

    sleep_ms(3000);
    printf("GO\n");
    while (1) {

          time = to_ms_since_boot (get_absolute_time ());
    ds.convert();
    time = to_ms_since_boot (get_absolute_time ()) - time;
    printf("Covert time %d ms \n", time);

        sleep_ms(1000);

        time = to_ms_since_boot (get_absolute_time ());
temp = ds.getTemperature();
        time = to_ms_since_boot (get_absolute_time ()) - time;
        printf("DS18B20 Temp %f in %d ms\r\n", temp, time);

        printf("Pico Temp was %f\n", getTemp());
        sleep_ms(500);
         gpio_xor_mask(1ul << BUILTIN_LED); // Toggle the LED
    }

    return 0;
}

在这里插入图片描述

📘DHT11 PIO驱动例程

  • 📍dht11驱动例程参考:https://github.com/vmilea/pico_dht
  • 🔖DHT11.PIO引脚7。
  • 🍁工程结构:
    在这里插入图片描述
  • 🔖CMakeLists.txt相关内容:
add_subdirectory(dht)
# Add executable. Default name is the project name, version 0.1

add_executable(RP2040_DHT11_PIO  RP2040_DHT11_PIO.c
        dht/dht.c)
# Add any user requested libraries
pico_generate_pio_header(RP2040_DHT11_PIO ${CMAKE_CURRENT_LIST_DIR}/dht/dht.pio)

# Add the standard library to the build
target_link_libraries(RP2040_DHT11_PIO
        pico_stdlib
        hardware_adc
        hardware_pio
        hardware_gpio
        hardware_dma)

# Add the standard include files to the build
target_include_directories(RP2040_DHT11_PIO PRIVATE
  ${CMAKE_CURRENT_LIST_DIR}
  ${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts or any other standard includes, if required
    ${CMAKE_CURRENT_LIST_DIR}/dht/include
)
  • 📝程序:
/*
 CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program RP2040_DHT11_PIO.elf verify reset exit"

 jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_DHT11_PIO.elf verify reset exit"

*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "hardware/timer.h"
#include "hardware/clocks.h"
#include "hardware/adc.h" //读取内部温度需要
#include "dht.h"

#define BUILTIN_LED PICO_DEFAULT_LED_PIN // LED is on the same pin as the default LED 25

// change this to match your setup
static const dht_model_t DHT_MODEL = DHT11;
static const uint DATA_PIN = 7;//DHT11数据引脚定义

static float celsius_to_fahrenheit(float temperature)
{
    return temperature * (9.0f / 5) + 32;
}

//芯片内部温度读取函数
float getTemp()
{
    const float conversion_factor = 3.3f / (1 << 12);
    adc_select_input(4);

    float v = (float)adc_read() * conversion_factor;
    float t = 27.0 - ((v - 0.706) / 0.001721);

    return t;
}

int main()
{
    stdio_init_all();
    // setup_default_uart();
    gpio_init(BUILTIN_LED);
    gpio_set_dir(BUILTIN_LED, GPIO_OUT);
    gpio_pull_up(BUILTIN_LED);
    adc_init();
    adc_set_temp_sensor_enabled(true);
    puts("\nDHT test");

    dht_t dht;
    dht_init(&dht, DHT_MODEL, pio0, DATA_PIN, true /* pull_up */);
    do
    {
        dht_start_measurement(&dht);

        float humidity;
        float temperature_c;
        dht_result_t result = dht_finish_measurement_blocking(&dht, &humidity, &temperature_c);
        if (result == DHT_RESULT_OK)
        {
            printf("%.1f C (%.1f F), %.1f%% humidity\n", temperature_c, celsius_to_fahrenheit(temperature_c), humidity);
        }
        else if (result == DHT_RESULT_TIMEOUT)
        {
            puts("DHT sensor not responding. Please check your wiring.");
        }
        else
        {
            assert(result == DHT_RESULT_BAD_CHECKSUM);
            puts("Bad checksum");
        }
         printf("Pico Temp was %f\n", getTemp()); //打印芯片内部温度
        gpio_xor_mask(1ul << BUILTIN_LED); // Toggle the LED
        sleep_ms(2000);
    } while (true);

    return 0;
}

在这里插入图片描述

📘PWM PIO驱动例程

  • 🔖来自自带例程:pico-examples\pio\pwm
  • 📝测试代码:
#include <stdio.h>
/*
 CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program RP2040_PIO_PWM.elf verify reset exit"

 jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_PIO_PWM.elf verify reset exit"
Sysclk = 125MHz  PIO_clk =41,667,788.8Hz
Sysclk = 270MHz  PIO_clk =44,892,160Hz
PWM输出频率 = 41,667,788.8Hz / ( PWM_period+1)
*/
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "pwm.pio.h"

#define BUILTIN_LED PICO_DEFAULT_LED_PIN // LED is on the same pin as the default LED 25
#define PWM_PIN 7

// Write `period` to the input shift register
void pio_pwm_set_period(PIO pio, uint sm, uint32_t period)
{
    pio_sm_set_enabled(pio, sm, false);
    pio_sm_put_blocking(pio, sm, period);
    pio_sm_exec(pio, sm, pio_encode_pull(false, false));
    pio_sm_exec(pio, sm, pio_encode_out(pio_isr, 32));
    pio_sm_set_enabled(pio, sm, true);
}

// Write `level` to TX FIFO. State machine will copy this into X.
void pio_pwm_set_level(PIO pio, uint sm, uint32_t level)
{
    pio_sm_put_blocking(pio, sm, level);
}

int main()
{
   // set_sys_clock_khz(270000, true);//270000KHz
    stdio_init_all();
    // setup_default_uart();
    puts("PIO PWM Example");
    gpio_init(BUILTIN_LED);
    gpio_set_dir(BUILTIN_LED, GPIO_OUT);
    gpio_pull_up(BUILTIN_LED);

    // todo get free sm
    PIO pio = pio0;
    int sm = 0;
    uint offset = pio_add_program(pio, &pwm_program);
    printf("Loaded program at %d\n", offset);

    pwm_program_init(pio, sm, offset, PWM_PIN);
   // pio_pwm_set_period(pio, sm, (1u << 16) - 1); // 65535
    pio_pwm_set_period(pio, sm, 4167 - 1);
    int level = 4166/2;//32768;
    //      printf("Level = %d\n", level);
    pio_pwm_set_level(pio, sm, level);
    //   level = (level + 1) % 256;
    while (true)
    {
        printf("Level = %d\n", level);
        sleep_ms(1000);
        gpio_xor_mask(1ul << BUILTIN_LED); // Toggle the LED
    }
    return 0;
}

  • 📏PWM输出10KHz.占空比:50%
    在这里插入图片描述
  • 🎉超频情况下:set_sys_clock_khz(270000, true);//270000KHz
    在这里插入图片描述
  • 🌿也就是说通过PIO 产生的PWM输出频率,在没有超频的情况下。RP2040默认时钟频率125MHz情况下,PWM输出最大频率:41,667,788Hz / ( 1+1)=20,833,894Hz
  • 🌿时钟频率超频到270MHz情况下,PWM输出最大频率:44,892,160/2=22,446,080Hz

原文地址:https://blog.csdn.net/weixin_42880082/article/details/142460036

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!