串口发送数据给STM32F103然后保存到W25Wxx中,速度可以达到115200

2019-12-09 14:25发布

如题“串口发送数据给STM32F103然后保存到W25Wxx中,速度可以达到115200”,遍历了莫大的论坛好像是第一个发送速度可以达到115200的哦

最近在使用W25Q128保存字库,看了莫大上前人发的参考,串口发送速度不能太快,否则丢数据,于是我开始试用DMA接收数据,结果成功搞定了,希望能帮到需要的人

1.数据可以通过串口以115200的速度保存数据到W25Qxx中,而不丢数据
2.程序采用了串口发送DMA接收方式,
3.DMA接收256个数据产生半中断,保存数据,这样做目的是可以循环利用缓存,而不会产生丢数据
4.DMA接收512个数据产生满中断,保存数据
5.接收数据不是256的整倍数时,如一定时间未接收到数据,可以查询DMA的计数器,如不是256倍数,则认为接收数据完成,保存不是256倍数的数据,程序中未处理,需要的可自行添加上
6.程序是以正点原子改动而来的,程序亲测没有任何问题
7.修改日期:2017-05-28


  1. //DMA1的各通道配置
  2. //这里的传输形式是固定的,这点要根据不同的情况来修改
  3. //外设模式->从存储器/8位数据宽度/存储器增量模式
  4. //DMA_CHx:DMA通道CHx
  5. //cpar:外设地址
  6. //cmar:存储器地址
  7. //cndtr:数据传输量
  8. void DMA1CH5_Config(u32 cpar,u32 cmar,u16 cndtr)
  9. {
  10.         DMA_InitTypeDef DMA_InitStructure;
  11.        
  12.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);        //使能DMA传输
  13.        
  14.     DMA_DeInit(DMA1_Channel5);   //将DMA的通道6寄存器重设为缺省值
  15.         DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设基地址
  16.         DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址
  17.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //数据传输方向,从外设读取发送到内存
  18.         DMA_InitStructure.DMA_BufferSize = cndtr;  //DMA通道的DMA缓存的大小,此程序在使能处重新定义了,在此无实意
  19.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
  20.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
  21.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位
  22.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
  23.         DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  //工作在循环模式,DMA_Mode_Normal正常缓存模式
  24.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级
  25.         DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
  26.         DMA_Init(DMA1_Channel5, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Rx_DMA_Channel所标识的寄存器        
  27.         DMA_ITConfig(DMA1_Channel5, DMA_IT_HT|DMA_IT_TC, ENABLE);//开启DMA中断使能
  28. }


  29. u8 buf[256];
  30. u8 GetBuf[512];
  31. u8 SendBuf[512];

  32. //开启一次DMA传输
  33. void DMA1CH5_Enable(u16 Value)
  34. {
  35.         DMA_Cmd(DMA1_Channel5, DISABLE );  //关闭USART1 RX DMA1 所指示的通道      
  36.         DMA_SetCurrDataCounter(DMA1_Channel5,Value);//DMA通道的DMA缓存的大小
  37.         DMA_Cmd(DMA1_Channel5, ENABLE);  //使能USART1 RX DMA1 所指示的通道
  38. }

  39. void uart_init(u32 bound){
  40.   //GPIO端口设置
  41. GPIO_InitTypeDef GPIO_InitStructure;
  42. USART_InitTypeDef USART_InitStructure;
  43. NVIC_InitTypeDef NVIC_InitStructure;

  44.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);        //使能USART1,GPIOA时钟

  45.         //USART1_TX   GPIOA.9
  46.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  47.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  48.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
  49.         GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9

  50.         //USART1_RX          GPIOA.10初始化
  51.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  52.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  53.         GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

  54. //  //Usart1 NVIC 配置
  55. //  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  56. //        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
  57. //        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
  58. //        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
  59. //        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
  60.   
  61.    //USART 初始化设置

  62.         USART_InitStructure.USART_BaudRate = bound;//串口波特率
  63.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
  64.         USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
  65.         USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
  66.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
  67.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;        //收发模式

  68.         USART_Init(USART1, &USART_InitStructure); //初始化串口1
  69.         //  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
  70.         USART_Cmd(USART1, ENABLE);                    //使能串口1

  71.         DMA1CH5_Config((u32)&USART1->DR,(u32)GetBuf,512);

  72.         USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); //使能串口2的DMA收发送
  73.         DMA1CH5_Enable(512);
  74.   
  75.   
  76.         NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
  77.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
  78.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
  79.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
  80.         NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器

  81. }

  82. void W25QXX_Write_Page(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite);
  83. void W25QXX_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite);
  84. void W25QXX_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead);
  85. void DMA1_Channel5_IRQHandler(void)
  86. {
  87. u16 i;
  88. u8 buf[256];
  89. static u32 Add=0;
  90.         if(DMA_GetITStatus(DMA1_IT_HT5))//半
  91.         {
  92.                 for(i=0;i<256;i++) buf[i] = GetBuf[i];
  93.                 W25QXX_Write_Page(buf,Add*256,256);       
  94. //                printf(" GetNum:%d",512-DMA1_Channel5->CNDTR);
  95.                 printf(" add:%d :",Add);
  96.                 DMA_ClearFlag(DMA1_IT_HT5);
  97.                 Add++;
  98.         }
  99.         else if(DMA_GetITStatus(DMA1_IT_TC5))//满
  100.         {
  101.                 for(i=0;i<256;i++) buf[i] = GetBuf[i+256];
  102.                 W25QXX_Write_Page(buf,Add*256,256);
  103.                 printf(" add:%d :",Add);
  104. //                printf(" GetNum:%d",512-DMA1_Channel5->CNDTR);
  105.                 DMA_ClearFlag(DMA1_IT_TC5);
  106.                 Add++;
  107.         }
  108. }
复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
42条回答
zhcj66
1楼-- · 2019-12-12 07:49
njjh1718 发表于 2017-6-2 10:29
有测试过串口采集数据,然后直接写入SD大卡数据吗?我现在还在用57600,太高了。稳定性没测试过  ,楼上 ...

DMA接收串口数据,DMA做sd卡的存储速度应该会更快些,请问你用的什么方式接收和存储的?
first_blood
2楼-- · 2019-12-12 11:45
 精彩回答 2  元偷偷看……
wt3333
3楼-- · 2019-12-12 12:39
设计不错  谢谢分享
cumt_123456
4楼-- · 2019-12-12 12:39
zhcj66 发表于 2017-6-2 10:48
用什么方式做的速度这么快?

这个和DMA关系不大吧,外围器件和通信转换器性能决定了。
一般的USB转422,USB转232和USART转转422,USART转232的速度很难达到这么高。
zhcj66
5楼-- · 2019-12-12 15:12
first_blood 发表于 2017-6-2 11:20
串口DMA接收,接收的同时写上一帧的4K到flash,921600没有问题

在接收的时候 一边擦除一边写入数据,不知道这样是否还能达到921600的速度?
zhcj66
6楼-- · 2019-12-12 16:28
cumt_123456 发表于 2017-6-2 11:30
这个和DMA关系不大吧,外围器件和通信转换器性能决定了。
一般的USB转422,USB转232和USART转转422,USAR ...

cp2102的速度可以达到1M的速度

一周热门 更多>