教えてください。CY8CKIT-059 シフトレジスタの使い方2

Tip / ログイン to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
NaMi_4553661
Level 3
Level 3
10 replies posted 5 replies posted First question asked

1週間悩みましたが、問題が解決しないため再度質問させてください。

前回、シフトレジスタについて質問させていただきました。

疑似外部トリガとして、CY8CKIT-059の12_2ピンからのPWM信号を

内部に取り込んで

8ビットのパターンを出していただきました。

12_2ピンからのPWM信号からの取り込みですと

所望のパターンできれいに動作するのですが、

200Hzの外部トリガを入れると

1ビット目の幅が時間軸方向に変動し、

クロック毎の8ビットパターンとなりません。

1ビット目のみで、2-8ビットの幅は変化しません。

PWM信号代替の外部入力トリガとして、

ファンクションジェネレータを使用し、

5Vp-p、2.5VOffset、周波数200Hz、50%Duty

をPin2‗3に入れています。

ハードウエア側の問題でしょうか。

知見ありましたら、ご意見お願い致します。

1 解決策
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

こんばんは、

> 1週間悩みましたが、問題が解決しないため再度質問させてください。

1週間も悩まれる前にご質問していただいた方が良かったかと思います。

ご指摘のように、前回のデモではトリガ発生のクロックと受信側のクロックが同一でしたので

際どい設定でもつじつまが合っていました。

先のお問合せでは 8bit パターンを生成するのに必要な時間と

トリガの間隔が一致していたかと思います。

この場合、基板のクロックとトリガのクロックが高精度で同期していない限り

観測されているようなズレは発生してしまうかと思います。

さて、ここで取り得る対策で思いつくのは

(1) 外部のパルスの精度が非常に高く、変化しないと考えられる場合には

 パルスの間隔サンプリングをして時間を測り、その周期に合わせて内部のカウンタの値を変更する。

(2) 8-bit の周期を少し短めにしておいて、8-bit 目だけは少し長くなるけれど、

 次のパルスで再度 8-bit の送信を始める

等でしょうか?

外部パルスの想定されるズレ範囲と、8-bit パルスに求められる精度によって

対策を検討する必要があるかと思います。

moto

元の投稿で解決策を見る

0 件の賞賛
6 返答(返信)
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

こんばんは、

> 1週間悩みましたが、問題が解決しないため再度質問させてください。

1週間も悩まれる前にご質問していただいた方が良かったかと思います。

ご指摘のように、前回のデモではトリガ発生のクロックと受信側のクロックが同一でしたので

際どい設定でもつじつまが合っていました。

先のお問合せでは 8bit パターンを生成するのに必要な時間と

トリガの間隔が一致していたかと思います。

この場合、基板のクロックとトリガのクロックが高精度で同期していない限り

観測されているようなズレは発生してしまうかと思います。

さて、ここで取り得る対策で思いつくのは

(1) 外部のパルスの精度が非常に高く、変化しないと考えられる場合には

 パルスの間隔サンプリングをして時間を測り、その周期に合わせて内部のカウンタの値を変更する。

(2) 8-bit の周期を少し短めにしておいて、8-bit 目だけは少し長くなるけれど、

 次のパルスで再度 8-bit の送信を始める

等でしょうか?

外部パルスの想定されるズレ範囲と、8-bit パルスに求められる精度によって

対策を検討する必要があるかと思います。

moto

0 件の賞賛

早々のご回答ありがとうございます。

当初の計画とは変わっていまして、

トリガは、モータの回転よるトリガになります。

測定したところ、

周波数140Hz~240Hz までです。

頻繁に変わるわけではなく、

標準偏差0.6Hzです。

現状、マニュアルで任意に前述の周波数範囲で変更する可能性があります。

なるほど、内部のカウンタを変える必要があるのですね。

(1)の手法がイメージに合いそうです。

タイマを使って、変数をインクリメントして、内部カウンタに適用する。。。

感じでしょうか。

(にしても、1ビット目だけ変わるのがよくわかりません。)

0 件の賞賛
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

こんばんは、

回路を下記の様に変更して実験をしてみました。

000-schematic.JPG

例によって Pulse_Gen はテスト用信号発生源です。

PWM400Hz の用途がわかりませんでしたので、他のページに移動してそのままにしてあります。

デバッグ用の UART も場所が足りなかったので他のページに移動しました。

Pins

001-pins.JPG

試験用信号源と内部クロックが同期してしまっていますので、多少の不安は残りますが、

こちらで実験した限りではパルスの周波数を 100Hz から 300Hz まで振った範囲ではシフトレジスタへの

パルスはほぼ安定した位置にでているように見えました。

尚、分解能と速度を稼ぐために、CPU のクロックは 24MHz から 66MHz へドーピングしました。

もしかしたら不要だったかも知れません。

main.c

================

#include "project.h"

#include "stdio.h"

#include "tty_utils.h"

#define SHIFT_REG_WIDTH 8

#define NUM_LED 10

volatile int led_num = 1 ; /* for testing */

/*

const uint32_t PATTERNS[] = {

//LED10 ------>LED1

  0b0101010101,

  0b1001100110,

  0b0001111000,

  0b1110000000,

  0b1111111111,

  0b0000000000,

  0b0000000000,

  0b1111111111,

};

const uint32_t PATTERNS[] = {

//LED10 ------>LED1

  0b1010101010,

  0b0110011001,

  0b1110000111,

  0b0001111111,

  0b0000000000,

  0b1111111111,

  0b1111111111,

  0b0000000000,

};

const uint32_t PATTERNS[] = {

//LED10 ------>LED1

  0b0110011001,

  0b1010101010,

  0b0001111111,

  0b1110000111,

  0b1111111111,

  0b0000000000,

  0b0000000000,

  0b1111111111,

};

*/

uint8_t led_pattern[NUM_LED] = {

    0b10111001,

    0b01111001,

    0b00111001,

    0b11101001,

    0b10101001,

    0b01101001,

    0b00101001,

    0b11011001,

    0b10011001,

    0b01011001

} ;

volatile uint16_t freq_count = 10000 ;

CY_ISR(freq_isr)

{

    FreqCounter_Stop() ;

    freq_count = FreqCounter_ReadCapture() ;

    Timer_WritePeriod((freq_count / 8)) ;

    Timer_WriteCounter(0) ;

    FreqCounter_WriteCounter(0) ;

    FreqCounter_ReadStatusRegister() ;

    FreqCounter_Start() ;

}

CY_ISR(timer_isr)

{

   // ShiftReg_1_WriteRegValue(led_pattern[led_num-1]) ;  

    ShiftReg_1_WriteRegValue(led_pattern[0]) ;   

    ShiftReg_2_WriteRegValue(led_pattern[1]) ; 

    ShiftReg_3_WriteRegValue(led_pattern[2]) ; 

    ShiftReg_4_WriteRegValue(led_pattern[3]) ; 

    ShiftReg_5_WriteRegValue(led_pattern[4]) ; 

    ShiftReg_6_WriteRegValue(led_pattern[5]) ;   

    ShiftReg_7_WriteRegValue(led_pattern[6]) ; 

    ShiftReg_8_WriteRegValue(led_pattern[7]) ; 

    ShiftReg_9_WriteRegValue(led_pattern[8]) ; 

    ShiftReg_10_WriteRegValue(led_pattern[9]) ; 

    isr_1_ClearPending() ;

}

void start_sift_registers()

{

    ShiftReg_1_Start() ;

    ShiftReg_2_Start() ;

    ShiftReg_3_Start() ;

    ShiftReg_4_Start() ;

    ShiftReg_5_Start() ;

    ShiftReg_6_Start() ;

    ShiftReg_7_Start() ;

    ShiftReg_8_Start() ;

    ShiftReg_9_Start() ;

    ShiftReg_10_Start() ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */   

    tty_init() ;

    start_sift_registers() ;

    isr_1_ClearPending() ;

    isr_1_StartEx(timer_isr) ;

    Timer_Start() ;

    isr_freq_ClearPending() ;

    isr_freq_StartEx(freq_isr) ;

    FreqCounter_Start() ;

    PWM400Hz_Start() ;

    Pulse_Gen_Start() ;

}

void set_out_pulse(uint16_t freq)

{

    uint16_t period ;

    uint16_t compare ;

    if ((freq < 100) || (freq > 300)) {

        snprintf(str,STR_BUF_LEN, "Freq %hd out of range (100-300Hz)\n\r", freq) ;

        print(str) ;

        return ;

    }

    period = (2000000 / freq) - 1 ;

    compare = (1000000 / freq) - 1 ;

    Pulse_Gen_Stop() ;

    Pulse_Gen_WritePeriod(period) ;

    Pulse_Gen_WriteCompare(compare) ;

    Pulse_Gen_WriteCounter(0) ;

    Pulse_Gen_Enable() ;  

}

int main(void)

{

    uint16_t prev_freq_count = 0 ;

    uint16_t pulse_freq = 0 ;

   

    init_hardware() ;

   

    prompt() ;

    for (;;) {

        if (get_line()) {

            sscanf(str, "%hd", &pulse_freq) ;

            set_out_pulse(pulse_freq) ;

            snprintf(str, STR_BUF_LEN, "Out Freq: %hd Hz\n\r", pulse_freq) ;

            print(str) ;

            prompt() ;

        }

    }

}

================

18-May-2020

moto

0 件の賞賛

早々にありがとうございます。

いきなり動き出しました。

FreqCounterの

Period:16777218

はどのような計算によるものでしょうか。

pastedImage_0.png

0 件の賞賛
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

こんにちは

> いきなり動き出しました。

(笑)

> FreqCounterの

> Period:16777218

> はどのような計算によるものでしょうか。

16777213 だと思いますが、これは右にある [Max] ボタンをおして

16777214 となったので、念のために 1 下げて 16777213 になっているだけです。

基本的に、なるべく大きな数字まで対応できるようにと考えて大きな数字にしました。

本来は、アプリケーションの設定を考えて計算すべきだったとは思うのですが、

夜分で頭が働いていなかった為そのような数字になりました。

(実際はかなりオーバースペックな数字と思いますが、

 16bit だと際どくなりそうな気もしたために 24bit にしました。)

どうしても因果律の関係でパルスが入ってから起動するまでに遅延が発生してしまいます。

一周期待って可能な限り合わせるというのも脳裏をよぎったのですが、かなり複雑に

なりそうでした、もしこのくらいで実用にともせたなら幸いです。

moto

0 件の賞賛

16777213

了解いたしました。24bit長でもないので、何かやられているのかと思いました。

ありがとうございます。

解決しました。