新闻中心

EEPW首页>嵌入式系统>设计应用> 串行通信口SCI__HCS12学习笔记(2)

串行通信口SCI__HCS12学习笔记(2)

作者: 时间:2016-11-24 来源:网络 收藏
基本概念:

SCI采用NRZ数据格式,用负电平表示一种二进制值,正电平表示另一种二进制值,不使用零电平。空闲状态为1,发送器通过发送一个0表示一字节传输开始随后是数据位,最后发送1~2位的停止位,表示一字节的传送结束。一个开始位到一个停止位,为1帧Frame。

本文引用地址://m.amcfsurvey.com/article/201611/321072.htm

波特率有300、600、900、1200、1800、2400、4800、9600、19200、38400。随着波特率的提高,信号受干扰的程度也越大,因此,串行口的传输速率有限。

寄存器:

对于编程者来说,直接面对的就是寄存器,因此对于寄存器的介绍是非常重要的。

这里只列举,详细各个位的介绍参照数据手册:

波特率寄存器 SCIBDH SCIBDL H的高3位无效,因此一种13位1~8191

控制寄存器SCICR1 SCICR2 传输格式,中断使能

状态寄存器SCISR1 SCISR2 中断标志,发送与接收状态

数据寄存器收发的数据

初始化、收、发子函数:

//串行通信需要用到的头文件
#include "mc9s12dg128.h"//MCU映像寄存器名
#include "Type.h"//类型别名定义

//串行通信寄存器及标志位定义
#define ReSendStatusR SCI0SR1//SCI状态寄存器
#define ReTestBit5//接收缓冲区满标志位
#define SendTestBit7//发送缓冲区空标志位
#define ReSendDataRSCI0DRL//数据寄存器

//串行通信相关函数声明
void SCIInit(void);//串行口初始化函数声明
void SCISend1(INT8U o);//串行发送1个字节
void SCISendN(INT8U n,INT8U ch[]);//串行发送n个字节
INT8U SCIRe1(INT8U *p);//串行接收1个字节
INT8U SCIReN(INT8U n,INT8U ch[]);//串行接收n个字节

//特别声明,这里的INT8U表示8位无符号数

//[SCI.c]串行通信----------------------------------------------------------*
//本文件包含:*
//(1)SCIInit:串行口初始化*
//(2)SCISend1:串行发送1个字节*
//(3)SCISendN:串行发送n字节*
//(4)SCIRe1:串行接收1字节*
//(5)SCIReN:串行接收n字节*
//硬件连接:*
//MCU的SCI0模块接口与PC方的串行口相连*
//-------------------------------------------------------------------------*

//头文件
#include "SCI.h"//串行通信头文件

//SCIInit:DG128串行口0初始化函数-------------------------------------------*
//功能:*
//开SCI0关SCI1,关串口中断,对串行口进行初始化,默认为允许SCI,正常码输出*
//,8位数据,无校验等,允许发送器允许接收器.查询方式收发,波特率为9600*
//(设fBUS=19.6608Mhz)*
//参数:无*
//返回:无*
//说明:*
//(1)若初始化SCI1,只需SCI0->SCI1*
//(2)该初始化函数与芯片有关*
//-------------------------------------------------------------------------*
void SCIInit(void)
{
INT8U t;
//定义波特率Bt=9600,SCI0BD=fBUS/(16*Bt)
SCI0BDL = 0x80;//须先给低8位赋值
SCI0BDH = 0x00;//再给高8位赋值
SCI0CR1 = 0x00;//设置允许SCI,正常码输出,8位数据,无校验
t = SCI0DRL;//读数据寄存器(清0)
t = SCI0SR1;//读状态寄存器(清0)
SCI0CR2 = 0x0C;//允许SCI0接收和发送 查询方式
}

//SCISend1:串行发送1个字节-------------------------------------------------*
//功能:串行发送1个字节*
//参数:o=要发送的数据*
//返回:无*
//-------------------------------------------------------------------------*
void SCISend1(INT8U o)
{
//判断ReStatusR的第SendTestBit位是否为1,是1可以发送
while (1)
if ((ReSendStatusR & (1< {
ReSendDataR = o;
break;
}
}

//SCISendN:串行发送N个字节-------------------------------------------------*
//功能:发送数组中的N个字节数据*
//参数:n=待发送的数据字节数,ch=存放待发送数据的数组首地址*
//返回:无*
//内部调用函数:SCISend1*
//-------------------------------------------------------------------------*
void SCISendN(INT8U n,INT8U ch[])
{
INT8U i;
for (i=0; i SCISend1(ch[i]);
}

//SCIRe1:串行收一个字节数据------------------------------------------------*
//功能:从串行口接收1个字节的数据*
//参数:p=标志指针*
//返回:接收到的数据(若接收失败,返回0xff)*
//说明:参数*p带回接收标志=0收到数据,=1未收到数据*
//-------------------------------------------------------------------------*
INT8U SCIRe1(INT8U *p)
{
INT16U k;
INT8U i;
//ReStatusR第ReTestBit位为1表示可接收数据
for (k=0; k<0xfbbb; k++)
if ((ReSendStatusR & (1< {
i = ReSendDataR;
*p = 0x00;
break;
}
//接收失败
if (k >= 0xfbbb)
{
i=0xff;
*p=0x01;
}
return i;//返回接收到的数据
}

//SCIReN:HC08串行接收N个字节-----------------------------------------------*
//功能:接收N个字节数据,并存放在ch数组中*
//参数:n=待接收的数据字节数,ch=存放待接收数据的数组首地址*
//返回:接收标志=0收到数据,=1未收到数据*
//内部调用函数:SCIRe1*
//-------------------------------------------------------------------------*
INT8U SCIReN(INT8U n,INT8U ch[])
{
INT8U m;
INT8U fp;
m = 0;
//接收n个数据
while (m {
ch[m] = SCIRe1(&fp);
if (fp == 1) return 1;//只要有1个字节数据没接收到就返回报错
m++;
}
return 0;
}

这段程序是嵌入式系统--使用HCS12微控制器的设计与应用中附带的。格式很规范。

在计算机上使用软件收发给单片机时也容易出错,一般是波特率不匹配,这样出现的就是乱码,一定要注意。

Bt=fBUS/(16*BR)



评论


技术专区

关闭