串口通信,尤其指UART通信,大约是使用最广泛的协议了。
下面以M16C/6N4系列为例。
该系列一共有3个UART设备,每个设备可以配置为不同的模式,如图:
我们以UART模式为例
UART0初始化,配置串口的时钟,波特率等。
prc0 = 1; // Write enable
pclk1 = 1; // Clock source for UART0 is f1SIO
prc0 = 0; // Disable write
pd6_2 = 0; // RXD0 is input
u0c0 = 0x10; // LSB first
// TXD0 pin is CMOS output
// CTS/RTS function is disabled
// No data present in the transmit register (transmission completed)
// f1SIO is selected (BRG count source select bit)
u0mr = 0x05; // UART mode transfer data 8 bits long
// internel clock
// 1 stop bit
// no parity
// parity disabled
// TXD, RXD polarity is no reverse
u0brg = 0x67; // 波特率配置为9600
/* u0c1 register */
u0ere = 0; // error signal output is disabled
u0smr = 0x00;
u0smr2 = 0x00;
u0smr3 = 0x00;
u0smr4 = 0x00;
u0irs = 1; // UART0 transmit interrupt cause (transmission completed)
u0rrm = 1;
te_u0c1 = 1; // 使能发送
re_u0c1 = 1; // 使能接收
以上配置串口0为UART模式,波特率9600, 8N1。
发送过程:
直接向发送缓冲寄存器里填入数据就可以发送了,不过在发送前要先判断发送标志位,以确保先前的数据是否发送完。
由于我们只用了8个数据位,所以只需要向发送缓冲寄存器的低8位填入数据.
while(!ti_u0c1);
u0tbl = data; // 向u0tb的低8位填入数据,发送。
如果开了发送中断,需要在发送中断里清除某个标志位。不过我一般都不开发送中断的,影响效率。
接收过程:
以中断方式接收数据,中断后,直接从接收缓冲寄存器里读取数据。
接收缓冲寄存器为16位,结构如下:
在接收中断里读取低8位数据之前,要先判断接收标志位,以确保先前的数据是否被读走。
#pragma interrupt uart0_rx_irq()
void uart0_rx_irq(void)
{
unsigned char buf;
while(!ri_u0c1);
buf = u0rbl;
}
M16C的串口还是很简单的,没有FIFO缓冲区,所以很好处理。
如果大家对串口不太清楚的,可以看看芯片上的串口结构以及通信时序图。
用户1664498 2015-8-4 19:53