冰楓論壇

標題: EFM32PG12 [打印本頁]

作者: 洪嵐峰    時間: 2023-4-21 06:01
標題: EFM32PG12
EFM32PG12是一款由Silicon Labs生產的微控制器芯片。

它是32位ARM Cortex-M4F內核,並且具有豐富的外設和接口,包括多個通用定時器,模數轉換器,通用串行總線接口,以太網MAC,USB控制器和LCD控制器。

此外,EFM32PG12還具有超低功耗特性,使其非常適合用於電池供電設備和低功耗應用。

製作一個多通道示波器需要以下零件:

EFM32PG12微控制器芯片
電容和電阻用於構建示波器前端電路
多通道模擬輸入放大器
模數轉換器(ADC)用於將模擬信號轉換為數字信號
顯示屏(可以選擇TFT LCD或OLED)
連接線和電源
關於EFM32PG12的引腳連接,您需要參考EFM32PG12的數據手冊來確定每個引腳的功能和用途。

下面是一個示波器的基本框架代碼

您可以根據您的需求進行修改和優化:


#include "em_device.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_adc.h"
#include "em_lcd.h"
#include "em_timer.h"
#include "stdio.h"

#define ADC_CHANNELS    4   // number of ADC channels used
#define LCD_REFRESH     50  // LCD refresh rate in Hz
#define LCD_WIDTH       240 // LCD width in pixels
#define LCD_HEIGHT      320 // LCD height in pixels

static volatile uint32_t adcData[ADC_CHANNELS];
static uint32_t adcCount = 0;

void initADC(void)
{
    ADC_Init_TypeDef init = ADC_INIT_DEFAULT;
    init.ovsRateSel = adcOvsRateSel4;
    init.timebase = ADC_TimebaseCalc(0);
    ADC_Init(ADC0, &init);

    ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
    singleInit.input = adcSingleInpCh5;
    singleInit.reference = adcRefVDD;
    singleInit.resolution = adcRes12Bit;
    ADC_InitSingle(ADC0, &singleInit);

    ADC_IntEnable(ADC0, ADC_IF_SINGLE);
    NVIC_EnableIRQ(ADC0_IRQn);

    ADC_Start(ADC0, adcStartSingle);
}

void ADC0_IRQHandler(void)
{
    ADC_IntClear(ADC0, ADC_IF_SINGLE);
    adcData[adcCount] = ADC_DataSingleGet(ADC0);
    adcCount++;
    if (adcCount >= ADC_CHANNELS) {
        adcCount = 0;
    }
    ADC_InitSingle(ADC0, &ADC_INITSINGLE_DEFAULT);
    ADC_Start(ADC0, adcStartSingle);
}

void initLCD(void)
{
    LCD_Init_TypeDef init = LCD_INIT_DEFAULT;
    init.ctrlBias = lcdBiasOneThird;
    init.mux = lcdMuxQuadruple;
    init.contrast = 0x1F;
    LCD_Init(&init);

    LCD_FrameCountInit(0xFFFF);
    LCD_ContrastSet(0x1F);
    LCD_VBoostSet(5);
    LCD_DSCaptureEnable();
    LCD_DisplayEnable();
}

void updateLCD(void)
{
    LCD_SegmentRange_TypeDef range;
    range.start = 0;
    range.end = LCD_WIDTH - 1;
    LCD_SegmentRangeClear(&range);

    uint32_t x, y;
    uint32_t dataWidth = LCD_WIDTH / ADC_CHANNELS;
    uint32_t dataHeight = LCD_HEIGHT / 4096;
    for (x = 0; x < ADC_CHANNELS; x++) {
        for (y = 0; y < adcData[x]; y++) {
            LCD_SegmentSet(x * dataWidth, LCD_HEIGHT - y * dataHeight,

        x * dataWidth + dataWidth - 1, LCD_HEIGHT - y * dataHeight - dataHeight + 1);
    }
}
}

int main(void)
{
CHIP_Init();
CMU_ClockEnable(cmuClock_ADC0, true);
CMU_ClockEnable(cmuClock_GPIO, true);
CMU_ClockEnable(cmuClock_LCD, true);

initADC();
initLCD();

TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
timerInit.enable = false;
TIMER_Init(TIMER0, &timerInit);
TIMER_TopSet(TIMER0, CMU_ClockFreqGet(cmuClock_CORE) / LCD_REFRESH);
TIMER_IntEnable(TIMER0, TIMER_IF_OF);
NVIC_EnableIRQ(TIMER0_IRQn);
TIMER_Enable(TIMER0, true);

while (1) {
    // main loop
}
}

void TIMER0_IRQHandler(void)
{
TIMER_IntClear(TIMER0, TIMER_IF_OF);
updateLCD();
}






歡迎光臨 冰楓論壇 (https://bingfong.com/) Powered by 冰楓