PSoCで割り込みによりロータリーエンコーダーを2つ使う


psoc_int_encoder_01.gif
今回はPSoCに2つのロータリーエンコーダーとスイッチを接続し、それらの操作を割り込みにより検出する。ロータリーエンコーダーの回転量に応じて液晶モジュールに数値を表示、スイッチを押すと数値がゼロにクリアされるようにする。

psoc_int_encoder_02.gif
PSoC Designerを起動したらまず「Misc Digital」の「LCD」をダブルクリックしてプロジェクトに追加する。そして配線の設定画面に切り替えるため「Config」メニューの「Interconnect」を選択する。

psoc_int_encoder_03.gif
ここで「LCD_1」の「LCDPort」を「Port_2」にする。さらにポートの設定欄で
「Port_1_1」の「Drive」を「Pull Down」に「Interrupt」を「RisingEdge」に、(スイッチ用)
「Port_1_2」の「Drive」を「Pull Up」に「Interrupt」を「FallingEdge」に、(1つ目のロータリーエンコーダー用、A端子)
「Port_1_3」の「Drive」を「Pull Up」に、(1つ目のロータリーエンコーダー用、B端子)
「Port_1_6」の「Drive」を「Pull Up」に「Interrupt」を「FallingEdge」に、(2つ目のロータリーエンコーダー用、A端子)
「Port_1_7」の「Drive」を「Pull Up」(2つ目のロータリーエンコーダー用、B端子)にする。

psoc_int_encoder_04.gif
ポートの設定をよく確認して「View」メニューの「Application Editor」で画面を切り替える。

psoc_int_encoder_05.gif
まず割り込みのプログラミングに必要なソースコードを自動生成させるためビルドする。「Build」メニューの「Build」を選択すればいい。

psoc_int_encoder_06.gif
そして「Library Source」の「psocgpioint.asm」ファイル中の「PSoC_GPIO_ISR:」の後ろに「ljmp _GPIO_INT」の行を追加する。

psoc_int_encoder_07.gif
さらに「Source Files」の「main.c」の中にメイン処理を記述する。今回は簡単に実現するため、どのポートに対して割り込みが発生したのかの判断処理は省いた。そのためロータリーエンコーダーを2つ同時に回転させたときなど意図しない動作をすることがあり得る。流用の際は注意してほしい。


//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------

#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules

#include "stdlib.h"

#define SW_1_PORT PRT1DR
#define SW_1_A 0x04
#define SW_1_B 0x08

#define SW_2_PORT PRT1DR
#define SW_2_A 0x40
#define SW_2_B 0x80

int g_nCount1;
int g_nCount2;


void PrintCount(void)
{
char pszBuff[6];

itoa(pszBuff,g_nCount1,10);
LCD_1_Position(0,0);
LCD_1_PrCString("A: ");
LCD_1_PrString(pszBuff);
LCD_1_PrCString(" ");

itoa(pszBuff,g_nCount2,10);
LCD_1_Position(1,0);
LCD_1_PrCString("B: ");
LCD_1_PrString(pszBuff);
LCD_1_PrCString(" ");
}


#pragma interrupt_handler GPIO_INT
void GPIO_INT(void)
{
if((SW_1_PORT & SW_1_A) == 0)
{
if(SW_1_PORT & SW_1_B)
g_nCount1--;
else
g_nCount1++;
PrintCount();
}

if((SW_2_PORT & SW_2_A) == 0)
{
if(SW_2_PORT & SW_2_B)
g_nCount2--;
else
g_nCount2++;
PrintCount();
}

if(PRT1DR & 0x02)
{
g_nCount1 = 0;
g_nCount2 = 0;
PrintCount();
}
}


void main()
{
LCD_1_Start();
SW_1_PORT |= SW_1_A | SW_1_B; //Enable Pull-UP
SW_2_PORT |= SW_2_A | SW_2_B; //Enable Pull-UP

g_nCount1 = 0;
g_nCount2 = 0;
PrintCount();

M8C_EnableGInt;
M8C_EnableIntMask(INT_MSK0, INT_MSK0_GPIO);

while(1)
{
}
}





_DSC9078.JPG
1つ目のロータリーエンコーダーのA端子とB端子をそれぞれをポート12とポート13に、2つ目をポート16とポート17に、基板上のスイッチようのSW端子をポートポート11に接続する。

_DSC9079.JPG
これでmain処理は「while(1){}」という空の無限ループにも関わらず、ロータリーエンコーダーを回転させると数値が変わり、スイッチによりリセットできた。

トラックバック

この一覧は、次のエントリーを参照しています: PSoCで割り込みによりロータリーエンコーダーを2つ使う:

» PSoCでUSBマウスを作る 送信元 dinop.com
今回はUSB機能を内蔵したPSoC「CY8C24794-24LFXI」を利用し... [詳しくはこちら]


カテゴリー「電子工作」 のエントリー