- UID
- 373967
- 帖子
- 8867
- 主題
- 2609
- 精華
- 0
- 積分
- 1000
- 楓幣
- 0
- 威望
- 977
- 存款
- 34822
- 贊助金額
- 0
- 推廣
- 0
- GP
- 1205
- 閱讀權限
- 70
- 在線時間
- 455 小時
- 註冊時間
- 2023-1-12
- 最後登入
- 2024-11-21
|
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數據的讀取速率和顯示速率。 |
|