-
Aunque en las PC los puertos serie están desapareciendo gradualmente, en el campo integrado, se puede decir que los puertos serie todavía son populares porque son de bajo costo y convenientes de programar. En sistemas sin pantallas de visualización o dispositivos de entrada, los puertos serie son aún más populares. Indispensable, junto con HyperTerminal, resuelve el problema de visualización e introducción de información.
Después de varios días de arduo trabajo, el trabajo de trasplante de NativeSample de .Net Micro Framework en la plataforma Cortex-M3 está a punto de llegar a una etapa. En la actualidad, el código de inicio, SRAM, reloj (RCC), interrupción (NVIC), SysTick, GPIO, puerto serie, NandFlash (FMSC) y otras funciones relacionadas, se puede decir que estos códigos son el conjunto mínimo para que TinyClr funcione normalmente. Con estos trabajos como base, el siguiente paso puede ser trasplantar TinyClr. La placa de desarrollo M3 que utilizamos tiene más de 2 M de RAM, entonces nuestro trabajo puede estar completado en un 90% en este punto, pero debido a recursos limitados, el siguiente paso de depuración debe ser la versión Flash, por lo que habrá mucho trabajo desconocido. y la depuración también será difícil, no importa cómo El viaje de .Net Micro Framework PortingKit continuará. Sin embargo, para ser honesto, completar estas tareas desde cero es difícil pero gratificante. Mi comprensión del desarrollo de ARM (especialmente Cortex-M3). mejorado a un nuevo nivel.
Bien, hablemos del desarrollo del controlador del puerto serie.
Al igual que el desarrollo de GPIO, todavía necesitamos escribir el código de registro relacionado con el puerto serie en CortexM3.h.
estructura CortexM3_Usart
{
constante estática UINT32 c_MAX_BAUDRATE = 45000000;
constante estática UINT32 c_MIN_BAUDRATE = 1200;
constante estática UINT32 c_Base1 = 0x40013800;
constante estática UINT32 c_Base2 = 0x40004400;
constante estática UINT32 c_Base3 = 0x40004800;
/****/ volátil UINT16 SR;
constante estática UINT16 SR_TXE=((UINT16)0x0080);
constante estática UINT16 SR_TC=((UINT16)0x0040);
constante estática UINT16 SR_RXNE=((UINT16)0x0020);
UINT16 RESERVADO0;
/****/ volátil UINT16 DR;
UINT16 RESERVADO1;
/****/ volátil UINT16 BRR;
UINT16 RESERVADO2;
/****/ volátil UINT16 CR1;
constante estática UINT16 CR1_UE_Set = ((UINT16)0x2000 // Máscara de habilitación USART);
constante estática UINT16 CR1_UE_Reset = ((UINT16)0xDFFF //USART Desactivar máscara);
constante estática UINT16 CR1_Parity_No = ((UINT16)0x0000);
constante estática UINT16 CR1_Parity_Even = ((UINT16)0x0400);
constante estática UINT16 CR1_Parity_Odd = ((UINT16)0x0600);
constante estática UINT16 CR1_DataBit_8 = ((UINT16)0x0000);
constante estática UINT16 CR1_DataBit_9 = ((UINT16)0x1000);
constante estática UINT16 CR1_Mode_Rx = ((UINT16)0x0004);
constante estática UINT16 CR1_Mode_Tx = ((UINT16)0x0008);
constante estática UINT16 CR1_CLEAR_Mask = ((UINT16)0xE9F3);
constante estática UINT16 CR1_PEIE = ((UINT16)0x0100);
constante estática UINT16 CR1_TXEIE = ((UINT16)0x0080);
constante estática UINT16 CR1_TCIE = ((UINT16)0x0040);
constante estática UINT16 CR1_RXNEIE = ((UINT16)0x0020);
UINT16 RESERVADO3;
/****/ volátil UINT16 CR2;
constante estática UINT16 CR2_StopBits_1 = ((UINT16)0x0000);
constante estática UINT16 CR2_StopBits_0_5 = ((UINT16)0x1000);
constante estática UINT16 CR2_StopBits_2 = ((UINT16)0x2000);
constante estática UINT16 CR2_StopBits_1_5 = ((UINT16)0x3000);
constante estática UINT16 CR2_StopBits_Mask= ((UINT16)0xCFFF /* Máscara de bits de PARADA USART CR2 */);
UINT16 RESERVADO4;
/****/ volátil UINT16 CR3;
constante estática UINT16 CR3_HardwareFlowControl_None = ((UINT16)0x0000);
constante estática UINT16 CR3_HardwareFlowControl_RTS = ((UINT16)0x0100);
constante estática UINT16 CR3_HardwareFlowControl_CTS = ((UINT16)0x0200);
constante estática UINT16 CR3_HardwareFlowControl_RTS_CTS = ((UINT16)0x0300);
constante estática UINT16 CR3_HardwareFlowControl_Mask = ((UINT16)0xFCFF);
UINT16 RESERVADO5;
/****/ volátil UINT16 GTPR;
UINT16 RESERVADO6;
};
Con el código anterior, podemos operar fácilmente el registro del puerto serie.
La inicialización del puerto serie requiere el siguiente trabajo de inicialización (la placa de desarrollo STM3210E tiene tres puertos serie, tomaremos el puerto serie 1 como ejemplo):
1. Encienda el reloj del puerto serie.
UsartId = CortexM3_NVIC::c_IRQ_Index_USART1;
RCC.APB2ENR |= CortexM3_RCC::APB2_GPIOA | CortexM3_RCC::APB2_USART1;
2. Interrupción de activación
if(!CPU_INTC_ActivateInterruptEx( UsartId, (UINT32)(void *)USART1_IRQHandler)) devuelve FALSO;
3. Configure los parámetros del puerto serie, como velocidad en baudios, paridad, bits de datos, bits de parada, etc.
levemente
4. Redefinición de 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. Habilitación del puerto serie
Usart.CR1 |= CortexM3_Usart::CR1_UE_Set;
Complete el envío y recepción de datos en la función de interrupción:
void CortexM3_USART_Driver::ISR( void* parámetro )
{
UINT32 comPort = (UINT32)param;
CortexM3_Usart &Usart=CortexM3::Usart(comPort);
carácter c;
Estado UINT32;
Estado = Usart.SR;
if(Estado y CortexM3_Usart::SR_RXNE)
{
c = Usart.DR;
USART_AddCharToRxBuffer( comPort, c );
Conjunto_de_eventos( SYSTEM_EVENT_FLAG_COM_IN );
}
if(Estado y CortexM3_Usart::SR_TC)
{
if(0 == (c_RefFlagTx & g_CortexM3_USART_Driver.m_RefFlags[comPort]))
{
devolver;
}
if(USART_RemoveCharFromTxBuffer( comPort, c ))
{
WriteCharToTxBuffer( comPort, c );
}
demás
{
// deshabilitamos más interrupciones de Tx ya que estamos activados por nivel
TxBufferEmptyInterruptEnable(comPort, FALSO);
}
Conjunto de eventos (SYSTEM_EVENT_FLAG_COM_OUT);
}
}
El código principal es el contenido relevante presentado anteriormente. A continuación escribimos un código de prueba de puerto serie en NativeSample:
anular ApplicationEntryPoint()
{
mientras (VERDADERO)
{
si(Eventos_EsperarEventos(SYSTEM_EVENT_FLAG_COM_IN,100))
{
Eventos_Borrar(SYSTEM_EVENT_FLAG_COM_IN);
char bytData[512];
int Tamaño=USART_BytesInBuffer(0,TRUE);
USART_Read(0,bytData,Tamaño);
para(int i=0;i<Tamaño;i++)
debug_printf("%c",bytData[i]);
}
debug_printf("¡¡Hola Micro Framework!!!rn");
}
}