« ラズピコのPWM。 なんかおかしいような #2 | トップページ | ラズピコのPWM。やっぱしanalogWriteは捨てちゃえ #2 »

2023年2月21日 (火)

ラズピコのPWM。 やっぱしanalogWriteは捨てちゃえ

2023年2月20日:ラズピコのPWM。 なんかおかしいような #2
この続き。

ここ↓で、PWMを使ったタイマー割り込みを試していました。
2022年4月12日:Arduino IDEでラズパイ・ピコ:1msタイマー割り込み
それの応用で500HzのPWMを確認してみます。
  ※analogWriteを捨てるための実験です

/****************************/
/* PWM出力 */
/****************************/
#include "pwm.h" // PWM処理に必要
// PWMデータ
int pwm_port; // PWMポート番号
int pwm_range = 256; // PWM レンジ 初期値は256
int pwm_data; // PWM設定値データ
/***** PWM出力 *****/
// pinに出力 valがPWM H区間 最大がrange
// val=0ならL出力 val=rangeならH出力
// ピコのクロックは125MHz
// val,rangeを10倍して処理
// set_clkdivは256.0未満 m・n/16で分周
// set_wrap,set_chan_levelはuint16_tなので65535がmax
void pwmWrite(pin_size_t pin, int val, int range)
{
uint sn; // slice number
gpio_set_function(pwm_port, GPIO_FUNC_PWM); // ポートはPWM出力で
sn = pwm_gpio_to_slice_num(pwm_port); // スライス番号を得る
pwm_set_clkdiv(sn, 97.66); // 1.28MHzに
pwm_set_wrap(sn, (10 * range) - 1); // 256で500Hz
pwm_set_chan_level(sn, (pwm_port & 1), 10 * val); // ch-A,ch-B
pwm_set_enabled(sn, true); // PWMスタート
}

グラフにすると、よく分かるかと。
   ※前のと同じスケールで
Cap110
   ※拡大
Cap111
へんな周期性は見えません。

「半値」のあたりはこんな具合。

・range = 255で
PWM発生  実測値   n/255で  実測値   差分
n 1/255 H H+L
126 255 15744 31864 49.412% 49.410% -0.002%
127 255 15870 31865 49.804% 49.804% -0.000%
128 255 15995 31865 50.196% 50.196% 0.000%
129 255 16120 31865 50.588% 50.588% 0.000%
130 255 16245 31865 50.980% 50.981% 0.000%

・range = 256で
PWM発生  実測値   n/255で  実測値   差分
n 1/256 H H+L
126 256 15745 31990 49.219% 49.219% -0.000%
127 256 15870 31990 49.609% 49.609% -0.000%
128 256 15995 31990 50.000% 50.000% 0.000%
129 256 16120 31990 50.391% 50.391% 0.000%
130 256 16245 31990 50.781% 50.781% 0.000%

実測値は16MHzのクロックでサンプリングしたHとLのパルス幅です。
128/255も128/256も期待値が出ています。

◆テストプログラム
  ・ダウンロード - pwm_serial_in4.txt

(.inoではなく.txtにしてます。 UTF-8Nエンコード)

|

« ラズピコのPWM。 なんかおかしいような #2 | トップページ | ラズピコのPWM。やっぱしanalogWriteは捨てちゃえ #2 »

ラズパイ・ピコ」カテゴリの記事

1023 vs 1024」カテゴリの記事

コメント

せっかくだから analogWritePure なんて関数というかライブラリを作っちゃいましょう。

投稿: ラジオペンチ | 2023年2月21日 (火) 17時26分

汎用のライブラリはむつかしいです。
あれこれ考慮すべきことが多すぎて。

Auduino UNOのdigitalWriteでもこんだけ。
ポート出力をH/Lするだけなのに・・・

void digitalWrite(uint8_t pin, uint8_t val)
{
uint8_t timer = digitalPinToTimer(pin);
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *out;

if (port == NOT_A_PIN) return;

// If the pin that support PWM output, we need to turn it off
// before doing a digital write.
if (timer != NOT_ON_TIMER) turnOffPWM(timer);

out = portOutputRegister(port);

uint8_t oldSREG = SREG;
cli();

if (val == LOW) {
*out &= ~bit;
} else {
*out |= bit;
}

SREG = oldSREG;
}

投稿: 居酒屋ガレージ店主(JH3DBO) | 2023年2月22日 (水) 08時43分

お試しを。
http://igarage.cocolog-nifty.com/blog/2023/02/post-ea12af.html

投稿: 居酒屋ガレージ店主(JH3DBO) | 2023年2月22日 (水) 12時58分

コメントを書く



(ウェブ上には掲載しません)




« ラズピコのPWM。 なんかおかしいような #2 | トップページ | ラズピコのPWM。やっぱしanalogWriteは捨てちゃえ #2 »