SCI中断接收

SCI 是全双工异步串行通信接口,主要用于 MCU 与其他计算机或设备之间的通信,几个独立的 MCU也能通过 SCI 实现串行通信,形成网络。 MC9S12XS128里有两个SCI(SCI0和 SCI1) 。设计 SCI 串口通信程序,主要是掌握八个寄存器,设置好初始化。
SCI中断接收_第1张图片
以下为SCI相关寄存器:
SCIBDH, SCIBDL寄存器
SCI中断接收_第2张图片
IREN(红外调制模式使能位) = 1 时,使能
= 0 时,禁止

TNP[0:1]:窄脉冲发射位
SBR[0:12]:波特率设置位
IREN = 1 时,SCI baud rate = SCI bus clock / (16 x SBR[12:0])
IREN = 0 时,SCI baud rate = SCI bus clock / (32 x SBR[12:1])

SCIDRH, SCIDRL寄存器
SCI中断接收_第3张图片
SCI 内部分别设有发送和接收两个数据寄存器,其低位都通过 SCIDRL 访问,读操作返回接收数据寄存器 RDR 的内容,写操作数据置入发送数据寄存器TDR。当 M=1 即运行在 9 位数据模式时,SCIDRL 和 SCIDRH 形成 9 位的 SCI数据字,这时必须先写入 SCIDRH,以便与低位字节(SCIDRL)一起进入发送移 位器。如果 M=0 即 SCI 只用于 7 位或 8 位的数据传送,可以只访问 SCIDRL。 当 PE=1 即奇偶校验允许时,奇偶校验位由硬件负责,无需软件干预。
R8:接收到的位 8,该位写操作无效。当 SCI 设置成 9 位数据运行模式时,该位是从串行数据流中接收到的第 9 位。
T8:发送位 8,任何时候可写。当 SCI 设置成 9 位数据模式时,该位是送到串行 数据流的第 9 位。该位不必为每个数据重新设置,每次发送可重复使用。
R[0…7]T[0…7]:收/发数据位 7-0,读操作返回只读寄存器 RDR 的内容,写操 作写入只写寄存器 TDR。

SCICR1寄存器
在这里插入图片描述
LOOPS: 在LOOP模式下,RXD引脚与SCI接收部分断开,发射部分输出在内部和接收部分相连接,此时RXD可作为普通IO口,TXD输出SCI信号
= 1 时, LOOP模式使能
= 0 时, 正常模式

SCISWAI:等待模式下 SCI 停止位
= 1 时:在等待模式下禁止 SCI
= 0 时:在等待模式下允许 SCI

RSRC:接收器信号源选择位,当 LOOPS=1 时,RSRC 决定接收器的内部反馈信号路径
= 1 时,接收器的输入连接到 TxD 引脚
= 0 时,接收器的输入在内部连接到发送器输出(并非 TxD 引脚)

M:方式选择位(选择字符帧格式)
= 1 时,1 个起始位,8 个数据位,第 9 个数据位,1 个停止位
= 0 时,1 个起始位,8 个数据位,1 个停止位
WAKE:唤醒选择位。
= 1 时,地址标志(最后一个数据位为 1)唤醒
= 0 时,介质空闲唤醒

ILT:空闲检测方式选择位,该位在 SCI 接收器可以使用的两种空闲检测方式中 选择一种。
= 1 时,保守检测,SCI 在停止位后才开始对“1”计数,因此最后一个字节的停止位以及该位以前的各个为“广的位,对检测的时间长短无影响
= 0 时,快速检测,SCI 在一个帧的开始位后立即开始对“1”计数,因此停止位以及停止位前面的任何“1”均被计算在内,这样可以提前检测到空闲状态

PE:奇偶校验允许位。
= 1 时,允许奇偶校验
= 0 时,禁止奇偶校验

PT:奇/偶校验选择位,如果奇偶校验允许,该位决定收发器使用奇校验还是偶校验。
= 1 时,选择奇校验
= 0 时,选择偶校验

SCICR2寄存器
在这里插入图片描述
TIE: 发送中断允许位,清 0 时禁止 TDRE 产生中断,若置 1 则允许 TDRE 位置 1 时产生 SCI 中断请求
TCIE:发送结束中断允许位,清 0 时禁止 TC 产生中断,若置 1 则允许 TC 位置1 时产生SCI 中断请求
RIE:接收中断允许位,清 0 时禁止 RDRF 和 OR 产生中断,若置 1 则允许 RDRF或 OR 置 1 时产生 SCI 中断请求
ILIE:空闲中断允许位,清 0 时禁止 IDLE 产生中断,若置 1 则允许 IDLE 位置1 时产生 SCI 中断请求
TE:发送允许位。该位由 0 置 1 时可用来发送空闲报头
= 1 时, 允许 SCI 发送部分工作,TxD 引脚(PSl/PS3)用于发送。
= 0 时, 发送器禁止

RE:接收允许位
= 1 时, 允许 SCI 接收器工作。
= 0 时, 接收器禁止

RWU:接收器唤醒控制位
= 1 时,允许唤醒功能,禁止接收器中断。通常,硬件通过自动清除该位来唤醒接收器
= 0 时,SCI 接收器正常工作
SBK:中止符发送允许位。只要该位保持为 1,发送器就不停地发出“0”;如果 变为 0,当前的全“0”帧发送结束后,TxD 引脚将变成空闲状态。如果 SBK 开 关一次,发送器将只发出 10(11)个“0”,然后复原,处于空闲或发送数据状态
= 1 时, 产生中止符,至少 10 或 11 个连续的“0”
= 0 时, 中止符产生器关闭

SCISR1寄存器
SCI中断接收_第4张图片
TDRE: 发送保持器空标志位。发送前必须读 SCISR1,并确认 TDRE=1,然
后将新的数据写入发送保持器以开始发送过程。复位后该位为1
= 1 时,发送保持器的数据已被传送到发送移位器,这时可以向发送保持器写入
新的数据
= 0 时,SC0DR 处于忙状态

TC: 发送结束标志。该位在发送器空闲(无发送动作)时置位。读 SCISRl,然
后写 SCIDR将清除该位
= 1 时,发送器空闲
= 0 时,发送器忙

RDRF:接收数据就绪标志。当收到的字符已经在SCIDR中就绪时,RDRF置 1,
顺次读取 SCISRl 和 SCIDR将会自动清除 RDRF。该位被清除后,必须等到 RxD
线变为活动,然后重新变成空闲以后,IDLE位才会被再次置 1
= 1 时,SCIDR 中数据已就绪
= 0 时,SCIDR 空。

IDLE: 空闲标志。检测到接收器 RxD 端空闲(收到 10 或者 11 个以上连续的
“1”)。当 RWU 位为 1 时,空闲状态不会使该位置 1。该位被清除后,必须等
到 RDRF置位(RxD线变为活动,然后重新变成空闲),IDLE位才会被再次置 1。
= 1 时,RxD线空闲
= 0 时,RxD线活动

OR:重叠错误标志。如果接收数据寄存器中的数据尚未读取(RDRF=1),接受移
位寄存器又准备向其传送新的数据,则称为重叠错误,该位被置1。必须清除该
位,才能使新的数据进入接收数据寄存器
= 1 时,出现重叠错误
= 0 时,无重叠

NF:噪声错误标志。噪声错误出现时,该位与 RDRF 在同一个周器内置位,但
如果同时或已经出现重叠错误,该位不置位
=1 时,在起始位、数据位或停止位接收期间检测到噪声
= 0 时,采样结果一致

FE:帧格式错误。如果在应该出现停止位的时刻,检测到0,则该位置位。顺次
读取寄存器 SCISRl 和 SCIDR 将清除 FE标志
= 1 时,在预期的停止位处检测到 0
= 0 时,检测到停止位

PF:奇偶错误标志。指示收到数据的奇偶性与校验位是否一致。奇偶校验允许
(PE=1)时,该标志才有意义。所要求的奇偶性由 SC0CR1 中的 PT位决定
= 1 时,奇偶校验错误
= 0 时,奇偶校验正确

SCISR2寄存器
在这里插入图片描述
AMAP:另类地图该位控制寄存器共享相同的地址空间进行访问。在复位状况的SCI的行为与以前的版本。 AMAP= 1,允许访问另一套控制和状态寄存器和隐藏的波特率和SCI控制寄存器
TXPOL:发送极性该位控制传输数据的极性。 NRZ的格式,一个是代表一个标记和一个零代表为正极性空间,相反的极性相反。在IrDA格式,零代表在中间位时间由短而高的脉冲其余为正常的闲置低,在中间的一个为闲置高有点剩余时间短的低脉冲极性,是代表一个零极性反相。
= 1 时,极性相反
= 0 时,正常模式

RXPOL :接受极性
= 1 时,极性相反
= 0 时,正常模式

BRK13:中止符长度控制位
= 1 时,中止符长度为 13 或 14 位
= 0 时,中止符长度为 10 或 11 位

TXDIR:单线模式下发送管脚数据方向控制位
= 1 时,单线模式下 TxD 脚用于输出
= 0 时,单线模式下 TxD 脚用于输入

RAF:接收器活动标志位。反映接收器是否处于活动状态。在搜索起始位的RT1
期间该位置 1,当接收器器检测到空闲状态或者出现一个伪起始位(通常由于噪
声或波特率匹配错误引起)时,该位清0。该位由接收器前端控制

以下为SCI中断接收的完整代码:


#include            
#include "derivative.h"      

#define LED PORTB_PB0         //定义连接发光二级管的PORTB_PB0口数据寄存
                              //器为LED,写'0'亮,写'1' 灭
#define LED_dir DDRB_DDRB0    //定义连接发光二级管的PORTB_PB0口方向寄存器
                              //为LED_dir,写'0'做输入口,写'1'做输出口
#define LED_ON 0              //LED点亮
#define LED_OFF 1             //LED熄灭
#define BUS_CLOCK		   32000000	    //总线频率
#define OSC_CLOCK		   16000000	    //晶振频率
#define BAUD 9600                   //串口波特率

unsigned char data_receive;   //定义SCI接收数据变量


void INIT_PLL(void)          //初始化锁相环
{   
   
   CLKSEL_PLLSEL=0;	        //内部总线时钟来源于外部晶振
           
   PLLCTL_PLLON=0;  //关闭PLL

   SYNR=0x40 | 0x03; 	
   
   REFDV=0x80 | 0x01;
             
   POSTDIV=0x00;  //PLL为64MHz   

   PLLCTL_PLLON=1;  //打开PLL

   _asm(nop);         
   _asm(nop);       //执行2个机器周期
   while(CRGFLG_LOCK==0); //根据CRGFLG寄存器的LOCK位,确定PLL是否稳定	 LOCK==1 稳定,==0 不稳定  
   CLKSEL_PLLSEL =1;     //选择PLL作为时钟源		       
}


void INIT_SCI(void)     //初始化SCI
{

  SCI1BD = BUS_CLOCK/16/BAUD;  //设置SCI0波特率为9600
  SCI1CR1 = 0x00;              // LOOPS=0 正常模式
                               // SCISWAI=0:在等待模式下允许 SCI
                               // RSRC=0:当 LOOPS=1 时,接收器信号源选择位
                               // M=0:方式选择位 0:1 个起始位,8 个数据位,1 个停止位
                               // WAKE=0:唤醒选择位0:介质空闲唤醒
                               // ILT=0:空闲检测方式选择位0:快速检测
                               // PE=0:奇偶校验允许位0:禁止奇偶校验
                               // PT=0:奇/偶校验选择位(在PE=1时有效)
                               //设置SCI0为正常模式,八位数据位,无奇偶校验
  SCI1CR2 = 0x2c;              //允许发送数据,允许接收中断功能 
                               //TIE=0:发送中断允许位 0:禁止
                               //TCIE=0:发送结束中断允许位0:禁止
                               //RIE=1:接收中断允许位  1:允许
                               //ILIE=0:空闲中断允许位 0:禁止
                               //TE=1:发送允许位 1:允许 SCI 发送部分工作,TxD 引脚(PSl/PS3)用于发送
                               //RE=1:接收允许位 1:允许SCI接收
                               //RWU=0:接收器唤醒控制位 0:正常模式
                               //SBK=0:中止符发送允许位 0: 中止符产生器关闭
}



void SCI_send(unsigned char data)     //串口发送函数
{
  while(!SCI1SR1_TDRE);       //等待发送数据寄存器为空
  SCI1DRL = data;             //把数据放入SCI数据存储器
}

unsigned char SCI_receive(void)         //串口接收函数
{
  while(!SCI1SR1_RDRF);          //等待发送数据寄存器满
  return(SCI1DRL);               //返回接受的数据
}


#pragma CODE_SEG __NEAR_SEG NON_BANKED   //中断函数置于非分页区内
void interrupt VectorNumber_Vsci1 receivedata(void)     //串口中断接收函数
{
    data_receive = SCI_receive();   //将SCI接收的数据传送给data_receive变量
    if(data_receive == 'O')         //如果接收的数据为'O'时,LED点亮
    {                 
      LED = LED_ON;                 
    }
    if(data_receive == 'C')         //如果接收的数据为'C'时,LED熄灭
    {
      LED = LED_OFF;                
    }
}

#pragma CODE_SEG DEFAULT   //后续代码置于默认区域内  


void main(void) 
{
  DisableInterrupts;     //禁止打开所有中断
  INIT_PLL();            //初始化PLL模块,设置busclock=32Mhz
  INIT_SCI();            //初始化SCI模块
  LED_dir = 1;           //LED接口PB0设置为输出口
  EnableInterrupts;      //允许打开所有中断  
  LED = LED_ON;          //初始化LED初始状态为亮


  for(;;) 
  {} 
}

通过USB转串口模块,用电脑的串口调试助手发送数据给单片机,具体的接线实物图如下(USE转串口的TXD接S2,RXD接S3)

发送大写字母“O”时,指示灯变亮;
发送大写字母“C”时,指示灯熄灭;
发送其他任意字符,指示灯无变化。
SCI中断接收_第5张图片

你可能感兴趣的:(单片机)