Фактические изменения, необходимые для кода, представленного ниже, являются скромными. Мы должны настроить два дополнительных контакта для 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)