SCI中断接收

本文详细介绍了SCI(Serial Communication Interface)在MCU中的应用,特别是在MC9S12XS128型号中如何配置和使用SCI0和SCI1进行串行通信。内容包括SCI的相关寄存器配置,如SCIBDH、SCIBDL、SCIDRH、SCIDRL等,以及中断接收的相关设置。文中提到SCI的波特率计算、数据传输模式,并提供了SCI中断接收的代码实现。通过USB转串口模块与电脑进行通信,实现了发送特定字符控制指示灯亮灭的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SCI 是全双工异步串行通信接口,主要用于 MCU 与其他计算机或设备之间的通信,几个独立的 MCU也能通过 SCI 实现串行通信,形成网络。 MC9S12XS128里有两个SCI(SCI0和 SCI1) 。设计 SCI 串口通信程序,主要是掌握八个寄存器,设置好初始化。
在这里插入图片描述
以下为SCI相关寄存器:
SCIBDH, SCIBDL寄存器
在这里插入图片描述
IREN(红外调制模式使能位) = 1 时,使能
= 0 时,禁止

TNP[0:1]:窄脉冲发射位
SBR[0:12]:波特率设置位
IREN = 1 时,SCI baud rate = SCI bus clock / (16 x SBR[12:0])
IREN = 0 时,SCI baud rate = SCI bus clock / (32 x SBR[12:1])

SCIDRH, SCIDRL寄存器
在这里插入图片描述
SCI 内部分别设有发送和接收两个数据寄存器,其低位都通过 SCIDRL 访问,读操作返回接收数据寄存器 RDR 的内容,写操作数据置入发送数据寄存器TDR。当 M=1 即运行在 9 位数据模式时,SCIDRL 和 SCIDRH 形成 9 位的 SCI数据字,这时必须先写入 SCIDRH,以便与低位字节(SCIDRL)一起进入发送移 位器。如果 M=0 即 SCI 只用于 7 位或 8 位的数据传送,可以只访问 SCIDRL。 当 PE=1 即奇偶校验允许时,奇偶校验位由硬件负责,无需软件干预。
R8:接收到的位 8,该位写操作无效。当 SCI 设置成 9 位数据运行模式时,该位是从串行数据流中接收到的第 9 位。
T8:发送位 8,任何时候可写。当 SCI 设置成 9 位数据模式时,该位是送到串行 数据流的第 9 位。该位不必为每个数据重新设置,每次发送可重复使用。
R[0…7]T[0…7]:收/发数据位 7-0,读操作返回只读寄存器 RDR 的内容,写操 作写入只写寄存器 TDR。

SCICR1寄存器
在这里插入图片描述
LOOPS: 在LOOP模式下,RXD引脚与SCI接收部分断开,发射部分输出在内部和接收部分相连接,此时RXD可作为普通IO口,TXD输出SCI信号
= 1 时, LOOP模式使能
= 0 时, 正常模式

SCISWAI:等待模式下 SCI 停止位
= 1 时:在等待模式下禁止 SCI
= 0 时:在等待模式下允许 SCI

RSRC:接收器信号源选择位,当 LOOPS=1 时,RSRC 决定接收器的内部反馈信号路径
= 1 时,接收器的输入连接到 TxD 引脚
= 0 时,接收器的输入在内部连接到发送器输出(并非 TxD 引脚)

M:方式选择位(选择字

<think>我们正在配置DSP28335的SCI模块以实现中断接收功能。根据引用内容,我们需要关注以下几个关键点: 1. 波特率设置:使用外部低速时钟(37.5MHz),通过公式计算波特率寄存器的值。 2. FIFO的使用:引用[2]提到了使用FIFO中断,并涉及状态位RXFFST(接收FIFO中当前的数据个数)。 3. 中断配置:包括接收中断的使能以及中断服务程序(ISR)的编写。 配置步骤: 1. 初始化SCI模块的GPIO引脚(复用为SCI功能)。 2. 配置SCI的波特率。 3. 配置SCI的通信格式(数据位、停止位、校验等)。 4. 使能接收FIFO并设置接收FIFO的中断深度(即接收到多少个数据后产生中断)。 5. 配置SCI接收中断(使能SCI模块的接收中断,并在PIE中使能相应的中断向量)。 6. 编写中断服务程序(ISR),在中断中读取接收到的数据,并清除中断标志。 具体步骤: 1. GPIO配置: - 根据数据手册,将相应的GPIO引脚配置为SCI功能(例如SCIRXDA引脚)。 2. 波特率计算: - 公式:`scibaud = 37500000/(8*baud) - 1`,其中baud为所需波特率(如115200)。 - 然后分别设置波特率寄存器的高字节和低字节: ```c SCIHBAUD = scibaud >> 8; SCILBAUD = scibaud & 0xFF; ``` 3. SCI通信控制寄存器配置(SCICCR): - 设置数据位长度(通常8位)、停止位(1位或2位)、奇偶校验等。 4. FIFO配置(SCICTL2、SCIFFTX、SCIFFRX、SCIFFCT): - 使能SCI模块(SCICTL2寄存器)。 - 使能接收FIFO(SCIFFRX寄存器中的SCIFFEN位)。 - 设置接收FIFO的中断深度(SCIFFRX寄存器中的RXFFIL位,例如设置为7,表示当FIFO中有8个数据时产生中断)。 - 使能接收FIFO中断SCIFFRX寄存器中的RXFFIENA位)。 5. 中断配置: - 使能SCI接收中断SCICTL2寄存器中的RX/BK INT ENA位,即位1)。 - 在PIE控制器中使能相应的中断(例如SCIA的接收中断对应INT9.1)。 - 在中断服务程序中,需要读取接收到的数据(从SCIRXBUF读取),并清除中断标志(包括SCI模块的中断标志和PIE应答寄存器)。 6. 中断服务程序(ISR)示例: - 在ISR中,首先判断中断来源(接收FIFO中断还是其他中断)。 - 读取接收FIFO状态寄存器(SCIFFRX)中的RXFFST位,获取当前FIFO中的数据个数。 - 根据数据个数,循环读取SCIRXBUF寄存器,直到FIFO为空。 - 清除中断标志: - 清除SCI模块的接收中断标志(SCIRXST寄存器中的中断标志位)。 - 清除接收FIFO中断标志(SCIFFRX寄存器中的RXFFINTCLR位写1清除)。 - 清除PIE应答寄存器(PIEACK)。 注意:引用[2]中提到,在中断服务程序中,通过循环读取数据,每读一个数据,RXFFST状态位会减1,当减到0时,表示FIFO为空。然后需要清除两个中断标志(可能是指SCI模块的中断标志和FIFO中断标志)。 具体代码实现步骤(以SCIA为例): ```c // 1. 初始化GPIO EALLOW; GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0; // 使能SCIRXDA(GPIO28)的上拉 GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3; // 异步输入(因为SCIRXDA是异步信号) GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1; // 配置为SCIRXDA功能 EDIS; // 2. 配置波特率为115200 Uint16 baud = 115200; Uint16 scibaud = (37500000/(8*baud))-1; SciaRegs.SCIHBAUD = scibaud >> 8; SciaRegs.SCILBAUD = scibaud & 0xFF; // 3. 配置SCICCR:8位数据位,1位停止位,无校验 SciaRegs.SCICCR.all = 0x0007; // 1停止位,无校验,禁止自测试,8位数据,空闲线模式 // 4. 配置SCICTL1:使能SCI,使能接收 SciaRegs.SCICTL1.all = 0x0003; // 使能RX和TX,禁止休眠模式,禁止错误中断 // 5. 配置FIFO SciaRegs.SCIFFTX.all = 0xE040; // 使能SCI发送FIFO,TXFIFO复位(注意:这里也配置了发送FIFO,但接收FIFO在SCIFFRX中配置) SciaRegs.SCIFFRX.all = 0x204F; // 使能接收FIFO,复位接收FIFO,设置接收FIFO中断深度为15(0x204F中的低8位为0x4F,但实际中断深度由RXFFIL位(4:0)设置,这里设置为15表示当FIFO中有15个数据时产生中断?注意:实际深度设置应为中断触发点,例如我们想当接收到8个数据时中断,则设置RXFFIL=7) // 更改为:我们设置接收FIFO中断深度为7(即当FIFO中有8个数据时中断),并允许接收FIFO中断 SciaRegs.SCIFFRX.bit.RXFFIL = 7; // 设置中断深度为8(因为0~7对应1~8个数据) SciaRegs.SCIFFRX.bit.RXFFIENA = 1; // 使能接收FIFO中断 SciaRegs.SCIFFRX.bit.RXFIFORESET = 1; // 使能接收FIFO // 6. 配置SCICTL2:使能接收中断(RX/BK INT ENA) SciaRegs.SCICTL2.bit.RXINTENA = 1; // 使能接收中断(注意:这里使能的是非FIFO模式下的接收中断,但当我们使用FIFO中断时,通常不使用这个中断,而是使用FIFO中断。所以这里可能需要根据情况选择) // 注意:在FIFO模式下,我们通常使用FIFO中断(即SCIFFRX中的RXFFINT),而不是SCICTL2中的接收中断。因此,我们可能不需要使能SCICTL2.RXINTENA,而应该禁用。所以修改如下: SciaRegs.SCICTL2.bit.RXINTENA = 0; // 禁用非FIFO接收中断 // 7. 配置中断(在PIE中) // 使能PIE组9的中断1(SCIA的接收中断对应INT9.1,发送中断对应INT9.2,但FIFO中断使用单独的FIFO中断向量,即SCIA的FIFO中断向量在PIE组9的中断8(INT9.8)) // 注意:SCI的FIFO中断使用单独的向量,即SCIA的FIFO中断向量是INT9.8(在DSP2833x_PieVect.h中定义) // 因此,我们需要配置PIE向量表,将中断服务程序关联到INT9.8 EALLOW; PieVectTable.SCIAFIFOINT = &SCIAFIFO_ISR; // 关联中断服务程序 EDIS; // 使能PIE组9的中断8 PieCtrlRegs.PIEIER9.bit.INTx8 = 1; // 使能INT9.8 // 使能CPU级中断(INT9) IER |= M_INT9; // 全局使能中断 EINT; // 8. 中断服务程序 interrupt void SCIAFIFO_ISR(void) { Uint16 i; Uint16 rxffst_value; // 检查接收FIFO中断标志(SCIFFRX.RXFFINT) if (SciaRegs.SCIFFRX.bit.RXFFINT == 1) { // 获取当前FIFO中数据个数 rxffst_value = SciaRegs.SCIFFRX.bit.RXFFST; // 循环读取数据 for (i=0; i<rxffst_value; i++) { // 读取一个字节(从SCIRXBUF中读取,注意SCIRXBUF是16位寄存器,但数据在低8位) scia_rx_buffer[scia_rx_index] = SciaRegs.SCIRXBUF.all & 0xFF; scia_rx_index = (scia_rx_index+1) % BUFFER_SIZE; } // 清除接收FIFO中断标志(写1清除) SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1; } // 清除PIE应答寄存器(对于组9) PieCtrlRegs.PIEACK.all = PIEACK_GROUP9; } ``` 注意:上述代码中的中断向量INT9.8是用于SCI FIFO中断的。在DSP28335中,每个SCI模块有一个FIFO中断(包括接收和发送FIFO事件),该中断在PIE组9的中断8(INT9.8)中。而传统的接收中断(非FIFO)在INT9.1,发送中断在INT9.2。 另外,在FIFO中断中,我们只处理接收FIFO中断(通过检查RXFFINT标志),但要注意,FIFO中断也可能由发送FIFO事件(TXFFINT)触发。因此,在中断服务程序中,我们通常需要检查具体是哪个中断源,但在这个例子中,我们只关心接收FIFO中断。 如果只需要接收中断,也可以配置为不使用FIFO中断,而使用传统的接收中断(即每接收到一个字符就中断一次)。但使用FIFO可以减少中断次数,提高效率。 参考文献: [^1]: DSPTMS320F28335_SCI详解 [^2]: DSP28335的SCI的FIFO中断使用心得 §§相关问题§§ 1. DSP28335的SCI模块如何配置为不使用FIFO的中断接收模式? 2. 如何计算DSP28335在不同时钟源下的SCI波特率? 3. DSP28335的SCI接收FIFO中断与传统的接收中断有何区别?</think>### DSP28335 SCI中断接收配置方法 在DSP28335中实现SCI中断接收功能,需通过以下步骤配置: #### 1. **波特率设置** 使用外部低速时钟(37.5MHz),计算公式: $$ \text{scibaud} = \frac{37500000}{8 \times \text{baud}} - 1 $$ 其中 `baud` 为目标波特率(如115200)。配置寄存器: ```c SCIHBAUD = scibaud >> 8; // 高字节 SCILBAUD = scibaud & 0xFF; // 低字节 ``` #### 2. **FIFO配置** - 使能接收FIFO:`SCIFFRX.bit.RXFIFORESET = 1` - 设置接收深度(如深度8):`SCIFFRX.bit.RXFFIL = 7`(深度值减1) - 使能接收FIFO中断:`SCIFFRX.bit.RXFFIENA = 1` #### 3. **中断使能** - 使能SCIA接收中断:`SCICTL2.bit.RXINTENA = 1` - 在PIE控制器中使能中断: ```c PieCtrlRegs.PIEIER9.bit.INTx1 = 1; // SCIA接收中断对应INT9.1 IER |= M_INT9; // 使能CPU级INT9中断 EINT; // 全局中断使能 ``` #### 4. **中断服务程序(ISR)** ```c interrupt void SCIA_RX_ISR(void) { Uint16 i; Uint16 data_count = SciARegs.SCIFFRX.bit.RXFFST; // 获取FIFO数据量 for(i=0; i<data_count; i++) { rx_buffer[i] = SciARegs.SCIRXBUF.all; // 读取数据 } SciARegs.SCIFFRX.bit.RXFFOVRCLR = 1; // 清除溢出标志 SciARegs.SCIFFRX.bit.RXFFINTCLR = 1; // 清除中断标志 PieCtrlRegs.PIEACK.all = PIEACK_GROUP9; // PIE应答 } ``` **关键点**: - `RXFFST` 值随数据读取递减,需循环读取直至为0[^2]。 - 必须清除 `RXFFINTCLR` 和 `RXFFOVRCLR` 标志。 #### 5. **状态寄存器监控** 通过 `SCIRXST` 寄存器检测错误: - 帧错误:`SCIRXST.bit.FE` - 溢出错误:`SCIRXST.bit.OE` - 需在ISR中处理这些错误标志。 > **注意事项**: > 1. FIFO深度需与数据包大小匹配,避免频繁中断或数据溢出[^2]。 > 2. 若使用非FIFO模式,需在 `SCIRXST.bit.RXRDY` 置位时立即读取 `SCIRXBUF`。 #### 完整配置流程: ```c void Init_SCIA(void) { // 1. 引脚复用配置 EALLOW; GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0; // SCIRXDA上拉使能 GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1; // GPIO28为SCIRXDA功能 EDIS; // 2. 波特率设置 (115200) Uint16 baud = 115200; Uint16 scibaud = 37500000/(8*baud) - 1; SciARegs.SCIHBAUD = scibaud >> 8; SciARegs.SCILBAUD = scibaud & 0xFF; // 3. FIFO与中断配置 SciARegs.SCIFFRX.all = 0xE040; // 复位FIFO SciARegs.SCIFFRX.bit.RXFFIL = 7; // FIFO深度=8 SciARegs.SCIFFRX.bit.RXFFIENA = 1; // FIFO中断使能 SciARegs.SCICTL2.bit.RXINTENA = 1; // 接收中断使能 // 4. 启动SCI SciARegs.SCICTL1.all = 0x0023; // 使能TX/RX, 退出休眠 } ``` [^1]: DSPTMS320F28335_SCI详解 [^2]: DSP28335的SCI的FIFO中断使用心得
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值