Holtek사 MCU중 HT32F52357와 HT32F52367은 기능은 같은데 Flash와 SRAM 용량 차이가 있음. Holtek 사에 CodeConfig 프로그램을 이용하여 DAC에 Sine wave를 출력 해보자.
New 버튼을 눌러 SelectMCU 창이 나오면 아래로 스크롤 하여 HT32F52367을 확장한다음 LQFP80을 선택후 OK 버튼을 눌러주자.
바로 뜨는창은 내부 클럭으로 최대 Clock으로 셋팅된 화면이 나온다.
변경 없이 AFIO 탭을 선택 하고 스크롤 하여 아래로 내리면 DAC 포트는 PC3, PB8 두개가 있다.
DAC0_OUT 글씨를 마우스 왼쪽 버튼으로 더블 클릭 해주자. DAC1_OUT도 더블 클릭 해주자.
타이머를 하나 써야 합니다.
기존에 BFTM0 가 자동으로 셋팅이 되어 있어 있다.
Datasheet를 확인하면 BFTM은 APB Clock을 받는다. APB Clock은 60MHz이다.
Timer 탭에 보면 BFTM0가 체크 되어 있다.
ADC/DAC 탭에서 Enable Interrupt 체크박스를 해제 해주자.
F7을 눌러 파일을 생성할 위치를 지정해 주고 확인을 누르자.
필자 같은 경우는 DAC 폴더를 만들어서 그곳을 클릭후 확인을 눌러 주었다.
생성이 완료 되면 Open Project를 눌러서 파일을 열어 보자.
F7을 눌러 Build하면 에러가 발생한다.
에러를 찾아가면 DAC_Configuration 안에 있다.
void DAC_Configuration(void)
{
CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}};
CKCUClock.Bit.DAC = 1; //DAC 클럭 공급
CKCUClock.Bit.AFIO = 1; //AFIO 클럭 공급
CKCU_PeripClockConfig(CKCUClock, ENABLE); //클럭 셋팅
AFIO_GPxConfig(GPIO_PC, AFIO_PIN_3, AFIO_FUN_DAC); //PC3 포트를 DAC로 동작 변경 하는것.
AFIO_GPxConfig(GPIO_PB, AFIO_PIN_8, AFIO_FUN_DAC); //PB8 포트를 DAC로 동작 변경 하는것.
DAC_ModeConfig(ASYNC_MODE); //DAC 비동기 모드로 동작
DAC_ReferenceConfig(DAC_CH0, DAC_REFERENCE_VDDA); //DAC CH0에 기준 전압은 VDDA(3.3V)로 설정
DAC_ResolutionConfig(DAC_CH0, DAC_RESOLUTION_12BIT); //DAC 분해능은 12Bit (2^12Bit = 0 ~ 4095단계)
DAC_OutBufCmd(DAC_CH0, ENABLE); //DAC CH0 출력 버퍼 활성
//DAC_IntConfig(DAC_INT_DOR0IE,ENABLE); //DAC CH0에 대한 인터럽트 활성인데 홀텍사에 확인하니 인터럽트를 지원 안한다고 한다. Skip 해주자.
DAC_SetData(DAC_CH0,0); //DAC CH0(PC3) 초기 출력은 0V
DAC_ReferenceConfig(DAC_CH1, DAC_REFERENCE_VDDA); //DAC CH1에 기준 전압은 VDDA(3.3V)로 설정
DAC_ResolutionConfig(DAC_CH1, DAC_RESOLUTION_12BIT); //DAC 분해능은 12Bit (2^12Bit = 0 ~ 4095단계)
DAC_OutBufCmd(DAC_CH1, ENABLE); //DAC CH1 출력 버퍼 활성
//DAC_IntConfig(DAC_INT_DOR1IE,ENABLE); //DAC CH1에 대한 인터럽트 활성인데 홀텍사에 확인하니 인터럽트를 지원 안한다고 한다. Skip 해주자.
DAC_SetData(DAC_CH1,0); //DAC CH1(PB8) 초기 출력은 0V
DAC_Cmd(DAC_CH0,ENABLE); //Enable DAC0
DAC_Cmd(DAC_CH1,ENABLE); //Enable DAC1
}
//DAC_IntConfig(DAC_INT_DOR0IE,ENABLE);
//DAC_IntConfig(DAC_INT_DOR1IE,ENABLE);
위 우개에 인터럽트 설정이 있는데 Skip을 해주어야 한다. (홀텍사에서 인터럽트가 없어졌단다..)
AFIO_GPxConfig(GPIO_PC, AFIO_PIN_3, AFIO_FUN_DAC); //PC3 포트를 DAC로 동작 변경 하는것.
AFIO_GPxConfig(GPIO_PB, AFIO_PIN_8, AFIO_FUN_DAC); //PB8 포트를 DAC로 동작 변경 하는것.
포트 셋팅도 안해주어서 추가 해주어햐 한다. CodeConfig에서 이부분을 만들어주지 않는다.
그렇지 않으면 DAC 동작을 못한다.
#include "BFTM0.h"
//-----------------------------------------------------------------------------
#define BFTM0_TIMER_BASE ((long long)SystemCoreClock * 10/1000)
#define DAC_SINE_WAVE_SAMPLES 500 //500포인트로 잡을 예정임.
//-----------------------------------------------------------------------------
vu32 bftm0_ct;
extern uint16_t sine_wave[DAC_SINE_WAVE_SAMPLES]; //main.c 파일에서 사용중인 변수를 사용하기 위해 extern을 해준다.
//-----------------------------------------------------------------------------
void BFTM0_Configuration(void)
{
CKCU_PeripClockConfig_TypeDef CKCUClock = {{ 0 }};
CKCUClock.Bit.BFTM0 = 1; //BFTI0에 클럭 공급
CKCU_PeripClockConfig(CKCUClock, ENABLE); //클럭 셋팅
NVIC_EnableIRQ(BFTM0_IRQn); // interrupt enable
BFTM_IntConfig(HT_BFTM0, ENABLE); //BFTM0 인터럽트 활성화
BFTM_SetCompare(HT_BFTM0, BFTM0_TIMER_BASE); //BFTM0 인터럽트 발생할 카운터값 설정
BFTM_SetCounter(HT_BFTM0, 0); //BFTM0 카운터값을 초기화
//BFTM_EnaCmd(HT_BFTM0, ENABLE);
}
BFTM셋팅이다. 마지막에 BFTM_EnaCmd(HT_BFTM0, ENABLE); 이부분을 Skip 해주자.
DAC가 셋팅이 안되었는데 인터럽트가 걸려서 DAC_SetData 명령을 수행 하면 HardFault_Handler 에러가 발생한다.
void BFTM0_IRQHandler(void)
{
static uint16_t index =0; //지워지지 않는 변수이다.
BFTM_ClearFlag(HT_BFTM0);
bftm0_ct++;
DAC_SetData(DAC_CH0, sine_wave[index]); //DAC_CH0 출력을 변경한다.
DAC_SetData(DAC_CH1, sine_wave[index]); //DAC_CH1 출력을 변경한다.
index++; //읽어올 sine_wave 배열 변수를 증가한다.
index %= DAC_SINE_WAVE_SAMPLES; //index값이 500이 돼면 0으로 해준다.
}
BFTM0 인터럽트에서 위와 같이 추가 해준다.
main.c 파일에 있는 내용이다.
#include "ht32.h"
#include "BFTM0.h"
#include "DAC.h"
#include "math.h" //rint와 sintf를 사용하기 위해 포함.
#define PI 3.141592 //추가
#define DAC_SINE_WAVE_SAMPLES 500 //500포인트로 잡을 예정임.
uint16_t sine_wave[DAC_SINE_WAVE_SAMPLES] = { 0 }; //Sine wave 값을 저장하기 위한 변수 추가
uint16_t sine_wave_idx = 0; //Sine wave를 만들때 카운터로 사용할 변수 추가
//-----------------------------------------------------------------------------
int main(void)
{
uint16_t i, alpha, beta; //변수 추가
BFTM0_Configuration(); //BFTM0 셋팅
DAC_Configuration(); //DAC 셋팅
///////////// Sine wave를 만들어주는 부분
alpha = 255;
beta = 100;
for (i = 0; i < DAC_SINE_WAVE_SAMPLES; i++)
{
sine_wave[i] = (uint16_t)rint((sinf(((2 * PI) / DAC_SINE_WAVE_SAMPLES) * i) + 1) * alpha) + beta;
if (sine_wave[i] >= 4095) sine_wave[i] = 4095;
}
BFTM_EnaCmd(HT_BFTM0, ENABLE); //BFTM0 동작 시작
while (1)
{
if (HT_CKCU->APBCCR1 & (1 << 4)) //와치독 클럭이 공급 되고 있는지 확인
WDT_Restart(); //와치독 카운터 초기화
//DAC_test(); //Can be removed
}
}
이렇게 프로그램을 작성하고 실행하면 다음과 같은 DAC 출력을 확인 할수 있다.
주파수가 너무 낮게 나온다. 주파수를 높일려면 BFTM0에 인터럽트 발생 시간을 줄여주면 된다.
BFTM0.C에 가면 현재 10mSEC 인터럽트가 발생 하게 되어 있다.
#define BFTM0_TIMER_BASE ((long long)SystemCoreClock * 10/1000)
이부분에서 10을 0.1로 변경하면 10mSEC에서 0.1mSEC가 되어 주파수가 100배는 빨라 질것이다.
#define BFTM0_TIMER_BASE ((long long)SystemCoreClock * 0.1/1000)
이렇게 변경한 파형이다.
주파수가 약 20Hz 나오는것을 확인 할수 있다.
'프로그램 > Holtek 32Bit' 카테고리의 다른 글
DAC를 이용하여 Sine wave를 출력 해보자. 실패.. (0) | 2023.08.16 |
---|---|
Motor Control Timer (MCTM) 예제 실행 (0) | 2023.08.14 |
USART Interrupt 예제 실행 (2) | 2023.08.11 |
NVIC에 Vector_Table_Offset 예제 실행 (0) | 2023.08.05 |
NVIC에 System_Exception 예제 실행 (0) | 2023.08.05 |