查看: 1110|回复: 0

NXPS08P试用 串口(SCI外设)

[复制链接]
  • TA的每日心情
    无聊
    2021-12-29 19:06
  • 签到天数: 47 天

    [LV.5]常住居民I

    49

    主题

    188

    帖子

    21

    金牌会员

    Rank: 6Rank: 6

    积分
    1371
    最后登录
    2024-3-21
    发表于 2019-9-4 17:20:41 | 显示全部楼层 |阅读模式
    本帖最后由 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主要配置中断使能和发送接收使能。


    根据上述寄存器可以进行基本的初始化:
    1.     SCI2_BD = 104; //16MHz/16/9600
    2.     SCI2_C1  = 0;     // 8bit mode, 1 stop bit, no parity
    3.     SCI2_C2  = 0x0C;  // enable TX , enable RX
    复制代码

    此外,还需要使能SCI的时钟,这个功能在时钟体系的寄存器SCG寄存器组中的SCG_C3中实现:
    1. 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。发送完成后,该位清零,需要通过手动置位,或者读取该位时,硬件会自动置位。
    因此发送的代码如下:
    1.     while(!( SCI2_S1 & SCI2_S1_TDRE_MASK));
    2.     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.
    代码配置:
    1. SCI2_C2  = 0x2C;  // enable TX , enable RX , Receiver Interrupt Enable for RDRF
    复制代码





    2、中断标志
    S08没有额外设置中断标志位,用接收完成标志位统一作为标志位 RDRF



    3、中断向量
    每个SCI外设都有一个单独为 rx设置的中断向量 :VectorNumber_Vsci2rx


    设置接收缓存结构体:
    1. unsigned char buttonStates = 0;
    2. int button2IsPressedFlag=0;
    3. int button3IsPressedFlag=0;

    4. #define _UartRxBufSize 50
    5. struct _UartBufStruct{
    6.                 char RecBuf[_UartRxBufSize];
    7.                 unsigned char RecFinishFlag;         //finish-1; not finish-0; err-2;
    8.                 unsigned int RecBufCounter;
    9. };
    10. struct _UartBufStruct Uart2BufStruct={"\0",0,0};
    复制代码
    接收的中断服务函数:
    1. interrupt VectorNumber_Vsci2rx void Sci2rx_ISR(void)
    2. {
    3.         char  temp = SCI2_D;
    4.         if(( SCI2_S1 & SCI2_S1_RDRF_MASK) == SCI2_S1_RDRF_MASK)
    5.         {
    6.                 if(Uart2BufStruct.RecFinishFlag == 0){
    7.                         Uart2BufStruct.RecBuf[Uart2BufStruct.RecBufCounter] = temp;
    8.                         Uart2BufStruct.RecBufCounter++;
    9.                         if(temp == 0x0A )
    10.                                 Uart2BufStruct.RecFinishFlag = 1;
    11.                         else if(Uart2BufStruct.RecFinishFlag>=_UartRxBufSize-1)
    12.                                 Uart2BufStruct.RecFinishFlag = 2;
    13.                 }
    14.         }
    15. }
    复制代码





    该会员没有填写今日想说内容.
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-5-2 02:45 , Processed in 0.104931 second(s), 18 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表