STM32F205串口1使用不正常,输出错误
// usart.c
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the USARTx Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void Uart_Init(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
uchar temp;
temp++;
// PA9 -- TX PA10 -- RX
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 115200;
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_Cmd(USART1, ENABLE);
//USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//NVIC_Config();
}
void UART1Write(uchar* data,uint len)
{
u16 i;
for(i=0; i<len; i++)
UART1_SendBuf = data;
UART1_SendSum = len;
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
for (i=0; i<len; i++)
{
USART_SendData(USART1, data);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
{
;
}
}
}
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
UART1_BUF[UART1_COUNT++] = USART_ReceiveData(USART1); //接收数据
if(UART1_COUNT >= UART1BUF_SIZE_MAX) //超过最大缓存,清零计数
{
UART1_COUNT = 0;
}
}
}
// main.c
uchar array[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
SystemInit();
while(1)
{
UART1Write(array, 1);
}
//-------------------------程序分割线------------------------------------
以上是usart.c和main.c中的内容 省略了头文件和一些参数的声明
遇到了两个问题:
1.发送的数据错误,不是0xaa,而是别的值。测试过Tx脚的波特率,应该是正确的,不知道是什么原因了,求解。
2.如果//NVIC_Config();去掉注释,则程序会一直死在里面出不来,后面的数据也不会发送。
以上配置都是从其他贴子中复制过来的,不知道错在哪里。
接收到的是什么,是通过串口调试软件显示的,是否显示的位16进制
不要发送一个数组,发送一个数,调试试试。
你的系统时钟和例子的系统时钟是不是一样的?
你串口调试助手和你的设置是不是一样 的,你先发送一个数试试能不能成功。你的这一句USART_ITConfig(USART1, USART_IT_TXE, ENABLE); 应该放在初始化中。
问题都解决了,做以下结贴:
第一个问题:
USART1是由PCLK2提供时钟,故读取如下的值:
apbclock_SYSCLK = RCC_ClocksStatus.SYSCLK_Frequency;// 系统时钟
apbclock_PCLK2 = RCC_ClocksStatus.PCLK2_Frequency; //PCLK2值
Uart_Init(); // 使用的波特率是9600
baud_div = USART1->BRR; // 串口分频值
可以读出apbclock_SYSCLK = 0x7270E0000(120M)
apbclock_PCLK2 = 0x3938700(60M)
baud_div = 0x186A(6250)
计算baudrate = apbclock_PCLK2 / baud_div = 9600 一切都是如此完美
可,这一切都是假象,在stm32f2xx.h中有这么一句
#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
原来这里把外围晶振定义为了25MHZ,修改为12MHZ,
从新读取apbclock_SYSCLK = 0x57600000(57.6M)
apbclock_PCLK2 = 0x28800000(28.8M)
baud_div = 0xBB8(3000)
USART1使用的实际频率是28.8MHZ,28800000 / 6250 = 4608(实际的波特率) 原来这才是真相啊
之后修改了RCC寄出器一些寄存器的值,使系统时钟达到120MHZ就可以了
第二个问题:打开NVIC_Config();会“死”在中断中因为开启了串口发送中断,但是没有对TXE中断进行处
datesheet有如下说明:
Bit 7TXE: Transmit data register empty
This bit is set by hardware when the content of the TDR register has been transferred into
the shift register. An interrupt is generated if the TXEIE bit =1 in the USART_CR1 register. It
is cleared by a write to the USART_DR register.
0: Data is not transferred to the shift register
1: Data is transferred to the shift register)
即当向USART_DR中写数据的时候才可以将标志位清楚。所以我将中断函数做了如写的修改
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
UART5_RcvBuf[UART5_COUNT++] = USART_ReceiveData(USART1);
//USART1->SR &= ~0x20;
}
if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
{
UART1_SendCount++;
/* Write one byte to the transmit data register */
USART_SendData(USART1, 0xAA);
if(UART1_SendCount >= 10)
{
/* Disable the USART1 Transmit interrupt */
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
}
}
}
