ARIES(STM32F103評価ボード)でタッチパネルを試してみる [ARM&Cortex-M3]
ダウンロードは🎥こちら
|
回路図の一部を拡大していますが、40pin FPCケーブルの一部にX軸方向、Y軸方向の端子が出ています。
このタッチパネルは抵抗膜方式で4線式です。抵抗値はX軸方向が600Ω以上、Y軸方向が100Ω以上です。
これをマイコンのポートでドライブし、反対側の軸に接続された端子の出力をADCで変換して読み込む訳です。
イメージとしては2枚目の回路図の感じでしょうか。指で押したところでX軸とY軸が短絡されます。
指で押された時の回路イメージが3枚目の回路図です。例えばX軸方向で中心が押されると、大体300Ωずつに分割されてY軸の抵抗膜に短絡しますので、XRにVCC、XLにGND、YDは600Ωよりも十分に大きな抵抗値のプルアップ抵抗を接続し、YUをADCに接続して変換結果を得ます。
実際には抵抗値は公称値に過ぎないので何等かの方法でキャリブレーションが必要になってくると思います。
運用するならキャリブレーション画面を表示して何箇所かポイントしてその位置のADC変換値を得て、まあSTM32Fのデータ用フラッシュ領域にでも書き込むと言うのが大体の流れでしょうね。
/*************************************************************************/ /* ARIES rev.2 */ /*************************************************************************/ void aries_rev2( void ) { #define __X_MAX__ 3808 #define __X_MIN__ 258 #define __Y_MAX__ 2099 #define __Y_MIN__ 365 int i,j,k,r; int pos_x,pos_y; unsigned short x,y; DrawForm df; static const struct { int x; int y; } xy[] = { {99, 29}, {422,88}, {477,106}, {69 ,122}, {160,69}, {153,125}, {361,37}, {123,53}, {128,147}, {175,194}, {154,224}, {235,127}, {402,96}, {432,4}, {338,7}, {265,169}, {206,62}, {96 ,80}, {439,203}, {413,196}, {244,169}, {332,41}, {338,74}, {440,127}, {473,93}, {140,257}, {274,27}, {396,234}, {231,225}, {186,80}, {399,238}, {366,66}, }; static const unsigned short plt[] = { WHITE, // BLACK, GREY, LIGHTGREY, RED, GREEN, BLUE, YELLOW, SAXEBLUE, MAGENTA, DARKRED, DARKYELLOW, DARKGREEN, DARKSAXEBLUE, DARKBLUE, DARKMAGENTA, }; /*背景色=white*/ // BG_Set( 0, X_MAX_PIXEL, 0, Y_MAX_PIXEL, BLACK ); /*シャトル*/ PutPics( 0, shuttle_Width, 0, shuttle_Height, shuttle_BMPTable ); TouchPanel_Init(); for( j = 0, pos_x = pos_y = 4095;; ) { for( i = 0; i < sizeof(xy) / sizeof(xy[0]); i++ ) { for( r = 1; r < Y_MAX_PIXEL / 2; r += 4 ) { #if 0 DrawCircle( xy[i].x, xy[i].y, r, plt[ j ] ); DrawCircle( xy[i].x, xy[i].y, r + 1, plt[ j ] ); DrawCircle( xy[i].x, xy[i].y, r + 2, plt[ j ] ); DrawCircle( xy[i].x, xy[i].y, r + 3, plt[ j ] ); #else if( pos_x >= 0 && pos_x < X_MAX_PIXEL && pos_y >= 0 && pos_y < Y_MAX_PIXEL ) { DrawCircle( pos_x, pos_y, r, plt[ j ] ); DrawCircle( pos_x, pos_y, r + 1, plt[ j ] ); DrawCircle( pos_x, pos_y, r + 2, plt[ j ] ); DrawCircle( pos_x, pos_y, r + 3, plt[ j ] ); } #endif // BG_Set( 0, X_MAX_PIXEL, 0, Y_MAX_PIXEL, BLACK ); // PutPics( 0, shuttle_Width, 0, shuttle_Height, shuttle_BMPTable ); PutPics( 0, shuttle_Width, 0, shuttle_Height - 60, shuttle_BMPTable ); // Wait17ms( 4 ); } if( ++j >= sizeof(plt) / sizeof(plt[0]) ) j = 0; /*xとyの移動平均を求める*/ for( k = 0,x = 0; k < sizeof(ave_x_tbl) / sizeof(ave_x_tbl[0]); k++ ) { if( ave_x_tbl[ k ] >= 3900 ) { x = 4095 * 16; break; } x += ave_x_tbl[ k ]; } x >>= 4; for( k = 0,y = 0; k < sizeof(ave_y_tbl) / sizeof(ave_y_tbl[0]); k++ ) { if( ave_y_tbl[ k ] >= 3900 ) { y = 4095 * 16; break; } y += ave_y_tbl[ k ]; } y >>= 4; FourNineDisplay( (480 / 2) - 10 - (38 * 4), 272 - 60, x ); FourNineDisplay( (480 / 2) + 10, 272 - 60, y ); pos_x = ((__X_MAX__ - x) * 10) / (((__X_MAX__ - __X_MIN__) * 10) / X_MAX_PIXEL); pos_y = ((__Y_MAX__ - y) * 10) / (((__Y_MAX__ - __Y_MIN__) * 10) / Y_MAX_PIXEL); IWDG_WriteAccessCmd( 0xaaaa ); /*IWDG延長*/ } } } /*************************************************************************/ /* タッチパネルのADC初期化 */ /*************************************************************************/ void TouchPanel_Init( void ) { /*ADC1へクロックの供給開始*/ RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1, ENABLE ); RCC_APB2PeriphResetCmd( RCC_APB2Periph_ADC1, DISABLE ); RCC->CFGR |= (3 << 14); /*PCLK2を8分周*/ if( !(ADC1->CR2 & 0x00000001) ) ADC1->CR2 |= 0x00000001; /*ADON*/ ADC1->CR2 |= 0x00000004; /*較正開始*/ while( ADC1->CR2 & 0x00000004) ; /*較正完了待ち*/ ADC_Calibration_Value = ADC1->DR; /*較正値の読み出し*/ ADC1->CR2 |= (7 << 17); /*ソフトウエア変換を選択*/ ADC1->SMPR2 = 3 << 0; /*サンプリングタイミング=28.5サイクル*/ ADC1->SQR1 = (0 << 20); /*レギュラー変換グループの項目数=1*/ } /*************************************************************************/ /* タッチパネルのX側の読み出し */ /* PC0(IN10)がUP、PC1(IN11)がDOWN、PC2(IN12)がRIGHT、PC3(IN13)がLEFT。 */ /*************************************************************************/ unsigned short TouchPanel_X_Read( void ) { volatile unsigned short temp; LEFT_HI; /*左端をHI、右端をLOとする*/ RIGHT_LO; GPIO_Terminal_Init( GPIOC, GPIO_Speed_2MHz, GPIO_Mode_Out_PP, GPIO_Pin_3 | GPIO_Pin_2 ); /*RIGHTとLEFTを出力に*/ GPIO_Terminal_Init( GPIOC, GPIO_Speed_2MHz, GPIO_Mode_AIN, GPIO_Pin_0 ); /*PC0(IN10)をアナログ入力に*/ GPIO_Terminal_Init( GPIOC, GPIO_Speed_2MHz, GPIO_Mode_IPU, GPIO_Pin_1 ); /*PC1をプルアップ付き入力に*/ PC_ODR |= 0x0002; ADC1->SQR3 = (10 << 0); /*ADC10の変換位置*/ ADC1->CR2 |= (1 << 22); /*ソフトウエア変換開始*/ ADC1->CR2 |= 0x00000001; /*ADON*/ while( !(ADC1->SR & 0x00000002) ) ; /*変換完了待ち*/ temp = ADC1->DR - ADC_Calibration_Value; /*変換完了後の読み出し*/ /*2回行う*/ ADC1->CR2 |= (1 << 22); /*ソフトウエア変換開始*/ ADC1->CR2 |= 0x00000001; /*ADON*/ while( !(ADC1->SR & 0x00000002) ) ; /*変換完了待ち*/ temp = ADC1->DR - ADC_Calibration_Value; /*変換完了後の読み出し*/ RIGHT_LO; /*電気食うので電圧の印加を停止*/ LEFT_LO; return temp & 0x0fff; } /*************************************************************************/ /* タッチパネルのY側の読み出し */ /* PC0(IN10)がUP、PC1(IN11)がDOWN、PC2(IN12)がRIGHT、PC3(IN13)がLEFT。 */ /*************************************************************************/ unsigned short TouchPanel_Y_Read( void ) { volatile unsigned short temp; UP_HI; /*上端をHI、下端をLOとする*/ DOWN_LO; GPIO_Terminal_Init( GPIOC, GPIO_Speed_2MHz, GPIO_Mode_Out_PP, GPIO_Pin_1 | GPIO_Pin_0 ); /*UPとDOWNを出力に*/ GPIO_Terminal_Init( GPIOC, GPIO_Speed_2MHz, GPIO_Mode_AIN, GPIO_Pin_3 ); /*PC3(IN13)をアナログ入力に*/ GPIO_Terminal_Init( GPIOC, GPIO_Speed_2MHz, GPIO_Mode_IPU, GPIO_Pin_2 ); /*PC2をプルアップ付き入力に*/ PC_ODR |= 0x0004; ADC1->SQR3 = (13 << 0); /*ADC13の変換位置*/ ADC1->CR2 |= (1 << 22); /*ソフトウエア変換開始*/ ADC1->CR2 |= 0x00000001; /*ADON*/ while( !(ADC1->SR & 0x00000002) ) ; /*変換完了待ち*/ temp = ADC1->DR - ADC_Calibration_Value; /*変換完了後の読み出し*/ /*2回行う*/ ADC1->CR2 |= (1 << 22); /*ソフトウエア変換開始*/ ADC1->CR2 |= 0x00000001; /*ADON*/ while( !(ADC1->SR & 0x00000002) ) ; /*変換完了待ち*/ temp = ADC1->DR - ADC_Calibration_Value; /*変換完了後の読み出し*/ UP_LO; /*電気食うので電圧の印加を停止*/ DOWN_LO; return temp & 0x0fff; } /*************************************************************************/ /* TE割込みハンドラから呼ばれる。 */ /*************************************************************************/ void ARIES_GLCD_Int_Hdr( void ) { unsigned short x,y; static int wptr; x = TouchPanel_X_Read(); y = TouchPanel_Y_Read(); ave_x_tbl[ wptr ] = x; ave_y_tbl[ wptr ] = y; if( ++wptr >= sizeof(ave_x_tbl) / sizeof(ave_x_tbl[0]) ) wptr = 0; }
※タッチパネルを動かすのにELMさんのページを参考にさせて頂きました。
http://elm-chan.org/index_j.html
ARM Cortex‐M3システム開発ガイド―最新アーキテクチャの理解からソフトウェア開発までを詳解 (Design Wave Advance)
- 作者: Joseph Yiu
- 出版社/メーカー: CQ出版
- 発売日: 2009/05
- メディア: 単行本
ARM組み込みソフトウェア入門―記述例で学ぶ組み込み機器設計のためのシステム開発 (Design Wave Advanceシリーズ)
- 作者: Andrew N. Sloss
- 出版社/メーカー: CQ出版
- 発売日: 2007/08
- メディア: 単行本
2009-09-02 20:28
nice!(0)
コメント(0)
トラックバック(0)
コメント 0