6 Replies Latest reply on May 18, 2020 7:19 PM by NaMi_4553661

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

    NaMi_4553661

      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. Re: 教えてください。CY8CKIT-059 シフトレジスタの使い方2
          MoTa_728816

          こんばんは、

           

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

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

           

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

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

           

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

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

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

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

           

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

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

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

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

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

          等でしょうか?

           

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

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

           

          moto

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

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

             

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

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

            測定したところ、

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

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

            標準偏差0.6Hzです。

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

             

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

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

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

            感じでしょうか。

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

            • 3. Re: 教えてください。CY8CKIT-059 シフトレジスタの使い方2
              MoTa_728816

              こんばんは、

               

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

              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

              • 4. Re: 教えてください。CY8CKIT-059 シフトレジスタの使い方2
                NaMi_4553661

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

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

                 

                FreqCounterの

                Period:16777218

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

                 

                • 5. Re: 教えてください。CY8CKIT-059 シフトレジスタの使い方2
                  MoTa_728816

                  こんにちは

                   

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

                  (笑)

                   

                  > FreqCounterの

                  > Period:16777218

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

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

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

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

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

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

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

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

                   

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

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

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

                   

                  moto

                  • 6. Re: 教えてください。CY8CKIT-059 シフトレジスタの使い方2
                    NaMi_4553661

                    16777213

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

                     

                    ありがとうございます。

                    解決しました。