- UID
- 373967
- 帖子
- 8850
- 主題
- 2609
- 精華
- 0
- 積分
- 999
- 楓幣
- 1
- 威望
- 976
- 存款
- 34705
- 贊助金額
- 0
- 推廣
- 0
- GP
- 1205
- 閱讀權限
- 50
- 在線時間
- 454 小時
- 註冊時間
- 2023-1-12
- 最後登入
- 2024-11-18
|
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();
}
|
|