-
PC에서는 직렬 포트가 점차 사라지고 있지만, 임베디드 분야에서는 저렴하고 프로그래밍이 편리하기 때문에 여전히 인기가 높다고 할 수 있습니다. 디스플레이 화면이나 입력 장치가 없는 시스템에서는 직렬 포트가 더욱 인기가 높습니다. . 필수입니다. HyperTerminal과 함께 정보 표시 및 입력 문제를 해결합니다.
며칠 간의 노력 끝에 Cortex-M3 플랫폼에서 .Net Micro Framework의 NativeSample 이식 작업은 현재 시작 코드, SRAM, 시계(RCC), 인터럽트(NVIC), SysTick, GPIO, 직렬 포트, NandFlash(FMSC) 및 기타 관련 기능은 TinyClr이 정상적으로 작동하기 위한 최소한의 설정이라고 할 수 있습니다. 이러한 작업을 기반으로 다음 단계는 TinyClr을 이식하는 것입니다. 우리가 사용하는 M3 개발 보드에는 2M 이상의 RAM이 있으며, 이 시점에서 작업이 90% 완료될 수 있지만 제한된 리소스로 인해 디버깅의 다음 단계는 플래시 버전이어야 하므로 알려지지 않은 작업이 많이 있을 것입니다. .Net Micro Framework PortingKit의 여정은 계속될 것입니다. 하지만 솔직히 말해서 이러한 작업을 처음부터 완료하는 것은 어렵지만 ARM 개발(특히 Cortex-M3)에 대한 이해가 쏠쏠합니다. 새로운 수준으로 향상되었습니다.
자, 직렬 포트 드라이버 개발에 대해 이야기해 봅시다.
GPIO 개발과 마찬가지로 CortexM3.h에 직렬 포트 관련 레지스터 코드를 작성해야 합니다.
CortexM3_Usart 구조체
{
정적 const UINT32 c_MAX_BAUDRATE = 45000000;
static const UINT32 c_MIN_BAUDRATE = 1200;
static const UINT32 c_Base1 = 0x40013800;
static const UINT32 c_Base2 = 0x40004400;
static const UINT32 c_Base3 = 0x40004800;
/****/ 휘발성 UINT16 SR;
static const UINT16 SR_TXE=((UINT16)0x0080);
static const UINT16 SR_TC=((UINT16)0x0040);
static const UINT16 SR_RXNE=((UINT16)0x0020);
UINT16 RESERVED0;
/****/ 휘발성 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 비활성화 마스크
static const UINT16 CR1_Parity_No = ((UINT16)0x0000);
static const UINT16 CR1_Parity_Even = ((UINT16)0x0400);
static const UINT16 CR1_Parity_Odd = ((UINT16)0x0600);
static const UINT16 CR1_DataBit_8 = ((UINT16)0x0000);
static const UINT16 CR1_DataBit_9 = ((UINT16)0x1000);
static const UINT16 CR1_Mode_Rx = ((UINT16)0x0004);
static const UINT16 CR1_Mode_Tx = ((UINT16)0x0008);
static const UINT16 CR1_CLEAR_Mask = ((UINT16)0xE9F3);
static const UINT16 CR1_PEIE = ((UINT16)0x0100);
static const UINT16 CR1_TXEIE = ((UINT16)0x0080);
static const UINT16 CR1_TCIE = ((UINT16)0x0040);
static const UINT16 CR1_RXNEIE = ((UINT16)0x0020);
UINT16 RESERVED3;
/****/ 휘발성 UINT16 CR2;
static const UINT16 CR2_StopBits_1 = ((UINT16)0x0000);
static const UINT16 CR2_StopBits_0_5 = ((UINT16)0x1000);
static const UINT16 CR2_StopBits_2 = ((UINT16)0x2000);
static const UINT16 CR2_StopBits_1_5 = ((UINT16)0x3000);
static const UINT16 CR2_StopBits_Mask= ((UINT16)0xCFFF) /* USART CR2 STOP 비트 마스크 */
UINT16 예약됨4;
/****/ 휘발성 UINT16 CR3;
static const UINT16 CR3_HardwareFlowControl_None = ((UINT16)0x0000);
static const UINT16 CR3_HardwareFlowControl_RTS = ((UINT16)0x0100);
static const UINT16 CR3_HardwareFlowControl_CTS = ((UINT16)0x0200);
static const UINT16 CR3_HardwareFlowControl_RTS_CTS = ((UINT16)0x0300);
static const UINT16 CR3_HardwareFlowControl_Mask = ((UINT16)0xFCFF);
UINT16 예약5;
/****/ 휘발성 UINT16 GTPR;
UINT16 예약됨6;
};
위의 코드를 사용하면 직렬 포트 레지스터를 쉽게 조작할 수 있습니다.
직렬 포트를 초기화하려면 다음 초기화 작업이 필요합니다(STM3210E 개발 보드에는 3개의 직렬 포트가 있으며 직렬 포트 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* param )
{
UINT32 comPort = (UINT32)param;
CortexM3_Usart &Usart=CortexM3::Usart(comPort);
문자 C;
UINT32 상태;
상태 = Usart.SR;
if(상태 & CortexM3_Usart::SR_RXNE)
{
c = Usart.DR;
USART_AddCharToRxBuffer( comPort, c );
Events_Set( SYSTEM_EVENT_FLAG_COM_IN );
}
if(상태 & CortexM3_Usart::SR_TC)
{
if(0 == (c_RefFlagTx & g_CortexM3_USART_Driver.m_RefFlags[comPort]))
{
반품;
}
if(USART_RemoveCharFromTxBuffer( comPort, c ))
{
WriteCharToTxBuffer( comPort, c );
}
또 다른
{
// 레벨 트리거되었으므로 추가 Tx 인터럽트를 비활성화합니다.
TxBufferEmptyInterruptEnable(comPort, FALSE);
}
Events_Set( SYSTEM_EVENT_FLAG_COM_OUT );
}
}
핵심 코드는 위에 소개된 관련 내용입니다. 아래에서는 NativeSample에 직렬 포트 테스트 코드를 작성합니다.
무효 애플리케이션엔트리포인트()
{
동안(참)
{
if(이벤트_WaitForEvents(SYSTEM_EVENT_FLAG_COM_IN,100))
{
Events_Clear(SYSTEM_EVENT_FLAG_COM_IN);
char 바이트데이터[512];
int 크기=USART_BytesInBuffer(0,TRUE);
USART_Read(0,bytData,Size);
for(int i=0;i<크기;i++)
debug_printf("%c",bytData[i]);
}
debug_printf("안녕하세요 마이크로 프레임워크!!!rn");
}
}