金钱
大家好!我是初学者,有个问题,我用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]); //Ïò′®¿ú1·¢Ëíêy¾Y
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//μè′y·¢Ëí½áêø
}
while(1);
}
附上 我的时钟设置图:
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
另外说明一下,
USARTx->BRR = (uint16_t)tmpreg;
不论是正点原子的,还是我自己写的,tmpreg值是一样的,都是0x02D9
自己用的什么芯片?
串口助手是怎样发送数据的?
情况是这样子的,我在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,
但是这样还是不行,不明白??????
请各位给个讨论下吧!虽然直接用原子的例程为模板,也能解决问题,但这对一个人的成长很不利,只解决问题,而不去查找问题的根源,
用的STM32不多,所以总会碰到很多问题,现在想建立属于自己的STM32知识体系。所以路不好走啊!
单片机发数据给电脑,单发数据
一周热门 更多>