当前位置: 首页 > news >正文

DSP28335 SCI 串口回显功能案例解析

#include "DSP2833x_Device.h"
#include "DSP2833x_Examples.h"// Function prototypes (函数声明,统一英文命名风格)
void scia_echoback_init(void);
void scia_fifo_init(void);
void scia_xmit(int a);
void scia_send_str(char *str);  //  renamed from "scia_msg" for clarity// Global count variables (全局计数变量)
Uint16 LoopCount;   // Counts total echoed characters (统计总回显字符数)
Uint16 ErrorCount;  // Reserved for error monitoring (预留用于错误统计)void main(void)
{Uint16 ReceivedChar;  // Stores single received character (存储单个接收字符)char *init_prompt1;   // Initial welcome prompt (初始欢迎提示)char *init_prompt2;   // Function explanation prompt (功能说明提示)char *input_prompt;   // Loop input prompt (循环输入提示)// Step 1: Initialize system control (PLL, watchdog, peripheral clocks)// 步骤1:初始化系统控制(锁相环、看门狗、外设时钟)InitSysCtrl();// Step 2: Initialize SCI-A GPIO pins (TX: GPIO28, RX: GPIO29)// 步骤2:初始化SCI-A引脚(发送脚GPIO28,接收脚GPIO29)InitSciaGpio();// Step 3: Initialize interrupts (disable all to avoid interference)// 步骤3:初始化中断(关闭所有中断,避免干扰)DINT;                      // Disable global CPU interrupts (禁用全局CPU中断)InitPieCtrl();             // Reset PIE control registers to default (复位PIE控制寄存器)IER = 0x0000;              // Disable all CPU interrupts (禁用所有CPU中断)IFR = 0x0000;              // Clear all CPU interrupt flags (清空所有CPU中断标志)InitPieVectTable();        // Initialize PIE vector table (初始化PIE向量表)// Step 4: Initialize user variables (初始化用户变量)LoopCount = 0;ErrorCount = 0;// Step 5: Initialize SCI FIFO and core parameters// 步骤5:初始化SCI FIFO和核心参数scia_fifo_init();scia_echoback_init();// Step 6: Send initial welcome prompts (发送初始欢迎提示)init_prompt1 = "\r\n\n\nHello! SCI Echo Test (DSP28335)\0";  // 欢迎语+功能标识init_prompt2 = "\r\nSend any characters/strings - DSP will echo them back.\0";  // 功能说明input_prompt = "\r\nEnter input: \0";  // 循环输入提示scia_send_str(init_prompt1);scia_send_str(init_prompt2);scia_send_str(input_prompt);// Infinite loop: Continuous receive and echoUint16 recv_count = 0;  // 统计本次接收的总字符数// 无限循环:持续接收并回显for(;;){Uint16 has_enter = 0;  // 标记是否收到回车符// 1. 读取FIFO中所有字符,同时检查是否有回车// 读取FIFO所有字符,同时计数while(SciaRegs.SCIFFRX.bit.RXFFST > 0){ReceivedChar = SciaRegs.SCIRXBUF.all;scia_xmit(ReceivedChar);if(ReceivedChar == 0x0D) has_enter = 1;recv_count++;  // 每读1个字符,计数+1LoopCount++;}// 2. 仅当收到回车时,才发送下一次输入提示if(has_enter == 1){scia_send_str("\r\nEnter input: ");  // 换行后提示,格式更清晰}// 3. 等待下一批数据(避免空循环占用CPU)while(SciaRegs.SCIFFRX.bit.RXFFST == 0) { }}
}// SCI Core Initialization (9600 baud, 8-bit data, no parity, 1 stop bit)
// SCI核心初始化(9600波特率,8位数据位,无校验,1位停止位)
void scia_echoback_init()
{// SCI Communication Control Register (SCI通信控制寄存器)SciaRegs.SCICCR.all = 0x0007;    // 8-bit data, 1 stop bit, no parity, async mode// 8位数据,1位停止位,无校验,异步模式// SCI Control Register 1 (SCI控制寄存器1)SciaRegs.SCICTL1.all = 0x0003;   // Enable TX/RX, internal clock; disable RX error/sleep// 使能发送/接收,内部时钟;禁用接收错误检测/睡眠模式// SCI Control Register 2 (SCI控制寄存器2)SciaRegs.SCICTL2.all = 0x0003;   // Enable TX/RX interrupts (reserved for future use)// 使能发送/接收中断(预留后续扩展使用)SciaRegs.SCICTL2.bit.TXINTENA = 1;  // Enable TX interrupt (使能发送中断)SciaRegs.SCICTL2.bit.RXBKINTENA = 1;// Enable RX interrupt (使能接收中断)// Baud Rate Configuration (based on CPU frequency)// 波特率配置(根据CPU频率选择)#if (CPU_FRQ_150MHZ)SciaRegs.SCIHBAUD = 0x0001;  // 9600 baud @ LSPCLK = 37.5MHz (150MHz CPU)SciaRegs.SCILBAUD = 0x00E7;#endif#if (CPU_FRQ_100MHZ)SciaRegs.SCIHBAUD = 0x0001;  // 9600 baud @ LSPCLK = 25.0MHz (100MHz CPU)SciaRegs.SCILBAUD = 0x0044;#endifSciaRegs.SCICTL1.all = 0x0023;   // Release SCI from reset (启动SCI,解除复位)
}// Transmit single character via SCI (通过SCI发送单个字符)
void scia_xmit(int a)
{// Wait until transmit FIFO is empty (避免发送溢出,等待发送FIFO为空)while (SciaRegs.SCIFFTX.bit.TXFFST != 0) {}SciaRegs.SCITXBUF = a;  // Write character to transmit buffer (写入发送缓冲区)
}// Transmit string via SCI (循环调用单字符发送函数,实现字符串发送)
void scia_send_str(char *str)
{int i = 0;// Send each character until null terminator ('\0') is reached// 循环发送字符,直到遇到字符串结束符('\0')while(str[i] != '\0'){scia_xmit(str[i]);i++;}
}// SCI FIFO Initialization (SCI FIFO初始化)
void scia_fifo_init()
{SciaRegs.SCIFFTX.all = 0xE040;  // Enable TX FIFO, clear TX FIFO (使能发送FIFO,清空缓冲区)SciaRegs.SCIFFRX.all = 0x2001;  // Enable RX FIFO, threshold = 1 (使能接收FIFO,阈值=1)SciaRegs.SCIFFCT.all = 0x0;     // Disable FIFO timeout (禁用FIFO超时功能)
}

一、代码整体层次结构

DSP28335 SCI 串口回显代码遵循 “系统基础→外设配置→驱动封装→应用逻辑” 的嵌入式开发层次逻辑,各层职责明确、依赖关系清晰,具体分层如下:

层次

核心职责

关键代码 / 函数

应用逻辑层

实现串口回显业务(发送欢迎提示、等待接收、回显数据、统计计数)

main() 函数中的无限循环、交互逻辑

驱动封装层

封装 SCI 硬件操作,提供简洁的软件接口(单字符发送、字符串发送)

scia_xmit()scia_send_str()

外设配置层

配置 SCI 核心参数(通信协议、波特率)和 FIFO(缓冲区阈值、使能)

scia_echoback_init()scia_fifo_init()

系统基础层

初始化系统运行环境(时钟、GPIO 引脚、中断屏蔽),为 SCI 提供硬件前提

InitSysCtrl()InitSciaGpio()、中断初始化函数

硬件抽象层

直接操作 SCI 寄存器,连接软件与硬件(如 FIFO 状态位、数据缓冲区)

SciaRegs 结构体(SCIFFTXSCIFFRXSCITXBUF等)

二、SCI 初始化完整流程

初始化是 SCI 正常工作的前提,需按 “系统→GPIO→中断→SCI 参数→FIFO” 的顺序执行,避免因硬件依赖导致配置失效,具体步骤如下:

1. 系统控制初始化(InitSysCtrl()

  1. 核心作用:配置 DSP 主频(如 150MHz/100MHz)、使能 SCI 外设时钟、禁用看门狗。
  2. 关键细节:SCI 模块默认处于 “时钟关闭” 状态,InitSysCtrl() 会开启 SCI 的外设时钟(LSPCLK,如 150MHz 主频下 LSPCLK=37.5MHz),否则后续 SCI 寄存器操作全部无效。

2. GPIO 引脚初始化(InitSciaGpio()

  1. 核心作用:将指定 GPIO 配置为 SCI 功能,建立物理通信通路。
  2. 具体配置:DSP28335 的 SCI-A 默认对应引脚为:
    1. TX 引脚:GPIO28(SCITXDA),配置为 “外设功能模式”,禁用通用 IO 输出;
    2. RX 引脚:GPIO29(SCIRXDA),配置为 “外设功能模式”,禁用通用 IO 输入。
  3. 为什么必须配置:若 GPIO 保持默认的 “通用 IO 模式”,SCI 发送的电信号无法通过 TX 引脚输出,接收的信号也无法通过 RX 引脚传入硬件缓冲区。

3. 中断初始化(屏蔽无关中断)

  1. 核心作用:避免未使用的中断干扰 SCI 通信(如 ADC、SPI 中断)。
  2. 关键操作
    1. DINT:禁用全局 CPU 中断,防止初始化过程中被中断打断;
    2. InitPieCtrl():复位 PIE(外设中断扩展模块)控制寄存器,禁用所有 PIE 中断;
    3. IER=0x0000IFR=0x0000:清空 CPU 中断使能和标志寄存器;
    4. InitPieVectTable():初始化 PIE 向量表,将未使用的中断映射到默认空函数。

4. SCI 核心参数配置(scia_echoback_init()

  1. 核心作用:设定 SCI 的通信协议,确保与接收设备(如电脑串口助手)一致,是串口通信的 “规则约定”。
  2. 关键配置项(寄存器级)

寄存器

配置值

功能说明

SCICCR.all

0x0007

8 位数据位、1 位停止位、无校验、异步模式(标准串口配置,匹配电脑默认设置)

SCICTL1.all

0x0003

使能 TX(发送)和 RX(接收)功能,禁用睡眠模式和接收错误中断(简化调试)

SCICTL2.all

0x0003

使能 TX 和 RX 中断(预留扩展,当前代码未使用中断,仅为后续功能准备)

SCIHBAUD+SCILBAUD

分主频配置

9600 波特率:150MHz 主频下为0x0001+0x00E7,100MHz 主频下为0x0001+0x0044

SCICTL1.all

0x0023

释放 SCI 复位状态(初始化最后一步,相当于 “启动” SCI 模块)

5. SCI FIFO 配置(scia_fifo_init()

  1. 核心作用:启用 SCI 的 FIFO(先进先出缓冲区),减少 CPU 等待时间,避免数据丢失。
  2. 关键配置项(寄存器级)

寄存器

配置值

功能说明

SCIFFTX.all

0xE040

使能发送 FIFO(E0 bit)、清空发送 FIFO(40 bit),确保初始无残留数据

SCIFFRX.all

0x2001

使能接收 FIFO(20 bit)、设置接收 FIFO 阈值为 1(01 bit),即收到 1 个字符就可读取

SCIFFCT.all

0x00

禁用 FIFO 超时功能(简化调试,默认无需启用)

三、SCI 发送 “1234” 的底层原理(含SCIFFTX.bit.TXFFST解析)

发送 “1234” 的本质是 “软件写入数据→FIFO 缓冲→硬件串行发送”,全程由SciaRegs寄存器协作完成,其中SCIFFTX.bit.TXFFST是核心状态位。

1. 发送流程拆解(以scia_send_str("1234")为入口)

步骤 1:字符串发送函数调用

scia_send_str("1234") 会循环调用 scia_xmit() 函数,逐个发送字符 '1'(ASCII 码0x31)、'2'0x32)、'3'0x33)、'4'0x34)。

步骤 2:单字符发送(scia_xmit('1')
  1. 核心操作 1:等待发送 FIFO 为空(SCIFFTX.bit.TXFFST == 0

scia_xmit()while (SciaRegs.SCIFFTX.bit.TXFFST != 0) {} 的作用:

    1. SCIFFTX.bit.TXFFST发送 FIFO 的填充计数位(0~16,16 为 FIFO 满),值为 0 表示 FIFO 无数据,可写入新字符;
    2. 若 FIFO 已满(TXFFST=16),直接写入会导致数据溢出(新数据覆盖旧数据),因此必须等待 FIFO 为空。
  1. 核心操作 2:写入发送缓冲区(SCITXBUF

执行 SciaRegs.SCITXBUF = '1'(即写入0x31):

    1. 硬件检测到SCITXBUF有新数据,自动将数据移入发送 FIFO;
    2. 此时 SCIFFTX.bit.TXFFST 从 0 变为 1(FIFO 中存入 1 个字符)。
步骤 3:硬件自动串行发送

发送 FIFO 有数据后,SCI 硬件模块无需 CPU 干预,自动执行以下操作:

  1. FIFO 取数:从发送 FIFO 中 “弹出”'1'0x31),送入串行发送逻辑单元;
  2. 并行→串行转换:将 8 位并行数据0x31(二进制00110001)转换为串口帧:起始位(0+ 数据位(00110001+ 停止位(1(共 10 位);
  3. 按波特率发送:9600 波特率下,每 bit 发送时间约 104μs,硬件按此时序将 10 位帧逐位输出到 TX 引脚(GPIO28);
  4. 更新 FIFO 状态'1'发送完成后,发送 FIFO 的填充计数自动减 1,SCIFFTX.bit.TXFFST 从 1 变回 0,等待下一个字符写入。
步骤 4:循环发送剩余字符
  1. 发送'2''3''4'时,重复步骤 2~3;
  2. 若 CPU 写入速度快于硬件发送速度(如连续写入 4 个字符),发送 FIFO 会短暂缓存数据,SCIFFTX.bit.TXFFST 会依次变为 1→2→3→4,硬件发送时再逐次减为 0,实现 “批量缓冲 + 连续发送”。

四、SCI 接收 “1234” 的底层原理(含SCIFFRX.bit.RXFFST解析)

接收 “1234” 的本质是 “硬件串行接收→FIFO 缓冲→软件读取数据”,核心状态位为SCIFFRX.bit.RXFFST

1. 接收流程拆解(以main()函数中的无限循环为入口)

步骤 1:等待接收 FIFO 有数据(SCIFFRX.bit.RXFFST > 0

main()while(SciaRegs.SCIFFRX.bit.RXFFST == 0) {} 的作用:

  1. SCIFFRX.bit.RXFFST接收 FIFO 的填充计数位(0~16),值为 0 表示 FIFO 无数据,需等待外部设备发送;
  2. 当电脑通过串口发送 “1234” 时,RX 引脚(GPIO29)会逐位接收串行信号,硬件自动将其转换为并行数据。
步骤 2:硬件自动接收并缓存到 FIFO
  1. 串行→并行转换:硬件接收 RX 引脚的串行帧(如'1'的 10 位帧),剥离起始位和停止位,提取 8 位数据0x31
  2. FIFO 缓存:将0x31存入接收 FIFO,此时 SCIFFRX.bit.RXFFST 从 0 变为 1(匹配 FIFO 阈值 1);
  3. 连续接收:接收'2''3''4'时,FIFO 依次缓存数据,SCIFFRX.bit.RXFFST 依次变为 2→3→4。
步骤 3:软件读取 FIFO 数据

main()while(SciaRegs.SCIFFRX.bit.RXFFST > 0) 循环读取数据:

  1. 读取操作:执行 ReceivedChar = SciaRegs.SCIRXBUF.all,从接收缓冲区读取 1 个字符(如'1');
  2. 更新 FIFO 状态:读取后,接收 FIFO 的填充计数自动减 1,SCIFFRX.bit.RXFFST 从 4→3→2→1→0;
  3. 回显数据:调用 scia_xmit(ReceivedChar),将读取的字符回传给电脑,完成 “接收→回显” 闭环。
步骤 4:检测回车并提示下一次输入

若用户发送 “1234” 后按回车(ASCII 码0x0D),代码会检测到ReceivedChar == 0x0D,设置has_enter=1,随后发送"Enter input: ",等待下一次接收。

五、核心状态位总结

状态位

功能描述

发送 / 接收场景下的关键作用

SCIFFTX.bit.TXFFST

发送 FIFO 填充计数(0~16)

发送时:等待其为 0,确保 FIFO 有空位,避免数据溢出;发送中:观察其变化,判断 FIFO 缓存状态

SCIFFRX.bit.RXFFST

接收 FIFO 填充计数(0~16)

接收时:等待其 > 0,确保有数据可读取;接收中:观察其变化,判断是否有残留数据未读取

通过以上层次解析、初始化流程和底层原理,可清晰理解 DSP28335 SCI 串口回显功能的实现逻辑,以及核心寄存器的作用,为后续扩展(如中断发送、多字节通信)奠定基础。

http://www.dtcms.com/a/420502.html

相关文章:

  • dede电影网站网站建设与网络编辑综合实训课程指导手册
  • 网站建设费税率多少韶关做网站公司
  • 四川省建设主管部门网站有源码如何搭建app
  • logo在线设计图片seo外链平台热狗
  • 做网站 阿里云滨湖区建设局官方网站
  • 广州建站服务电商公司网站建设流程
  • 专门建设网站的公司网上商城官网入口
  • 建网站设置网站首页网站版面布局设计的原则
  • Altium Designer(AD)PCB拼版——两种方法教程
  • 模板板网站网站备案需要多久时间
  • 百度搜索引擎网站开发公司资质等级
  • 做购物网站需不需要交税费怎么免费咨询律师
  • 瑞安哪里有培训做网站的2022年新闻热点事件
  • 网站图片设计效果图搜狐三季度营收多少
  • SSRF - 服务器端请求伪造
  • 个人网站要备案吗山东裕达建设工程咨询有限公司网站
  • 门户网站建设 考核青岛外贸网站建设
  • 网站排版的优点重庆网站排名外包
  • 带端口的服务器怎么做网站建网站和软件需要什么
  • 行业网站建设价格创意经济型网站建设
  • 小制作图片镇江网站建设优化排名
  • 南宁网站建设gxskmseo搜索优化公司排名
  • 【数据结构——十字链表】
  • JSON-LD 的格式
  • 有域名怎么发布网站吗中企动力网站报价
  • 新网站怎么做流畅wordpress更新机制
  • 网站开发 流程图搜索引擎营销的原理是什么
  • 生成论坛网站自己建网站怎么做影视资源
  • 怎么免费搭建属于自己的网站做视频网站需要
  • 第三十七天:2025 图形绘制