Holtek사 MCU중 HT32F52357와 HT32F52367은 기능은 같은데 Flash와 SRAM 용량 차이가 있음. Holtek 사에 예제 프로그램을 이용하여 USART에 있는 Interrupt을 사용해 보자.
example -> USART -> Interrupt 폴더에 들어가서 _CreateProject.bat를 실행.
Project가 만들어지면 MDK_ARMv5 폴더에 들어가서 Project_52367.uvprojx 더블 클릭 하여 실행
int main(void)
{
HT32F_DVB_LEDInit(HT_LED1); //LED1 포트 셋팅
HT32F_DVB_LEDInit(HT_LED2); //LED2 포트 셋팅
gURRx_Ptr = gRx_Buffer; //gRx_Buffer주소를 gURRx_Ptr 포인트 변수에 입력
UxART_Configuration(); //USART 포트 셋팅
UxART_TxTest(); //USART 통신 포트를 이용하여 전송 시험
while (1)
{
UxART_RxTest(); //UART 통신 포트를 이용하여 수신 시험.
}
}
main함수 설명이다.
void UxART_Configuration(void)
{
#if 0 // Use following function to configure the IP clock speed.
// The UxART IP clock speed must be faster 16x then the baudrate.
CKCU_SetPeripPrescaler(CKCU_PCLK_UxARTn, CKCU_APBCLKPRE_DIV2);
#endif
{ /* Enable peripheral clock of AFIO, UxART */
CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}};
CKCUClock.Bit.AFIO = 1; //AFIO 클럭 공급
CKCUClock.Bit.HTCFG_UART_RX_GPIO_CLK = 1; //Port A 클럭 공급
CKCUClock.Bit.HTCFG_UART_IPN = 1; //USART1 클럭 공급
CKCU_PeripClockConfig(CKCUClock, ENABLE); //클럭 셋팅
}
/* Turn on UxART Rx internal pull up resistor to prevent unknow state */
GPIO_PullResistorConfig(HTCFG_UART_RX_GPIO_PORT, HTCFG_UART_RX_GPIO_PIN, GPIO_PR_UP); //UART1에 RX핀에 내부 Pull up 셋팅.
/* Config AFIO mode as UxART function. */
AFIO_GPxConfig(HTCFG_UART_TX_GPIO_ID, HTCFG_UART_TX_AFIO_PIN, AFIO_FUN_USART_UART); //PA4 포트를 UART TX모드로 사용하도록 셋팅
AFIO_GPxConfig(HTCFG_UART_RX_GPIO_ID, HTCFG_UART_RX_AFIO_PIN, AFIO_FUN_USART_UART); //PA5 포트를 UART RX모드로 사용하도록 셋팅
{
/* UxART configured as follow:
- BaudRate = 115200 baud
- Word Length = 8 Bits
- One Stop Bit
- None parity bit
*/
/* !!! NOTICE !!!
Notice that the local variable (structure) did not have an initial value.
Please confirm that there are no missing members in the parameter settings below in this function.
*/
USART_InitTypeDef USART_InitStructure = {0};
USART_InitStructure.USART_BaudRate = 115200; //USART1 포트 속도는 115200bps로 셋팅
USART_InitStructure.USART_WordLength = USART_WORDLENGTH_8B; //Data 크기는 8Byte로 셋팅
USART_InitStructure.USART_StopBits = USART_STOPBITS_1; //Stop Bit는 1개로 설정
USART_InitStructure.USART_Parity = USART_PARITY_NO; //Parity Bit는 없음 으로 설정.
USART_InitStructure.USART_Mode = USART_MODE_NORMAL; //비동기 통신 방식으로 설정
USART_Init(HTCFG_UART_PORT, &USART_InitStructure); //위 설정값 적용
}
/* Enable UxART interrupt of NVIC */
NVIC_EnableIRQ(HTCFG_UART_IRQn); //UART 인터럽트 활성
/* Enable UxART Rx interrupt */
USART_IntConfig(HTCFG_UART_PORT, USART_INT_RXDR, ENABLE); //수신 인터럽트 활성
/* Enable UxART Tx and Rx function */
USART_TxCmd(HTCFG_UART_PORT, ENABLE); //USART1에 Tx 포트 활성
USART_RxCmd(HTCFG_UART_PORT, ENABLE); //USART1에 Rx 포트 활성
}
USART 설정에 대한 설명이다.
void UxART_TxTest(void)
{
gIsTxFinished = FALSE; //전송을 위해 현재 전송이 끝나지 않았다고 변수에 저장
gURTx_Ptr = (u8 *)gHelloString; //gHelloString 변수 주소를 gURTx_Ptr라는 포인터 변수에 저장
gURTx_Length = sizeof(gHelloString) - 1; //gHelloString 배열의 크기를 gURTx_Length 변수에 저장
USART_IntConfig(HTCFG_UART_PORT, USART_INT_TXDE | USART_INT_TXC, ENABLE); //USART1 송신 변수가 비여있으면 인터럽트 발생하게 셋팅
while (gURTx_Length != 0); // Latest byte move to UxART shift register, but the transmission may be on going. //송신데이터가 모두 송신 될때까지 대기
while (gIsTxFinished == FALSE); // Set by TXC interrupt, transmission is finished. //송신이 완전히 끝나지 않았으면 대기
}
UxART_TxTest 함수에 대한 설명이다.
void UxART_RxTest(void)
{
u32 i;
u32 uLength;
/* Waiting for receive 5 data */
if (gURRx_Length >= 5) //gURRx_Length(수신 받은 데이터 수량)값이 5이상이면 아래 실행
{
// Process Rx data by gRx_Buffer[] and gURRx_Length here
// .....
uLength = gURRx_Length; //데이터 수량을 uLength에 저장
for (i = 0; i < uLength; i++)
{
gTx_Buffer[i] = gRx_Buffer[i]; //gRx_Buffer 변수에 있는 데이터를 gTx_Buffer로 복사 (에코 기능)
}
#if 1 // Loop back Rx data to Tx for test
gIsTxFinished = FALSE; //전송을 위해 현재 전송이 끝나지 않았다고 변수에 저장
gURTx_Ptr = gTx_Buffer; //보낼 데이터가 있는 변수 주소를 gURTx_Ptr이라는 포인트 변수에 넣음.
gURTx_Length = uLength; //수신 받은 수량을 송신할 수량에 복사
USART_IntConfig(HTCFG_UART_PORT, USART_INT_TXDE | USART_INT_TXC, ENABLE); //USART1 송신 변수가 비여있으면 인터럽트 발생하게 셋팅
#endif
gURRx_Length = 0; //수신 받은 데이터 수량 초기화
}
}
UxART_RxTest 함수에 대한 설명이다.
ht32f5xxxx_01_it.c 파일로 가면 송신 및 수신하는 인터럽트 함수가 있다.
void HTCFG_UART_IRQHandler(void)
{
extern uc8 *gURTx_Ptr;
extern vu32 gURTx_Length;
extern u8 *gURRx_Ptr;
extern vu32 gURRx_Length;
extern vu32 gIsTxFinished;
#if (DEBUG_IO == 1)
#define DBG_IO1_LO() HT32F_DVB_LEDOn(HT_LED1)
#define DBG_IO1_HI() HT32F_DVB_LEDOff(HT_LED1)
#define DBG_IO2_LO() HT32F_DVB_LEDOn(HT_LED2)
#define DBG_IO2_HI() HT32F_DVB_LEDOff(HT_LED2)
#else
#define DBG_IO1_LO(...)
#define DBG_IO1_HI(...)
#define DBG_IO2_LO(...)
#define DBG_IO2_HI(...)
#endif
/* Rx: Move data from UART to buffer */
if (USART_GetFlagStatus(HTCFG_UART_PORT, USART_FLAG_RXDR)) //수신된 데이터가 있는지 확인
{
DBG_IO1_LO();
gURRx_Ptr[gURRx_Length++] = USART_ReceiveData(HTCFG_UART_PORT); //수신 받은 데이터를 gRx_Buffer에 넣어라.
DBG_IO1_HI();
#if 0
if (gURRx_Length == 128)
{
while (1) {}; // Rx Buffer full
}
#endif
}
/* Tx, move data from buffer to UART */
if (USART_GetIntStatus(HTCFG_UART_PORT, USART_INT_TXDE) && //송신 인터럽트가 발생 했는지 확인
USART_GetFlagStatus(HTCFG_UART_PORT, USART_FLAG_TXDE)) //송신 인터럽트중 송신 버퍼가 비였다는 인터럽트가 발생했는지 확인
{
DBG_IO2_LO();
if (gURTx_Length > 0) //보낼 데이터가 있으면 실행
{
USART_SendData(HTCFG_UART_PORT, *gURTx_Ptr++); //gTx_Buffer에 있는 데이터를 하나씩 순서대로 전송
gURTx_Length--; //보낼 데이터 하나 감소
if (gURTx_Length == 0) //보낼 데이터가 없는지 확인
{
USART_IntConfig(HTCFG_UART_PORT, USART_INT_TXDE, DISABLE); //보낼 데이터가 없으면 송신 버퍼가 비여있으면 인터럽트 발생되는것을 비활성 시킴
}
}
DBG_IO2_HI();
}
if (USART_GetIntStatus(HTCFG_UART_PORT, USART_INT_TXC) && //송신 인터럽트가 발생 했는지 확인
USART_GetFlagStatus(HTCFG_UART_PORT, USART_FLAG_TXC)) //송신 버퍼에 들어 있던 데이터를 보냈는지 확인
{
USART_IntConfig(HTCFG_UART_PORT, USART_INT_TXC, DISABLE); //송신 버퍼에 들어 있던 데이터를 보냈다면 송신 인터럽트 비활성 시킴
gIsTxFinished = TRUE; //송신이 끝났다고 변수에 저장
}
}
송신과 수신이 인터럽트로 처리 되는 부분을 적어놓음.
TEST를 하다보니 버그가 있다.
5글자를 PC에서 보내면 5글자가 오는데 6글자를 보내면 마지막 한글자가 다음에 나오는 현상이 있음.
예제에 있는 버그다.
'프로그램 > Holtek 32Bit' 카테고리의 다른 글
DAC를 이용하여 Sine wave를 출력 해보자. 실패.. (0) | 2023.08.16 |
---|---|
Motor Control Timer (MCTM) 예제 실행 (0) | 2023.08.14 |
NVIC에 Vector_Table_Offset 예제 실행 (0) | 2023.08.05 |
NVIC에 System_Exception 예제 실행 (0) | 2023.08.05 |
WDT (Watchdog Timer) 예제 실행 (0) | 2023.08.02 |