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)!