-
Embora nos PCs as portas seriais estejam desaparecendo gradualmente, no campo incorporado, as portas seriais ainda podem ser consideradas populares porque são de baixo custo e fáceis de programar. Em sistemas sem telas ou dispositivos de entrada, as portas seriais são ainda mais populares. . Indispensável, junto com o HyperTerminal, resolve o problema de exibição e entrada de informações.
Após vários dias de trabalho árduo, o trabalho de transplante NativeSample do .Net Micro Framework na plataforma Cortex-M3 está prestes a atingir um estágio. Atualmente, o código de inicialização, SRAM, clock (RCC), interrupção (NVIC), SysTick,. GPIO, porta serial, NandFlash (FMSC) e outras funções relacionadas, esses códigos podem ser considerados o conjunto mínimo para fazer o TinyClr funcionar normalmente. Com eles funcionando como base, o próximo passo pode ser transplantar o TinyClr. A placa de desenvolvimento M3 que usamos tem mais de 2M de RAM, então nosso trabalho pode estar 90% concluído neste ponto, mas devido aos recursos limitados, a próxima etapa de depuração deve ser a versão Flash, então haverá muito trabalho desconhecido, e a depuração também se tornará difícil. Não importa o quanto A jornada do .Net Micro Framework PortingKit continuará. No entanto, para ser honesto, concluir essas tarefas do zero é difícil, mas gratificante. melhorado para um novo nível.
Ok, vamos falar sobre o desenvolvimento do driver da porta serial.
Assim como o desenvolvimento do GPIO, ainda precisamos escrever o código de registro relacionado à porta serial no CortexM3.h.
estrutura CortexM3_Usart
{
const estático UINT32 c_MAX_BAUDRATE = 45000000;
const estático UINT32 c_MIN_BAUDRATE = 1200;
const estático UINT32 c_Base1 = 0x40013800;
const estático UINT32 c_Base2 = 0x40004400;
const estático UINT32 c_Base3 = 0x40004800;
/****/ volátil UINT16 SR;
const estático UINT16 SR_TXE=((UINT16)0x0080);
const estático UINT16 SR_TC=((UINT16)0x0040);
const estático UINT16 SR_RXNE=((UINT16)0x0020);
UINT16 RESERVADO0;
/****/ volátil UINT16 DR;
UINT16 RESERVADO1;
/****/ volátil UINT16 BRR;
UINT16 RESERVADO2;
/****/ volátil UINT16 CR1;
static const UINT16 CR1_UE_Set = ((UINT16)0x2000); //USART Habilita Máscara;
static const UINT16 CR1_UE_Reset = ((UINT16)0xDFFF); //USART desabilita máscara
const estático UINT16 CR1_Parity_No = ((UINT16)0x0000);
const estático UINT16 CR1_Parity_Even = ((UINT16)0x0400);
const estático UINT16 CR1_Parity_Odd = ((UINT16)0x0600);
const estático UINT16 CR1_DataBit_8 = ((UINT16)0x0000);
const estático UINT16 CR1_DataBit_9 = ((UINT16)0x1000);
const estático UINT16 CR1_Mode_Rx = ((UINT16)0x0004);
const estático UINT16 CR1_Mode_Tx = ((UINT16)0x0008);
const estático UINT16 CR1_CLEAR_Mask = ((UINT16)0xE9F3);
const estático UINT16 CR1_PEIE = ((UINT16)0x0100);
const estático UINT16 CR1_TXEIE = ((UINT16)0x0080);
const estático UINT16 CR1_TCIE = ((UINT16)0x0040);
const estático UINT16 CR1_RXNEIE = ((UINT16)0x0020);
UINT16 RESERVADO3;
/****/ volátil UINT16 CR2;
const estático UINT16 CR2_StopBits_1 = ((UINT16)0x0000);
const estático UINT16 CR2_StopBits_0_5 = ((UINT16)0x1000);
const estático UINT16 CR2_StopBits_2 = ((UINT16)0x2000);
const estático UINT16 CR2_StopBits_1_5 = ((UINT16)0x3000);
static const UINT16 CR2_StopBits_Mask= ((UINT16)0xCFFF); /* Máscara de bits USART CR2 STOP */
UINT16 RESERVADO4;
/****/ volátil UINT16 CR3;
const estático UINT16 CR3_HardwareFlowControl_None = ((UINT16)0x0000);
const estático UINT16 CR3_HardwareFlowControl_RTS = ((UINT16)0x0100);
const estático UINT16 CR3_HardwareFlowControl_CTS = ((UINT16)0x0200);
const estático UINT16 CR3_HardwareFlowControl_RTS_CTS = ((UINT16)0x0300);
const estático UINT16 CR3_HardwareFlowControl_Mask = ((UINT16)0xFCFF);
UINT16 RESERVADO5;
/****/ volátil UINT16 GTPR;
UINT16 RESERVADO6;
};
Com o código acima, podemos operar facilmente o registro da porta serial.
A inicialização da porta serial requer o seguinte trabalho de inicialização (a placa de desenvolvimento STM3210E possui três portas seriais, tomaremos a porta serial 1 como exemplo):
1. Ligue o relógio da porta serial
UsartId = CortexM3_NVIC::c_IRQ_Index_USART1;
RCC.APB2ENR |= CortexM3_RCC::APB2_GPIOA |
2. Interrupção de ativação
if(!CPU_INTC_ActivateInterruptEx( UsartId, (UINT32)(void *)USART1_IRQHandler)) retorna FALSO;
3. Defina os parâmetros da porta serial, como taxa de transmissão, paridade, bits de dados, bits de parada, etc.
um pouco
4. Redefinição 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. Ativação de porta serial
Usart.CR1 |= CortexM3_Usart::CR1_UE_Set;
Conclua o envio e recebimento de dados na função de interrupção:
void CortexM3_USART_Driver::ISR( void* parâmetro )
{
UINT32 comPort = (UINT32)param;
CortexM3_Usart &Usart=CortexM3::Usart(comPort);
caracter c;
Estado UINT32;
Status = Usart.SR;
if(Status & CortexM3_Usart::SR_RXNE)
{
c = usart.DR;
USART_AddCharToRxBuffer( comPort, c );
Eventos_Set(SYSTEM_EVENT_FLAG_COM_IN);
}
if(Status & CortexM3_Usart::SR_TC)
{
if(0 == (c_RefFlagTx & g_CortexM3_USART_Driver.m_RefFlags[comPort]))
{
retornar;
}
if(USART_RemoveCharFromTxBuffer( comPort, c ))
{
WriteCharToTxBuffer(comPort,c);
}
outro
{
// desativa outras interrupções de Tx já que somos acionados por nível
TxBufferEmptyInterruptEnable(comPort, FALSE);
}
Eventos_Set(SYSTEM_EVENT_FLAG_COM_OUT);
}
}
O código principal é o conteúdo relevante apresentado acima. Abaixo, escrevemos um código de teste de porta serial em NativeSample:
void ApplicationEntryPoint()
{
enquanto (VERDADEIRO)
{
if(Events_WaitForEvents(SYSTEM_EVENT_FLAG_COM_IN,100))
{
Eventos_Clear(SYSTEM_EVENT_FLAG_COM_IN);
char bytData[512];
int Tamanho=USART_BytesInBuffer(0,TRUE);
USART_Read(0,bytData,Tamanho);
for(int i=0;i<Tamanho;i++)
debug_printf("%c",bytData[i]);
}
debug_printf("Olá Micro Framework!!!rn");
}
}