首先点进来的大神先说生感谢,本人刚刚进入STM32世界没有多久,希望大神给点指点。
从百度上看了很多类似的问题,均无法解决。首先我的启动文件startup_stm32f10x_cl.s里已经包含了Usart123,Uart4,5.。配置如下:
void NVIC_GroupConfig(void)
{
/* 配置NVIC中断优先级分组:
- 1比特表示主优先级 主优先级合法取值为 0 或 1
- 3比特表示次优先级 次优先级合法取值为 0..7
- 数值越低优先级越高,取值超过合法范围时取低bit位
*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/*==================================================================================
NVIC_PriorityGroup | 主优先级范围 | 次优先级范围 | 描述
==================================================================================
NVIC_PriorityGroup_0 | 0 | 0-15 | 0 比特表示主优先级
| | | 4 比特表示次优先级
----------------------------------------------------------------------------------
NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 比特表示主优先级
| | | 3 比特表示次优先级
----------------------------------------------------------------------------------
NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 比特表示主优先级
| | | 2 比特表示次优先级
----------------------------------------------------------------------------------
NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 比特表示主优先级
| | | 1 比特表示次优先级
----------------------------------------------------------------------------------
NVIC_PriorityGroup_4 | 0-15 | 0 | 4 比特表示主优先级
| | | 0 比特表示次优先级
==================================================================================*/
}
void __SZ_STM32_COMInit(COM_TypeDef COM, USART_InitTypeDef* USART_InitStruct)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIO clock */
/* 使能STM32的USART对应GPIO的Clock时钟 */
void NVIC_COMConfiguration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
// NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);//将中断矢量放到Flash的0地址
USART_ITConfig(SZ_STM32_COM1, USART_IT_RXNE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = SZ_STM32_COM1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(SZ_STM32_COM3, USART_IT_RXNE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = SZ_STM32_COM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
RCC_APB2PeriphClockCmd(COM_TX_PORT_CLK[COM] | COM_RX_PORT_CLK[COM] | RCC_APB2Periph_AFIO, ENABLE);
if (COM == COM1)
{
/* 使能STM32的USART1的Clock时钟 */
RCC_APB2PeriphClockCmd(COM_USART_CLK[COM], ENABLE);
}
else
{
/* Enable the USART2 Pins Software Remapping */
/* 使能STM32的USART2的管脚重映射 */
GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);
/* 使能STM32的USART的Clock时钟 */
RCC_APB1PeriphClockCmd(COM_USART_CLK[COM], ENABLE);
}
/* Configure USART Tx as alternate function push-pull */
/* 初始化STM32的USART的TX管脚,配置为复用功能推挽输出 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = COM_TX_PIN[COM];
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(COM_TX_PORT[COM], &GPIO_InitStructure);
/* Configure USART Rx as input floating */
/* 初始化STM32的USART的RX管脚,配置为复用功能输入 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = COM_RX_PIN[COM];
GPIO_Init(COM_RX_PORT[COM], &GPIO_InitStructure);
/* USART configuration */
/* 根据传入的参数初始化STM32的USART配置 */
USART_Init(COM_USART[COM], USART_InitStruct);
/* Enable USART */
/* 使能STM32的USART功能模块 */
USART_Cmd(COM_USART[COM], ENABLE);
}
void SZ_STM32_COMInit(COM_TypeDef COM, uint32_t BaudRate)
{
USART_InitTypeDef USART_InitStructure;
/* USARTx 默认配置:
- BaudRate = 115200 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = BaudRate; //串口的波特率,例如115200 最高达4.5Mbits/s
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据字长度(8位或9位)
USART_InitStructure.USART_StopBits = USART_StopBits_1; //可配置的停止位-支持1或2个停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //双工模式,使能发送和接收
__SZ_STM32_COMInit(COM, &USART_InitStructure); // 调用STM32的USART初始化底层函数
SystemCoreClockUpdate();
}
以下是开发板里我摘录的接收和中断
SZ_USART_DATA_TypeDef SZ_USART1_DATA, SZ_USART2_DATA, SZ_USART3_DATA;
/**-------------------------------------------------------
* @函数名 UsartIrqHandlerUser
* @功能 共用的串口中断处理函数
* @参数 SZ_USART 串口数据结构体指针
* @返回值 无
***------------------------------------------------------*/
void UsartIrqHandlerUser(SZ_USART_DATA_TypeDef* SZ_USART)
{
uint8_t uartRxData = 0;
if(USART_GetITStatus(SZ_USART->uart, USART_IT_RXNE) != RESET)
{
/* save on rx buffer */
while (SZ_USART->uart->SR & USART_FLAG_RXNE)
{
/* save character */
uartRxData = SZ_USART->uart->DR & 0xff;
SZ_USART->uartRxBuffer[SZ_USART->uart_rx_write_point] = uartRxData;
SZ_USART->uart_rx_write_length ++;
SZ_USART->uart_rx_write_point ++;
if (SZ_USART->uart_rx_write_point >= UART_RX_BUFFER_SIZE)
SZ_USART->uart_rx_write_point = 0;
/* if the next position is read index, discard this 'read char' */
if (SZ_USART->uart_rx_write_point == SZ_USART->uart_rx_read_point)
{
//即将覆盖未读的数据,如何处理用户根据需要自己添加
}
}
/* clear interrupt */
USART_ClearITPendingBit(SZ_USART->uart, USART_IT_RXNE);
/* 接收完成 */
if ((uartRxData == 0x05) || (SZ_USART->uart_rx_write_length >= UART_RX_BUFFER_SIZE))
{
SZ_USART->uart_rx_length = SZ_USART->uart_rx_write_length;
SZ_USART->uart_rx_done= 1;
SZ_USART->uart_rx_write_length = 0;
}
}
/* If overrun condition occurs, clear the ORE flag
and recover communication */
if (USART_GetFlagStatus(SZ_USART->uart, USART_FLAG_ORE) != RESET)
{
(void)USART_ReceiveData(SZ_USART->uart);
}
if (USART_GetITStatus(SZ_USART->uart, USART_IT_TC) != RESET)
{
/* clear interrupt */
USART_ClearITPendingBit(SZ_USART->uart, USART_IT_TC);
}
}
/**-------------------------------------------------------
* @函数名 UsartReadData
* @功能 共用的串口数据读取子函数
* @参数1 SZ_USART 串口数据结构体指针
* @参数2 串口数据存放的Buffer
* @返回值 无
***------------------------------------------------------*/
uint32_t UsartReadData(SZ_USART_DATA_TypeDef* SZ_USART, uint8_t* Buffer)
{
uint32_t uartRxLength = 0, i;
/* if the next position is read index, discard this 'read char' */
if (SZ_USART->uart_rx_length != 0)
{
/* 开始临界资源访问,禁止中断 */
__disable_irq();
uartRxLength = SZ_USART->uart_rx_length;
SZ_USART->uart_rx_length = 0;
SZ_USART->uart_rx_done = 0;
/* 结束临界资源访问,开放中断 */
__enable_irq();
for(i=0; i<uartRxLength; i++)
{
Buffer[i] = SZ_USART->uartRxBuffer[SZ_USART->uart_rx_read_point];
SZ_USART->uart_rx_read_point++;
if (SZ_USART->uart_rx_read_point >= UART_RX_BUFFER_SIZE)
{
SZ_USART->uart_rx_read_point = 0;
}
}
Buffer[i] = '\0';
}
return uartRxLength;
}
/**-------------------------------------------------------
* @函数名 USART1_IRQHandler
* @功能 串口1中断处理函数
* @参数 无
* @返回值 无
***------------------------------------------------------*/
void USART1_IRQHandler(void)
{
/* 开始临界资源访问,禁止中断 */
__disable_irq();
/* 串口1中断时将指示灯1状态取反 */
LED1OBB = !LED1OBB;
/* 调用共用的串口中断处理子函数 */
UsartIrqHandlerUser(&SZ_USART1_DATA);
/* 结束临界资源访问,开放中断 */
__enable_irq();
}
/**-------------------------------------------------------
* @函数名 USART2_IRQHandler
* @功能 串口2中断处理函数
* @参数 无
* @返回值 无
***------------------------------------------------------*/
void USART3_IRQHandler(void)
{
/* 开始临界资源访问,禁止中断 */
__disable_irq();
/* 串口2中断时将指示灯2状态取反 */
LED3OBB = !LED3OBB;
/* 调用共用的串口中断处理子函数 */
// UsartIrqHandlerUser(&SZ_USART3_DATA);
/* 结束临界资源访问,开放中断 */
__enable_irq();
}
主函数如下:
int main(void)
{
/*!< 在系统启动文件(startup_stm32f10x_xx.s)中已经调用SystemInit()初始化了时钟,
所以main函数不需要再次重复初始化时钟。默认初始化系统主时钟为72MHz。
SystemInit()函数的实现位于system_stm32f10x.c文件中。
*/
uint8_t ucStr[UART_RX_BUFFER_SIZE+1];//多一个用于存放'\0'
/* 初始化板载LED指示灯 */
SZ_STM32_LEDInit(LED1);
SZ_STM32_LEDInit(LED2);
SZ_STM32_LEDInit(LED3);
SZ_STM32_LEDInit(LED4);
SZ_STM32_SysTickInit(1000);
SZ_USART1_DATA.uart = SZ_STM32_COM1;
SZ_USART1_DATA.uart_rx_done = 0;
SZ_USART1_DATA.uart_rx_length= 0;
SZ_USART1_DATA.uart_rx_read_point = 0;
SZ_USART1_DATA.uart_rx_write_point = 0;
SZ_USART1_DATA.uart_rx_write_length = 0;
SZ_USART3_DATA.uart = SZ_STM32_COM3;
SZ_USART3_DATA.uart_rx_done = 0;
SZ_USART3_DATA.uart_rx_length= 0;
SZ_USART3_DATA.uart_rx_read_point = 0;
SZ_USART3_DATA.uart_rx_write_point = 0;
SZ_USART3_DATA.uart_rx_write_length = 0;
/* 注意串口2使用Printf时"SZ_STM32F107VC_LIB.c"文件中fputc定义中设备改为SZ_STM32_COM2 */
/* 串口2初始化 */
SZ_STM32_COMInit(COM3, 115200);
/* 串口1初始化 注意JP3和JP5跳到2<->3侧 */
xPrintf_Init();
NVIC_GroupConfig();
NVIC_COMConfiguration();
printf("\n\n\r 提示: 当前显示的窗口为串口2/COM2/USART2。 请将注意JP4跳到2<->3侧。\r\n");
xprintf("\n\n\r 提示: 当前显示的窗口为串口1/COM1/USART1。请将注意JP3和JP5跳到2<->3侧。\r\n");
/* Infinite loop 主循环 */
LED1OBB = 1;
LED3OBB = 1;
LED4OBB = 0;
while (1)
{
if(SZ_USART1_DATA.uart_rx_done == 1)
{
if(UsartReadData(&SZ_USART1_DATA, ucStr))
{
LED4OBB = 1;
// xprintf("\n\n\r 串口1/COM1/USART1接收到-->%s\r\n", ucStr);
Usart1SendStr(ucStr,8);
LED4OBB = 0;
}
}
if(SZ_USART3_DATA.uart_rx_done == 1)
{
if(UsartReadData(&SZ_USART3_DATA, ucStr))
// printf("\n\n\r 串口2/COM2/USART2接收到-->%s\r\n", ucStr);
Usart3SendStr(ucStr,8);
}
/* 此处可以添加用户的程序 */
}
}
这里我还省略的部分代码,USART1的Xprint功能均能正常使用,两个串口发送我自己写的Usart3SendStr();也没问题。可中断一直无法进入USART3_IRQHandler(void),可原先我使用USART2,接收和发送完全没问题。
补充一下,使用的是STM32F103VC 我这里USART3重映射到PC10,PC11.原先我是想使用UART4,可惜没弄出来。退而求其次想弄USART3,发现问题依旧,于是没有办法了。希望可以解决。 |