你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F103做JSON时,char型指针与DMA的u32地址转换问题

[复制链接]
wdshuang09 提问时间:2019-4-14 11:16 /
最近用JOSN数据通信,JSON数据包用printf去发送,是OK的,发送函数,如图片2       char *string = NULL;
        string = cJSON_PrintUnformatted(root);
        printf("%s\n",string);
        free(string);
为了提高速度,采用DMA发送,代码如下,现在发送给遇到一个问题,发送数据会丢掉第2、3、4数据,后面的数据是正常的,如图片1
  char *string = NULL;
  string = cJSON_PrintUnformatted(root);
  DMA_Uart2_Tx_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART2->DR;
  DMA_Uart2_Tx_InitStructure.DMA_MemoryBaseAddr =(u32)string;
  DMA_Uart2_Tx_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_Uart2_Tx_InitStructure.DMA_BufferSize = strlen(string);
  DMA_Uart2_Tx_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_Uart2_Tx_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_Uart2_Tx_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;// 外设数据宽度8位,1个字节
  DMA_Uart2_Tx_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;// 内存数据宽度8位,1个字节
  DMA_Uart2_Tx_InitStructure.DMA_Mode = DMA_Mode_Normal;
  DMA_Uart2_Tx_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_Uart2_Tx_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel7, &DMA_Uart2_Tx_InitStructure);
  DMA_Cmd(DMA1_Channel7, ENABLE);
  free(string);
分析原因:string = cJSON_PrintUnformatted(root);string是char型的,而DMA_Uart2_Tx_InitStructure.DMA_MemoryBaseAddr =(u32)string;强制转化为32位的,首地址数据只有sting的第一个数据,当DMA_MemoryBaseAddr++时,相当于加了4字节,就直接到string的第5个字节了,造成丢掉数据。
解决方案一先定义u32指针,将string数据一个个地复制到u32指针中去,但由于sting有1000多字节数据,复制到U32指针会造成空间不够,方法行不通;

现不知道如何解决,不知有没有其它方法解决,求解

1.jpg
2.jpg
收藏 评论6 发布时间:2019-4-14 11:16

举报

6个回答
天臆弄人 回答时间:2019-4-15 13:48:06
我再帮楼主补充个知识点,用DMA 发送并不会提高发送速度,他只是把原来CPU发送的那段代码通过硬件自己发送了,他原来发送要 100ms,用DMA也不会提高到50ms,

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

edmundlee 回答时间:2019-4-14 11:57:37
这个(u32)string; 中的(u32)不是你想的意思, 它是把指针转换为32位数的意思, DMA发送的类型是用DMA_MemoryDataSize_Byte指定的
你的问题应该是别的原因引起的
问题是在free(string);
free(string);应该放在DMA完成中断里
都还没开始发送, 你就free了,string的内容可以随时改变

评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

wdshuang09 回答时间:2019-4-14 13:43:47
edmundlee 发表于 2019-4-14 11:57
这个(u32)string; 中的(u32)不是你想的意思, 它是把指针转换为32位数的意思, DMA发送的类型是用DMA_Mem ...

楼上正解,是我分析错了,
fengyu01 回答时间:2019-4-15 09:39:13
666666
七哥 回答时间:2019-4-15 10:01:15
wdshuang09 发表于 2019-4-14 13:43
楼上正解,是我分析错了,

既然解决了,那就结贴吧。

DMA的传输数据类型已经是 DMA_MemoryDataSize ,就不存在32位对齐,或指针加4的问题。
(u32)string只是传输的首地址,跟指针加几没有关系,到了DMA里,也不存在指针。DMA中和内存的步进长度是按照DMA_MemoryDataSize 来走的。
STM1024 回答时间:2019-4-16 00:22:04
本帖最后由 stm1024 于 2019-4-16 00:24 编辑

DMA_Uart2_Tx_InitStructure.DMA_MemoryBaseAddr =(u32)string;
这个不应该是DMA_Uart2_Tx_InitStructure.DMA_MemoryBaseAddr =(u32*)string; 嘛?
至少是个地址吧?

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版