Фактические изменения, необходимые для кода, представленного ниже, являются скромными. Мы должны настроить два дополнительных контакта для nCTS и nRTS, изменить инициализацию USART, чтобы позволить nCTS остановить передатчик, и изменить как обработчик прерываний, так и процедуры getchar. Наша стратегия состоит в том, чтобы определить метку «высокого уровня» во входном буфере, ниже которой программное обеспечение устанавливает nRTS, и выше которого оно отменяет nRTS. Верхняя отметка обеспечивает место для добавления дополнительных символов после отмены nRTS.
В дополнение к tx и rx, которые мы предварительно настроили, мы должны настроить nRTS (PA12) и nCTS (PA11):
// Configure CTS pin GPIO_InitStructure . GPIO_Pin = GPIO_Pin_11 ; GPIO_InitStructure . GPIO_Mode = GPIO_Mode_IN_FLOATING ; GPIO_InitStructure . GPIO_Speed = GPIO_Speed_2MHz ; GPIO_Init (GPIOA , & GPIO_InitStructure ); // Configure RTS pin -- software controlled GPIO_WriteBit (GPIOA , GPIO_Pin_12 , 1); // nRTS disabled GPIO_InitStructure . GPIO_Pin = GPIO_Pin_12 ; GPIO_InitStructure . GPIO_Mode = GPIO_Mode_Out_PP ; GPIO_InitStructure . GPIO_Speed = GPIO_Speed_2MHz ; GPIO_Init (GPIOA , & GPIO_InitStructure );
Мы немного изменим конфигурацию USART:
USART_InitStructure . USART_HardwareFlowControl = USART_HardwareFlowControl_CTS ;
и включим nRTS
// nRTS enabled GPIO_WriteBit (GPIOA , GPIO_Pin_12 , 0);
Как уже говорилось выше, мы добавляем код в процедуру getchar
char getchar ( void ) { uint8_t data; while (Dequeue (& UART1_RXq , &data , 1) != 1); // If the queue has fallen below high water mark , enable nRTS if ( QueueAvail (& UART1_RXq ) <= HIGH_WATER ) GPIO_WriteBit (GPIOA , GPIO_Pin_12 , 0); return data; }
и получающая часть обработчика прерываний:
if ( USART_GetITStatus (USART1 , USART_IT_RXNE ) != RESET) { uint8_t data; // clear the interrupt USART_ClearITPendingBit (USART1 , USART_IT_RXNE ); // buffer the data (or toss it if there 's no room // Flow control is supposed to prevent this data = USART_ReceiveData (USART1) & 0xff; if (! Enqueue (& UART1_RXq , &data , 1)) RxOverflow = 1; // If queue is above high water mark , disable nRTS if ( QueueAvail (& UART1_RXq ) > HIGH_WATER ) GPIO_WriteBit (GPIOA , GPIO_Pin_12 , 1); }
Наконец, мы определяем высшую отметку в uart.h
#define HIGH_WATER ( QUEUE_SIZE - 6)