-
Хотя в ПК последовательные порты постепенно исчезают, в области встраиваемых систем последовательные порты по-прежнему остаются популярными, поскольку они недороги и удобны в программировании. В системах без экранов дисплея или устройств ввода последовательные порты еще более популярны. Незаменим, вместе с HyperTerminal решает проблему отображения и ввода информации.
После нескольких дней напряженной работы работа по трансплантации .Net Micro Framework NativeSample на платформу Cortex-M3 приближается к стадии. В настоящее время код запуска, SRAM, часы (RCC), прерывания (NVIC), SysTick, GPIO, последовательный порт, NandFlash (FMSC) и другие связанные функции, можно сказать, что эти коды являются минимальным набором для нормальной работы TinyClr. Если они работают в качестве основы, следующим шагом может быть пересадка TinyClr. Плата разработки M3, которую мы используем, имеет более 2 МБ ОЗУ, тогда наша работа может быть завершена на 90% на этом этапе, но из-за ограниченности ресурсов следующим шагом отладки должна быть версия Flash, поэтому будет много неизвестной работы. и отладка также станет трудной. улучшился до нового уровня.
Хорошо, давайте поговорим о разработке драйвера последовательного порта.
Как и при разработке GPIO, нам все еще нужно написать код регистра, связанный с последовательным портом, в CortexM3.h.
структура CortexM3_Usart
{
статическая константа UINT32 c_MAX_BAUDRATE = 45000000;
статическая константа UINT32 c_MIN_BAUDRATE = 1200;
статическая константа UINT32 c_Base1 = 0x40013800;
статическая константа UINT32 c_Base2 = 0x40004400;
статическая константа UINT32 c_Base3 = 0x40004800;
/****/ энергозависимый UINT16 SR;
статическая константа UINT16 SR_TXE=((UINT16)0x0080);
статическая константа UINT16 SR_TC=((UINT16)0x0040);
статическая константа UINT16 SR_RXNE=((UINT16)0x0020);
UINT16 ЗАРЕЗЕРВИРОВАНО0;
/****/ энергозависимый UINT16 DR;
UINT16 ЗАРЕЗЕРВИРОВАНО1;
/****/ изменчивый UINT16 BRR;
UINT16 ЗАРЕЗЕРВИРОВАНО2;
/****/ энергозависимый UINT16 CR1;
static const UINT16 CR1_UE_Set = ((UINT16)0x2000 // Маска включения USART;
static const UINT16 CR1_UE_Reset = ((UINT16)0xDFFF); // Маска отключения USART;
статическая константа UINT16 CR1_Parity_No = ((UINT16)0x0000);
статическая константа UINT16 CR1_Parity_Even = ((UINT16)0x0400);
статическая константа UINT16 CR1_Parity_Odd = ((UINT16)0x0600);
статическая константа UINT16 CR1_DataBit_8 = ((UINT16)0x0000);
статическая константа UINT16 CR1_DataBit_9 = ((UINT16)0x1000);
статическая константа UINT16 CR1_Mode_Rx = ((UINT16)0x0004);
статическая константа UINT16 CR1_Mode_Tx = ((UINT16)0x0008);
статическая константа UINT16 CR1_CLEAR_Mask = ((UINT16)0xE9F3);
статическая константа UINT16 CR1_PEIE = ((UINT16)0x0100);
статическая константа UINT16 CR1_TXEIE = ((UINT16)0x0080);
статическая константа UINT16 CR1_TCIE = ((UINT16)0x0040);
статическая константа UINT16 CR1_RXNEIE = ((UINT16)0x0020);
UINT16 ЗАРЕЗЕРВИРОВАНО3;
/****/ энергозависимый UINT16 CR2;
статическая константа UINT16 CR2_StopBits_1 = ((UINT16)0x0000);
статическая константа UINT16 CR2_StopBits_0_5 = ((UINT16)0x1000);
статическая константа UINT16 CR2_StopBits_2 = ((UINT16)0x2000);
статическая константа UINT16 CR2_StopBits_1_5 = ((UINT16)0x3000);
static const UINT16 CR2_StopBits_Mask= ((UINT16)0xCFFF /* Маска стоп-битов USART CR2 */);
UINT16 ЗАРЕЗЕРВИРОВАНО4;
/****/ энергозависимый UINT16 CR3;
статическая константа UINT16 CR3_HardwareFlowControl_None = ((UINT16)0x0000);
статическая константа UINT16 CR3_HardwareFlowControl_RTS = ((UINT16)0x0100);
статическая константа UINT16 CR3_HardwareFlowControl_CTS = ((UINT16)0x0200);
статическая константа UINT16 CR3_HardwareFlowControl_RTS_CTS = ((UINT16)0x0300);
static const UINT16 CR3_HardwareFlowControl_Mask = ((UINT16)0xFCFF);
UINT16 ЗАРЕЗЕРВИРОВАНО5;
/****/ изменчивый UINT16 GTPR;
UINT16 ЗАРЕЗЕРВИРОВАНО6;
};
С помощью приведенного выше кода мы можем легко управлять регистром последовательного порта.
Инициализация последовательного порта требует следующих работ по инициализации (плата разработки STM3210E имеет три последовательных порта, в качестве примера мы возьмем последовательный порт 1):
1. Включите часы последовательного порта.
UsartId = CortexM3_NVIC::c_IRQ_Index_USART1;
RCC.APB2ENR |= CortexM3_RCC::APB2_GPIOA | CortexM3_RCC::APB2_USART1;
2. Прерывание активации
if(!CPU_INTC_ActivateInterruptEx(UsartId, (UINT32)(void *)USART1_IRQHandler)) return FALSE;
3. Установите параметры последовательного порта, такие как скорость передачи данных, четность, биты данных, стоповые биты и т. д.
немного
4. Переопределение GPIO
CPU_GPIO_DisablePin(GPIO_Driver::PA9,RESISTOR_DISABLED,FALSE,GPIO_ALT_MODE_1);
CPU_GPIO_DisablePin(GPIO_Driver::PA10,RESISTOR_DISABLED,TRUE,GPIO_ALT_MODE_2);
5. Включение последовательного порта
Usart.CR1 |= CortexM3_Usart::CR1_UE_Set;
Завершите отправку и получение данных в функции прерывания:
void CortexM3_USART_Driver::ISR(параметр void*)
{
UINT32 comPort = (UINT32)параметр;
CortexM3_Usart &Usart=CortexM3::Usart(comPort);
символ с;
Статус UINT32;
Статус = Усарт.СР;
если (Состояние и CortexM3_Usart::SR_RXNE)
{
в = Усарт.ДР;
USART_AddCharToRxBuffer(comPort, c);
Events_Set(SYSTEM_EVENT_FLAG_COM_IN);
}
если (статус и CortexM3_Usart::SR_TC)
{
if(0 == (c_RefFlagTx & g_CortexM3_USART_Driver.m_RefFlags[comPort]))
{
возвращаться;
}
если (USART_RemoveCharFromTxBuffer (comPort, c))
{
WriteCharToTxBuffer(comPort, c);
}
еще
{
// отключаем дальнейшие прерывания Tx, так как мы сработали по уровню
TxBufferEmptyInterruptEnable (comPort, FALSE);
}
Events_Set(SYSTEM_EVENT_FLAG_COM_OUT);
}
}
Основной код представляет собой соответствующий контент, представленный выше. Ниже мы пишем код тестирования последовательного порта в NativeSample:
недействительный ApplicationEntryPoint()
{
пока (ИСТИНА)
{
если (Events_WaitForEvents (SYSTEM_EVENT_FLAG_COM_IN, 100))
{
Events_Clear(SYSTEM_EVENT_FLAG_COM_IN);
символ bytData[512];
int Size = USART_BytesInBuffer (0, TRUE);
USART_Read(0,bytData,Размер);
for(int i=0;i<Size;i++)
debug_printf("%c",bytData[i]);
}
debug_printf("Привет, Micro Framework!!!rn");
}
}