野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 13959|回复: 2

串口接收到数据后RXNE标志位不置1

[复制链接]
发表于 2017-11-27 15:46:07 | 显示全部楼层 |阅读模式
20火花
问题描述:
     最近在做一个关于串口读压力模块压力值的项目,用到的压力模块的基本工作原理为,通过串口向压力模块发送读压力指令"1:R:MRMD:0:0"(字符串),压力模块会返回压力值字符串"1:F:MRMD:101.00:KPA"(非定长字符串),收到压力值字符串后需要对其进行分割,以提取标识位'F'、压力值'101.00',以及压力单位'KPA'。
     我做该项目的思路是通过DMA传输的方式将串口接收到的压力字符串从串口数据寄存器传输到内存,通过串口的总线空闲中断(IDLE)判断压力值字符串是否接收完成,若接收完成触发中断程序,在中断程序中对字符串中进行分割并提取具有关键值的子串。
    但是通过keil仿真器仿真过程中rxne状态位在接收到字符串后始终不会被置位,导致空闲中断不被响应,最终导致压力字符串没不能被有效处理,刚接触stm32,不知道问题出在哪里,希望前辈能指点一二。
下面是我的程序:
主函数:
void Delay(__IO u32 nCount)     /*自定义的延时函数*/
{
      for(;nCount!=0;nCount--);
}
void USART_SendChar(USART_TypeDef* USARTx,uint8_t data)     /*自定义的串口发送数据函数*/
{
      USART_SendData(USARTx,data);
      while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET);
}
int main(void)
{
      char *str1;
      int i=0;
      USART1_Config();     /*串口初始化*/
      USART1_DMA_Config();     /*DMA初始化*/
      NVIC_Configuration();     /*中断优先级配置*/
      while(1)
      {
           str1="1:R:MRMD:0:0\n";     /*读压力指令*/
           USART_ClearFlag(USART1,USART_FLAG_TC);
           for(i=0;str1!='\0';i++)     /*发送读压力指令*/
           {
                USART_SendChar(USART1,str1);
           }
           USART_SendChar(USART1,0x0D);
           USART_SendChar(USART1,0x0A);     /*压力模块规定读压力指令以0D、0A结束*/
           Delay(500000);
           if(*temp1=='F')
           break;
      }
      while(1)
      {

      }
      pressure=atof(temp2);
}
串口及DMA配置:
#include "bsp_usart1.h"
#include "stm32f10x.h"
#include "stm32f10x_conf.h"
#define USART1_DR_Base 0x40013804
char PRESSURE[PRESSURE_LENGTH];    /*压力字符串在内存的缓冲区,其长度为512*/

void USART1_Config(void)
{
      GPIO_InitTypeDef GPIO_InitStructure;
      USART_InitTypeDef USART_InitStructure;

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);

      GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
      GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
      GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
      GPIO_Init(GPIOA,&GPIO_InitStructure);

      GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
      GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
      GPIO_Init(GPIOA,&GPIO_InitStructure);

      USART_InitStructure.USART_BaudRate=9600;
      USART_InitStructure.USART_WordLength=USART_WordLength_8b;
      USART_InitStructure.USART_StopBits=USART_StopBits_1;
      USART_InitStructure.USART_Parity=USART_Parity_No;
      USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
      USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
      USART_Init(USART1,&USART_InitStructure);
      USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);
     USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
     USART_Cmd(USART1,ENABLE);
      USART_ClearFlag(USART1,USART_FLAG_TC);
}
void USART1_DMA_Config(void)
{
      DMA_InitTypeDef DMA_InitStructure;
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
      DMA_DeInit(DMA1_Channel5);
      DMA_InitStructure.DMA_PeripheralBaseAddr=USART1_DR_Base;
      DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&PRESSURE;
      DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;
      DMA_InitStructure.DMA_BufferSize =PRESSURE_LENGTH;    /*传输数量为512*/
      DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
      DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
      DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
      DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
      DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;
      DMA_InitStructure.DMA_Priority=DMA_Priority_Medium;
      DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;
      DMA_Init(DMA1_Channel5,&DMA_InitStructure);
      USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);
      DMA_Cmd(DMA1_Channel5,ENABLE);
}
中断程序:
void USART1_IRQHandler(void)
{
      uint16_t i;
      uint8_t Clear=Clear;
   
      if(USART_GetITStatus(USART1,USART_IT_IDLE)!=RESET)
      {
           DMA_Cmd(DMA1_Channel5,DISABLE);
           Clear=USART1->SR;
           Clear=USART1->DR;    /*清除标志位*/
           DATA_LEN=512-DMA_GetCurrDataCounter(DMA1_Channel5);
   
           for(i=0;i<DATA_LEN;i++)
           {
               PRESSURE_COPY1=PRESSURE;
               PRESSURE_COPY2=PRESSURE;
               PRESSURE_COPY3=PRESSURE;    /*将压力字符串复制3份已备切割*/
           }
          temp1=StringCut1(PRESSURE_COPY1);
          temp2=StringCut2(PRESSURE_COPY2);
          temp3=StringCut3(PRESSURE_COPY3);
   
          DMA_SetCurrDataCounter(DMA1_Channel5,PRESSURE_LENGTH);
          n=DMA1_Channel5->CNDTR;
          DMA_Cmd(DMA1_Channel5,ENABLE);
     }
}
自定义的字符串切割函数
char* StringCut1(char string[])
{
      char*temp = strtok(string,":");
      temp=strtok(NULL,":");
      return temp;
}
char* StringCut2(char string[])
{
      char*temp = strtok(string,":");
      temp=strtok(NULL,":");
      temp=strtok(NULL,":");
      temp=strtok(NULL,":");
      return temp;
}
char* StringCut3(char string[])
{
      char*temp = strtok(string,":");
      temp=strtok(NULL,":");
      temp=strtok(NULL,":");
      temp=strtok(NULL,":");
      temp=strtok(NULL,":");
      return temp;
}

回复

使用道具 举报

发表于 2017-11-27 17:56:07 | 显示全部楼层
中断函数之后的代码没看,但之前的代码,可能有两个问题,1)发送读压力命令,for循环,难道不应该是 str1[i] 吗  2)DMA配置,DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&PRESSURE;  错误,PRESSURE已经是一个地址了,不用再 & ,直接(u32)PRESSURE就可以。
回复

使用道具 举报

 楼主| 发表于 2017-11-27 21:01:18 | 显示全部楼层
小伟V 发表于 2017-11-27 17:56
中断函数之后的代码没看,但之前的代码,可能有两个问题,1)发送读压力命令,for循环,难道不应该是 str1  ...

谢谢您的建议,您说的都对,我按照您的建议修改了代码,数据依然能正常接收,但仍然不会将RXNE位置1
回复

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-7 19:50 , Processed in 0.035625 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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