UART数据发送不正常

2019-07-21 04:16发布



金钱
大家好!我是初学者,有个问题,我用UART1发送数据,用我自己写的,数据发送会出错,而用官方的例程,发送则全是对的,后来我把官方例程对串口被始化的部分全复制过来,还是会一样的结果!
比如我发10数:
原数为:B1 C2 D3 E4 F5 B1 C2 D3 E4 F5
收到的:     C2 93 E4 F5 31 C2 93 E4 F5

实在是搞不明白,我这里还有哪个地方要去设置的
串口初始化如下:
void uart_init(u32 bound){
   //GPIO¶Ë¿úéèÖÃ
  GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //ê1ÄüGPIOAê±Öó
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//ê1ÄüUSART1ê±Öó

        //′®¿ú1¶Ôó|òy½Å¸′óÃó3éä
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9¸′óÃÎaUSART1
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10¸′óÃÎaUSART1
        
        //USART1¶Ë¿úÅäÖÃ
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9óëGPIOA10
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//¸′óÃ1|Äü
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //Ëù¶è50MHz
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //íÆíì¸′óÃêä3ö
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //éÏà-
        GPIO_Init(GPIOA,&GPIO_InitStructure); //3õê¼»ˉPA9£¬A10

   //USART1 3õê¼»ˉéèÖÃ
        USART_InitStructure.USART_BaudRate = bound;//2¨ìØÂêéèÖÃ
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;//×Ö3¤Îa8λêy¾Y¸ñê½
        USART_InitStructure.USART_StopBits = USART_StopBits_1;//ò»¸öí£Ö1λ
        USART_InitStructure.USART_Parity = USART_Parity_No;//ÎTÆæżD£Ñéλ
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ÎTó2¼têy¾Yá÷¿ØÖÆ
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;        //êÕ·¢Ä£ê½
  USART_Init(USART1, &USART_InitStructure); //3õê¼»ˉ′®¿ú1
        
  USART_Cmd(USART1, ENABLE);  //ê1Äü′®¿ú1
        
        //USART_ClearFlag(USART1, USART_FLAG_TC);
        
#if EN_USART1_RX        
        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//¿aÆôÏà1ØÖD¶Ï

        //Usart1 NVIC ÅäÖÃ
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//′®¿ú1ÖD¶Ïí¨μà
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//ÇàÕ¼óÅÏ輶3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;                //×óóÅÏ輶3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQí¨μàê1Äü
        NVIC_Init(&NVIC_InitStructure);        //¸ù¾YÖ¸¶¨μÄ2Îêy3õê¼»ˉVIC¼Ä′æÆ÷¡¢

#endif
        
}

主函数如下:
int main(void)
{
        u8 t;
        u16 times=0;  
        STM32CLK_Initialization();//将PCLK2设置为84MH,PLLCLK为168MHz
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//éèÖÃÏμí3ÖD¶ÏóÅÏ輶·Ö×é2
        uart_init(115200);        //′®¿ú3õê¼»ˉ2¨ìØÂêÎa115200

    for(t=0;t<10;t++)
    {
        USART_SendData(USART1, TempArray[t]);         //&#207;ò′&#174;&#191;ú1·¢&#203;íêy&#190;Y
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//μè′y·¢&#203;í&#189;áê&#248;
    }
    while(1);
}

附上 我的时钟设置图:
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
0312221024
1楼-- · 2019-07-21 04:30

另外说明一下,
USARTx->BRR = (uint16_t)tmpreg;
不论是正点原子的,还是我自己写的,tmpreg值是一样的,都是0x02D9
peng1554
2楼-- · 2019-07-21 09:11
官方例程是指原子例程?
自己用的什么芯片?
串口助手是怎样发送数据的?
0312221024
3楼-- · 2019-07-21 12:12
本帖最后由 0312221024 于 2019-3-15 18:39 编辑

情况是这样子的,我在STM32的官网上下载了一个工程模板,想以后都利用这个工程模板来开展工作,STM官网里的STM32F4xx_DSP_StdPeriph_Lib_V1.8.0,路径为STM32F4xx_DSP_StdPeriph_Lib_V1.8.0ProjectSTM32F4xx_StdPeriph_Templates,然后就先调调串口通信,工发板是正点原子的探索者,MCU为STM32F407,用原子的串口例程,发数据不会错,但用我自己的工程模块,发数据就会出错;
那么我的方法有:1、将原子库函数版本的串口初始化函数复制过来,结果还是一样,10个数里,会有2个数出错,
                        2、用原子寄存器版本的串口初始化函数复制过来,当然还要复制MCU的时钟设置,那么数据正常,
经过查找后,发现差别就在     
         apbclock = RCC_ClocksStatus.PCLK2_Frequency;
正点原子的例程里,读出来的是84MHz,
而我自己的读出来是200多MHz,但这个就很奇怪了,这个STM32F470最高速只能是168MHz,出不了这么高的频率的。
所以就会导致波特率设置不对。
那我现在是想了很多办法,也处理不好这个问题!因为这是MCU时钟设置的问题,我重写了这个MCU时钟设置,都没办法做好
我的时钟配置如下:
void STM32CLK_Initialization(void)//SYSCLK=168MHz
{

//#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx)|| defined(STM32F469_479xx)
/******************************************************************************/
/*            PLL (clocked by HSE) used as System clock source                */
/******************************************************************************/
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;

  /* Enable HSE */
  RCC_DeInit();
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);

  /* Wait till HSE is ready and if Time out is reached exit */
  do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  {
    HSEStatus = (uint32_t)0x01;
  }
  else
  {
    HSEStatus = (uint32_t)0x00;
  }

  if (HSEStatus == (uint32_t)0x01)
  {
    /* Select regulator voltage output Scale 1 mode */
    RCC->APB1ENR |= RCC_APB1ENR_PWREN;
    PWR->CR |= PWR_CR_VOS;

    /* HCLK = SYSCLK / 1*/
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;

//#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) ||  defined(STM32F412xG) || defined(STM32F446xx) || defined(STM32F469_479xx)   
    /* PCLK2 = HCLK / 2*/
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;

    /* PCLK1 = HCLK / 4*/
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
//#endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx  || STM32F412xG || STM32F446xx || STM32F469_479xx */
//#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F469_479xx)   
    /* Configure the main PLL */
    RCC->PLLCFGR = 8 | (336 << 6) | (((2 >> 1) -1) << 16) |
                   (RCC_PLLCFGR_PLLSRC_HSE) | (7 << 24);
//#endif /* STM32F40_41xxx || STM32F401xx || STM32F427_437x || STM32F429_439xx || STM32F469_479xx */   
    /* Enable the main PLL */
    RCC->CR |= RCC_CR_PLLON;
    /* Wait till the main PLL is ready */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
//#if defined(STM32F40_41xxx)  || defined(STM32F412xG)  
    /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
    FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
//#endif /* STM32F40_41xxx  || STM32F412xG */
    /* Select the main PLL as system clock source */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= RCC_CFGR_SW_PLL;
    /* Wait till the main PLL is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
    {
    }
  }
  else
  { /* If HSE fails to start-up, the application will have wrong clock
         configuration. User can add here some code to deal with this error */
  }
//#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx || STM32F469_479xx */  
}

这里其实只是我把模板里的system_stm32f4xx.c文件里的SetSysClock()复制过来而已,然后自己手动修改  PLL_M=8   PLL_N=336    PLL_P=2    PLL_Q=7,
但是这样还是不行,不明白??????
请各位给个讨论下吧!虽然直接用原子的例程为模板,也能解决问题,但这对一个人的成长很不利,只解决问题,而不去查找问题的根源,
0312221024
4楼-- · 2019-07-21 15:52
peng1554 发表于 2019-3-15 17:57
官方例程是指原子例程?
自己用的什么芯片?
串口助手是怎样发送数据的?

用的STM32不多,所以总会碰到很多问题,现在想建立属于自己的STM32知识体系。所以路不好走啊!
0312221024
5楼-- · 2019-07-21 19:54
peng1554 发表于 2019-3-15 17:57
官方例程是指原子例程?
自己用的什么芯片?
串口助手是怎样发送数据的?

单片机发数据给电脑,单发数据

一周热门 更多>