STM32 USART 接收问题 已经解决

long609521   2010-12-14 11:07 楼主
实现功能:我用串口接收PC端一串数据   然后在把数组中的数据发送给串口 传到PC  
遇到问题:串口接收正常 但是发送每次只能发送一两个数据
环境       :串口5 中断接收

请大家帮忙分析下原因 谢谢!

部分主函数:
while(1){
                        if(flag)
                                {
                                   for(j=1;j<20;j++)
                                   {
                                USART_SendData(UART5, TxBuffer5[j]);  //回发给PC       
                          while(USART_GetFlagStatus(UART5, USART_IT_TXE)==RESET);//等待发完
                              }
                          flag=0;
                          i=0;
                                  
                    }     
}

中断函数

void UART5_IRQHandler(void)
{
           if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)    //若接收数据寄存器满
       {
         TxBuffer5=USART_ReceiveData(UART5);
                 i++;
                }
                 if(i==20)
                 {        flag=1;         //接收固定长度数据标志
                 }
}


[ 本帖最后由 long609521 于 2010-12-14 14:23 编辑 ]

回复评论 (9)

TxBuffer5=USART_ReceiveData(UART5);
i++;  
这里怎么少了个括号  改为
TxBuffer5(i)=USART_ReceiveData(UART5);
i++;
方括号显示不出来 郁闷。。。

[ 本帖最后由 long609521 于 2010-12-14 13:03 编辑 ]
点赞  2010-12-14 11:11
TxBuffer5[]=USART_ReceiveData(UART5);?
处处留心皆学问!
点赞  2010-12-14 12:41

回复 板凳 daicheng 的帖子

那个数组的括号为什么显示不出来呢?  
我的程序哪里有问题么  请指教 谢谢
点赞  2010-12-14 13:04
你的意思是用串口5接收 到20个后 在发送给PC
你可以建都个循环队列,目前来说 如果 i>20 程序仍然在接收数据 不知道你接收的频率是多少?数组是多大? 清除 计数指针是在输出后,如果输出的时候 又接收到的就丢掉了,还有for(j=1;j<20;j++)怎么先输出的是第二个呢

[ 本帖最后由 daicheng 于 2010-12-14 13:42 编辑 ]
处处留心皆学问!
点赞  2010-12-14 13:41
引用: 原帖由 daicheng 于 2010-12-14 13:41 发表
你的意思是用串口5接收 到20个后 在发送给PC
你可以建都个循环队列,目前来说 如果 i>20 程序仍然在接收数据 不知道你接收的频率是多少?数组是多大? 清除 计数指针是在输出后,如果输出的时候 又接收到的就丢掉了 ...


1.波特率是115200  数组设置的大小 是  100  因为我要加上协议 且我接收到的数据个数是绝对小于100 的  
2. 我也有想过在接收到20个数据以后直接把计数指针清除掉 但是由于我每次发送一帧数据的间隔非常大 应该不会存在输出时又接收到新的数据
3.我现在把程序改为下面  出现的问题是 每接收到20个数据  j 就输出一个值  如发送20个数据后 串口输出 j=00 再发20个数据  串口输出j=01 .。。。。。j循环依次递加    for循环好像并没有工作一样   我把USART_SendData(UART5,j); 这里的 j换为 0x55;也是接收20个数据 才会发送出一个0x55;
4.  发送的时候是不是要加上延时函数?
while(1){
                        if(flag)
                                {
                                   for(j=0;j<20;j++)
                                   {
                                USART_SendData(UART5,j);  //回发给PC       
                          while(USART_GetFlagStatus(UART5, USART_IT_TXE)==RESET);//等待发完
                              }                                   
                          flag=0;                          
                           }                           
}
点赞  2010-12-14 14:04

程序已经调通我知道哪里有误了

在主函数里
USART_SendData(UART5,j); //回发给PC       
while(USART_GetFlagStatus(UART5, USART_IT_TXE)==RESET);//等待发完
这里应该是 USART_FLAG_TXE  之前那个是清除中断

下面是全部代码

#include "stm32f10x_lib.h"
unsigned char TxBuffer5[100] ;
unsigned int i;
unsigned int flag;

/***************************************************
* 函数名称    :void RCC_Configuration()
* 功能描述    : 复位和时钟控制 配置
* 参数        :  无
* 返回值      :  无
* 全局变量    :  无
* 全局静态变量:  无
* 局部静态变量:  无
***********************************************************/
void RCC_Configuration()
{
       ErrorStatus HSEStartUpStatus;             //定义外部高速晶振启动状态枚举变量
       RCC_DeInit();                                                                                 //复位RCC外部寄存器到默认值
       RCC_HSEConfig(RCC_HSE_ON);                 //打开外部高速晶振
       HSEStartUpStatus=RCC_WaitForHSEStartUp();      //等待外部高速时钟准备好

       if(HSEStartUpStatus==SUCCESS){         //外部高速时钟已经准备好

              FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  //开启FLASH预读缓冲功能,加速FLASH的读取。所有程序中必须的用法,位置:RCC初始化子函数里面,时钟起振之后
              FLASH_SetLatency(FLASH_Latency_2);        //FLASH时序延迟几个周期,等待总线同步操作。推荐按照单片机系统运行频率,0—24MHz时,取Latency=0;24—48MHz时,取Latency=1;48~72MHz时,取Latency=2。

              RCC_HCLKConfig(RCC_SYSCLK_Div1);       //配置AHB(HCLK)==系统时钟/1
              RCC_PCLK2Config(RCC_HCLK_Div1);      //配置APB2(高速)(PCLK2)==系统时钟/1  
              RCC_PCLK1Config(RCC_HCLK_Div2);     //配置APB1(低速)(PCLK1)==系统时钟/2
              //注:AHB主要负责外部存储器时钟。APB2负责AD,I/O,高级TIM,串口1。APB1负责DA,USB,SPI,I2C,CAN,串口2345,普通TIM。


              RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);   //配置PLL时钟==(外部高速晶体时钟/1)* 9 ==72MHz
              RCC_PLLCmd(ENABLE);                                                                   //使能PLL时钟
              while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);  //等待PLL时钟就绪
              RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  //配置系统时钟==PLL时钟
              while(RCC_GetSYSCLKSource()!=0x08); //等待系统时钟源的启动
       }
                                                                                                                                                                     
       //------------------------以下为开启外设时钟的操作-----------------------//
       //   RCC_AHBPeriphClockCmd (ABP2设备1 | ABP2设备2 , ENABLE); //启动AHB设备
       //   RCC_APB2PeriphClockCmd(ABP2设备1 | ABP2设备2 , ENABLE); //启动ABP2设备
       //   RCC_APB1PeriphClockCmd(ABP2设备1 | ABP2设备2 , ENABLE); //启动ABP1设备

//      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1 , ENABLE);   //打开APB2外设
         
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO
                                                   |RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);
          RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE);


}

/*********************************************
* 函数名称    : NVIC_Configuration(void)
* 功能描述    : NVIC(嵌套中断控制器)配置
* 参数        :  无
* 返回值      :  无
* 全局变量    :  无
* 全局静态变量:  无
* 局部静态变量:  无
***********************************************/
void NVIC_Configuration( )
{
      NVIC_InitTypeDef NVIC_InitStructure;    //定义一个中断结构体

//     NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  //设置中断向量表的起始地址为0x08000000
//     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //设置NVIC优先级分组,方式。
       //注:一共16个优先级,分为抢占式和响应式。两种优先级所占的数量由此代码确定,NVIC_PriorityGroup_x可以是0、1、2、3、4,
       //分别代表抢占优先级有1、2、4、8、16个和响应优先级有16、8、4、2、1个。规定两种优先级的数量后,所有的中断级别必须在其中选择,
       //抢占级别高的会打断其他中断优先执行,而响应级别高的会在其他中断执行完优先执行。

       NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQChannel; //通道设置为串口1中断
       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //中断响应优先级0
       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断
       NVIC_Init(&NVIC_InitStructure);   //初始化

           /* Enable the USART1 Interrupt
           NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
           NVIC_Init(&NVIC_InitStructure);*/
}

/****************************************
* 函数名称    :GPIO_Configuration()
* 功能描述    : GPIO配置
* 参数        :  无
* 返回值      :  无
* 全局变量    :  无
* 全局静态变量:  无
* 局部静态变量:  无
****************************************/
void GPIO_Configuration()
{
       GPIO_InitTypeDef GPIO_InitStructure;    //定义GPIO初始化结构体

       //--------将UART5 的TX 配置为复用推挽输出 AF_PP---------------------//
       GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12;     //管脚位置定义,标号可以是NONE、ALL、0至15。
       GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;  //输出速度50MHz
       GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;   //推挽输出模式 Out_PP
       GPIO_Init(GPIOC,&GPIO_InitStructure);     //E组GPIO初始化

           //--------将USART1 的TX 配置为复用推挽输出 AF_PP---------------------//
           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
           GPIO_Init(GPIOA, &GPIO_InitStructure);

       //--------将UART5 的RX 配置为复用浮空输入 IN_FLOATING---------------------//
       GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;   //管脚位置定义
       //输入模式下配置输出速度无意义
       //GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;  //输出速度2MHz
       GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //浮空输入 IN_FLOATING                     
       GPIO_Init(GPIOD,&GPIO_InitStructure); //C组GPIO初始化

           //--------将USART1 的RX 配置为复用浮空输入 IN_FLOATING---------------------//
           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
       GPIO_Init(GPIOA, &GPIO_InitStructure);
      
}

/****************************************************
* 函数名称    :USART1_Configuration( )
* 功能描述    : 配置USART1数据格式、波特率等参数
* 参数        :  无
* 返回值      :  无
* 全局变量    :  无
* 全局静态变量:  无
* 局部静态变量:  无
*******************************************************/
void UART5_Configuration( )
{
       USART_InitTypeDef USART_InitStructure; //串口设置恢复默认参数

       USART_InitStructure.USART_BaudRate = 115200; //波特率115200
       USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长8位
       USART_InitStructure.USART_StopBits = USART_StopBits_1; //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;      //打开Rx接收和Tx发送功能
       /* Configure USART1 */
           USART_Init(USART1, &USART_InitStructure);
       /* Configure UART5 */
           USART_Init(UART5, &USART_InitStructure);  //初始化
       /* Enable USART1 Receive and Transmit interrupts */
//           USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//           USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
          
           /* Enable UART5 Receive and Transmit interrupts */
           USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);  // 若接收数据寄存器满,则产生中断
  //     USART_ITConfig(UART5, USART_IT_TXE, ENABLE);
           /* Enable the USART1 */
//           USART_Cmd(USART1, ENABLE);
           /* Enable the UART5 */
           USART_Cmd(UART5, ENABLE);                                                             //启动串口                  
                                                   
       //-----如下语句解决第1个字节无法正确发送出去的问题-----//
       USART_ClearFlag(UART5, USART_FLAG_TC);     // 清标志
//           USART_ClearFlag(USART1, USART_FLAG_TC);
}
/********这是中断服务子程序,在stm32f10x_it.c中************************         */
void UART5_IRQHandler(void)
{
       if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)    //若接收数据寄存器满
       {
         TxBuffer5=USART_ReceiveData(UART5);
                 i++;
                }               
                 if(i==20)
                 {        flag=1;
                    i=0;}
                 //     USART_SendData(UART5, USART_ReceiveData(UART5));  //回发给PC
                //           while(USART_GetFlagStatus(UART5, USART_IT_TXE)==RESET);//等待发完

      
}
/*
void delay(void)                                                                  
{
        unsigned int a,b;
        for(a=0;a<1000;a++)
         for(b=0;b<200;b++)
} */
/**************************************************
* 函数名称    :main()
* 功能描述    : 主函数
* 参数        :  无
* 返回值      :  无
* 全局变量    :  无
* 全局静态变量:  无
* 局部静态变量:  无
****************************************************/
int main()
{          
           unsigned int j;
       RCC_Configuration();
       GPIO_Configuration();
       NVIC_Configuration( );
       UART5_Configuration();
          

       while(1){
                        if(flag)
                                {
                                   for(j=0;j<20;j++)
                                   {
                                USART_SendData(UART5,j);  //回发给PC       
                          while(USART_GetFlagStatus(UART5, USART_FLAG_TXE)==RESET);//等待发完         USART_IT_TXE
                              }  
                          flag=0;                          
                           }                       
}
}
点赞  2010-12-14 14:22

你好,请问你做这个usart试验的时候是不是电脑上的超级终端默认有回显呢??就是说即使你没有设置超级终端中属性为回显模式,它也会回显你键入的字符。。。

我现在用查询的方式写的接收函数,不管我怎么写,超级终端上都会回显键入的字符,让我实在没办法了。。。谢谢

点赞  2011-12-22 16:04
点赞  2012-2-24 11:11

错了 吧

你的中断标志都没清呢
点赞  2012-7-6 12:28
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复