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

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

cross mob
NaMi_4553661
Level 3
Level 3
10 replies posted 5 replies posted First question asked

おしえてください。初心者です。

CY8CKIT-059を使っています。

シフトレジスタを使ってLEDをチカチカさせようとしています。

LEDの個数は10個で8パターンをラッチクロック毎に点灯させたいです。

シフトレジスタを使って実現したいのですが、使い方がよくわからず難儀しています。

初めてPsocにチャレンジしたのですが、HWの方がよくわかりません。

// 点灯パターン(1=点灯, 0=消灯)
const uint32_t PATTERNS[] = {

//LED10 ------>LED1

  0b0101010101
  0b1001100110,
  0b0001111000,
  0b1110000000,
  0b1111111111,
  0b0000000000,
  0b0000000000,
  0b1111111111,

};

よろしくお願いします。

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

こんばんは、

私も ShiftRegister は初めて使用しました。

パターンが

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

// 点灯パターン(1=点灯, 0=消灯)
const uint32_t PATTERNS[] = {

//LED10 ------>LED1

  0b0101010101
  0b1001100110,
  0b0001111000,
  0b1110000000,
  0b1111111111,
  0b0000000000,
  0b0000000000,
  0b1111111111,

};

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

ということですので、

LED1 の挙動は 1, 0, 0, 0, 1, 0, 0, 1 となるということで

ShiftRegister には 0b10001001 を書き込んでシフトアウトすれば良いと考えました。

私の手持ちの CY8CKIT-059 には LED が一つしかついていませんので、LED1 だけの実験をしました。

10 個の LED を同時に点灯する場合には ShiftReg が 10個必要かと思います。

プログラムをビルド後デバッグして、89行目にブレークポイントを張って実行すると

予定どおりの LED の点灯を見ることが出来ました。

あと、ShiftRegister は ShiftReg_Start() 後に一回以上はクロックを

動かさないと ShiftReg_ReadRegValue() で固まる現象が見られました。

68行目の led_num を 1以外の 2~10 の数字にしてあげれば

それぞれの LED のパターンも見えるかと思いますが、実は実験していません。 (^ ^;

001-debug-screen.JPG

TeraTerm の画面

※ 一サイクル目の出力が 00000000 と表示されるのですが、LEDはちゃんと点灯していました。

000-TeraTerm-log.JPG

回路図

002-schematic.JPG

ピン

003-pins.JPG

main.c

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

#include "project.h"

#include "stdio.h"

#include "tty_utils.h"

#define SHIFT_REG_WIDTH 8

const uint32_t PATTERNS[] = {

//LED10 ------>LED1

  0b0101010101,

  0b1001100110,

  0b0001111000,

  0b1110000000,

  0b1111111111,

  0b0000000000,

  0b0000000000,

  0b1111111111,

};

uint8_t LED1_pattern = 0 ;

uint8_t make_led_reg_value(int led_num)

{

    uint8_t result = 0 ;

    int i ;

   

    for (i = 0 ; i < SHIFT_REG_WIDTH ; i++ ) {

        result <<= 1 ;

        if (PATTERNS & (0x01 << (led_num - 1))) {

            result |= 0x01 ;

        }

    }

    return(result) ;

}

void print_as_bin8(uint8_t value)

{

    uint8_t mask = 0x80 ;

    while(mask) {

        if (value & mask) {

            print("1") ;

        } else {

            print("0") ;

        }

        mask >>= 1 ;

    }

    print("\n") ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */   

    tty_init() ;

    ShiftReg_Start() ;

}

void clock_pulse(uint16_t delay)

{   

    Control_Reg_Write(1) ;

    CyDelay(delay) ;

    Control_Reg_Write(0) ;

    CyDelay(delay) ;  

}

int main(void)

{

    uint8_t led1_pattern = 0 ;

    uint8_t current_value ;

    int led_num = 1 ;

    int i ;

   

    init_hardware() ;

   

    splash("CY8CKIT-059 ShiftRegister Test") ;

   

    led1_pattern = make_led_reg_value(led_num) ;

    snprintf(str, STR_BUF_LEN, "Pattern for LED %d : ", led_num) ;

    print(str) ;

    print_as_bin8(led1_pattern) ;

    print("\n\r") ;

   

    clock_pulse(500) ; /* one dummy cycle */ 

   

    for(;;)

    {   

        ShiftReg_WriteRegValue(led1_pattern) ;

//       clock_pulse(500) ; /* one dummy cycle */   

       

        for (i = 0 ; i < SHIFT_REG_WIDTH ; i++ ) {

            current_value = ShiftReg_ReadRegValue() ;

            print_as_bin8(current_value) ;

            clock_pulse(500) ; /* shift 1 bit */

        }

        print("\n") ;

        CyDelay(1000) ; /* wait 1 sec */

    }

}

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

moto

元の投稿で解決策を見る

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

こんばんは、

私も ShiftRegister は初めて使用しました。

パターンが

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

// 点灯パターン(1=点灯, 0=消灯)
const uint32_t PATTERNS[] = {

//LED10 ------>LED1

  0b0101010101
  0b1001100110,
  0b0001111000,
  0b1110000000,
  0b1111111111,
  0b0000000000,
  0b0000000000,
  0b1111111111,

};

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

ということですので、

LED1 の挙動は 1, 0, 0, 0, 1, 0, 0, 1 となるということで

ShiftRegister には 0b10001001 を書き込んでシフトアウトすれば良いと考えました。

私の手持ちの CY8CKIT-059 には LED が一つしかついていませんので、LED1 だけの実験をしました。

10 個の LED を同時に点灯する場合には ShiftReg が 10個必要かと思います。

プログラムをビルド後デバッグして、89行目にブレークポイントを張って実行すると

予定どおりの LED の点灯を見ることが出来ました。

あと、ShiftRegister は ShiftReg_Start() 後に一回以上はクロックを

動かさないと ShiftReg_ReadRegValue() で固まる現象が見られました。

68行目の led_num を 1以外の 2~10 の数字にしてあげれば

それぞれの LED のパターンも見えるかと思いますが、実は実験していません。 (^ ^;

001-debug-screen.JPG

TeraTerm の画面

※ 一サイクル目の出力が 00000000 と表示されるのですが、LEDはちゃんと点灯していました。

000-TeraTerm-log.JPG

回路図

002-schematic.JPG

ピン

003-pins.JPG

main.c

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

#include "project.h"

#include "stdio.h"

#include "tty_utils.h"

#define SHIFT_REG_WIDTH 8

const uint32_t PATTERNS[] = {

//LED10 ------>LED1

  0b0101010101,

  0b1001100110,

  0b0001111000,

  0b1110000000,

  0b1111111111,

  0b0000000000,

  0b0000000000,

  0b1111111111,

};

uint8_t LED1_pattern = 0 ;

uint8_t make_led_reg_value(int led_num)

{

    uint8_t result = 0 ;

    int i ;

   

    for (i = 0 ; i < SHIFT_REG_WIDTH ; i++ ) {

        result <<= 1 ;

        if (PATTERNS & (0x01 << (led_num - 1))) {

            result |= 0x01 ;

        }

    }

    return(result) ;

}

void print_as_bin8(uint8_t value)

{

    uint8_t mask = 0x80 ;

    while(mask) {

        if (value & mask) {

            print("1") ;

        } else {

            print("0") ;

        }

        mask >>= 1 ;

    }

    print("\n") ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */   

    tty_init() ;

    ShiftReg_Start() ;

}

void clock_pulse(uint16_t delay)

{   

    Control_Reg_Write(1) ;

    CyDelay(delay) ;

    Control_Reg_Write(0) ;

    CyDelay(delay) ;  

}

int main(void)

{

    uint8_t led1_pattern = 0 ;

    uint8_t current_value ;

    int led_num = 1 ;

    int i ;

   

    init_hardware() ;

   

    splash("CY8CKIT-059 ShiftRegister Test") ;

   

    led1_pattern = make_led_reg_value(led_num) ;

    snprintf(str, STR_BUF_LEN, "Pattern for LED %d : ", led_num) ;

    print(str) ;

    print_as_bin8(led1_pattern) ;

    print("\n\r") ;

   

    clock_pulse(500) ; /* one dummy cycle */ 

   

    for(;;)

    {   

        ShiftReg_WriteRegValue(led1_pattern) ;

//       clock_pulse(500) ; /* one dummy cycle */   

       

        for (i = 0 ; i < SHIFT_REG_WIDTH ; i++ ) {

            current_value = ShiftReg_ReadRegValue() ;

            print_as_bin8(current_value) ;

            clock_pulse(500) ; /* shift 1 bit */

        }

        print("\n") ;

        CyDelay(1000) ; /* wait 1 sec */

    }

}

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

moto

0 件の賞賛

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

とても丁寧に記述いただいて本当に助かります。

おかげさまで、teratermで通信してみたところ動作していることが確認できました。

20200507_teraterm.png

ただ、LEDの方はオシロで確認したところ、ON時間1秒、周期5秒で点灯する動作を繰り返しているようで、

ON・OFFをしているようにみえません。

20200507_osi.png

print_as_bin8関数にLEDON・OFFの記述を加えればよいでしょうか?

お忙しいところすみません。ご回答いただけますと幸いです。

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

こんにちは、

サンプルは目で確認できるようにと、ずいぶん遅い設定で作成してありました。

CyDelay(1000) で一秒の遅延になりますので、オシロで動作確認は難しいと思い

新たにオシロのトリガ用に Trigger という出力ピンを設けて実験をしてみました。

また、一秒/パルスではオシロでトリガをかけるのが辛かったので、

half_pulse という変数で1/2パルスの幅を ms 単位で指定するようにしました。

010-schematic.JPG

011-pins.JPG

LED_1 はピン P2[1], Trigger は P2[0] に割り当ててあります。

あわせて main.c も for(;;) ループの最初で Trigger_Write(1) を行い、

シフトが終了した時点で Trigger_Write(0) を行うようにしてみました。

実験をして分かったのですが、

ShiftReg_WriteRegValue(led1_pattern) を行った時点で

最初のビットの値は出力され始めますので、

ここでも他のビットと同じだけ遅延を与えないと

最初のビットは一瞬で終わってしまっていました。

        ShiftReg_WriteRegValue(led1_pattern) ;

        CyDelay(half_pulse * 2) ; // <== New

そして、main() 関数を下記の様に変更して実験をしました。

main() from main.c

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

int main(void)

{

    uint8_t led1_pattern = 0 ;

    uint8_t current_value ;

    int     half_pulse = 5 ; // <=== New

    int led_num = 1 ;

    int i ;

   

    init_hardware() ;

   

    splash("CY8CKIT-059 ShiftRegister Test") ;

   

    led1_pattern = make_led_reg_value(led_num) ;

    snprintf(str, STR_BUF_LEN, "Pattern for LED %d : ", led_num) ;

    print(str) ;

    print_as_bin8(led1_pattern) ;

    print("\n\r") ;

   

    clock_pulse(half_pulse) ; /* one dummy cycle */ 

   

    for(;;)

    {

        Trigger_Write(1) ;        // <== New

        ShiftReg_WriteRegValue(led1_pattern) ;

        CyDelay(half_pulse * 2) ; // <== New

       

        for (i = 0 ; i < SHIFT_REG_WIDTH ; i++ ) {

        current_value = ShiftReg_ReadRegValue() ;

            print_as_bin8(current_value) ;

            clock_pulse(half_pulse) ; /* shift 1 bit */

        }

        Trigger_Write(0) ;       // <== New

        print("\n") ;

        CyDelay(half_pulse * 2) ; /* wait 1 pulse */

    }

}

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

オシロの出力画面

IMG_4261.JPG

予定通り 1, 0, 0, 1, 0, 0, 0, 1, (0, 0) と表示されているかと思います。

( ) 内はプログラムの遅延時間の分部となります。

7-May-2020

moto

0 件の賞賛

ご丁寧にありがとうございます。

解決しました。

今後ともよろしくお願い致します。

すみません。

甘えついでにもう一点だけご教示ください。

今回教えていただいた回路で

クロックを最速にした場合

1パルスあたり何秒まで短縮できるものでしょうか。

よろしくお願い致します。

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

こんばんは、

> 1パルスあたり何秒まで短縮できるものでしょうか。

現在のサンプルではタイミング(遅延)に CyDelay() を使用しています。

これは ms 単位の遅延を起こしてくれる関数ですので、

最小値の 1 を入れた場合、2ms で 1パルスになります。

また、CyDelay() を CyDelayUS() と差し替えた場合

us の遅延管理になりますので、論理上 2us で 1パルスまでいけるのではないかと思います。

PSoC Creator のコンポーネントはコンフィグレーションダイアログ

もしくはコンポーネントカタログからデータシートを参照することが可能です。

例えば ShiftReg ですと、左下の [ Datasheet ] ボタンからデータシートを参照することができます。

021-shiftreg-datasheet.JPG

データシートの P18 AC Characteristics には下記のような記述がありますので、

52MHz まで対応しているようです。ざっくり 50MHz と考えた場合で 20ns.

また、GPIO もハイスピードモードでは 12ns で上り下りできるようですので、

併せて24ns +ハイレベルの期間+ローレベルの期間 ということになるので、

大雑把にみて 40~50ns のパルスは生成できるかも知れませんね。

その場合、ControlReg の代わりに 40~50MHz のクロックを接続することになるかと思います。

020-shiftreg_freq.JPG

moto

0 件の賞賛

ご回答いただきありがとうございます。

HWを活用すると相当速いクロックまで追従できるのですね。

魅力的です。

何度もすみません。

できると思ってやってみたのですが、時間が迫ってきてしまい、

ロジックICで作ってしまおうかの瀬戸際です。。。

大変申し訳ないのですが再度ご教示ください。

(便利なので何とか使いこなしたいのですが、まだよちよち歩きすぎです。)

最終的にやりたいのは、

周波数400Hz(2.5msec)の外部クロックの入力(今のControl_Reg_1のところに対し、

1ビットあたりおよそ312.5usec(=2.5msec/8ビット)幅の8ビットの

前述のLED点灯パターンをLED10個にて点灯させたい。

です。はじめから記述すべきでした。

教えていただいたCyDelayをCyDelayUsにしてhulf_pulse=20 (20usec)にしてみたのですが、

Trigger短くなったものの1ビット当たりの時間は7.8msecより短くなりません。

画像参照。黄色がトリガです。

どのようにすればよいでしょうか。(1LED分で大丈夫です。(と思います。)

main.cを載せます。

tek00007.png

以下 main.c.

#include "project.h"
#include "stdio.h"
#include "tty_utils.h"

#define SHIFT_REG_WIDTH 8

const uint32_t PATTERNS[] = {
//LED10 ------>LED1
  0b0101010101,
  0b1001100110,
  0b0001111000,
  0b1110000000,
  0b1111111111,
  0b0000000000,
  0b0000000000,
  0b1111111111,
};

uint8_t LED1_pattern = 0 ;

uint8_t make_led_reg_value(int led_num)
{
    uint8_t result = 0 ;
    int i ;
   
    for (i = 0 ; i < SHIFT_REG_WIDTH ; i++ ) {
        result <<= 1 ;
        if (PATTERNS & (0x01 << (led_num - 1))) {
            result |= 0x01 ;
        }
    }
    return(result) ;
}

void print_as_bin8(uint8_t value)
{
    uint8_t mask = 0x80 ;
    while(mask) {
        if (value & mask) {
            print("1") ;
        } else {
            print("0") ;
        }
        mask >>= 1 ;
    }
    print("\n") ;
}

void init_hardware(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */   
    tty_init() ;
    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 clock_pulse(uint16_t delay)
{   
    Control_Reg_1_Write(1) ;
    CyDelayUs(delay) ;
    Control_Reg_1_Write(0) ;
    CyDelayUs(delay) ;  
}

int main(void)
{
    uint8_t led1_pattern = 0 ;
    uint8_t led2_pattern = 0 ;
    uint8_t led3_pattern = 0 ;
    uint8_t led4_pattern = 0 ;
    uint8_t led5_pattern = 0 ;
    uint8_t led6_pattern = 0 ;
    uint8_t led7_pattern = 0 ;
    uint8_t led8_pattern = 0 ;
    uint8_t led9_pattern = 0 ;
    uint8_t led10_pattern = 0 ;
   
   
    uint8_t current_value_1 ;
    uint8_t current_value_2 ;
    uint8_t current_value_3 ;
    uint8_t current_value_4 ;
    uint8_t current_value_5 ;
    uint8_t current_value_6 ;
    uint8_t current_value_7 ;
    uint8_t current_value_8 ;
    uint8_t current_value_9 ;
    uint8_t current_value_10 ;
   
    int     half_pulse = 20 ; // <=== New
   
    int led_num_1 = 1 ;
    int led_num_2 = 2 ;
    int led_num_3 = 3 ;
    int led_num_4 = 4 ;
    int led_num_5 = 5 ;
    int led_num_6 = 6 ;
    int led_num_7 = 7 ;
    int led_num_8 = 8 ;
    int led_num_9 = 9 ;
    int led_num_10 = 10 ;
   
    int i ;
   
    init_hardware() ;
   
    splash("CY8CKIT-059 ShiftRegister Test") ;
   
    led1_pattern = make_led_reg_value(led_num_1) ;
    led2_pattern = make_led_reg_value(led_num_2) ;
    led3_pattern = make_led_reg_value(led_num_3) ;
    led4_pattern = make_led_reg_value(led_num_4) ;
    led5_pattern = make_led_reg_value(led_num_5) ;
    led6_pattern = make_led_reg_value(led_num_6) ;
    led7_pattern = make_led_reg_value(led_num_7) ;
    led8_pattern = make_led_reg_value(led_num_8) ;   
    led9_pattern = make_led_reg_value(led_num_9) ;
    led10_pattern = make_led_reg_value(led_num_10) ; 
   
    snprintf(str, STR_BUF_LEN, "Pattern for LED1 %d : \n\r", led_num_1) ;
    print_as_bin8(led1_pattern) ;
    snprintf(str, STR_BUF_LEN, "Pattern for LED2 %d : \n\r", led_num_2) ;
    print_as_bin8(led2_pattern) ;
    snprintf(str, STR_BUF_LEN, "Pattern for LED3 %d : \n\r", led_num_3) ;
    print_as_bin8(led3_pattern) ;
    snprintf(str, STR_BUF_LEN, "Pattern for LED4 %d : \n\r", led_num_4) ;
    print_as_bin8(led4_pattern) ;
    snprintf(str, STR_BUF_LEN, "Pattern for LED5 %d : \n\r", led_num_5) ;
    print_as_bin8(led5_pattern) ;
    snprintf(str, STR_BUF_LEN, "Pattern for LED6 %d : \n\r", led_num_6) ;
    print_as_bin8(led6_pattern) ;
    snprintf(str, STR_BUF_LEN, "Pattern for LED7 %d : \n\r", led_num_7) ;
    print_as_bin8(led7_pattern) ;
    snprintf(str, STR_BUF_LEN, "Pattern for LED8 %d : \n\r", led_num_8) ;
    print_as_bin8(led8_pattern) ;
    snprintf(str, STR_BUF_LEN, "Pattern for LED9 %d : \n\r", led_num_9) ;
    print_as_bin8(led9_pattern) ;
    snprintf(str, STR_BUF_LEN, "Pattern for LED10 %d : \n\r", led_num_10) ;
    print_as_bin8(led10_pattern) ;
    print(str) ;
    print("\n\r") ;
   
    clock_pulse(half_pulse) ; /* one dummy cycle */ 
   
    for(;;)
    {
        Trigger_Write(1) ;        // <== New
        Control_Reg_2_Write(0);   //store
        ShiftReg_1_WriteRegValue(led1_pattern) ;
        ShiftReg_2_WriteRegValue(led2_pattern) ;
        ShiftReg_3_WriteRegValue(led3_pattern) ;
        ShiftReg_4_WriteRegValue(led4_pattern) ;
        ShiftReg_5_WriteRegValue(led5_pattern) ;
        ShiftReg_6_WriteRegValue(led6_pattern) ;
        ShiftReg_7_WriteRegValue(led7_pattern) ;
        ShiftReg_8_WriteRegValue(led8_pattern) ;
        ShiftReg_9_WriteRegValue(led9_pattern) ;
        ShiftReg_10_WriteRegValue(led10_pattern) ;
       
        CyDelayUs(half_pulse * 2) ; // <== New
        Control_Reg_2_Write(1);   //release
       
        for (i = 0 ; i < SHIFT_REG_WIDTH ; i++ ) {
            current_value_1 = ShiftReg_1_ReadRegValue() ;
            current_value_2 = ShiftReg_2_ReadRegValue() ;
            current_value_3 = ShiftReg_3_ReadRegValue() ;
            current_value_4 = ShiftReg_4_ReadRegValue() ;
            current_value_5 = ShiftReg_5_ReadRegValue() ;
            current_value_6 = ShiftReg_6_ReadRegValue() ;
            current_value_7 = ShiftReg_7_ReadRegValue() ;
            current_value_8 = ShiftReg_8_ReadRegValue() ;
            current_value_9 = ShiftReg_9_ReadRegValue() ;
            current_value_10 = ShiftReg_10_ReadRegValue() ;
           
            print_as_bin8(current_value_1) ;
            print_as_bin8(current_value_2) ;
            print_as_bin8(current_value_3) ;
            print_as_bin8(current_value_4) ;           
            print_as_bin8(current_value_5) ;
            print_as_bin8(current_value_6) ;
            print_as_bin8(current_value_7) ;
            print_as_bin8(current_value_8) ;  
            print_as_bin8(current_value_9) ;
            print_as_bin8(current_value_10) ;

            clock_pulse(half_pulse) ; /* shift 1 bit */
        }
        Trigger_Write(0) ;       // <== New
        print("\n") ;
        CyDelayUs(half_pulse * 2) ; /* wait 1 pulse */
    }
}

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

こんにちは、

> はじめから記述すべきでした。

はい、これを伺っていたらまたお話は少し違っていたかも知れません。

とりあえず対策を考えてみようかと思いますが、

並行して一つだけ実験をしてみてはいただけないでしょうか?

それは、for(;;)  {} ブロック内にある全ての print_as_bin8() をコメントアウトすることです。

ご指定のレベルの時間精度になりますと UART への出力は難しくなります。

まず、print_as_bin8() を下記のようにコメントアウトした状態で

どこまで追い込めるかご確認いただきご教示いただけますとありがたいです。

//            print_as_bin8(current_value_1) ;

moto

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

こんにちは、

今、こちらで実験したところでは half_pulse を 1250 にして

CyDelay を CyDelayUs に置き換えたところ 2.5ms のパルスは実現できているようです。

IMG_4262.JPG

moto

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

蛇足になりますが、

     print_as_bin8(current_value_1) ;

をコメントアウトするということは

     current_value_1 = ShiftReg_1_ReadRegValue() ; 

も不要になりますので、for() 文は

        for (i = 0 ; i < SHIFT_REG_WIDTH ; i++ ) {

            clock_pulse(half_pulse) ; /* shift 1 bit */

        }

だけになってしまいますね。

moto

0 件の賞賛

すごいです。

動きました。

for() 文は

        for (i = 0 ; i < SHIFT_REG_WIDTH ; i++ ) {

            clock_pulse(half_pulse) ; /* shift 1 bit */

        }

だけになってしまいますね。

シンプルになりました。

おかげさまです。

ありがとうございました。

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

こんばんは、

その後、もう少し実験をしてみました。

外部から400Hz 間隔のパルスが入り、その間に8bit の LEDパターンを表示するということですので

ソフトで行うと少し煩雑になるかと思い PSoC 5LP 内のハードで実験をしてみました。

回路は

Sheet 1

左上の四角内は立ち上がりエッジ検出です。

右下の四角内はテスト用の 400Hz クロック生成器です。

031-schematic-1.JPG

Sheet2

ShiftReg が 10個ということでしたので、丁度昨日勉強をしていた Sheet Connector を使用して

別ページに分けてみました。このページにShiftReg_2 ~ ShiftReg_10 を置いても良いですし、

他のページに置いても良いと思います。

032-schematic2.JPG

Pins

CY8CKIT-059 で実験したときのピン配置です。

実験は P12[2] と P2[3] をジャンパ線でショートして行いました。

main.c

テストで LED のパターンを変えられるようにしたために

main() 内の for()  ループ内にコマンド読み込みが入っていますが、

10個同時運用時には不要となります。

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

#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,

};

uint8_t led_pattern[NUM_LED] = {

    0x89, /* 10001001 */

    0x49, /* 01001001 */

    0xC9, /* 11001001 */

    0x29, /* 00101001 */

    0xA9, /* 10101001 */

    0x69, /* 01101001 */

    0xE9, /* 11101001 */

    0x19, /* 00011001 */

    0x99, /* 10011001 */

    0x59  /* 01011001 */

} ;

   

uint8_t make_led_reg_value(int led_num)

{

    uint8_t result = 0 ;

    int i ;

   

    for (i = 0 ; i < SHIFT_REG_WIDTH ; i++ ) {

        result <<= 1 ;

        if (PATTERNS & (0x01 << (led_num - 1))) {

            result |= 0x01 ;

        }

    }

    return(result) ;

}

void print_as_bin8(uint8_t value)

{

    uint8_t mask = 0x80 ;

    while(mask) {

        if (value & mask) {

            print("1") ;

        } else {

            print("0") ;

        }

        mask >>= 1 ;

    }

    print("\n") ;

}

CY_ISR(timer_isr)

{

    isr_1_ClearPending() ;

    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]) ; 

}

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() ;

    PWM400Hz_Start() ;

}

void report_led_pattern(int led_num)

{

    if ((1 <= led_num) && (led_num <= NUM_LED)) {

        snprintf(str, STR_BUF_LEN, "LED pattern %d : ", led_num) ;

        print(str) ;       

        print_as_bin8(led_pattern[led_num - 1]) ;

    } else {

        print("Invalid LED Number") ;

    }

}

int main(void)

{

    init_hardware() ;

       

    splash("CY8CKIT-059 ShiftRegister Test") ;

    report_led_pattern(led_num) ;

           

    print("To change pattern enter 1 .. 10\n\r") ;

    prompt() ;

    for(;;)

    {

        if (get_line()) {

            sscanf(str, "%d", &led_num) ;

            report_led_pattern(led_num) ;

            prompt() ;

        }

    }

}

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

Tera Term log

下記のようにプロンプト "> " に実験したい LED の番号 1 ~ 10 を入力すると

その LED のパターンで表示するようになります。

030-TeraTerm-log.JPG

LED1 のパターン

IMG_4263.JPG

LED2 のパターン

IMG_4264.JPG

以下省略

moto

0 件の賞賛

無事動きました。

わかりやすい記述で勉強になります。

こういう風に書けるといいんですが。。。。

ありがとうございます。