2025年4月1日火曜日

Pi Pico PIO 90度位相差 クロック - ヘッダーファイル変換

Arduno IDEによるPi Pico Rx - 公開プログラムnco_pioを使って、Raspberry Pi Pico (RP2040) PIO制御7MHz90度位相差クロックを出力しました。nco_pioをArduno IDEに使えるヘッダーソース用コードに変換してプログラムしています。
 




上ーGPIO0 下ーGPIO1 (7MHZ)














参考サイト
●pioasmでDCCパルス幅をカウントする
●【Arduino】(PIO : Lチカ)


VSCode【nco.pio】PIOソースコード
.program nco
    set pins, 0
    set pins, 1      ; Drive pin low
    set pins, 3      ; Drive pin high
    set pins, 2      ; Drive pin low

% c-sdk {
static inline void nco_program_init(PIO pio, uint sm, uint offset) {
    // PIOステートマシンコンフィグのデフォルト値を取得  
    pio_sm_config c = nco_program_get_default_config(offset);

    // Map the state machine's OUT pin group to one pin, namely the `pin`
    // parameter to this function. 
    //ピンと、ピンの数を指定
    sm_config_set_set_pins(&c, 0, 2);

    // Set this pin's GPIO function (connect PIO to the pad)
    //GPIOをPIO 0に割り当てる
    pio_gpio_init(pio, 0);
    //GPIOをPIO 1に割り当てる
    pio_gpio_init(pio, 1);
    //出力電流2mA
    gpio_set_drive_strength(0, GPIO_DRIVE_STRENGTH_2MA);
    gpio_set_drive_strength(1, GPIO_DRIVE_STRENGTH_2MA);
    //スルーレート 遅い
    gpio_set_slew_rate(0, GPIO_SLEW_RATE_SLOW);
    gpio_set_slew_rate(1, GPIO_SLEW_RATE_SLOW);

    // Set the pin direction to output at the PIO
    //PIOでピンの方向を出力に設定する
    pio_sm_set_consecutive_pindirs(pio, sm, 0, 2, true);

    //set pio divider
    //クロック周波数分周 1
    sm_config_set_clkdiv(&c,1);
    // Load our configuration, and jump to the start of the program
    //プログラムを読込、先頭から実行
    pio_sm_init(pio, sm, offset, &c);

    // Set the state machine running
    //PIOステートマシンを有効にする
    pio_sm_set_enabled(pio, sm, true);
}

%}




ヘッダーファイル用コード変換
●Online pioasm for Raspberry Pi Pico
【nco.pio】PIOソースコードを左画面に貼付
 →右画面にヘッダーファイル用コードが作成される














メモ帳でヘッダーファイル作成



【スタート】クリック
【メモ】インプット
【メモ帳】クリック
【ヘッダーファイル用コード】メモ帳に貼付
【名前を付けて保存】 
 ソースファイル保存場所(任意)
【ファイル名】nco.h
【ファイルの種類】すべてのファイル
【保存】















ソースファイル保存場所(任意)にヘッダーファイル(nco.h)








90度位相差クロック
上ーGPIO0 下ーGPIO1 (7MHZ)

















周波数カウンタ測定
●システムクロック125MHz
出力周波数(7.000.000)  
→GPIO0【7.005.260】Hz
●システムクロック133MHz
出力周波数(7.000.000)  
→GPIO0【7.000.005】Hz









nco.pioファイル
set pins0~3を個別に実行した結果
GPIO出力 0→0V 1→3.3V
                    GPIO 1    GPIO 0
set pins, 0             0             0
set pins, 1             0             1 
set pins, 3             1             1
set pins, 2             1             0
GPIO0・GPIO1位相差90度
set pins          0  1  3  2  0  1  3  2  0  1  3  2  0  1  3  2
 GPIO 0        _| ̄ ̄|__| ̄ ̄|__| ̄ ̄|__| ̄ ̄|_
 GPIO 1       __| ̄ ̄|__| ̄ ̄|__| ̄ ̄|__| ̄ ̄|

7MHzの出力
  システムクロック:  133MHz(任意)
  出力周波数:   7MHz
  命令サイクル: 4サイクル
  divider(クロック分周値)= システムクロック ÷(出力周波数 × 4サイクル) 
  クロック分周の設定:pio_sm_set_clkdiv(pio, sm, divider)



Arduno IDE

ボード【Raspberry Pi Pico】
CPU Speed【133 MHz】デフォルト値
シリアルポート【任意】



















プログラム   Arduino IDE【ボード:Raspberry Pi Pico】
#include <hardware/clocks.h>
#include <pico/stdlib.h>
#include <hardware/pio.h>
#include "nco.h"

void setup() {
    //set_sys_clock_khz(133000, true); //1MHz単位で変更可能
    //set_sys_clock_pll(12000000*125, 6, 2); //システムクロック125000000Hz
    set_sys_clock_pll(12000000*133, 6, 2); //システムクロック133000000Hz
    float system_clock_frequency = 133000000; //システムクロック  
    PIO pio = pio0; //pioを指定
    uint sm;        
    uint offset = pio_add_program(pio, &nco_program); //offset変数←アセンブラのアドレス      
    nco_program_init(pio, sm, offset);  //PIOの初期化    
    float adjusted_frequency = 7000000; //クロック周波数設定
    float divider = system_clock_frequency/(4 * adjusted_frequency); //周波数分周      
    pio_sm_set_clkdiv(pio, sm, divider);  //クロック出力    
}

void loop() {
   
}

nco.h
// -------------------------------------------------- //
// This file is autogenerated by pioasm; do not edit! //
// -------------------------------------------------- //

#pragma once

#if !PICO_NO_HARDWARE
#include "hardware/pio.h"
#endif

// --- //
// nco //
// --- //

#define nco_wrap_target 0
#define nco_wrap 3

static const uint16_t nco_program_instructions[] = {
            //     .wrap_target
    0xe000, //  0: set    pins, 0                    
    0xe001, //  1: set    pins, 1                    
    0xe003, //  2: set    pins, 3                    
    0xe002, //  3: set    pins, 2                    
            //     .wrap
};

#if !PICO_NO_HARDWARE
static const struct pio_program nco_program = {
    .instructions = nco_program_instructions,
    .length = 4,
    .origin = -1,
};

static inline pio_sm_config nco_program_get_default_config(uint offset) {
    pio_sm_config c = pio_get_default_sm_config();
    sm_config_set_wrap(&c, offset + nco_wrap_target, offset + nco_wrap);
    return c;
}

static inline void nco_program_init(PIO pio, uint sm, uint offset) {
    // PIOステートマシンコンフィグのデフォルト値を取得  
    pio_sm_config c = nco_program_get_default_config(offset);
    // Map the state machine's OUT pin group to one pin, namely the `pin`
    // parameter to this function. 
    //ピンと、ピンの数を指定
    sm_config_set_set_pins(&c, 0, 2);
    // Set this pin's GPIO function (connect PIO to the pad)
    //GPIOをPIO 0に割り当てる
    pio_gpio_init(pio, 0);
    //GPIOをPIO 1に割り当てる
    pio_gpio_init(pio, 1);
    //出力電流2mA
    gpio_set_drive_strength(0, GPIO_DRIVE_STRENGTH_2MA);
    gpio_set_drive_strength(1, GPIO_DRIVE_STRENGTH_2MA);
    //スルーレート 遅い
    gpio_set_slew_rate(0, GPIO_SLEW_RATE_SLOW);
    gpio_set_slew_rate(1, GPIO_SLEW_RATE_SLOW);
    // Set the pin direction to output at the PIO
    //PIOでピンの方向を出力に設定する
    pio_sm_set_consecutive_pindirs(pio, sm, 0, 2, true);
    //set pio divider
    //クロック周波数分周 1
    sm_config_set_clkdiv(&c,1);
    // Load our configuration, and jump to the start of the program
    //プログラムを読込、先頭から実行
    pio_sm_init(pio, sm, offset, &c);
    // Set the state machine running
    //PIOステートマシンを有効にする
    pio_sm_set_enabled(pio, sm, true);
}

#endif








0 件のコメント:

コメントを投稿

Pi Pico PIO 90度位相差 クロック - AM放送 受信テスト

 Pi Pico Rx - 公開プログラムnco_pioを使い、Raspberry Pi Pico (RP2040) PIO制御による90度位相差クロック530~1600KHzの局発I Qを直交ミキサに入力、出力IQ信号をZEPエンジニアリング株式会社公開 【 5_PicoSta...