例程里接收是中断接收,但是发送中断只是开机的时候将数组里的数中断发送了,其他数据都是在主循环里查询发送的. 我将其改为真正的中断发送。 步骤一:初始化GPIO GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //LED1-PC10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //USART1 TX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); //A端口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1 RX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //复用开漏输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //A端口 步骤二:开时钟 /* Enable USART1, GPIOA, GPIOD and AFIO clocks */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE); 在此说明,不用设置RCC_APB2Periph_AFIO也是可以的,也就是在此没有使用复用功能。这两个步骤与查询方式是一样的。 步骤三:初始化USART1 USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_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; /* Configure the USART1 */ USART_Init(USART1, &USART_InitStructure); /* Enable the USART Transmoit interrupt: this interrupt is generated when the USART1 transmit data register is empty */ USART_ITConfig(USART1, USART_IT_TXE, ENABLE); /* Enable the USART Receive interrupt: this interrupt is generated when the USART1 receive data register is not empty */ USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); /* Enable USART1 */ USART_Cmd(USART1, ENABLE); 在这里要使能USART1的外设中断,如USART_ITConfig(USART1, USART_IT_TXE, ENABLE);这就是使能发送中断,但发送寄存器空时能产生中断。 步骤四:编写中断函数 #define TxBufferSize1 (countof(TxBuffer1) - 1) #define RxBufferSize1 (countof(TxBuffer1) - 1) #define countof(a) (sizeof(a) / sizeof(*(a))) //表示数组a中元素的个数 uint8_t TxBuffer1[] = "USART Interrupt Example: This is USART1 DEMO"; uint8_t RxBuffer1[RxBufferSize1],rec_f; __IO uint8_t TxCounter1 = 0x00; __IO uint8_t RxCounter1 = 0x00; uint8_t NbrOfDataToTransfer1 = TxBufferSize1; uint8_t NbrOfDataToRead1 = RxBufferSize1; /*串口中断服务程序*/ void USART1_IRQHandler(void) { unsigned int i; /*接收中断*/ if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { /* Read one byte from the receive data register */ RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1); if(RxCounter1 == NbrOfDataToRead1) //接收数据达到需要长度,则将数据复制到发送数组中,并置标志 { /* Disable the USART1 Receive interrupt */ //USART_ITConfig(USART1, USART_IT_RXNE, DISABLE); for(i=0; i< RxCounter1; i++) TxBuffer1 = RxBuffer1; rec_f=1; RxCounter1=0; TxCounter1=0; USART_ITConfig(USART1, USART_IT_TXE, ENABLE); //打开发送中断,这句是关键 } } /*发送中断*/ if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) { USART_SendData(USART1, TxBuffer1[TxCounter1++]); if(TxCounter1 == NbrOfDataToTransfer1)//发送数据完成 { USART_ITConfig(USART1, USART_IT_TXE, DISABLE); //关闭发送中断 } } } 至此程序就结束了。 我们就会有个疑问,main()只包括前三个步骤的初始化和一个死循环,那么中断又是如何触发的呢,main()的结构如下: int main(void) { /* System Clocks Configuration */ RCC_Configuration(); /* NVIC configuration */ NVIC_Configuration(); /* Configure the GPIO ports */ GPIO_Configuration(); USART_Configuration(); while (1) { } } 原来是这样的:状态寄存器USART_SR的复位值为0x00C0H, 也就是第七位TXE和第六位TC复位值为1,而TXE=1,表明发送数据寄存器为空, TC=1表明发送已完成。而在USART的设置中有 USART_ITConfig(USART1, USART_IT_TXE, ENABLE); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); 这两句使能中断,也就是说当TXE=1就会进入中断,所以程序初始化后就能进入中断,执行 if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) { /* Write one byte to the transmit data register */ USART_SendData(USART1, TxBuffer[TxCounter++]); if(TxCounter == NbrOfDataToTransfer) { /* Disable the USART1 Transmit interrupt */ USART_ITConfig(USART1, USART_IT_TXE, DISABLE); } }
|