在线时间102 小时
UID3338547
注册时间2017-1-28
NXP金币49
TA的每日心情 | 无聊 2021-12-29 19:06 |
---|
签到天数: 47 天 [LV.5]常住居民I
金牌会员
- 积分
- 1371
- 最后登录
- 2024-3-21
|
本帖最后由 day_day 于 2019-9-4 17:20 编辑
(一)串口体系
S08单片机将串口外设命名为SCI。使用的时钟总线是BUSCLK,关于时钟总线的一些体会可以查看:
NXPS08P 时钟体系
里面可能会有疏漏之处,因为很多地方是基于实际情况的主观猜测。但总的来说,串口最终使用的时钟频率是没有错的,也能够正常配置、正常工作。
(二)寄存器配置
SCI有四种寄存器,其中包括
两个波特率寄存器 SCLx_BDH SCIx_BDL
三个控制寄存器 SCIx_C1 SCIx_C2 SCIx_C3
两个状态寄存器 SCIx_S1 SCIx_S2
一个数据寄存器 SCIx_D
首先看与时钟最紧密的波特率寄存器。
高位包含三个控制位:
LBKDIE RXEDGIE SBNS
前两个分别是发送和接收的中断使能寄存器位,第三个SBNS是配置停止位的。估计是控制寄存器不够用,征用了波特率寄存器的三个位吧。剩下的就全都是时钟分频的寄存器了,SCIx_BDH保存高位数据,SCIx_BDL保存地位数据。分频之后就产生对应的波特率,计算方法:
波特率=BUSCLK/(16×BR)
如果BUSCLK为16M,115200波特率取8.68,四舍五入为9,虽然误差有点大,但实测还是能用的。如果是9600波特率的话,取104.16,四舍五入为104就更加精准了。
再来看看控制寄存器,
首先C1是一些关于停止位、一帧8byte还是9byte的通用串口配置,此外还有一些地址位掩码的高级功能,应该是为485总线特配的。
C2主要配置中断使能和发送接收使能。
根据上述寄存器可以进行基本的初始化:
- SCI2_BD = 104; //16MHz/16/9600
- SCI2_C1 = 0; // 8bit mode, 1 stop bit, no parity
- SCI2_C2 = 0x0C; // enable TX , enable RX
复制代码
此外,还需要使能SCI的时钟,这个功能在时钟体系的寄存器SCG寄存器组中的SCG_C3中实现:
- SCG_C3 |= SCG_C3_SCI2_MASK;
复制代码
(三)发送配置
SCI的发送相当简单,只需要往数据寄存SCIx_D内填入数据就可以自动发送了。但这里必须注意一个状态位,SCIx_S1里面的TDRE位。
Transmit Data Register Empty Flag
TDRE is set out of reset and when a transmit data value transfers from the transmit data buffer to the
transmit shifter, leaving room for a new character in the buffer. To clear TDRE, read SCI_S1 with TDRE
set and then write to the SCI data register (SCI_D).
0 Transmit data register (buffer) full.
1 Transmit data register (buffer) empty.
数据手册提到,TDRE位上电复位默认状态为1。
想要发送,必须设置为空状态,即1。发送完成后,该位清零,需要通过手动置位,或者读取该位时,硬件会自动置位。
因此发送的代码如下:
- while(!( SCI2_S1 & SCI2_S1_TDRE_MASK));
- SCI2_D = 0x30;
复制代码 这样就发送了一个0x30字节
(四)接收中断配置
SCI接收实验思路:采用接收中断,接收完成后发回上位机。
1、开启中断
SCIx_C2 寄存器的第五位 RIE
Receiver Interrupt Enable for RDRF
0 Hardware interrupts from RDRF disabled; use polling.
1 Hardware interrupt requested when RDRF flag is 1. 代码配置:
- SCI2_C2 = 0x2C; // enable TX , enable RX , Receiver Interrupt Enable for RDRF
复制代码
2、中断标志
S08没有额外设置中断标志位,用接收完成标志位统一作为标志位 RDRF
3、中断向量
每个SCI外设都有一个单独为 rx设置的中断向量 :VectorNumber_Vsci2rx
设置接收缓存结构体:
- unsigned char buttonStates = 0;
- int button2IsPressedFlag=0;
- int button3IsPressedFlag=0;
- #define _UartRxBufSize 50
- struct _UartBufStruct{
- char RecBuf[_UartRxBufSize];
- unsigned char RecFinishFlag; //finish-1; not finish-0; err-2;
- unsigned int RecBufCounter;
- };
- struct _UartBufStruct Uart2BufStruct={"\0",0,0};
复制代码 接收的中断服务函数:
- interrupt VectorNumber_Vsci2rx void Sci2rx_ISR(void)
- {
- char temp = SCI2_D;
- if(( SCI2_S1 & SCI2_S1_RDRF_MASK) == SCI2_S1_RDRF_MASK)
- {
- if(Uart2BufStruct.RecFinishFlag == 0){
- Uart2BufStruct.RecBuf[Uart2BufStruct.RecBufCounter] = temp;
- Uart2BufStruct.RecBufCounter++;
- if(temp == 0x0A )
- Uart2BufStruct.RecFinishFlag = 1;
- else if(Uart2BufStruct.RecFinishFlag>=_UartRxBufSize-1)
- Uart2BufStruct.RecFinishFlag = 2;
- }
- }
- }
复制代码
。
|
|