Перейти к содержимому

#37. INTERRUPT DRIVEN SERIAL COMMUNICATIONS

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

Добавить комментарий