[Top]
AVR - テストボード
・書き込みボード
前回作成した書き込みボードに手を加え,多少のテストできるようにしました.
Fig. 1に改良した基板を示します.
Fig. 1 書き込み兼テスト用ボード
Fig. 1 書き込み兼テスト用ボード

・ボード仕様
私の使用しているAT90S2313には,8本のBポートと7本のポートDがあります.
15本のI/Oポートのうち特別な機能を持ったポートがいくつかありますが, まずは単純なことからしていきます.
以下に,テストボードのポート仕様を示します.
表. 1 書き込み兼テスト用ボードのポート仕様

・ポートB = 0,1,2,3,4,5,6,7の全てがLアクティブのLED出力.
・ポートD
 1)PD2がLアクティブのスイッチ.
 2)PD6がLアクティブのLED出力.


PD2ポートには,割り込み機能INT0があります.スイッチ入力を検出し割り込み処理を行いたい場合,
このポートを利用します.他にもアイデア次第で色々と用途が生まれると思います.
他のポートも,それぞれ特別な機能が割り当てられています.詳しくはデータシートを見れば分かります.
・テストプログラム
ここでは,このボードをターゲットにしたプログラムを紹介します.
設計仕様は,以下の通りです.
表. 2 テストプログラム仕様

・ポートBのLED列を色々なパターンで表示する.
・表示パターン
 1)左から右に流れる.
 2)右から左に流れる.
 3)両側から中央に往復表示.
 4)LED表示が徐々に明るくなってくる(PWM)
・スイッチを押すことで表示パターンが切り替わる.


この,プログラムを以下に示します.test.zip[main.c/makefile]
Programmers Notepad [WinAVR]で作成し,WinAVRでコンパイルしています.
ソース中の sbi cbi の定義は,s.h.logを参考にさせていただきました.
ソースにコメントを入れているので,C言語プログラムをやったことがある人ならすぐに理解できると思います.
簡単に理解できると思います.私自身も初心者なのでややこしい処理はしていません.
表. 3 テストプログラム

/*-------------------------------------------------------------
AVR 書き込みテストボード用ファームウェア
割り込み処理テスト

PortBは全てLED、Lで点灯(Lowアクティブ)
PortD6はLED、Lで点灯
PortD2はSwに接続、押した状態でL、 割り込みINT0ポート
-------------------------------------------------------------*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

//sbi  cbi をC言語で感覚的に使えるように…。
#define sbi(PORT,BIT) PORT|=_BV(BIT) // PORTの指定BITに1をセット
#define cbi(PORT,BIT) PORT&=~_BV(BIT) // PORTの指定BITをクリア


static char g_type;
//-------------------------------------------------------------
//プロトタイプ宣言
//-------------------------------------------------------------
static void wait(unsigned char);
static void LtoR(void);
static void RtoL(void);
static void CtoW(void);
void PWM(void);

//-------------------------------------------------------------
//外部割り込み INT0設定
//-------------------------------------------------------------
void interrupt0_init(void)
{
	cbi(DDRD, PD2); //INT0を入力にセット
	sbi(GIMSK, INT0); //一般割り込みマスクレジスタ(GIMSK)のINT0(外部割り込み0)を1にして割り込み許可
	sbi(MCUCR, ISC01);//INT0 割り込み条件設定
	cbi(MCUCR, ISC00); // INT0立ち下がりエッジ検出に設定
//	sbi(MCUCR, ISC00); // INT0立ち上がりエッジ検出に設定
	return;
}
//-------------------------------------------------------------
//メイン関数
//-------------------------------------------------------------
int main(void)
{
	//ポートIO設定
	DDRB = 0xFF;//Bポート OOOO OOOO
	DDRD = 0x40;//Dポート xOII IIII
	//ポート出力
	PORTB = 0xFF;//Port_B Out HHHH HHHH
	PORTD = 0x44;//Port_D Out xH__ _U__  H:出力1 L:出力0 U:内蔵プルアップ D:

	//ポートD2 INT0割り込み設定
	interrupt0_init();
	
	sei();//割り込み許可
	
	g_type = 0;
	
	while(1)
	{
		switch(g_type)
		{
			case 0:
				LtoR();
				break;
			case 1:
				RtoL();
				break;
			case 2:
				CtoW();
				break;
			case 3:
				PWM();
				break;
			default:
				g_type = 0;
				break;
		}
	}

	return 0;
}

//-------------------------------------------------------------
//左から右に流れる
//-------------------------------------------------------------
static void LtoR(void)
{
	static char c = 0x01;//static じゃないと変数の値が毎回初期化される。

	//LEDへ出力
	PORTB = ~c;//Lアクティブなので反転

	c = c  << 1;

	if( c == 0x00 )
		c = 0x01;

	wait(0xFF);

	return;
}
//-------------------------------------------------------------
//右から左に流れる
//-------------------------------------------------------------
static void RtoL(void)
{
	static char c = 0x80;//static じゃないと変数の値が毎回初期化される。

	//LEDへ出力
	PORTB = ~c;//Lアクティブなので反転
 
	c = (c >> 1) & 0x7F;

	if( c == 0x00 )
		c = 0x80;

	wait(0xFF);

	return;
}
//-------------------------------------------------------------
//中心とサイド往復
//-------------------------------------------------------------
static void CtoW(void)
{
	char c[] = {0x18,0x24,0x42,0x81,0x42,0x24};
	static char n = 0;

	//LEDへ出力
	PORTB = ~c[n];//Lアクティブなので反転

	if( n < 5 )
		n++;
	else
		n = 0;

	wait(0xFF);

	return;
}
//-------------------------------------------------------------
//明暗PWM
//-------------------------------------------------------------
void PWM(void)
{
	static unsigned char i = 0xFF;
	static unsigned char j = 0xFF;

	if( 0 < i) i--;
	else
	{
		i = 255;
		if( 0 < j) j--;
		else
			j = 255;
	}
	
	if( i < j)
		PORTB = 0xFF;
	else
		PORTB = 0x00;
	
	wait(1);
	
	return;
}
//-------------------------------------------------------------
//ウェイト関数
//-------------------------------------------------------------
static void wait(unsigned char ucLoop)
{
	unsigned char i,j;
	for(i = 0;i < ucLoop;i++)
	{
		for(j = 1;j < 0xFF;j++)//unsigned char は最大0xFFのはず
		{
			j--;	/*dummy*/
			j++;	/*dummy*/
		}
	}
	return;
}
//-------------------------------------------------------------
//INT0 外部割り込み処理
//-------------------------------------------------------------
SIGNAL(SIG_INTERRUPT0)
{
	//
	g_type++;
}
//-------------------------------------------------------------


以上で簡単なプログラムと割り込み処理を理解できると思います.