MSPM0 시리즈는 1$이하의 저렴한 가격이지만 아날로그 기능이 풍부해서 아날로그 기능이 필요하면서 저비용으 시스템에 적합한 MCU인것 같다.
기본적인 ADC기능은 MSPM0L 시리즈에와 동일하지만 MSPM0G시리즈에 몇 가지 추가된 기능이 있다.
MSPMG 시리즈는 클럭이 32Mhz에서 80Mhz로 빨라져 ADC 속도가 빨라 졌고 12bit DAC기능이 추가 되었다.
기본 구성은 MSPM0L 시리즈 ADC와 동일한 구조로 테스트 할 수 있다.
SYSCFG에서 ADC추가 하고 기본 설정을 하면 된다.
[MSPM0G3107 SSM] 보드의 PA15에 연결되 ADC1(CH0)를 할당해 테스트 해보자
MSPM0 확장 테스트보드의 가변저항은 ADC0에 연결되어 있고 PA15과 연결되려면 CN21의 1-3번펀을 점퍼로 연결해 주면 된다.
syscfg 에서 ADC 입력 채널을 ADC1.0 으로 설정하고
핀맵을 PA15로 할당할 수 있다.
syscfg 설정 후 인터럽트 핸들러 정의 및 ADC read 하는 부분의 코드 작성하면 ADC값을 읽어 올 수 있다.
volatile bool gCheckADC;
volatile uint16_t gADCResult;
void ADC12_0_INST_IRQHandler(void)
{
switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
case DL_ADC12_IIDX_MEM0_RESULT_LOADED:
gCheckADC = true;
break;
default:
break;
}
}
unsigned int GetADC(void)
{
unsigned int adc = 0;
DL_ADC12_startConversion(ADC12_0_INST);
while (false == gCheckADC) {
__WFE();
}
/*
* UART is 8 bits and the ADC result is 16 bits
* Split the ADC result into 2 then send via UART.
*/
adc = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
gCheckADC = false;
DL_ADC12_enableConversions(ADC12_0_INST);
return adc;
}
int main(void)
{
SYSCFG_DL_init();
//DL_SYSTICK_config(32000000);
DL_SYSTICK_enable();
NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
printf("ADC Test\r\n");
gCheckADC = false;
while (1)
{
gADCResult = GetADC();
printf("%d\r\n", gADCResult);
}
}
MSPM0 14bit ADC 테스트
MSPM0는 ADC12 하드웨어 평균화 기능이 있고 16개의 샘플을 누적하고 4로 나누어 14비트 유효 분해능가질 수 있다.
오버샘플링을 하려면 DMA 기능을 활성화 해야 한다.
DMA초기화 하고 하드웨어 평균화가 활성화된 상태에서 최대 샘플링 속도로 12비트 ADC 분해능 모드를 사용하여 ADC 채널의 1024개 샘플을 캡처해서 시리얼 포트로 출력 하는 예제 코드
#include "ti_msp_dl_config.h"
#define ADC_SAMPLE_SIZE (1024)
uint16_t gADCSamples[ADC_SAMPLE_SIZE];
volatile bool gCheckADC;
void ADC12_0_INST_IRQHandler(void)
{
switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
case DL_ADC12_IIDX_DMA_DONE:
gCheckADC = true;
break;
default:
break;
}
}
unsigned int adc_getValue(unsigned int number)
{
unsigned long gAdcResult = 0;
unsigned char i = 0;
for( i = 0; i < number; i++ )
{
gAdcResult += gADCSamples[i];
}
gAdcResult /= number;
return gAdcResult;
}
unsigned int GetADC(void)
{
while(false == gCheckADC)
{
__WFE();
}
//Reset gCheckADC
gCheckADC = true;
return adc_getValue(8);
}
int main(void)
{
SYSCFG_DL_init();
printf("test\r\n");
/* Configure DMA source, destination and size */
DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID,
(uint32_t) DL_ADC12_getMemResultAddress(
ADC12_0_INST, DL_ADC12_MEM_IDX_0));
/* Setup interrupts on device */
NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
gCheckADC = false;
/* Configure DMA size and destination address before starting a new
* capture
*/
DL_DMA_disableChannel(DMA, DMA_CH0_CHAN_ID);
DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t) &gADCSamples[0]);
DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, ADC_SAMPLE_SIZE);
DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);
/* Re-enable DMA mode in ADC12 since this gets cleared every time the
* transfer completes
*/
DL_ADC12_enableDMA(ADC12_0_INST);
DL_ADC12_startConversion(ADC12_0_INST);
while (1)
{
printf("%d\r\n", GetADC());
}
}
테스트 결과 14bit(16384) 까지 출력 되는 것을 확인 할 수 있다.