冰楓論壇

標題: EFM32WG990F256-QFP100 [打印本頁]

作者: 洪嵐峰    時間: 2023-4-20 18:47
標題: EFM32WG990F256-QFP100
EFM32WG990F256-QFP100是一款由Silicon Labs生產的微控制器,其主要規格如下:

處理器核心:ARM Cortex-M4F
工作頻率:48 MHz
記憶體:256 KB 閃存,32 KB RAM
外設:USB、UART、SPI、I2C、GPIO、ADC、DAC、PWM、計時器等
封裝:QFP100

EFM32WG990F256-QFP100適用於許多應用場景,例如智慧家居、工業自動化、物聯網等。

它的主要特點是低功耗、高性能和豐富的外設,可以滿足各種應用的需求。

製作多通道示波器需要的主要零件包括:

EFM32WG990F256-QFP100微控制器
ADC模塊(例如MCP3208等)
電容、電阻、晶振等外部元件
LCD顯示屏(例如SSD1306等)
以下是EFM32WG990F256-QFP100微控制器的連結腳位圖:

             ___________________
           VDD  |1                100|  VDD
           PC0  |2                99 |  PD7
           PC1  |3                98 |  PD6
           PC2  |4                97 |  PD5
           PC3  |5                96 |  PD4
           PC4  |6                95 |  PD3
           PC5  |7                94 |  PD2
           PC6  |8                93 |  PD1
           PC7  |9                92 |  PD0
           PB12 |10               91 |  PC13
           PB13 |11               90 |  PC12
           PB14 |12               89 |  PC11
           PB15 |13               88 |  PC10
           PC8  |14               87 |  PC9
           PA0  |15               86 |  PB11
           PA1  |16               85 |  PB10
           PA2  |17               84 |  PB9
           PA3  |18               83 |  PB8
           PA4  |19               82 |  PB7
           PA5  |20               81 |  PB6
           PA6  |21               80 |  PB5
           PA7  |22               79 |  PB4
           PC12 |23               78 |  PB3
           PC11 |24               77 |  PB2
           PC10 |25               76 |  PB1
           PC9  |26               75 |  PB0
           PC13 |27               74 |  PA15
           PF2  |28               73 |  PA14
           PF3  |29               72 |  PA13
           PF4  |30               71 |  PA12
           PF5  |31               70 |  PA11
           PF6  |32               69 |  PA10
           PF7  |33               68 |  PA9
           PF8  |34               67 |  PA8
           PF9  |35               66 |  PF0
           PF10 |36               65 |  PF1
           PB9  |37               64 |  PE10
           PB10 |38               63 |  PE11
           PB11 |39               62 |  PE12
           PB12 |40               61 |  PE13
           PB13 |41               60 |  PE14
           PB14 |42               59 |  PE15
           PB15 |43               58 |  PD15
           PA15 |44               57 |  PD14
           PA14 |45               56 |  PD13
           PA13 |46               55 |  PD12
           PA12 |47               54 |  PD11
           PA11 |48               53 |
           PA10 |49               52 |  PD10
            PA9  |50               51 |  PD9
                     -------------------
該程式碼使用EFM32WG990F256-QFP100微控制器,連接了MCP3208 ADC模塊和SSD1306 LCD顯示屏:


#include "em_device.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_adc.h"
#include "em_usart.h"
#include "em_timer.h"
#include "em_i2c.h"
#include "em_lcd.h"
#include "em_emu.h"
#include "mcp3208.h"
#include "ssd1306.h"

#define ADC_VREF                    3300    // ADC參考電壓,單位mV
#define ADC_RESOLUTION              4096    // ADC分辨率
#define ADC_CHANNEL_NUM             8       // ADC通道數量
#define LCD_I2C_ADDR                0x78    // LCD顯示屏I2C地址

uint16_t adc_data[ADC_CHANNEL_NUM];         // ADC數據
volatile uint32_t msTicks;                  // 毫秒計數器

void SysTick_Handler(void)
{
    msTicks++;                              // 毫秒計數器遞增
}

void delay_ms(uint32_t ms)
{
    uint32_t startTicks = msTicks;          // 記錄開始時的毫秒計數器值
    while ((msTicks - startTicks) < ms) {}  // 等待指定的毫秒數
}

void init_sysclk(void)
{
    CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);    // 使用外部高速晶振作為HFCLK
    CMU_ClockEnable(cmuClock_GPIO, true);              // 使能GPIO時鐘
    CMU_ClockEnable(cmuClock_USART1, true);            // 使能USART1時鐘
    CMU_ClockEnable(cmuClock_TIMER0, true);            // 使能TIMER0時鐘
    CMU_ClockEnable(cmuClock_I2C0, true);              // 使能I2C0時鐘
    CMU_ClockEnable(cmuClock_LCD, true);               // 使能LCD時鐘
}

void init_gpio(void)
{
    // 初始化LCD顯示屏控制腳
    GPIO_PinModeSet(gpioPortE, 10, gpioModePushPull, 1);    // LCD RST
    GPIO_PinModeSet(gpioPortE, 11, gpioModePushPull, 1);    // LCD SCL
    GPIO_PinModeSet(gpioPortE, 12, gpioModePushPull, 1);    // LCD SDA
}

void init_adc(void)
{
    // 初始化ADC模塊
    ADC_Init_TypeDef init = ADC_INIT_DEFAULT;
    ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
    init.warmUpMode = adcWarmupKeepADCWarm;
    ADC_Init(ADC0, &init);
    for (int i = 0; i < ADC_CHANNEL_NUM; i++) {
        singleInit.posSel = (ADC_PosSel_TypeDef)i;
        singleInit.reference= adcRefVDD; // 使用VDD作為參考電壓
ADC_InitSingle(ADC0, &singleInit);
}
}

void init_usart(void)
{
// 初始化USART1模塊
USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT;
init.baudrate = 115200;
init.parity = usartNoParity;
init.stopbits = usartStopbits1;
USART_InitAsync(USART1, &init);
USART_Enable(USART1, usartEnable);
}

void init_timer(void)
{
// 初始化TIMER0模塊,用於定時讀取ADC數據
TIMER_Init_TypeDef init = TIMER_INIT_DEFAULT;
init.enable = false;
init.prescale = timerPrescale1;
TIMER_Init(TIMER0, &init);
TIMER_TopSet(TIMER0, CMU_ClockFreqGet(cmuClock_TIMER0) / 1000 - 1); // 設置計數器上限,即每毫秒計數器值達到多少時觸發計時器中斷
NVIC_EnableIRQ(TIMER0_IRQn); // 使能TIMER0中斷
TIMER_IntEnable(TIMER0, TIMER_IF_OF); // 設置計時器溢出中斷
}

void init_i2c(void)
{
// 初始化I2C0模塊,用於控制LCD顯示屏
I2C_Init_TypeDef init = I2C_INIT_DEFAULT;
init.freq = I2C_FREQ_STANDARD_MAX;
init.clhr = i2cClockHLRStandard;
I2C_Init(I2C0, &init);
GPIO_PinModeSet(gpioPortC, 4, gpioModeWiredAndPullUpFilter, 1); // I2C SCL
GPIO_PinModeSet(gpioPortC, 5, gpioModeWiredAndPullUpFilter, 1); // I2C SDA
I2C0->ROUTELOC0 = I2C_ROUTELOC0_SCLLOC_LOC14 | I2C_ROUTELOC0_SDALOC_LOC16; // 設置I2C SCL和SDA腳位
I2C0->ROUTEPEN = I2C_ROUTEPEN_SCLPEN | I2C_ROUTEPEN_SDAPEN;
}

void init_lcd(void)
{
// 初始化SSD1306 LCD顯示屏
ssd1306_init(I2C0, LCD_I2C_ADDR);
ssd1306_clear_display();
ssd1306_display_on();
}

void TIMER0_IRQHandler(void)
{
TIMER_IntClear(TIMER0, TIMER_IF_OF); // 清除計時器溢出中斷標誌
for (int i = 0; i < ADC_CHANNEL_NUM; i++) {
adc_data[i] = ADC_DataSingleGet(ADC0); // 讀取ADC數據
}
}

int main(void)
{
CHIP_Init(); // 初始化芯片
init_sysclk(); // 初始化系統時鐘
init_gpio(); // 初始化GPIO
init_adc(); // 初始化ADC模塊
init_usart(); // 初始化USART1模塊
init_timer(); // 初始化TIMER0模塊
init_i2c(); // 初始化I2
init_lcd();                     // 初始化SSD1306 LCD顯示屏

while (1) {
    // 顯示ADC數據到串口和LCD顯示屏上
    for (int i = 0; i < ADC_CHANNEL_NUM; i++) {
        char buffer[16];
        sprintf(buffer, "Ch%d: %d   ", i, adc_data[i]);
        USART_Tx(USART1, (uint8_t *)buffer, strlen(buffer));
        ssd1306_draw_string(0, i * 10, buffer);
    }
    ssd1306_refresh();

    // 暫停100ms
    for (volatile uint32_t i = 0; i < 800000; i++) {}
}
}



以上是EFM32WG990F256-QFP100製作多通道示波器的程式碼,可以看到程式碼中完成了設置系統時鐘、GPIO、ADC、USART1、TIMER0、I2C0和SSD1306 LCD顯示屏等模塊的初始化,並在主函數中進行了ADC數據的定時讀取和顯示。在主循環中,將ADC數據分別顯示到串口和LCD顯示屏上,並通過ssd1306_refresh()函數刷新LCD顯示屏。程式碼還設置了一個100ms的延時,以控制ADC數據的讀取速率和顯示速率。




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