串口发送数据

2023-05-16

关于串口发送数据,自己以前呢是这样

void Usart_Out_Char(unsigned char *c,uint32_t cnt)
{
while(cnt--)
{
USART_SendData(USART1, *c++);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET );
}
}

下面的调用方式

uint8_t aaa[1024]={1,2,3,42,0};

int main(void)
{
NVIC_Configuration();
Led_Gpio_Init();
Timer2_Config();
uart_init(115200); //串口初始化为115200while(1)
{
Usart_Out_Char(aaa,1024);
delay_ms(1000);
PFout(6) = ~PFout(6);
}
}

当发送数据的时候,会一直在调用此函数的地方等着,,,,,,直至发送完所有的数据,要知道用串口中断发送数据要比这样发送快的多.......瞎耽误时间

假设现在我用中断发送

void UsartOutChar(unsigned char *Buff,uint32_t cnt)
{
dat = Buff;//把发送地址给dat
BuffCnt = cnt;//记录发送的个数
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);//打开发送中断
}

 

void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
}
if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)//发送中断
{
if(BuffCnt--)
{
USART_SendData(USART1,*dat);//发送数据
dat++;
}
else
{
//发送字节结束
USART_ClearITPendingBit(USART1,USART_IT_TXE);
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
USART_ITConfig(USART1, USART_IT_TC, ENABLE);
}
}
//发送完成
if (USART_GetITStatus(USART1, USART_IT_TC) != RESET)
{
USART_ClearITPendingBit(USART1,USART_IT_TC);
USART_ITConfig(USART1, USART_IT_TC, DISABLE);
}
}

 

uint8_t aaa[1024]={1,2,3,42,0};

int main(void)
{
NVIC_Configuration();
Led_Gpio_Init();
Timer2_Config();
uart_init(115200); //串口初始化为115200while(1)
{
UsartOutChar(aaa,10);
delay_ms(10);
}
}

 

加一个缓冲区---假设是下面这样子,中断发送的数据从这个缓冲区里面取

然后呢,接着又填入了

接着

假设我又想添加数据,可是呢后面空的那一块数据空间不够了......要是能把数组的尾和头联系起来就好啦......

假设加满了,,,如果能自动的加到前面就好啦.....

 

今天先这样...太晚啦..现在最大的愿望什么时候能安心睡个早觉..再这样下去真担心会挂了......有空再详加..

下面是实现程序--实现程序是自己想学Esp8266连接机智云的时候无意中看到的,,,,,记得 天鲁哥 曾经说过环形队列实现的很巧妙,,,改天有空再研究下当初天鲁哥给的程序

 往里面加数据尾指针向右增加...加到头回到首地址

从里面读数据头指针向右增加...加到头回到首地址

 

 注意      

还是在唠叨唠叨

 

 

 

 

rb_t pRb; ///< 环形缓冲区结构体变量
uint8_t rbBuf[RB_MAX_LEN]; ///< 环形缓冲区数据缓存区

void rbCreate(rb_t* rb,u8 *Buff,uint32_t BuffLen)//创建或者说初始化环形缓冲区
{
if(NULL == rb)
{
printf("ERROR: input rb is NULL\n");
return;
}
rb->rbCapacity = BuffLen;
rb->rbBuff = Buff;
rb->rbHead = rb->rbBuff;//头指向数组首地址
rb->rbTail = rb->rbBuff;//尾指向数组首地址
}

void rbDelete(rb_t* rb)//删除一个环形缓冲区
{
if(NULL == rb)
{
printf("ERROR: input rb is NULL\n");
return;
}

rb->rbBuff = NULL;//地址赋值为空
rb->rbHead = NULL;//头地址为空
rb->rbTail = NULL;//尾地址尾空
rb->rbCapacity = 0;//长度为空
}

int32_t rbCapacity(rb_t *rb)//获取链表的长度
{
if(NULL == rb)
{
printf("ERROR: input rb is NULL\n");
return -1;
}

return rb->rbCapacity;
}

int32_t rbCanRead(rb_t *rb)//返回能读的空间
{
if(NULL == rb)
{
printf("ERROR: input rb is NULL\n");
return -1;
}

if (rb->rbHead == rb->rbTail)//头与尾相遇
{
return 0;
}

if (rb->rbHead < rb->rbTail)//尾大于头
{
return rb->rbTail - rb->rbHead;
}

return rbCapacity(rb) - (rb->rbHead - rb->rbTail);//头大于尾
}

int32_t rbCanWrite(rb_t *rb)//返回能写入的空间
{
if(NULL == rb)
{
printf("ERROR: input rb is NULL\n");
return -1;
}

return rbCapacity(rb) - rbCanRead(rb);//总的减去已经写入的空间
}

/*
rb--要读的环形链表
data--读出的数据
count--读的个数
*/
int32_t rbRead(rb_t *rb, void *data, size_t count)
{
int copySz = 0;

if(NULL == rb)
{
printf("ERROR: input rb is NULL\n");
return -1;
}

if(NULL == data)
{
printf("ERROR: input data is NULL\n");
return -1;
}

if (rb->rbHead < rb->rbTail)//尾大于头
{
copySz = min(count, rbCanRead(rb));//查看能读的个数
memcpy(data, rb->rbHead, copySz);//读出数据到data
rb->rbHead += copySz;//头指针加上读取的个数
return copySz;//返回读取的个数
}
else //头大于等于了尾
{
if (count < rbCapacity(rb)-(rb->rbHead - rb->rbBuff))//读的个数小于头上面的数据量
{
copySz = count;//读出的个数
memcpy(data, rb->rbHead, copySz);//
rb->rbHead += copySz;
return copySz;
}
else//读的个数大于头上面的数据量
{
copySz = rbCapacity(rb) - (rb->rbHead - rb->rbBuff);//先读出来头上面的数据
memcpy(data, rb->rbHead, copySz);
rb->rbHead = rb->rbBuff;//头指针指向数组的首地址
//还要读的个数
copySz += rbRead(rb, (char*)data+copySz, count-copySz);//接着读剩余要读的个数
return copySz;
}
}
}

int32_t rbWrite(rb_t *rb, const void *data, size_t count)
{
int tailAvailSz = 0;

if(NULL == rb)
{
printf("ERROR: rb is empty \n");
return -1;
}

if(NULL == data)
{
printf("ERROR: data is empty \n");
return -1;
}

if (count >= rbCanWrite(rb))//如果剩余的空间不够
{
printf("ERROR: no memory \n");
return -1;
}

if (rb->rbHead <= rb->rbTail)//头小于等于尾
{
tailAvailSz = rbCapacity(rb) - (rb->rbTail - rb->rbBuff);//查看尾上面剩余的空间
if (count <= tailAvailSz)//个数小于等于尾上面剩余的空间
{
memcpy(rb->rbTail, data, count);//拷贝数据到环形数组
rb->rbTail += count;//尾指针加上数据个数
if (rb->rbTail == rb->rbBuff+rbCapacity(rb))//正好写到最后
{
rb->rbTail = rb->rbBuff;//尾指向数组的首地址
}
return count;//返回写入的数据个数
}
else
{
memcpy(rb->rbTail, data, tailAvailSz);//填入尾上面剩余的空间
rb->rbTail = rb->rbBuff;//尾指针指向数组首地址
//剩余空间 剩余数据的首地址 剩余数据的个数
return tailAvailSz + rbWrite(rb, (char*)data+tailAvailSz, count-tailAvailSz);//接着写剩余的数据
}
}
else //头大于尾
{
memcpy(rb->rbTail, data, count);
rb->rbTail += count;
return count;
}
}
/**@} */

/**
* @brief 向环形缓冲区写入数据
* @param [in] buf : buf地址
* @param [in] len : 字节长度
* @return 正确 : 返回写入的数据长度
失败 : -1
*/
int32_t PutData(uint8_t *buf, uint32_t len)
{
int32_t count = 0;

if(NULL == buf)
{
printf("ERROR: gizPutData buf is empty \n");
return -1;
}

count = rbWrite(&pRb, buf, len);
if(count != len)
{
printf("ERROR: Failed to rbWrite \n");
return -1;
}
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
return count;
}

 

#ifndef LOOPLIST_H_
#define LOOPLIST_H_

#ifndef LOOPLIST_C_//如果没有定义 AnnularArray_C_
#define LOOPLIST_C_ extern
#else
#define LOOPLIST_C_
#endif

#include <stm32f10x.h>

#define size_t uint16_t

#define RB_MAX_LEN 1024 //缓冲区最大长度
#define min(a, b) (a)<(b)?(a):(b) ///< 获取最小值

/** 环形缓冲区数据结构 */
typedef struct {
size_t rbCapacity;//空间大小
uint8_t *rbHead; //头
uint8_t *rbTail; //尾
uint8_t *rbBuff; //数组的首地址
}rb_t;

LOOPLIST_C_ rb_t pRb; ///< 环形缓冲区结构体变量
LOOPLIST_C_ uint8_t rbBuf[RB_MAX_LEN]; ///< 环形缓冲区数据缓存区

LOOPLIST_C_ void rbCreate(rb_t *rb,u8 *Buff,uint32_t BuffLen);//创建或者说初始化环形缓冲区
LOOPLIST_C_ void rbDelete(rb_t* rb);
LOOPLIST_C_ int32_t rbCapacity(rb_t *rb);//得到环形大小
LOOPLIST_C_ int32_t rbCanRead(rb_t *rb);//能读出数据的个数
LOOPLIST_C_ int32_t rbCanWrite(rb_t *rb);//还剩余的空间
LOOPLIST_C_ int32_t rbRead(rb_t *rb, void *data, size_t count);//读取数据
LOOPLIST_C_ int32_t rbWrite(rb_t *rb, const void *data, size_t count);
LOOPLIST_C_ int32_t PutData(uint8_t *buf, uint32_t len);


#endif

 

#include "include.h"

uint8_t aaa[50]={1,1,1,1,1,1,1,1,1,1};

uint8_t bbb[50]={3,3,3,3,3,3,3,3,3,3};
int main(void)
{
NVIC_Configuration();
Led_Gpio_Init();
Timer2_Config();
uart_init(115200); //串口初始化为115200
rbCreate(&pRb,SendBuff,USART_REC_LEN);//创建环形队列
while(1)
{
PutData(aaa,10);//发送数据
PutData(bbb,10);//发送数据
delay_ms(10);
}
}

 

void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
}
if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
{
if(rbCanRead(&pRb)>0)//如果里面的数据个数大于0
{
rbRead(&pRb, &SendDat, 1);//读取一个数据
USART_SendData(USART1, SendDat);//发送
}
else
{
//发送字节结束
USART_ClearITPendingBit(USART1,USART_IT_TXE);
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
USART_ITConfig(USART1, USART_IT_TC, ENABLE);
}
}
//发送完成
if (USART_GetITStatus(USART1, USART_IT_TC) != RESET)
{
USART_ClearITPendingBit(USART1,USART_IT_TC);
USART_ITConfig(USART1, USART_IT_TC, DISABLE);
}
}

 

其实再完美点就是加上DMA....后期我尽量用LPC的单片机做....不对是一定要用LPC的单片机做成dma的---

 

  程序链接:http://pan.baidu.com/s/1pLlXDfP 密码:6kci

 

转载于:https://www.cnblogs.com/wolf-man/p/10875482.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

串口发送数据 的相关文章

  • 使用Formik轻松开发更高质量的React表单(二)使用指南

    一个基本的例子 设想你要开发一个可以编辑用户数据的表单 不过 xff0c 你的用户API端使用了具有类似下面的嵌套对象表达 xff1a id string email string social facebook string twitte
  • Media Foundation基本概念

    Media Foundation Media Foundation xff08 简称MF xff09 是微软用来替换DirectShow的视频API xff0c 从Vista开始支持 xff0c 直到现在的Windows 8 xff0c W
  • 算法公式 - 图形化

    在定制 数学公式的时候 可能 希望有个直观的 展现 http www wolframalpha com 我们前一段时间用到的 推荐分值 90 天 递减公式 xff0c 如果这东西早发现 公式就不会错了 xff01 目前我们递减的公式 y 6
  • windows平台使用SecureCRT+Xming实现图形界面来执行linux平台的一些图形程序

    需求分析 xff1a windows平台下使用ssh远程连接linux服务器 xff0c 实现图形界面来执行linux平台的一些程序 xff0c 如system config kickstart xeyes 等 实验环境 xff1a 服务器
  • 上线:准备和部署软件包时开发和运维的角色

    按照发布流程正确的部署软件 二进制代码和与之相关的配置文件 到你的开发 测试 验收或产品环境 xff08 DTAP xff09 是一项复杂的任务 xff0c 涉及到众多部门和团队 不幸的是 xff0c 在许多组织中这项关键的流程还是费时并容
  • TortoiseGit安装与配置

    2019独角兽企业重金招聘Python工程师标准 gt gt gt TortoiseGit 简称 tgit 中文名海龟Git 海龟Git只支持神器 Windows 系统 有一个前辈海龟SVN TortoiseSVN和TortoiseGit都
  • 在CentOS 7中Samba服务安装和配置

    这篇指南介绍了如何在CentOS7中配置匿名和安全的Samba服务器 Samba是一个开源 自由软件套件 xff0c 提供无缝的文件和打印服务SMB CIFS客户端 Samba是免费的 xff0c 不像其他的SMB CIFS的实现着 Sam
  • 如何清除团队中的“害群之马”?(下篇)

    阅读更多系列文章请访问我的GitHub博客 这篇文章来自于一位同事面试时被问到的一个问题 xff1a 如果团队内有老员工 xff0c 能力不强又喜欢偷懒 xff0c 怎么办 xff1f 对于这类问题 xff0c 最简单的回答就是 xff1a
  • oracle 备份失败 RMAN-03002,RMAN-00569,RMAN-00571等处理方法

    备份失败 1 备份失败信息 xff1a 39 52 备份 200 3 oracle 数据 开始执行 11 39 54 NICEGAIN SW741B 开始分析备份数据源 xff0c 请稍候 11 39 54 Oracle Database
  • KVM 开启嵌套虚拟化

    问题 在 CentOS KVM 上启动虚拟机来部署 OpenStack 测试环境 xff0c 在启动具有 CPU 绑定 NUMA 亲和的虚拟机时触发错误 xff1a libvirtError Requested operation is n
  • VNC指定用户屏幕号登录(Oracle安装时使用)

    由于oracle在安装的过程中需要从oracle切换到root用户 xff0c 为了在安装的时候 xff0c 可以远程安装 xff0c 故对VNC进行配置 vim etc sysconfig vncservers定义root的屏幕号为1 o
  • ubuntu 18.04屏幕共享

    2019独角兽企业重金招聘Python工程师标准 gt gt gt windows7系统通过连接ubuntu 18 04屏幕共享 xff0c 来访问Ubuntu桌面 1 安装 xff1a sudo apt install xrdp 2 编辑
  • Git:分支管理

    本文目录 1 使用方法 1 1 常规开发 1 2 热修复 1 3 净化Test分支 2 冲突解决 3 分支说明 3 1 master分支 3 2 release分支 3 3 test分支 3 4 feature分支 3 5 hotfix分支

随机推荐

  • [转载]打造自己喜欢的Linux桌面----archlinux

    原文地址 xff1a 打造自己喜欢的Linux桌面 archlinux 作者 xff1a 三尺椴 打造自己的Linux桌面 Archlinux 2011 01 16 文 s cd xff08 常用桌面组合 Archlinux 43 fvwm
  • 操作日志工具类

    package com util import java util Date import java util UUID import javax servlet http HttpServletRequest import org spr
  • 其他窗体赋值给comboBox实现值的回显,并使赋的值处于选中状态(根据text获取selectedindex)...

    Form1 发货单位的这个下拉框comboBox1已经绑定数据库test表的name字段 xff0c 里面有很多单位名称 比如有 xff1a 甲公司 乙公司 1 Form1的comboBox1首先绑定数据库的数据表test using SQ
  • 树莓派之OLED12864视频播放—BadApple

    代码地址如下 xff1a http www demodashi com demo 13218 html 概述 本篇教程讲述了使用树莓派驱动OLED12864液晶屏 并在液晶屏上播放动画和视频 硬件平台 树莓派一台 RaspberryPi 2
  • 帮你解决无法安装ia32-libs 的问题

    在安装安装wpsforlinux等软件时 xff0c 我们要经常要运行 代码 sudo apt get install ia32 libs 问题 xff1a 解决办法 xff1a 一 在终端运行 sudo apt get install g
  • 爬虫带你了解一下Golang的市场行情

    了解一下Golang的市场行情 项目地址 xff1a https github com go crawler 如果对你有所帮助 xff0c 欢迎 Star xff0c 给文章来波赞 xff0c 这样可以让更多的人看见 目标 在工作中 Gol
  • C语言如何分离一个数的高低位,如何将2个字节变成一个字节

    关于这个概念 xff0c 是我从工作中学习的 xff0c 虽然在读书的时候就应该要掌握 xff0c 但是在开发中 xff0c 这项技能尤其重要 我是做嵌入式开发的 xff0c 在嵌入式开发过程中 xff0c 如何对数据操作必然是不可缺少的问
  • 你要的免费Proxy资源全在这里了

    地址 xff1a github com derekhe Pro 介绍 在 爬虫实战 xff1a 从数据到产品 一书中 xff0c 我讲到了一个基于ProxyBroker的代理池 经过我的长时间的实践 xff0c 这个代理池用起来非常的方便和
  • 短视频App源码:如何搭建短视频社区

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 短视频App源码 xff1a 如何搭建短视频社区 随着国内移动互联网的发展 xff0c 中国的移动互联网时代已经来临 xff0c 以快手 抖音为主的短视频平台迅速火热起来
  • mysql 百万级数据的模糊查询 优化 笔记

    最近老大给了一个需求 xff0c 是要写一个姓名的模糊查询 问题很简单 xff0c 难度在于这张表有将近500W条数据 如果要做中文的模糊查询 xff0c 效率简直惨不忍睹 网上查了一下资料 xff0c 发现全文索引挺符合我的需要的 结果
  • 如何在Ubuntu 18.04上创建启用了Sudo的新用户[快速入门]

    介绍 Introduction The sudo command provides a mechanism for granting administrator privileges ordinarily only available to
  • Sql语句批量更新数据(多表关联)

    最近在项目中遇到一个问题 xff0c 原来设计的功能是不需要一个特定的字段值depid的 xff0c 但是新的功能需要根据depid来展现 xff0c 于是出现了这样一个问题 xff0c 新增加的数据都有正确的depid 而原来的大量的数据
  • Matlab M文件“程序块”注释方法

    方法一 xff1a 注释语句的快捷键是Ctrl 43 R 取消注释的快捷键是Ctrl 43 T 并且支持一次注释 xff08 或者取消注释 xff09 多行语句 选定要注释 xff08 或者取消注释 xff09 的那些语句 xff0c 然后
  • 如何开发高性能低成本的网站之技术选择

    每个企业都是慢慢发展起来的 xff0c 在起步阶段成本是一个不得不考虑的重大问题 直接入正题 xff1a 前台框架 ASP NET MVC 43 Jquery 43 Json 43 Flash ASP NET MVC 高性能速度快 xff0
  • 密码学题库

    参考题库 一 选择题 1 第一个实用的 迄今为止应用最广的公钥密码体制是 A A RSA B Elgamal C ECC D NTRU 2 一个密码系统至少由明文 密文 加密算法和解密算法 密钥五部分组成 xff0c 而其安全性是由 xff
  • 【linux】linux 下 shell命令 执行结果赋值给变量【两种方式】

    方法1 xff1a 通用方法 使用Tab键上面的反引号 例子如下 xff1a find命令 模糊查询在 apps swapping目录下 查找 文件名中包含swapping并且以 jar结尾的文件 使用反引号 引住命令 xff0c 然后使用
  • Octet 和 Byte 的区别

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 关于程序的文章中 Octet 和 Byte是常见的词汇 xff0c 他们都表示8 bit 在读RFC或网络设备文档时 xff0c 经常见到Octet这量词来指代8位 xff
  • 云计算的弹性

    云计算最大的优势就在于弹性 目前 xff0c 阿里云已拥有在数分钟内开出一家中型互联网公司所需要的IT资源的能力 xff0c 这就能够保证大部分企业在云上所构建的业务都能够承受巨大的业务量压力 计算弹性 纵向的弹性 xff0c 即单个服务器
  • LACP 详解

    一 LACP简介 1 LACP协议简介 基于 IEEE802 3ad 标准的LACP xff08 Link Aggregation Control Protocol xff0c 链路汇聚控 制协议 xff09 是一种实现链路动态汇聚与解汇聚
  • 串口发送数据

    关于串口发送数据 自己以前呢是这样 void Usart Out Char unsigned char c uint32 t cnt while cnt USART SendData USART1 c 43 43 while USART G