ステップ7
シリアル通信
■SCI(シリアルコミュニケーションインターフェース)とは?
1ビットずつ逐次的にデータを送ることをシリアル通信(SCI)といいます。実際に1秒毎にカウントアップを行い、カウント値をLEDへ2進出力すると同時に、SCIを通して、PC側のシリアル通信端末へカウントを10進出力をしてみましょう。
通信は調歩同期式(非同期式)で行います。
■調歩同期式(非同期式)とクロック同期式
調歩同期式(非同期式)とは、データの先頭にスタートビットとデータの末尾にストップビットを付け加えて送受信を行うことです。クロック同期式とは、クロック周波数と信号が一緒に送られ、クロックの立ち上がりまたは立ち下がりのときデータを送受信することです。
■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回カウントしていきます。