OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2556|回复: 2

正點STM32F103 DMA USART範例沒有外設到內部的範例程式碼

[复制链接]

52

主题

75

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
249
金钱
249
注册时间
2018-10-17
在线时间
40 小时
发表于 2023-9-18 09:58:31 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 hunkchen2000 于 2023-9-18 10:04 编辑

AAAAA.jpg



請問各位,關於正點原子DMA USART的範例程式碼裡面只有內部到外設但是卻沒有外設到內部,請問各位強者可不可以給我外設到內部的程式碼??
謝謝~~因為我真的改不出來!我是初學者~~~感謝大家
希望大家看得懂繁體字!!


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

16

主题

426

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2765
金钱
2765
注册时间
2018-11-8
在线时间
438 小时
发表于 2023-9-18 11:00:43 | 显示全部楼层
这不就是改个方向的事嘛……  就是多了一步处理数据的部分
先开DMA 方向外设到内存 然后开串口空闲中断 在空闲中断中处理数据并重新开启下一次的DMA传输 同时尽快把本次收到的数据移走
发文章的难点可能是数据量太大 DMA一次传不完 分批传是做和上位机的通信还是通过改接收缓冲区位置就得具体考虑了
回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1040
金钱
1040
注册时间
2022-4-20
在线时间
373 小时
发表于 2023-9-18 11:49:39 | 显示全部楼层
有点巧合了,我上个周刚刚做了一个F103的串口接收的DMA,不过使用的是标准库

  1. uint16_t DMA1_RX_LEN;


  2. void MYDMA_RX_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
  3. {
  4.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);    //使能DMA传输

  5.     DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值

  6.     DMA1_RX_LEN=cndtr;
  7.     DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设基地址
  8.     DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址
  9.     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //数据传输方向,从外设读取发送到内存
  10.     DMA_InitStructure.DMA_BufferSize = cndtr;  //DMA通道的DMA缓存的大小
  11.     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
  12.     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
  13.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位
  14.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
  15.     DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //工作在正常模式
  16.     DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级
  17.     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
  18.     DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
  19. }


  20. void MYDMA_RX_Enable(DMA_Channel_TypeDef*DMA_CHx)
  21. {
  22.     DMA_Cmd(DMA_CHx, DISABLE );  //关闭USART1 DMA1 所RX的通道      
  23.     DMA_SetCurrDataCounter(DMA_CHx,DMA1_RX_LEN);//DMA通道的DMA缓存的大小
  24.     DMA_Cmd(DMA_CHx, ENABLE);  //使能USART1 DMA1 所RX的通道
  25. }
复制代码



main这边是这样的,值得注意的是要记得在MYDMA_RX_Config之后要MYDMA_RX_Enable

  1.     MYDMA_RX_Config(DMA1_Channel5, (u32)&USART1->DR, (u32)SetcmdBUF, BIG_BUF_SIZE);//DMA1通道5,外设为串口1RX,存储器为SetcmdBUF,长度BUF_SIZE.
  2.     MYDMA_RX_Enable(DMA1_Channel5);
复制代码


串口就是弄个空闲中断,然后使能一下接收,我是放在串口初始化里面的

  1.     USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); //使能串口1的DMA接收
复制代码


最后就是中断的处理


  1. void USART1_IRQHandler(void)                    //串口1中断服务程序
  2. {
  3.     if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
  4.     {
  5.         USART_ReceiveData(USART1);//读取接收到的数据,这个我也不知道为什么是这样的,但是我没有改动它

  6.         USART_ClearITPendingBit(USART1, USART_IT_IDLE);
  7.         MYDMA_RX_Config(DMA1_Channel5,(u32)&USART1->DR,(u32)SetcmdBUF,BIG_BUF_SIZE);//DMA1通道5,外设为串口1RX,存储器为SetcmdBUF,长度BUF_SIZE.
  8.         MYDMA_RX_Enable(DMA1_Channel5);
  9.     }
  10. }
复制代码


又菜又爱指点
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-24 15:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表