2025年3月1日土曜日

Pi Pico (RP2040) PIO - VSCode クロック出力

 Raspberry Pi Pico(RP2040)にはメイン処理と独立したアッセンブリ処理によるプログラマブルIO機能【PIO】があります。PIOをアッセブルしクロックパルスのテストを行いました。
※開発環境はVisual Studio Code【拡張機能】の【Raspberry Pi Pico】





参考サイト
●RP2040 Datasheet
【https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf】
●RP2040でPIOをプロジェクト新規作成して動かすまで(C言語)
●Raspberry Pi Pico C/C++ PIOでポート出力してみる
●Raspbrry Pi Pico(RP2040)のPIOを使ってワンファイルでLチカする(ArduinoIDE)
●【Arduino】Raspberry Pi Pico/W のPIOでウィンカー点滅を再現するぞ!(PIO : Lチカ)

アセンブラ命令
●RP2040開発ボードでProgrammable I/Oを使う
●ラズピコ PIO ~解説編~
●RP2040のPIOのJMP, MOV, PUSHとかの解説(C言語向け)
●RP2040 PIO レジスタと Pico SDK 覚え書き

New C/C++ Project






































【New C/C++ Project】
【Name】pio_LED
【board type】Pico
【フォルダーは任意】
【PIO Interface】レ点
【Create】

pio_ledフォルダ













コンパイル















【ファイル】
【フォルダを開く】pio_ledフォルダ
【フォルダの選択】
【Compile】

【pio_ledフォルダ】ー【buildフォルダ】を開いて
【pic_led.uf2】を【RPI-RP2】にドラッグ・アンド・ドロップ(書込み)

リセットボタン取付

内蔵LED点滅(3Hz)













print文の表示1





















【CMakeLists.txt】の
【pico_enable_stdio_usb(pio_led 1)】0→1に変更して再コンパイル
【pio_led.uf2】を【RPI-RP2】にドラッグ・アンド・ドロップ(書込み)

【シリアルモニタ】
【ポート】接続USBポート選択
【監視の開始】

print文の表示2




























print文「Loaded program.....」「Blinking pin.....」立上り表示が出来ないので
[sleep_ms(5000);]挿入しました。(リセット後5秒以内にシリアル ポートを指定し「監視の開始」を行う)


クロック分周
【led_pio.c】int main()
  blink_pin_forever(pio, 0, offset, PICO_DEFAULT_LED_PIN, 3);
                                       ↓          
   PICO_DEFAULT_LED_PIN:GPIO番号(25)  周波数:3(3Hz)
 
①10000000Hzに変更
 blink_pin_forever(pio, 0, offset, 3, 10000000);
 GPIO番号 = 3       周波数 = 10MHz に変更  
10.417MHz


















out y, 1 に変更(125MHz 8分周) 
【led_pio.c】int main() 
 blink_pin_forever(pio, 0, offset, 3, 1);
【blink.pio】.program blink
  out y, 32  → out y, 1
    
15.625MHz



















③ set pins,1 set pins,0 (125MHz 2分周) 
【led_pio.c】int main() 
 blink_pin_forever(pio, 0, offset, 3, 1);
【blink.pio】.program blink
.program blink  
.wrap_target   
    set pins, 1   ; Turn LED on
    set pins, 0   ; Turn LED off
.wrap             ; Blink forever!

62.500MHz






















プログラム
blink.pio
;
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
;
; SPDX-License-Identifier: BSD-3-Clause
;

; SET pin 0 should be mapped to your LED GPIO

.program blink
    pull block
    out y, 32     ; Y ← 32ビット 
.wrap_target      ; ~wrap ループ
    mov x, y      ; X ← Y
    set pins, 1   ; Turn LED on
lp1:              ; X = X - 1 ,X ≠ 0 時 lp1 にジャンプ
    jmp x-- lp1   ; Delay for (x + 1) cycles, x is a 32 bit number
    mov x, y      ; X ← Y
    set pins, 0   ; Turn LED off
lp2:
                  ; X = X - 1 ,X ≠ 0 時 lp2 にジャンプ
    jmp x-- lp2   ; Delay for the same number of cycles again
.wrap             ; Blink forever!


% c-sdk {
// this is a raw helper function for use by the user which sets up the GPIO output, and configures the SM to output on a particular pin

void blink_program_init(PIO pio, uint sm, uint offset, uint pin) {
   //GPIO番号"pin"をGPIOとして使用
   pio_gpio_init(pio, pin); 
   //GPIOを出力(true:出力 false:入力)
   pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
   //SMのデフォルト値を取得
   pio_sm_config c = blink_program_get_default_config(offset); 
   //ピンと、ピンの数を指定
   sm_config_set_set_pins(&c, pin, 1);
   //プログラムを読込、先頭から実行
   pio_sm_init(pio, sm, offset, &c);
}
%}



led_pio.c
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pio.h"

#include "blink.pio.h"

void blink_pin_forever(PIO pio, uint sm, uint offset, uint pin, uint freq) {
    //
    blink_program_init(pio, sm, offset, pin);
    // ステートマシン有効 (true-有効 false-無効)
    pio_sm_set_enabled(pio, sm, true);

    printf("Blinking pin %d at %d Hz\n", pin, freq);

    // PIO counter program takes 3 more cycles in total than we pass as
    // input (wait for n + 1; mov; jmp)
    pio->txf[sm] = (125000000 / (2 * freq)) - 3;
}



int main()
{
    stdio_init_all();
    sleep_ms(5000);
    // PIO Blinking example
    // pio0 と pio1 があり pio0 を指定
    PIO pio = pio0;
    // offset変数 ← アセンブラのアドレス(&blink_program)
    // pio_add_program(バイナリに変換して送る)     
    uint offset = pio_add_program(pio, &blink_program);
    printf("Loaded program at %d\n", offset);
    
    //LED_PIN定義(GP25)
    #ifdef PICO_DEFAULT_LED_PIN
    blink_pin_forever(pio, 0, offset, PICO_DEFAULT_LED_PIN, 3);
    #else
    blink_pin_forever(pio, 0, offset, 6, 3);
    #endif
    // For more pio examples see https://github.com/raspberrypi/pico-examples/tree/master/pio

    while (true) {
        printf("Hello, world!\n");
        sleep_ms(1000);
    }
}


CMakeLists.txt
# Generated Cmake Pico project file

cmake_minimum_required(VERSION 3.13)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# Initialise pico_sdk from installed location
# (note this can come from environment, CMake cache etc)

# == DO NOT EDIT THE FOLLOWING LINES for the Raspberry Pi Pico VS Code Extension to work ==
if(WIN32)
    set(USERHOME $ENV{USERPROFILE})
else()
    set(USERHOME $ENV{HOME})
endif()
set(sdkVersion 2.1.0)
set(toolchainVersion 13_3_Rel1)
set(picotoolVersion 2.1.0)
set(picoVscode ${USERHOME}/.pico-sdk/cmake/pico-vscode.cmake)
if (EXISTS ${picoVscode})
    include(${picoVscode})
endif()
# ====================================================================================
set(PICO_BOARD pico CACHE STRING "Board type")

# Pull in Raspberry Pi Pico SDK (must be before project)
include(pico_sdk_import.cmake)

project(pio_led C CXX ASM)

# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()

# Add executable. Default name is the project name, version 0.1

add_executable(pio_led pio_led.c )

pico_set_program_name(pio_led "pio_led")
pico_set_program_version(pio_led "0.1")

# Generate PIO header
pico_generate_pio_header(pio_led ${CMAKE_CURRENT_LIST_DIR}/blink.pio)

# Modify the below lines to enable/disable output over UART/USB
pico_enable_stdio_uart(pio_led 0)
pico_enable_stdio_usb(pio_led 0)

# Add the standard library to the build
target_link_libraries(pio_led
        pico_stdlib)

# Add the standard include files to the build
target_include_directories(pio_led PRIVATE
        ${CMAKE_CURRENT_LIST_DIR}
)

# Add any user requested libraries
target_link_libraries(pio_led
        hardware_pio
        )

pico_add_extra_outputs(pio_led)



0 件のコメント:

コメントを投稿

Pi Pico (RP2040) PIO - VSCode 90度位相差クロック出力

Pi Pico Rx - 公開プログラムnco_pioを使って、Raspberry Pi Picoのシステムクロックからメイン処理と独立したPIO制御による7MHz90度位相差クロックの出力テストを行いました。 ※開発環境はVisual Studio Code 拡張機能 の【Ra...