西比爱斯

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::

      串口通信是一种通信接口简写SCI,它可是实现异步和同步两种传输模式。可以思考一下同步和异步的区别。

      所谓同步就是接收方和发送方使用的是同一个时钟,步调一致的处理数据。典型的就是CPU和内存,通过总线存取数据。特点就是快,发送方和接收方不需要什么数据格式,数据线上的数据就是当前想读的数据,因为步调一致嘛。但是问题就是双方的速度要一致,且总线要提供时钟信号,否则就无法实现时钟的统一。这样的通信一般都在速度要求高,距离比较近的地方。

      异步就是发送数据的一方和接收数据的一方并不是拥有一个统一的时钟,发送方按照一个固定的数据格式发送,接收方也是按照同一个数据格式接受,但是即使时钟不是同一个,但是发送方和接收方所用的时钟的频率必须是一致的(否则在接受数据的时候如果频率不一致不能够辨别预先设置的数据格式,比如如果接收方的时钟太快,那么会把本来是一个周期的低电平认为是两个低电平信号)。目前异步通信使用的是RS232,单片机为了满足这样的协议都自带UART模块,将CPU的同步数据转换为异步数据。

     串口通信最基本的来说有一个数据发送端,一个数据接收端,在连接的时候只要发送端连接到接收端那么数据就可以开始工作。H8的串口模块的发送和接受模块都有缓冲寄存器,也就说把数据先写到缓冲里,然后芯片自行将数据拷贝到发送寄存器里发送,接受的时候也是一样。怎样确认发送寄存器或者接受寄存器是不是为空,即可以工作呢?由相应的状态寄存器的标志位来决定。这样一来的话,串口通信的方式就有讲究了,如果状态寄存器的标志位显示当前不能发送,发送寄存器里的数据还没有清空,那么是等待还是立即返回呢?同样,接受的时候,数据还没来标志位还没置位,是等待还是返回呢?一般来说,两种方式都提供,在后面会提到。

   串口通信的另一个问题就是波特率,以什么样的速度发送?

    最后就是串口通信的数据格式,前面提到串行异步通信要使用特殊的数据格式:

起始位:一个周期的低电平。在串口通信的无数据阶段是全高电平的,所以一个低电平就标志一个数据包开始传送了。

数据位:7位或者8位的数据位,D0-D7。

检验位:奇\偶校验位。

停止位:两个高电平。

 

所以,对H8芯片的串口编程主要做以下的工作:

1:选择是否添加奇偶校验位

2:选择传输速度

3:选择是同步还是异步:SMR(CPU启动时默认是异步所以不需要特别设置)。

4:选择是否是CPU间通信:SMR(默认为不是)。

5:选择在送信,收信时候是否发生中断:SCR(默认不产生中断)

6:开启异步通信:SCR(默认关闭)

7:清除错误FLAG

1 int i;
2 SCI1.SCR = 0;
3 SCI1.SMR = 0; /* パリティ無し STOP1 */
4 SCI1.BRR = 80; /* 9600bps 3052 */
5 for(i=0;i<280;i++); /* wait */
6 SCI1.SCR = 0x30; /* TE = 1 , RE = 1 */
7 i = SCI1.SSR;
8 SCI1.SSR = 0x80; /* Clear Error Flag (TDRE=1) */

 

 

在发送和接受的时候,因为存在缓冲区不空闲的情况,必须先判断状态寄存器再向缓冲寄存器放读取数据。

 

1 void PutSCI(char c)
2 {
3 unsigned char i;
4 while( 1 )
5 {
6 i = SCI1.SSR;
7 if( i & 0x80 ) break;
8 }
9 SCI1.TDR = c;
10 SCI1.SSR = i&0x7f;
11 }
12
13  /*==========================================================================
14 SCI入力
15 ----------------------------------------------------------------------------
16 データを受信するまで待ちつづけます。
17 ==========================================================================*/
18  char GetSCI()
19 {
20 unsigned char i;
21 char c;
22 while( 1 )
23 {
24 i = SCI1.SSR;
25 if( i & 0x40 ) break;
26 }
27 c = SCI1.RDR;
28 SCI1.SSR = i&0xbf;
29 return(c);
30 }
31
32  /*==========================================================================
33 SCI入力データチェック
34 ----------------------------------------------------------------------------
35 SCIにデータがあるかチェックします。
36 戻り値 1 = データあり、0 = データなし
37 ==========================================================================*/
38  int ScanSCI()
39 {
40 if( SCI1.SSR & 0x40 ) return(1);
41 return(0);
42 }

最后一个函数提供了扫描功能,仅仅是对状态寄存器的读取。

 

(以上)

 

 

 

posted on 2009-12-28 14:10  西比爱斯  阅读(532)  评论(0编辑  收藏  举报