SEO基础

SEO基础

Products

当前位置:首页 > SEO基础 >

南昌网站建设公司提供收费安全培训网站服务,您了解这些信息吗?

96SEO 2026-02-20 08:03 0


文章目录

使用DMA传输实现单片机高效串口转发——以STM32系列为例应用场景实现流程源码示例串口与中断配置DMA外设配置DMA发送数据函数串口中断服务函…使用DMA传输实现单片机高效串口转发——以STM32系列为例

南昌网站建设公司提供收费安全培训网站服务,您了解这些信息吗?

DateAuthorVersionNote2023.08.06Dog

TaoV1.01.

使用DMA传输实现单片机高效串口转发——以STM32系列为例应用场景实现流程源码示例串口与中断配置DMA外设配置DMA发送数据函数串口中断服务函数DMA中断服务函数Modbus协议代码

应用场景

在许多现实应用场景中例如工业自动化控制、嵌入式通信设备等领域单片机需要实时地从一个串口读取数据并转发到另一个串口。

如果使用常规的轮询或中断方法来完成这样的任务会消耗大量的CPU资源效率较低。

此时如果采用DMA直接存储器访问进行串口数据转发则可以具备很多优势例如降低数据转发延时、减轻CPU的运行负载、提高系统的实时性等。

通过串口转发也可以实现多个不同通讯形式例如无线传输与有线传输、不同通讯协议例如自定协议与Modbus协议、不同通讯参数例如两个设备分别具备不同波特率的设备通讯中转。

直接存储器访问DMADirect

Access是一种允许外设或内存直接与其他外设或内存交换数据而不需要通过CPU进行中介处理的技术。

DMA可以有效提高整体系统效率因为它允许数据传输的同时CPU仍可以执行其他任务。

STM32的DMA系统是一项强大的功能允许高效的数据传输同时减轻了CPU的负担。

其灵活的配置选项和与多种外设的兼容性使其适用于许多应用从简单的数据复制到复杂的外设管理。

正确使用DMA可以显著提高STM32微控制器的性能和功能。

From

使用单片机实现串口转发可以分为两种主要的模式直接转发模式与选择转发模式。

直接转发模式是指单片机从一个串口中接收到的数据不经CPU的判断与处理直接通过DMA传输从另个一串口发送出去。

间接转发模式是指单片机从一个串口中接收到的数据需经过CPU的判断与处理选择性的将部分数据或者修改后的数据通过DMA传输从另个一串口发送出去。

直接转发模式的核心实现过程为对于接收数据的DMA通道将串口的数据寄存器地址设置为源地址并设置一个内存地址为目标地址。

对于发送数据的DMA通道将之前设置的内存地址设置为源地址将另一个串口的数据寄存器地址设置为目标地址。

间接转发模式由于CPU的恰当介入而具备更好的灵活性与多场景的适应性因此得到更为广泛的应用。

以USART1与USART3为例间接转发的主要实现流程为

初始化串口初始化USART1和USART3配置波特率、数据位、停止位、奇偶校验等。

配置USART1用于中断接收和DMA转发启用USART1的接收中断功能并配置相关NVIC。

选择适当的DMA通道关联USART1的发送功能。

设置DMA源地址例如缓冲区和目标地址USART3的数据发送寄存器。

配置DMA的大小、方向、优先级、模式等。

配置USART3用于中断接收和DMA转发与USART1类似配置USART3以使用中断进行接收并选择适当的DMA通道用于发送。

设置DMA源地址例如缓冲区和目标地址USART1的数据发送寄存器。

配置DMA的大小、方向、优先级、模式等。

启用USART和DMA启用USART1、USART3以及相关的DMA通道。

中断服务程序处理在USART1的中断服务程序中读取接收到的数据并触发与USART3关联的DMA传输。

在USART3的中断服务程序中读取接收到的数据并触发与USART1关联的DMA传输。

错误处理和同步监视DMA和USART的错误标志并采取适当措施响应任何潜在问题。

根据需要实现缓冲区管理和同步机制以确保数据的完整性和时序。

源码示例

以STM32F407的USART1与USART3双向互发为例展示核心功能实现的源码。

其中部分自定外设配置函数例如USART_ConfigNVIC,

示例代码中本机为Modbus-RTU从机设备其USART1为Modbus-RTU/无线433MHz通讯口USART3为RS485通讯口485总线上连接多台Modbus-RTU从机设备。

单片机从USART1中接收到Modbus-RTU请求报文之后会首先判断从机地址是否为本机如果从机地址为本机地址则进行正常的报文回复处理。

如果从机地址不是本机地址则通过USART3/485端口进行数据转发。

接收到来自USART3/485端口上对应从机的回复后再通过USART1/无线433MHz通讯端口将报文进一步封装后发送到主机。

通过此方法可以实现一对一的无线通讯与一对多的Modbus/RS485的混合组网。

其通讯系统示意图如下所示

串口与中断配置

{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);USART_ConfigNVIC(1,

0);NVIC_InitTypeDef

NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel

DMA2_Stream7_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority

1;NVIC_InitStructure.NVIC_IRQChannelSubPriority

0;NVIC_InitStructure.NVIC_IRQChannelCmd

ENABLE;NVIC_Init(NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel

DMA1_Stream3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority

1;NVIC_InitStructure.NVIC_IRQChannelSubPriority

0;NVIC_InitStructure.NVIC_IRQChannelCmd

ENABLE;NVIC_Init(NVIC_InitStructure);

}void

DMA_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,

ENABLE);

DMA_DeInit(DMA2_Stream7);while(DMA_GetCmdStatus(DMA2_Stream7)

DISABLE){}

//等待stream可配置即DMAy_SxCR.EN变为0DMA_InitStructure.DMA_Channel

DMA_Channel_4;

//从8个channel中选择一个DMA_InitStructure.DMA_PeripheralBaseAddr

(u32)USART1-DR;

//外设地址DMA_InitStructure.DMA_Memory0BaseAddr

(u32)SendBuff;

//存储器0地址双缓存模式还要使用M1ARDMA_InitStructure.DMA_DIR

//存储器到外设模式DMA_InitStructure.DMA_BufferSize

SENDBUFF_SIZE;

DMA_InitStructure.DMA_PeripheralInc

//外设地址保持不变DMA_InitStructure.DMA_MemoryInc

//存储器地址递增DMA_InitStructure.DMA_PeripheralDataSize

//外设数据位宽:8位DMA_InitStructure.DMA_MemoryDataSize

//存储器数据位宽:8位DMA_InitStructure.DMA_Mode

DMA_Mode_Normal;

//普通模式(与循环模式对应)DMA_InitStructure.DMA_Priority

DMA_Priority_Medium;

//中等优先级DMA_InitStructure.DMA_FIFOMode

//禁止FIFO模式

DMA_InitStructure.DMA_FIFOThreshold

DMA_FIFOThreshold_Full;DMA_InitStructure.DMA_MemoryBurst

//单次传输DMA_InitStructure.DMA_PeripheralBurst

//单次传输DMA_ITConfig(DMA2_Stream7,

DMA_IT_TC,

DMA_InitStructure);//配置USART3_TX-Stream:

DMA-1

DMA_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,

ENABLE);

DMA_DeInit(DMA1_Stream3);while(DMA_GetCmdStatus(DMA1_Stream3)

DISABLE){}

//等待stream可配置即DMAy_SxCR.EN变为0DMA_InitStructure.DMA_Channel

DMA_Channel_4;

//从8个channel中选择一个DMA_InitStructure.DMA_PeripheralBaseAddr

(u32)USART3-DR;

//外设地址DMA_InitStructure.DMA_Memory0BaseAddr

(u32)SendBuff;

//存储器0地址双缓存模式还要使用M1ARDMA_InitStructure.DMA_DIR

//存储器到外设模式DMA_InitStructure.DMA_BufferSize

SENDBUFF_SIZE;

DMA_InitStructure.DMA_PeripheralInc

//外设地址保持不变DMA_InitStructure.DMA_MemoryInc

//存储器地址递增DMA_InitStructure.DMA_PeripheralDataSize

//外设数据位宽:8位DMA_InitStructure.DMA_MemoryDataSize

//存储器数据位宽:8位DMA_InitStructure.DMA_Mode

DMA_Mode_Normal;

//普通模式(与循环模式对应)DMA_InitStructure.DMA_Priority

DMA_Priority_Medium;

//中等优先级DMA_InitStructure.DMA_FIFOMode

//禁止FIFO模式

DMA_InitStructure.DMA_FIFOThreshold

DMA_FIFOThreshold_Full;DMA_InitStructure.DMA_MemoryBurst

//单次传输DMA_InitStructure.DMA_PeripheralBurst

//单次传输DMA_ITConfig(DMA1_Stream3,

DMA_IT_TC,

由于USART3是RS485协议传输需要选择收发状态。

本文源码中通过RS485_CTRL_ADDR的值实现收发转换。

在发送数据前先将RS485_CTRL_ADDR置1。

在DMA中断服务函数中发送完成中断将RS485_CTRL_ADDR置0恢复RS485的数据接收状态。

void

DMA_InitStructure;DMA_Cmd(DMA2_Stream7,

DISABLE);

//关闭DMA通道DMA_SetCurrDataCounter(DMA2_Stream7,

(uint16_t)length);

//发送DMA流的地址不自增DMA2_Stream7-M0AR

(uint32_t)tx_buffer;

//设置接收和发送的内存地址DMA_Cmd(DMA2_Stream7,

ENABLE);

//打开DMA通道USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);

while(

DMA_GetFlagStatus(DMA2_Stream7,

DMA_FLAG_TCIF7)

DMA_InitStructure;DMA_Cmd(DMA1_Stream3,

DISABLE);

//关闭DMA通道DMA_SetCurrDataCounter(DMA1_Stream3,

(uint16_t)length);

//发送DMA流的地址不自增DMA1_Stream3-M0AR

(uint32_t)tx_buffer;

//设置接收和发送的内存地址DMA_Cmd(DMA1_Stream3,

ENABLE);

//打开DMA通道USART_DMACmd(USART3,USART_DMAReq_Tx,ENABLE);

while(

DMA_GetFlagStatus(DMA1_Stream3,

DMA_FLAG_TCIF3)

data_temp[300];memcpy(data_temp,

MB_CommParam.MB_PreTrans_Num);memcpy(data_temp

tx_buffer,

length);USART1_DMA_SendData(data_temp,

length

MB_CommParam.MB_PreTrans_Num);//

MB_CommParam.MB_PreTrans_Num);//

tx_buffer,

本机地址不发送return;}*RS485_CTRL_ADDR

1;//

delay_ms(1);USART3_DMA_SendData(tx_buffer,

length);//

恢复RS485控制信号为接收状态的操作放到DMA发送完成中断中//

vtaskDelay(100);//

示例代码中本机为Modbus-RTU从机设备其USART1为Modbus-RTU/无线433MHz通讯串口USART3为RS485通讯串口485总线上连接多台Modbus-RTU从机设备。

因此MB_CommParam.MB_PortNum

USART1:

在串口接收中断USART_IT_RXNE的服务函数中调用Modbus-RTU协议的数据接收函数pxMBFrameCBByteReceived。

USART3:

在串口接收中断USART_IT_RXNE的服务函数中往FIFO队列缓冲中添加接收到的数据。

在串口空闲中断USART_IT_IDLE的服务函数中判断数据接收完成并实现数据转发的操作。

void

然后程序就不会因为ORE未被清除而一直不断的进入串口中断*/if

USART_FLAG_ORE)

RESET){USART_ReceiveByte(USART1);}if

1){if

RESET){pxMBFrameCBByteReceived();USART_ClearITPendingBit(USART1,

USART_IT_RXNE);}else

RESET){pxMBFrameCBTransmitterEmpty();USART_ClearITPendingBit(USART1,

USART_IT_TC);}else

通过读串口DR寄存器里的值来清除IDLE标志位否则将一直触发空闲中断uint16_t

data_temp

RESET){USART_ReceiveByte(USART3);}if

3){/*

RESET){USART_ClearITPendingBit(USART3,

USART_IT_RXNE);USART_WriteFIFO(2,

USART_IT_IDLE)

串口空闲数据接收完成时转发数据到USART1{uint16_t

data_temp

数据接收完成后转发数据到串口1USART3_RevBuffer_Handler(USART1_WSN32_SendData);//

USART3_RevBuffer_Handler(USART2_RS232_SendData);}}else

USART_IT_TC)

RESET){USART_ClearITPendingBit(USART3,

USART_IT_TC);//

在DMA中断服务函数中发送完成中断将RS485_CTRL_ADDR置0恢复RS485的数据接收状态。

void

(DMA_GetFlagStatus(DMA2_Stream7,

DMA_FLAG_TCIF7)

关闭DMA通道DMA_ClearFlag(DMA2_Stream7,

DMA_FLAG_TCIF7);}

(DMA_GetFlagStatus(DMA1_Stream3,

DMA_FLAG_TCIF3)

关闭DMA通道DMA_ClearFlag(DMA1_Stream3,

DMA_FLAG_TCIF3);//

delay_ms(1);delay_us(500);*RS485_CTRL_ADDR

}Modbus协议代码

Modbus-RTU协议通过移植freemodbus库实现笔者在此库中增加了报文接收的函数指针

///

RTU_ADU_ReceivedHandler;因此可以设计一个回调函数USART3_RS485_SendData已在上文提供实现源码注册给RTU_ADU_ReceivedHandler指针实现非本机地址的modbus请求指令通过USART3转发。

User_Init函数首先通过读取两个拨码开关的值来判断当前设备的功能设定如果处于无线通讯状态主机与本机一对一则使能串口转发功能。

通过将不是本机地址的Modbus报文通过RS485总线发送出去再将接收到的RS485回复数据通过无线通讯转发到主机则可以实现多机通讯与无线/有线混合组网。

void

Debug_GetDipSwitchValue(GPIO_Array_DevAddr,

0);SigChan_Val

Debug_GetDipSwitchValue(GPIO_Array_SigChan,

0);if

初始化Modbus四种寄存器User_MB_InitRegs();if(IsEnablePortForwarding



SEO优化服务概述

作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。

百度官方合作伙伴 白帽SEO技术 数据驱动优化 效果长期稳定

SEO优化核心服务

网站技术SEO

  • 网站结构优化 - 提升网站爬虫可访问性
  • 页面速度优化 - 缩短加载时间,提高用户体验
  • 移动端适配 - 确保移动设备友好性
  • HTTPS安全协议 - 提升网站安全性与信任度
  • 结构化数据标记 - 增强搜索结果显示效果

内容优化服务

  • 关键词研究与布局 - 精准定位目标关键词
  • 高质量内容创作 - 原创、专业、有价值的内容
  • Meta标签优化 - 提升点击率和相关性
  • 内容更新策略 - 保持网站内容新鲜度
  • 多媒体内容优化 - 图片、视频SEO优化

外链建设策略

  • 高质量外链获取 - 权威网站链接建设
  • 品牌提及监控 - 追踪品牌在线曝光
  • 行业目录提交 - 提升网站基础权威
  • 社交媒体整合 - 增强内容传播力
  • 链接质量分析 - 避免低质量链接风险

SEO服务方案对比

服务项目 基础套餐 标准套餐 高级定制
关键词优化数量 10-20个核心词 30-50个核心词+长尾词 80-150个全方位覆盖
内容优化 基础页面优化 全站内容优化+每月5篇原创 个性化内容策略+每月15篇原创
技术SEO 基本技术检查 全面技术优化+移动适配 深度技术重构+性能优化
外链建设 每月5-10条 每月20-30条高质量外链 每月50+条多渠道外链
数据报告 月度基础报告 双周详细报告+分析 每周深度报告+策略调整
效果保障 3-6个月见效 2-4个月见效 1-3个月快速见效

SEO优化实施流程

我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:

1

网站诊断分析

全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。

2

关键词策略制定

基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。

3

技术优化实施

解决网站技术问题,优化网站结构,提升页面速度和移动端体验。

4

内容优化建设

创作高质量原创内容,优化现有页面,建立内容更新机制。

5

外链建设推广

获取高质量外部链接,建立品牌在线影响力,提升网站权威度。

6

数据监控调整

持续监控排名、流量和转化数据,根据效果调整优化策略。

SEO优化常见问题

SEO优化一般需要多长时间才能看到效果?
SEO是一个渐进的过程,通常需要3-6个月才能看到明显效果。具体时间取决于网站现状、竞争程度和优化强度。我们的标准套餐一般在2-4个月内开始显现效果,高级定制方案可能在1-3个月内就能看到初步成果。
你们使用白帽SEO技术还是黑帽技术?
我们始终坚持使用白帽SEO技术,遵循搜索引擎的官方指南。我们的优化策略注重长期效果和可持续性,绝不使用任何可能导致网站被惩罚的违规手段。作为百度官方合作伙伴,我们承诺提供安全、合规的SEO服务。
SEO优化后效果能持续多久?
通过我们的白帽SEO策略获得的排名和流量具有长期稳定性。一旦网站达到理想排名,只需适当的维护和更新,效果可以持续数年。我们提供优化后维护服务,确保您的网站长期保持竞争优势。
你们提供SEO优化效果保障吗?
我们提供基于数据的SEO效果承诺。根据服务套餐不同,我们承诺在约定时间内将核心关键词优化到指定排名位置,或实现约定的自然流量增长目标。所有承诺都会在服务合同中明确约定,并提供详细的KPI衡量标准。

SEO优化效果数据

基于我们服务的客户数据统计,平均优化效果如下:

+85%
自然搜索流量提升
+120%
关键词排名数量
+60%
网站转化率提升
3-6月
平均见效周期

行业案例 - 制造业

  • 优化前:日均自然流量120,核心词无排名
  • 优化6个月后:日均自然流量950,15个核心词首页排名
  • 效果提升:流量增长692%,询盘量增加320%

行业案例 - 电商

  • 优化前:月均自然订单50单,转化率1.2%
  • 优化4个月后:月均自然订单210单,转化率2.8%
  • 效果提升:订单增长320%,转化率提升133%

行业案例 - 教育

  • 优化前:月均咨询量35个,主要依赖付费广告
  • 优化5个月后:月均咨询量180个,自然流量占比65%
  • 效果提升:咨询量增长414%,营销成本降低57%

为什么选择我们的SEO服务

专业团队

  • 10年以上SEO经验专家带队
  • 百度、Google认证工程师
  • 内容创作、技术开发、数据分析多领域团队
  • 持续培训保持技术领先

数据驱动

  • 自主研发SEO分析工具
  • 实时排名监控系统
  • 竞争对手深度分析
  • 效果可视化报告

透明合作

  • 清晰的服务内容和价格
  • 定期进展汇报和沟通
  • 效果数据实时可查
  • 灵活的合同条款

我们的SEO服务理念

我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。

提交需求或反馈

Demand feedback