MC9S12XDP512串口使用笔记(中断方式)

 

 

1.      相关寄存器:

1.      SCIBDH,SCIBDL:波特率寄存器(SCIBDH只有低5位有效)

波特率 = 总线频率 / (16 * SBR[12:0])

2.      SCICR2: SCI控制寄存器2

位数

7

6

5

4

3

2

1

0

含义

TIE

TCIE

RIE

ILIE

TE

RE

RWU

SBK

复位值

0

0

0

0

0

0

0

0

 

TIE: 发送中断使能位。使能发送数据寄存器空标志(TDRE)来产生中断申请

              TCIE: 发送完成中断使能位。使能发送完成标志(TC)来产生中断申请

              RIE: 接收器满中断使能位

              TE: 发送器使能位

              RE: 接收器使能位

3.      SCISR1: SCI状态寄存器1

位数

7

6

5

4

3

2

1

0

含义

TDRE

TC

RDRF

IDLE

OR

NF

FE

PF

复位值

1

1

0

0

0

0

0

0

      

       TDRE: 发送数据寄存器空标志

       TC: 发送完成标志

       RDRF: 接收数据寄存器满标志

4.      SCIDRL,(SCIDRH: SCI数据寄存器

2.寄存器使用注意事项:

1.  TDRE(TC)复位值为1,因此将SCICR2TIE(TCIE)置为1即可产生中断

2.  TDRETC的清除方法:读SCISR1,然后写SCIDRL,注意,发送完最后一个字节之后,会产生中断,但因为这是最后一个字节,故不会写SCIDRL,中断标志仍然存在

3.    RDRF的清除方法:读SCISR1,然后读SCIDRL

3.示例函数;

   说明:

1. 发送和接收都采用中断方式,以帧为基本处理单元,当接收到一帧完整数据时,置位接收标志,主程序不断查询接收标志,若接收标志置位,则调用接收处理函数解析接收到的帧。

2. 通信协议基本形式:帧头(1字节) +通信头(1字节) +通信数据长度(1字节) +通信数据+校验字(1字节)

通信头: 表示通信的内容

通信数据长度 = 通信数据长度 + 校验字长度

// ============================================================================ // SCI初始化程序 // 注:总线时钟为40MHZ // baudrate = 153600,即9600bytes/s 使能接收中断(实际:156250bps) // ============================================================================ void SCI_Init(void) { // SCI1 SCI1BDH = 0X00; // baud rate = bus clock / (16*SBR[12:0]) 波特率153600,SBR[12:0]= 16 = 0X0F; SCI1BDL = 0X0F; SCI1CR2 = 0x2C; // 接收使能,接收器满中断使能,发送使能 } // ============================================================================ // 发送数据请求函数 // 如果没有数据正在发送,则立即发送,如果有数据正在发送,则置位发送请求标志位 // 主流程不断查询发送请求标志位,若有该标志位,且没有数据正在发送则发送 // ============================================================================ void Send(byte commd) { SCI_Commd=commd; if(Status.Bits.Uart_R_Over==0) // 发送完成 { Send_1(); } else { Status.Bits.Uart_T_Commd=1; // 置位发送请求标志 } } // ============================================================================ // 发送函数 // Pre_Send():发送预处理函数,根据通信头(commd)内容处理发送缓冲区 // ============================================================================void Send_1(void) { Pre_Send(); Status.Bits.Uart_R_Over = 1; // 置位正在发送标志 SCI1CR2 |= 0x40; // 使能中断 }// ============================================================================ // 串口中断程序 // 中断接收和中断发送 // ============================================================================ interrupt void SCI1_INT(void) { static byte R_num = 0, R_curr = 0; // 接收数据总数和当前指针 static byte T_num = 0, T_curr = 0; // 发送数据总数和当前指针 if(SCI1SR1_RDRF == 1) // 接收中断 { Uart_R_Str[R_curr] = SCI1DRL; R_curr++; // 判断是否为帧头 if(R_curr == 1) { // 若不为帧头,复位指针 if(Uart_R_Str[0] != Frame_Header) { R_curr = 0; R_num = 0; } } if(R_curr == 3) // 第二字节,通信帧长度 R_num = Uart_R_Str[2]+1; // Uart_R_Str[1] 为通信帧长度 // 每接收一个数据,num减1,当num为0时,一帧数据接收完毕 if(R_num != 0) { R_num--; if(R_num == 0) { R_curr = 0; // 当前存储位置指向Uart_R_Str[0] Status.Bits.Uart_Status = 1; // 置Uart接收完一帧数据标志位 } } } // 发送中断 else if(SCI1SR1_TC == 1) // 发送完成标志 { // 最后一个字节发送完成 if(T_curr == Uart_T_Str[2]+3) { //SCI1CR2 &= 0XF7; // 关闭发送功能 SCI1CR2 &= 0xBF; T_curr = 0; // 复位数据指针 Status.Bits.Uart_R_Over = 0; // 发送完成 } else SCI1DRL = Uart_T_Str[T_curr++]; } } // ============================================================================ // 主程序 // ============================================================================ /******************************全局变量**************************/ volatile byte Uart_R_Str[Uart_R_Length]; // 串口接收数据缓冲区 volatile byte Uart_T_Str[Uart_T_Length]; // 串口发送数据缓冲区 /****************************************************************/ void main(void) { // 初始化代码 ... for(;;) { if(Status.Bits.Uart_Status) { Uart_Deal(); // 接收帧处理函数,功能:校验,解析帧。 } if(Status.Bits.Uart_T_Commd && (!Status.Bits.Uart_R_Over)) { Status.Bits.Uart_T_Commd = 0; // 清除发送请求命令位 Send_1(); // 发送 } // 其余代码 ... } }

你可能感兴趣的:(header,存储,360,byte)