ステップ7

シリアル通信

SCI(シリアルコミュニケーションインターフェース)とは?

 1ビットずつ逐次的にデータを送ることをシリアル通信(SCI)といいます。実際に1秒毎にカウントアップを行い、カウント値をLEDへ2進出力すると同時に、SCIを通して、PC側のシリアル通信端末へカウントを10進出力をしてみましょう。
 通信は調歩同期式(非同期式)で行います。

調歩同期式(非同期式)とクロック同期式

 調歩同期式(非同期式)とは、データの先頭にスタートビットとデータの末尾にストップビットを付け加えて送受信を行うことです。クロック同期式とは、クロック周波数と信号が一緒に送られ、クロックの立ち上がりまたは立ち下がりのときデータを送受信することです。

図7-1 クロック同期式と調歩同期式

SCIプログラム

●main.c

#include "iodefine.h"
#include "intrinsics.h"
#include "sci.h"

#ifdef CPPAPP
//Initialize global constructors
extern "C" void __main()
{
  static int initialized;
  if (! initialized)
    {
      typedef void (*pfunc) ();
      extern pfunc __ctors[];
      extern pfunc __ctors_end[];
      pfunc *p;

      initialized = 1;
      for (p = __ctors_end; p > __ctors; )
	(*--p) ();

    }
}
#endif 

unsigned char	count;      // カウンタ
unsigned char	count_sub;	// カウントサブカウンタ
unsigned char buff[64];

void initIO(void){
	P1.DDR = 0xff;
	P2.DDR = 0xff;
	P3.DDR = 0xff;
	P4.DDR = 0xff;
	P5.DDR = 0xff;
	P6.DDR = 0xf0;
	P8.DDR = 0xff;
	P9.DDR = 0xff;
	PA.DDR = 0xff;
	PB.DDR = 0xff;

	count = count_sub = 0;
}

void initITU(void){
	set_imask_ccr(1);		// 割込み禁止
	ITU0.TCR.BIT.CCLR = 1;	// GRAコンペアマッチ-->TCNTクリア
	ITU0.TCR.BIT.CKEG = 0;	// 立ち上がりエッジでカウント
	ITU0.TCR.BIT.TPSC = 2;	// 分周比  0:φ 1:φ/2 2:φ/4 3:φ/8
	ITU0.TCNT = 0;
	ITU0.GRA = 62499;		// 1/100秒でコンペアマッチ
	ITU0.TSR.BIT.IMFA = 0;	// フラグクリア
	ITU0.TIER.BYTE = 1;		// コンペアマッチA-->割込み
	ITU.TSTR.BYTE = 1;		// ITU0 START
	set_imask_ccr(0);		// 割込み許可
}

int main(void)
{
	initIO();
	P1.DR.BYTE = ~count;
	initITU();
	initSCI();

    while (1) {
    }
    return 0;
}

/*
 * 1/100秒 = 10ms間隔でコールされる。
 */
void onTimer(void){
	count_sub++;
	if (count_sub >= 100){
		count_sub = 0;
		count++;
		P1.DR.BYTE = ~count;
		sprintf(buff, "count = %d\n", count); //buffに書き込む
		sci_puts(buff);			   //出力
	}
}

●inthandler.c

#include "inthandler.h"
#include "iodefine.h"

void INT_IMIA0(void) {
	ITU0.TSR.BIT.IMFA = 0; // フラグクリア
	onTimer();
}

●sci.c

#include "iodefine.h"
#include "sci.h"


void sci_putc(unsigned char ch){
	while (SCI1.SSR.BIT.TDRE == 0)
		;
	SCI1.TDR = ch;
	SCI1.SSR.BIT.TDRE = 0;
}

void sci_puts(unsigned char *s){
	while (*s){
		if (*s == '\n')
			sci_putc('\r');
		sci_putc(*s++);
	}
}

unsigned char sci_read(void){
	unsigned char	c;
	if ( (SCI1.SSR.BYTE & 0x78) == 0 )
		return '\0';	// 入力なし

	if (SCI1.SSR.BIT.RDRF == 1){
		c = SCI1.RDR;
		SCI1.SSR.BIT.RDRF = 0;
		return c;
	}
	SCI1.SSR.BYTE &= 0x87;	// エラーフラグクリア
	return -1;
}

void initSCI(void){
	SCI1.SCR.BIT.TE = 0;	// 送信無効
	SCI1.SCR.BIT.RE = 0;	// 受信無効
	SCI1.SCR.BIT.CKE = 0;	// クロックソース:内部クロック
	SCI1.SMR.BYTE = 0;	// 調歩, キャラクタ8, パリティナシ, ストップ1, クロックφ
	SCI1.BRR = 80;		// 9600baud
	SCI1.SSR.BYTE &= 0x87;	// フラグクリア
	SCI1.SCR.BIT.TE = 1;	// 送信有効
	SCI1.SCR.BIT.RE = 1;	// 受信有効
}

●sci.h

#ifndef SCI_H_
#define SCI_H_

void initSCI(void);
void sci_putc(unsigned char ch);
void sci_puts(unsigned char *s);
unsigned char sci_read(void);

#endif

Tera Term

Tera Termを起動します。

SCI完成写真

このように1秒間に1回カウントしていきます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です