- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- Permalink
- 印刷
- 不適切なコンテンツを報告
おしえてください。初心者です。
CY8CKIT-059を使っています。
シフトレジスタを使ってLEDをチカチカさせようとしています。
LEDの個数は10個で8パターンをラッチクロック毎に点灯させたいです。
シフトレジスタを使って実現したいのですが、使い方がよくわからず難儀しています。
初めてPsocにチャレンジしたのですが、HWの方がよくわかりません。
// 点灯パターン(1=点灯, 0=消灯)
const uint32_t PATTERNS[] = {
//LED10 ------>LED1
0b0101010101
0b1001100110,
0b0001111000,
0b1110000000,
0b1111111111,
0b0000000000,
0b0000000000,
0b1111111111,
};
よろしくお願いします。
解決済! 解決策の投稿を見る。
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- Permalink
- 印刷
- 不適切なコンテンツを報告
こんばんは、
私も 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 のパターンも見えるかと思いますが、実は実験していません。 (^ ^;
TeraTerm の画面
※ 一サイクル目の出力が 00000000 と表示されるのですが、LEDはちゃんと点灯していました。
回路図
ピン
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
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- Permalink
- 印刷
- 不適切なコンテンツを報告
こんばんは、
私も 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 のパターンも見えるかと思いますが、実は実験していません。 (^ ^;
TeraTerm の画面
※ 一サイクル目の出力が 00000000 と表示されるのですが、LEDはちゃんと点灯していました。
回路図
ピン
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
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- Permalink
- 印刷
- 不適切なコンテンツを報告
ご回答ありがとうございます。
とても丁寧に記述いただいて本当に助かります。
おかげさまで、teratermで通信してみたところ動作していることが確認できました。
ただ、LEDの方はオシロで確認したところ、ON時間1秒、周期5秒で点灯する動作を繰り返しているようで、
ON・OFFをしているようにみえません。
print_as_bin8関数にLEDON・OFFの記述を加えればよいでしょうか?
お忙しいところすみません。ご回答いただけますと幸いです。
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- Permalink
- 印刷
- 不適切なコンテンツを報告
こんにちは、
サンプルは目で確認できるようにと、ずいぶん遅い設定で作成してありました。
CyDelay(1000) で一秒の遅延になりますので、オシロで動作確認は難しいと思い
新たにオシロのトリガ用に Trigger という出力ピンを設けて実験をしてみました。
また、一秒/パルスではオシロでトリガをかけるのが辛かったので、
half_pulse という変数で1/2パルスの幅を ms 単位で指定するようにしました。
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 */
}
}
==================
オシロの出力画面
予定通り 1, 0, 0, 1, 0, 0, 0, 1, (0, 0) と表示されているかと思います。
( ) 内はプログラムの遅延時間の分部となります。
7-May-2020
moto
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- Permalink
- 印刷
- 不適切なコンテンツを報告
ご丁寧にありがとうございます。
解決しました。
今後ともよろしくお願い致します。
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- Permalink
- 印刷
- 不適切なコンテンツを報告
すみません。
甘えついでにもう一点だけご教示ください。
今回教えていただいた回路で
クロックを最速にした場合
1パルスあたり何秒まで短縮できるものでしょうか。
よろしくお願い致します。
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- Permalink
- 印刷
- 不適切なコンテンツを報告
こんばんは、
> 1パルスあたり何秒まで短縮できるものでしょうか。
現在のサンプルではタイミング(遅延)に CyDelay() を使用しています。
これは ms 単位の遅延を起こしてくれる関数ですので、
最小値の 1 を入れた場合、2ms で 1パルスになります。
また、CyDelay() を CyDelayUS() と差し替えた場合
us の遅延管理になりますので、論理上 2us で 1パルスまでいけるのではないかと思います。
PSoC Creator のコンポーネントはコンフィグレーションダイアログ
もしくはコンポーネントカタログからデータシートを参照することが可能です。
例えば ShiftReg ですと、左下の [ Datasheet ] ボタンからデータシートを参照することができます。
データシートの P18 AC Characteristics には下記のような記述がありますので、
52MHz まで対応しているようです。ざっくり 50MHz と考えた場合で 20ns.
また、GPIO もハイスピードモードでは 12ns で上り下りできるようですので、
併せて24ns +ハイレベルの期間+ローレベルの期間 ということになるので、
大雑把にみて 40~50ns のパルスは生成できるかも知れませんね。
その場合、ControlReg の代わりに 40~50MHz のクロックを接続することになるかと思います。
moto
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- Permalink
- 印刷
- 不適切なコンテンツを報告
ご回答いただきありがとうございます。
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を載せます。
以下 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 */
}
}
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- Permalink
- 印刷
- 不適切なコンテンツを報告
こんにちは、
> はじめから記述すべきでした。
はい、これを伺っていたらまたお話は少し違っていたかも知れません。
とりあえず対策を考えてみようかと思いますが、
並行して一つだけ実験をしてみてはいただけないでしょうか?
それは、for(;;) {} ブロック内にある全ての print_as_bin8() をコメントアウトすることです。
ご指定のレベルの時間精度になりますと UART への出力は難しくなります。
まず、print_as_bin8() を下記のようにコメントアウトした状態で
どこまで追い込めるかご確認いただきご教示いただけますとありがたいです。
// print_as_bin8(current_value_1) ;
moto
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- Permalink
- 印刷
- 不適切なコンテンツを報告
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- Permalink
- 印刷
- 不適切なコンテンツを報告
蛇足になりますが、
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
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- Permalink
- 印刷
- 不適切なコンテンツを報告
すごいです。
動きました。
>
for() 文は
for (i = 0 ; i < SHIFT_REG_WIDTH ; i++ ) {
clock_pulse(half_pulse) ; /* shift 1 bit */
}
だけになってしまいますね。
シンプルになりました。
おかげさまです。
ありがとうございました。
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- Permalink
- 印刷
- 不適切なコンテンツを報告
こんばんは、
その後、もう少し実験をしてみました。
外部から400Hz 間隔のパルスが入り、その間に8bit の LEDパターンを表示するということですので
ソフトで行うと少し煩雑になるかと思い PSoC 5LP 内のハードで実験をしてみました。
回路は
Sheet 1
左上の四角内は立ち上がりエッジ検出です。
右下の四角内はテスト用の 400Hz クロック生成器です。
Sheet2
ShiftReg が 10個ということでしたので、丁度昨日勉強をしていた Sheet Connector を使用して
別ページに分けてみました。このページにShiftReg_2 ~ ShiftReg_10 を置いても良いですし、
他のページに置いても良いと思います。
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 のパターンで表示するようになります。
LED1 のパターン
LED2 のパターン
以下省略
moto
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- Permalink
- 印刷
- 不適切なコンテンツを報告
無事動きました。
わかりやすい記述で勉強になります。
こういう風に書けるといいんですが。。。。
ありがとうございます。