DSP开发:串口sci的发送与接收实现

DSP开发:串口sci的发送与接收实现


文章目录

  • DSP开发:串口sci的发送与接收实现
  • 串口配置
  • 串口SCI初始化详细分析
  • 串口SCI使用


串口配置

/*--------------------------------------------scia----------------------------*/
/*--------------------------------------------串口1----------------------------*/void UARTa_Init(Uint32 baud)
{unsigned char scihbaud=0;unsigned char scilbaud=0;Uint16 scibaud=0;scibaud=37500000/(8*baud)-1;scihbaud=scibaud>>8;scilbaud=scibaud&0xff;EALLOW;SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1;   // SCI-AEDIS;InitSciaGpio();//Initalize the SCI FIFOSciaRegs.SCIFFTX.all=0xE040;SciaRegs.SCIFFRX.all=0x204f;SciaRegs.SCIFFCT.all=0x0;// Note: Clocks were turned on to the SCIA peripheral// in the InitSysCtrl() functionSciaRegs.SCICCR.all =0x0007;   // 1 stop bit,  No loopback// No parity,8 char bits,// async mode, idle-line protocolSciaRegs.SCICTL1.all =0x0003;  // enable TX, RX, internal SCICLK,// Disable RX ERR, SLEEP, TXWAKESciaRegs.SCICTL2.all =0x0003;SciaRegs.SCICTL2.bit.TXINTENA =1;SciaRegs.SCICTL2.bit.RXBKINTENA =1;SciaRegs.SCIHBAUD    =scihbaud;  // 9600 baud @LSPCLK = 37.5MHz.SciaRegs.SCILBAUD    =scilbaud;
//  SciaRegs.SCICCR.bit.LOOPBKENA =1; // Enable loop backSciaRegs.SCICTL1.all =0x0023;     // Relinquish SCI from Reset
}
// Transmit a character from the SCI'
void UARTa_SendByte(int a)
{while (SciaRegs.SCIFFTX.bit.TXFFST != 0);SciaRegs.SCITXBUF=a;
}void UARTa_SendString(char * msg)
{int i=0;while(msg[i] != '\0'){UARTa_SendByte(msg[i]);i++;}
}char SCITXDA_TX_BUF[400];void printf_SCITXDa(char *fmt, ...)
{Uint16 i, j;va_list ap;va_start(ap, fmt);vsprintf((char*) SCITXDA_TX_BUF, fmt, ap);va_end(ap);i = strlen((const char*) SCITXDA_TX_BUF);     //此次发送数据的长度for (j = 0; j < i; j++)     //循环发送数据{while (SciaRegs.SCIFFTX.bit.TXFFST != 0);SciaRegs.SCITXBUF = SCITXDA_TX_BUF[j];}
}
/** @name   fputc,fputs* @brief  串口打印重定向* @param  None* @retval None*/
int fputc(int _c, register FILE *_fp)
{UARTa_SendByte(_c);return _c;
}
int putc(int _c, register FILE *_fp)
{UARTa_SendByte(_c);return _c;
}
int putchar(int data)
{UARTa_SendByte(data);return data;
}
int fputs(const char *_ptr, register FILE *_fp)
{unsigned int i, len;len = strlen(_ptr);for (i = 0; i < len; i++){UARTa_SendByte((char) _ptr[i]);}return len;
}

这段代码实现了串口SCI(串行通信接口)的初始化以及向串口发送数据的功能,并且通过函数重定向,将标准库的输出函数重定向到串口SCI上,实现了通过类似于标准库的 printf 函数的格式化字符串向串口SCI发送数据的功能。

以下是代码的详细解释:

UARTa_Init 函数:
这个函数用于初始化串口SCI通信。它接收一个参数 baud,表示所需的波特率。函数通过计算波特率分频寄存器的值来设置波特率。

UARTa_SendByte 函数:
这个函数用于将一个字符发送到串口SCI。它通过检查发送FIFO的状态位来判断是否可以发送数据,然后将字符 a 发送到SCI的发送缓冲区(SCITXBUF)中。

UARTa_SendString 函数:
这个函数用于将一个字符串发送到串口SCI。它通过循环逐个字符地将字符串中的字符发送到串口SCI。

printf_SCITXDa 函数:
这是一个自定义的输出函数。它采用了与标准库函数 printf 类似的格式,支持格式化字符串,通过变参列表处理不定数量的参数。

char *fmt, …:第一个参数 fmt 是格式化字符串,后续参数使用 … 表示不定数量的变参。
va_list ap:va_list 是C标准库中用于处理变参的类型。ap 是一个变参列表指针,用于访问传递给函数的变参。
标准库函数重定向:
代码中重定义了标准库中的 fputc、putc、putchar 和 fputs 函数,使它们调用 UARTa_SendByte 函数向串口SCI发送数据。
通过这些函数的重定向,程序可以使用类似于标准库的 printf 函数的格式化字符串,将数据输出到串口SCI。同时,fputc、putc、putchar 和 fputs 函数也能直接将数据输出到串口SCI,方便地进行调试和输出结果信息。需要注意的是,由于串口发送速率有限,如果发送数据过于频繁,可能会导致数据丢失或串口阻塞。因此,在实际使用中应该适度控制发送频率,确保数据发送的稳定性。

串口SCI初始化详细分析

void UARTa_Init(Uint32 baud)
{unsigned char scihbaud=0;unsigned char scilbaud=0;Uint16 scibaud=0;scibaud=37500000/(8*baud)-1;scihbaud=scibaud>>8;scilbaud=scibaud&0xff;EALLOW;SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1;   // SCI-AEDIS;InitSciaGpio();//Initalize the SCI FIFOSciaRegs.SCIFFTX.all=0xE040;SciaRegs.SCIFFRX.all=0x204f;SciaRegs.SCIFFCT.all=0x0;// Note: Clocks were turned on to the SCIA peripheral// in the InitSysCtrl() functionSciaRegs.SCICCR.all =0x0007;   // 1 stop bit,  No loopback// No parity,8 char bits,// async mode, idle-line protocolSciaRegs.SCICTL1.all =0x0003;  // enable TX, RX, internal SCICLK,// Disable RX ERR, SLEEP, TXWAKESciaRegs.SCICTL2.all =0x0003;SciaRegs.SCICTL2.bit.TXINTENA =1;SciaRegs.SCICTL2.bit.RXBKINTENA =1;SciaRegs.SCIHBAUD    =scihbaud;  // 9600 baud @LSPCLK = 37.5MHz.SciaRegs.SCILBAUD    =scilbaud;
//  SciaRegs.SCICCR.bit.LOOPBKENA =1; // Enable loop backSciaRegs.SCICTL1.all =0x0023;     // Relinquish SCI from Reset
}

这段代码是用于初始化串口SCI(串行通信接口)的函数 UARTa_Init,该函数用于配置SCI的寄存器和相关参数,以便实现指定的波特率和通信设置。让我们逐个分析设置的寄存器对应位的功能和效果:

unsigned char scihbaud=0;
unsigned char scilbaud=0;
Uint16 scibaud=0;
这里定义了用于保存波特率计算结果的变量 scihbaud 和 scilbaud 作为高8位和低8位,以及 scibaud 作为16位整数用于计算波特率分频寄存器的值。

scibaud=37500000/(8*baud)-1;
这行代码根据输入的波特率值 baud 计算波特率分频寄存器的值 scibaud。LSPCLK(低速外设时钟)的频率为 37.5MHz,SCI的分频因子为 8(由于设置了 SCIHBAUD 和 SCILBAUD 分别为高8位和低8位),所以分频后的SCI时钟频率为 37.5MHz / 8 = 4.6875MHz。因此,计算公式为:波特率分频值 = SCI时钟频率 / 波特率 - 1。

scihbaud=scibaud>>8;
scilbaud=scibaud&0xff;
这两行代码将计算得到的波特率分频寄存器的值 scibaud 分解成高8位和低8位,分别存储在 scihbaud 和 scilbaud 中。

EALLOW;
SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // SCI-A
EDIS;
这部分代码使能了SCI-A模块的时钟(PCLKCR0 寄存器的 SCIAENCLK 位设置为1),从而允许对SCI-A进行配置。

InitSciaGpio();
这是一个初始化SCI-A相关的GPIO(通用输入输出端口)的函数。通过这个函数,将相应的GPIO引脚设置为与SCI-A功能相匹配,从而实现SCI-A的通信。

SciaRegs.SCIFFTX.all=0xE040;
SciaRegs.SCIFFRX.all=0x204f;
SciaRegs.SCIFFCT.all=0x0;
这些代码用于配置SCI FIFO(First In, First Out)寄存器,用于配置SCI发送和接收的FIFO的触发阈值等参数。

SciaRegs.SCICCR.all =0x0007;
SciaRegs.SCICTL1.all =0x0003;
SciaRegs.SCICTL2.all =0x0003;
SciaRegs.SCICTL2.bit.TXINTENA =1;
SciaRegs.SCICTL2.bit.RXBKINTENA =1;
这些代码配置了SCI的控制寄存器(SCICCR)、控制寄存器1(SCICTL1)和控制寄存器2(SCICTL2)。其中的设置如下:

SCICCR.all = 0x0007:设置为 1 停止位,无环回,无奇偶校验,8 个字符位,异步模式,空闲线协议(idle-line protocol)。
SCICTL1.all = 0x0003:使能发送(TX)、接收(RX)和内部 SCICLK。同时,禁用接收错误、睡眠模式和发送唤醒。
SCICTL2.all = 0x0003:使能发送中断(TXINTENA)和接收中断(RXBKINTENA)。
SciaRegs.SCIHBAUD = scihbaud;
SciaRegs.SCILBAUD = scilbaud;
这里将之前计算得到的波特率分频寄存器值 scihbaud 和 scilbaud 分别设置到 SCI 模块的高位波特率寄存器(SCIHBAUD)和低位波特率寄存器(SCILBAUD),从而配置了SCI的波特率。

SciaRegs.SCICTL1.all = 0x0023;
最后,这行代码将 SCI 模块的控制寄存器1设置为 0x0023,从而解除 SCI 模块的复位状态,使得SCI模块开始工作。

通过上述配置,串口SCI(SCI-A)已经被成功初始化,并配置了指定的波特率和通信设置。接下来,可以通过串口SCI进行数据的发送和接收操作。

串口SCI使用

/** main.c**  Created on: 2023年7月9日*      Author: 黎*/#include  "main.h"
#define MAX_STRING_LENGTH 100 // 定义字符串的最大长度void main()
{int i = 0;char *msg;Uint16 ReceivedChar = 0;char scia_rx_buf[MAX_STRING_LENGTH] = { 0 };int rx_flag = 1;int StringIndex = 0; // 字符串索引InitSysCtrl();InitPieCtrl();IER = 0x0000;IFR = 0x0000;InitPieVectTable();UARTa_Init(4800);while (1){printf("\r\nEnter a character: ");while (rx_flag){// Wait for inc character// 等待接收字符while (SciaRegs.SCIFFRX.bit.RXFFST != 1); // wait for XRDY =1 for empty state// 等待 XRDY = 1,表示缓冲区非空// Get character读取接收到的字符ReceivedChar = SciaRegs.SCIRXBUF.all;// 检查是否为换行符或字符串超过最大长度if (ReceivedChar == '\n' || StringIndex >= MAX_STRING_LENGTH - 1){scia_rx_buf[StringIndex] = '\0'; // 在字符串末尾添加空字符rx_flag = 0;break; // 结束接收字符串}// 存储接收到的字符scia_rx_buf[StringIndex] = ReceivedChar;StringIndex++;}// Echo character backprintf("  You sent: ");printf("\n scia_rx_buf = %s\r\n",scia_rx_buf);rx_flag = 1;StringIndex = 0;DELAY_US(1000);}
}

这段代码是一个示例程序,主要功能是通过串口SCI(SCI-A)接收用户输入的字符,并将输入的字符显示回终端上。

以下是代码的详细解释:

#define MAX_STRING_LENGTH 100
这里定义了一个宏 MAX_STRING_LENGTH,用于指定字符串的最大长度。在这个示例中,最大长度被设置为100。

void main()
这是程序的主函数入口。

变量初始化:

int i = 0;:一个用于循环计数的变量。
char *msg;:未使用的指针变量。
Uint16 ReceivedChar = 0;:用于存储接收到的字符的变量,初始值为0。
char scia_rx_buf[MAX_STRING_LENGTH] = { 0 };:用于存储接收到的字符串的字符数组,初始值全部为0。
int rx_flag = 1;:用于控制接收字符的标志位,初始值为1表示正在接收字符。
int StringIndex = 0;:字符串索引,用于指示当前接收到的字符在 scia_rx_buf 数组中的位置。
初始化系统控制和中断控制寄存器。

初始化串口SCI(SCI-A):
UARTa_Init(4800);:这个函数用于初始化SCI-A通信,并设置波特率为4800。

进入主循环 while (1):

通过 printf 函数提示用户输入字符:“Enter a character: ”。
等待接收字符,while (rx_flag) 表示一直等待接收字符,直到 rx_flag 变为0。
在接收到字符时,通过 SciaRegs.SCIFFRX.bit.RXFFST 检查SCI接收缓冲区是否有字符到达。
读取接收到的字符,并存储在 ReceivedChar 中。
判断接收的字符是否为换行符或字符串长度是否超过最大长度(MAX_STRING_LENGTH),如果是,则结束接收,并在字符串末尾添加空字符(‘\0’),同时将 rx_flag 置为0,退出接收字符的循环。
否则,将接收到的字符存储在 scia_rx_buf 数组中,并增加 StringIndex 值,指示下一个字符应该存储在数组的下一个位置。
回显接收到的字符:

通过 printf 函数显示 "You sent: "。
通过 printf 函数显示接收到的字符串 scia_rx_buf。
最后,将 rx_flag 和 StringIndex 重置为初始值,然后通过 DELAY_US 函数延迟一段时间(这里是1000微秒)。

循环会不断重复,用户可以在终端输入字符,程序会接收并显示回显字符,直到结束。

如果文章对您有所帮助,点赞支持,感谢!!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/18960.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

七种遍历Map的方法

七种遍历Map的方法 import java.util.HashMap; import java.util.Iterator; import java.util.Map;public class Wan {public static void main(String[] args) {Map<String,String> dataMap new HashMap<>();dataMap.put("A","Abb");dataMap…

Linux系统CPU和磁盘性能进程分析工具pidstat

一、pidstat对CPU的分析 Linux 上的pidstat(1)工具按进程或线程打印CPU 用量&#xff0c;包括用户态和系统态时间的分解。默认情况下&#xff0c;仅循环输出活动进程的信息。例如&#xff1a; 这个例子捕捉到了系统备份&#xff0c;包含了tar(1)命令&#xff0c;从文件系统读取…

攻防世界zorropub题解与subprocess模块

目录 题目分析&#xff1a; subprocess模块&#xff1a; subprocess.Popen()函数&#xff1a; subprocess.run()函数&#xff1a; 题目脚本&#xff1a; 在攻防世界做到一个题目感觉还挺有意思&#xff0c;记录一下 这个放链接也只是攻防世界的页面&#xff0c;所以直接说…

AI技术快讯:清华开源ChatGLM2双语对话语言模型

ChatGLM2-6B是一个开源项目&#xff0c;提供了ChatGLM2-6B模型的代码和资源。根据提供的搜索结果&#xff0c;以下是对该项目的介绍&#xff1a; 论文&#xff1a;https://arxiv.org/pdf/2103.10360.pdf ChatGLM2-6B是一个开源的双语对话语言模型&#xff0c;是ChatGLM-6B模…

0802|IO进程线程day5 作业(打印时钟在终端上,若终端输入quit,结束时钟)

作业1&#xff1a;守护进程 守护进程的创建&#xff08;5步&#xff09;&#xff1a; 创建孤儿进程&#xff1a;所有工作都在子进程中执行&#xff0c;从形式上脱离终端控制。 fork(), 退出父进程 创建新的会话组&#xff1a;使子进程完全独立出来&#xff0c;防止兄弟进程对其…

Python集成开发环境IDE:Spyder自动换行、函数列表outline、代码折叠

Spyder是一个用PythonQt编写的集成开发环境&#xff0c;包含许多有用的函数和工具。以下是一些常用功能&#xff1a; 变量浏览器&#xff1a;可以动态交互并修改变量&#xff0c;可以进行绘制直方图、时间序列&#xff0c;编辑日期框架或Numpy数组&#xff0c;对集合进行排序&…

【python】两数之和 python实现(详细讲解)

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

【Java可执行命令】(十三)策略工具policytool:界面化创建、编辑和管理策略文件中的权限和配置 ~

Java可执行命令之policytool 1️⃣ 概念2️⃣ 优势和缺点3️⃣ 使用3.1 使用方式3.2 使用技巧3.3 注意事项 4️⃣ 应用场景&#x1f33e; 总结 1️⃣ 概念 在Java平台上&#xff0c;安全性是至关重要的。为了提供细粒度的安全管理机制&#xff0c;Java引入了policytool命令。p…

cmake使用笔记

vim CMakeLists.txt mkdir build cd build cmake ..创建 CMakeLists.txt&#xff0c;添加内容 cmake_minimum_required(VERSION 3.26) #工程名称 project(hello) #宏定义 add_definitions(-D宏名称) #头文件路径 include_directories(${PROJECT_SOURCE_DIR}/inc) #搜索源文件…

Python爬虫教程篇+图形化整理数据(数学建模可用)

一、首先我们先看要求 1.写一个爬虫程序 2、爬取目标网站数据&#xff0c;关键项不能少于5项。 3、存储数据到数据库&#xff0c;可以进行增删改查操作。 4、扩展&#xff1a;将库中数据进行可视化展示。 二、操作步骤&#xff1a; 首先我们根据要求找到一个适合自己的网…

Socket本质、实战演示两个进程建立TCP连接通信的过程

文章目录 Socket是什么引入面试题, 使你更深刻的理解四元组 Socket网络通信大体流程实战演示TCP连接建立过程需要用到的linux 查看网络的一些命令测试的程序一些准备工作启动服务端, 并没有调用accept启动客户端开启服务accept Socket是什么 通俗来说,Socket是套接字,是一种编…

InnoDB引擎底层逻辑讲解——架构之磁盘架构

1. System Tablespaces区域 系统表空间是change buffer&#xff08;更改缓冲区&#xff09;的存放区域&#xff0c;这是在8.0之后重新规划的&#xff0c;在5.x版本的时候&#xff0c;系统表空间还会存放innodb的数据字典undolog日志等信息&#xff0c;在8.0之后主要主要存放更…

常用椭圆曲线介绍

chat-gpt生成&#xff0c;对应python的miracl/core/python库 ED系列 一、ED25519 ED25519使用的椭圆曲线是Curve25519&#xff0c;它是一种高效且安全的椭圆曲线&#xff0c;由Daniel J. Bernstein等人设计。ED25519的密钥长度为256位&#xff0c;提供了128位的安全性。ED25…

Gitlab CI/CD笔记-第一天-GitOps和以前的和jenkins的集成的区别

一、GitOps-CI/CD的流程图 简单解释&#xff1a; 1.提交代码 2.编译构建 3.测试 4.部署 二、gitlab的实现 1、Runer 1.这个就是jenkins里的worker-slave的角色&#xff0c; 2.git-lab server 下发任务&#xff0c;Runner执行。 3.这个R…

关于样本方差为什么除以 n-1

今天上午集训摸鱼看到同学给我发的这个问题感觉挺有意思的 感性理解 这一部分的内容仅代表本蒟蒻没看严谨证明之前的个人见解&#xff0c;如果您想看严谨的证明&#xff0c;请翻到下一部分 还是先把图放上来罢省的有人不知道讲的什么东西 呃我知道这是生物竞赛的东西&#…

下载列表视频的具体操作

主要是介绍怎样获取上篇博客需要的HAR文件和请求域名

docker: Error response from daemon: No command specified.

执行 docker run -it -d -v /home/dell/workspace/workspace/test_192.168.1.202_pipeline:/home/workspace1 --name test_192.168.1.202_pipeline_10 qnx:7.1报错 问题定位&#xff1a;export导入的镜像需要带上command&#xff0c;以下命令查看command信息 docker ps --no…

十进制、八进制、二进制、十六进制

十进制 每一位都有 0~9 十个数码&#xff0c;逢十进一 二进制 每一位仅有 0 和 1 两个数码&#xff0c;逢二进一 八进制 每一位都有 0~7 八个数码&#xff0c;逢八进一 十六进制 每一位都有 0~9、A(10)、B(11)、C(12)、D(13)、E(14)、F(15)&#xff0c;十六个数码&#…

LeetCode每日一题822. 翻转卡片游戏

822. 翻转卡片游戏 中等 68 相关企业 在桌子上有 n 张卡片&#xff0c;每张卡片的正面和背面都写着一个正数&#xff08;正面与背面上的数有可能不一样&#xff09;。 我们可以先翻转任意张卡片&#xff0c;然后选择其中一张卡片。 如果选中的那张卡片背面的数字 x 与任意…

牛客网Verilog刷题——VL53

牛客网Verilog刷题——VL53 题目答案 题目 设计一个单端口RAM&#xff0c;它有&#xff1a; 写接口&#xff0c;读接口&#xff0c;地址接口&#xff0c;时钟接口和复位&#xff1b;存储宽度是4位&#xff0c;深度128。注意rst为低电平复位。模块的接口示意图如下。 输入输出描…