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

STM32串口通讯收不到数据

[复制链接]
gtygg 提问时间:2016-10-29 19:21 /
悬赏1ST金币未解决

//STM32串口DMA通讯接收不到数据

//请各位大神帮忙看看,下面的DMA配置问题出在哪里
//程序编写思路是:用串口助手发数据给STM32的串口2,收到数据后返回收到的数据给串口助手;
//现在遇到的问题:用串口助手发数据给它,但不能返回数据,LED0和LED1会常亮;

//小弟初学,这个问题弄了一个星期还没有解决,望大家高抬贵手帮帮我;

//谢谢



u8 rcv_num_temp=0;  //接收到的数据长度临时缓存

u8 rcv_num=0;  //接收到的数据长度缓存


u8 rcv_bufferfer_temp[128];  //接收数据临时缓存,最大64个字节

u8 rcv_buffer[128];  //接收缓存,最大64个字节


u8 rcv_complete_temp=0;  //一帧接收完成临时缓存(1为完成)

u8 rcv_complete=0;     //接收完成标志   1为完成


u8 send_complete=0;    //发送完成标志   1为完成





//USART2参数配置函数

void USART2_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART2_InitStructure;

       

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  //使能GPIOA时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);  //使能GPIOD时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);  //使能USART2时钟

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  //开启DMA1时钟

       

USART_DeInit(USART2);


//发送接收控制模式       

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;  //PD7

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽输出

GPIO_Init(GPIOD, &GPIO_InitStructure);


//USART2-TX       

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;  //PA2

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;  //复用推挽

GPIO_Init(GPIOA,&GPIO_InitStructure);


//USART2-RX       

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;  //PA3

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;  //浮空输入

GPIO_Init(GPIOA,&GPIO_InitStructure);


RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,ENABLE);//复位串口2

RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,DISABLE);//停止复位


//USART2通讯协议

USART2_InitStructure.USART_BaudRate=115200;  //波特率115200

USART2_InitStructure.USART_WordLength=USART_WordLength_8b;  //数据位8位

USART2_InitStructure.USART_StopBits=USART_StopBits_1;  //停止位1位

USART2_InitStructure.USART_Parity=USART_Parity_No ;  //无校验

USART2_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  //无硬件流

USART2_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;  //发送/接收使能

USART_Init(USART2,&USART2_InitStructure);  //初始化USART2成员变量


USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);  //开启串口空闲IDEL中断

USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);  //开启串口DMA接收

USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);  //开启串口DMA发送


RS485_TX_EN=0;                        //默认为接收模式

USART_Cmd(USART2,ENABLE);  //串口使能

}       




//USART2中断配置函数

void USART2_NVIC_Configuration(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;

       

  NVIC_InitStructure.NVIC_IRQChannel=USART2_IRQn;  //USART2全局中断

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;  //抢占优先级为2

  NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;  //子优先级为0

  NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;  //通道使能

  NVIC_Init(&NVIC_InitStructure);  //初始化中断成员变量

}




//USART2初始化函数

void USART2_Init(void)

{

  USART2_Configuration( );

  USART2_NVIC_Configuration( );

}






//DMA1_USART2_RX参数配置函数

void DMA1_USART2_RX_Configuration(void)

{

DMA_InitTypeDef DMA_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  //开启DMA1时钟

       

DMA_Cmd(DMA1_Channel6, DISABLE);  //关DMA1通道6

DMA_DeInit(DMA1_Channel6);  //恢复为缺省值

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART2->DR;  //DMA外设基地址

DMA_InitStructure.DMA_MemoryBaseAddr = rcv_bufferfer_temp[0];  //DMA内存基地址

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //设置外设为数据源

DMA_InitStructure.DMA_BufferSize = 128;  //DMA缓存大小

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不递增

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //外设数据宽度8位,一个字节

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;  //内存数据宽度8位,一个字节

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //单次传输模式

DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;  //优先级设置

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //关闭内存到内存的DMA模式

DMA_Init(DMA1_Channel6, &DMA_InitStructure);   //初始化DMA成员变量

DMA_ClearFlag(DMA1_FLAG_GL6);  //清除DMA1所有标志

       

// DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);   //开启DMA1通道6传输完成中断

       

DMA_Cmd(DMA1_Channel6, ENABLE);  //开启DMA1通道6,等待接收数据

}



/**************************************************************************************************

//当使用总线空闲检测一帧数据是否发完时,DMA1_USART2_RX_NVIC_Configuration( )就不需要

//DMA1_USART2_RX中断配置函数

void DMA1_USART2_RX_NVIC_Configuration(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;


  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;  //DMA1_USART2接收中断通道6  

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //抢占优先级为2

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //子优先级为0

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  //通道使能

  NVIC_Init(&NVIC_InitStructure);  //初始化成员变量

}

**************************************************************************************************/



//DMA1_USART2_RX初始化函数

void DMA1_USART2_RX_Init(void)

{

  DMA1_USART2_RX_Configuration( );

//        DMA1_USART2_RX_NVIC_Configuration( );

}






//DMA1_USART2_TX参数配置函数

void DMA1_USART2_TX_Configuration(void)

{

DMA_InitTypeDef DMA_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  //开启DMA1时钟  


DMA_Cmd(DMA1_Channel7, DISABLE);  //关DMA1通道7

DMA_DeInit(DMA1_Channel7);  //恢复为缺省值

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART2->DR;  //DMA外设基地址

DMA_InitStructure.DMA_MemoryBaseAddr = rcv_bufferfer_temp[0];  //DMA内存基地址

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //设置外设为目标

DMA_InitStructure.DMA_BufferSize = rcv_num_temp;   //需要发送的字节数

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不递增

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //外设数据宽度8位,一个字节

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;  //内存数据宽度8位,一个字节

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //单次传输模式

DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;  //优先级设置

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //关闭内存到内存的DMA模式

DMA_Init(DMA1_Channel7, &DMA_InitStructure);   //初始化DMA成员变量

DMA_ClearFlag(DMA1_FLAG_GL7);  //清除DMA所有标志       

       

DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);   //开启DMA1通道7传输完成中断

       

DMA_Cmd(DMA1_Channel7, ENABLE);  //开启DMA1通道7,等待发送数据

}




//DMA1_USART2_TX中断配置函数

void DMA1_USART2_TX_NVIC_Configuration(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;


  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;  //DMA1_USART2接收中断通道7

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //抢占优先级为2

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //子优先级为0

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  //通道使能

  NVIC_Init(&NVIC_InitStructure);  //初始化成员变量

}




//DMA1_USART2_TX初始化函数

void DMA1_USART2_TX_Init(void)

{

  DMA1_USART2_TX_Configuration( );

  DMA1_USART2_TX_NVIC_Configuration( );

}




//DMA1_USART2初始化函数

void DMA1_USART2_Init(void)

{

  DMA1_USART2_RX_Init( );  //DMA1_USART2_RX初始化函数

  DMA1_USART2_TX_Init( );  //DMA1_USART2_TX初始化函数


}





//RS485_USART2初始化函数

void RS485_USART2_Init(void)

{

  USART2_Init( );  //USART2初始化函数

  DMA1_USART2_Init( );  //DMA1_USART2初始化函数

}






//USART2数据接收中断函数

void USART2_IRQHandler(void)

{

  u8 Clear=Clear;


  LED0=0;

       

  if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)  //空闲中断

  {                       

     Clear=USART2->SR;  //读SR寄存器

     Clear=USART2->DR;  //读DR寄存器(先读SR再读DR,就是为了清除IDLE中断)               

               

     DMA_Cmd( DMA1_Channel6, DISABLE );  //关DMA1通道6

                   

     rcv_complete_temp= 1;          //一帧接收完成临时缓存                

  }

}






//USART2_DMA1数据发送中断函数

void DMA1_Channel7_IRQHandler(void)

{

  if(DMA_GetITStatus(DMA1_FLAG_TC7))  //如果DMA1通道7发送完成

  {

     LED1=1;

               

     DMA_Cmd( DMA1_Channel7, DISABLE );   // 关闭DMA通道7

     DMA_ClearITPendingBit( DMA1_FLAG_GL7 );  // 清除标志

                               

     send_complete=1;  //发送完成

  }

}







//USART2_DMA1数据接收函数

void USART2_DMA1_Rx_Data(void)

{       

  if( rcv_complete_temp== 0 )  //如果未接收到一帧数据

        {

           DMA_Cmd( DMA1_Channel6, DISABLE );  //关DMA1通道6

           DMA_ClearFlag( DMA1_FLAG_GL6 );  //清除DMA1所有标志

           DMA1_Channel6->CNDTR = 128;  //重新赋值计数值(DMA缓存大小)

           DMA_Cmd(DMA1_Channel6, ENABLE);  //开启DMA1通道6,等待接收数据

        }


  if( rcv_complete_temp== 1 )  //如果接收到一帧数据

  {

               

    DMA_Cmd( DMA1_Channel6, DISABLE );  //关DMA1通道6

    DMA_ClearFlag( DMA1_FLAG_GL6 );  //清除DMA1所有标志

    rcv_num_temp= 128- DMA_GetCurrDataCounter( DMA1_Channel6 );  //获取接收到的字节数


    LED0=1;


               

//  if( rcv_bufferfer_temp[0]>0 )  LED0=0;

               

               

    rcv_complete=1;  //接收完成  

  }

}






//USART2_DMA1数据发送函数

void USART2_DMA1_Tx_Data(void)

{       


  LED1=0;

       

  rcv_complete_temp= 0;

  DMA_Cmd( DMA1_Channel7, DISABLE );   // 关闭DMA通道

  DMA_ClearFlag(DMA1_FLAG_GL7);  //清除DMA所有标志       

  DMA1_Channel7->CNDTR = rcv_num_temp;  // 设置要发送的字节数       

  DMA_Cmd( DMA1_Channel7, ENABLE );  //开始DMA发送

}

收藏 评论3 发布时间:2016-10-29 19:21

举报

3个回答
peter001 回答时间:2016-10-30 03:18:57
帮顶,看看有高手解答没
gtygg 回答时间:2016-10-30 13:57:45
本帖最后由 gtygg 于 2016-10-30 14:00 编辑

刚注册的没有积分,所以就悬赏了一个积分,现在有积分重发
samhong 回答时间:2016-10-31 00:29:31
签到,好多内容,谢谢!
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版