下面来说使用USART接收数据,接收数据有中断模式、查询模式、DMA模式。我这里测试了中断模式。该芯片提供了两个重要的中断源,USART_IT_RXNE和USART_IT_IDLE,
USART_IT_RXNE模式为只要接收到一个字符就触发,USART_IT_IDLE只要接收到贞数据触发,好象和STM32一样,可是经过测试发现“不一样地“,USART_IT_IDLE是只要总线空闲就触发。只要打开就会反反复复的触发。唉!又一次草率啦。(当然也可能是不会用,为因为芯片重启后只有第一次是成功的,往后就不行了)这使我浪费了大量的时间。
我说一下关键的代码吧!
void USARTx_CFG(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //GPIO初始化结构
USART_InitTypeDef USART_InitStructure;//串口控制器初始化结构
NVIC_InitTypeDef NVIC_InitStructure;//串口中断优先级设置
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2|RCC_APB1Periph_USART3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB , ENABLE);
/* USART2 TX-->A.2 RX-->A.3 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
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_Tx | USART_Mode_Rx;
USART_Init(USART2, &USART_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART2, ENABLE);
}
一、打开USART2的中断功能。USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
这里注意好象该函数只能次打开一个中断。我写成USART_ITConfig(USART2, USART_IT_RXNE|USART_IT_IDLE, ENABLE);发现USART_IT_IDLE中断无法打开。
二、设置USART2_IRQn优先级,我设置成NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;(组2)的第一号中断
三、打开串口usart2
接下来就是编写中断函数。
/* Global typedef */
void USART2_IRQHandler(void) __attribute__((interrupt("machine")));
//这里我改成了"machine"不是"WCH-Interrupt-fast"
//void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
/*******************************************************************************
* Function Name : USART2_IRQHandler
* Description : This function handles USART2 global interrupt request.
* Input : None
* Return : None
*******************************************************************************/
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
RxBuffer[RxCnt++] = USART_ReceiveData(USART2);
if(RxCnt >= RxBufSize)
{
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
USART_ITConfig(USART2, USART_IT_IDLE, DISABLE);
Rxfinish = 1;
}
}else if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET){
GPIO_WriteBit(GPIOB, GPIO_Pin_1, Bit_RESET);
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
USART_ITConfig(USART2, USART_IT_IDLE, DISABLE);
Rxfinish = 2;
}
}
注意这里的函数名称是专用的!不可更改。
好了。主要的程序就写完了,经过测试除了USART_IT_IDLE反复中断,别的没有什么问题。如果不使用USART_IT_IDLE中断,一点问题都没有。
|