單芯片解決方案,開啟全新體驗——W55MH32 高性能以太網(wǎng)單片機
W55MH32是WIZnet重磅推出的高性能以太網(wǎng)單片機,它為用戶帶來前所未有的集成化體驗。這顆芯片將強大的組件集于一身,具體來說,一顆W55MH32內(nèi)置高性能Arm? Cortex-M3核心,其主頻最高可達216MHz;配備1024KB FLASH與96KB SRAM,滿足存儲與數(shù)據(jù)處理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP協(xié)議棧、內(nèi)置MAC以及PHY,擁有獨立的32KB以太網(wǎng)收發(fā)緩存,可供8個獨立硬件socket使用。如此配置,真正實現(xiàn)了All-in-One解決方案,為開發(fā)者提供極大便利。
在封裝規(guī)格上,W55MH32 提供了兩種選擇:QFN100和QFN68。
W55MH32L采用QFN100封裝版本,尺寸為12x12mm,其資源豐富,專為各種復(fù)雜工控場景設(shè)計。它擁有66個GPIO、3個ADC、12通道DMA、17個定時器、2個I2C、5個串口、2個SPI接口(其中1個帶I2S接口復(fù)用)、1個CAN、1個USB2.0以及1個SDIO接口。如此豐富的外設(shè)資源,能夠輕松應(yīng)對工業(yè)控制中多樣化的連接需求,無論是與各類傳感器、執(zhí)行器的通信,還是對復(fù)雜工業(yè)協(xié)議的支持,都能游刃有余,成為復(fù)雜工控領(lǐng)域的理想選擇。 同系列還有QFN68封裝的W55MH32Q版本,該版本體積更小,僅為8x8mm,成本低,適合集成度高的網(wǎng)關(guān)模組等場景,軟件使用方法一致。更多信息和資料請進入網(wǎng)站或者私信獲取。
此外,本W(wǎng)55MH32支持硬件加密算法單元,WIZnet還推出TOE+SSL應(yīng)用,涵蓋TCP SSL、HTTP SSL以及 MQTT SSL等,為網(wǎng)絡(luò)通信安全再添保障。
為助力開發(fā)者快速上手與深入開發(fā),基于W55MH32L這顆芯片,WIZnet精心打造了配套開發(fā)板。開發(fā)板集成WIZ-Link芯片,借助一根USB C口數(shù)據(jù)線,就能輕松實現(xiàn)調(diào)試、下載以及串口打印日志等功能。開發(fā)板將所有外設(shè)全部引出,拓展功能也大幅提升,便于開發(fā)者全面評估芯片性能。
若您想獲取芯片和開發(fā)板的更多詳細信息,包括產(chǎn)品特性、技術(shù)參數(shù)以及價格等,歡迎訪問官方網(wǎng)頁,我們期待與您共同探索W55MH32的無限可能。
第二十六章 DAC——輸出正弦波
本章參考資料:《W55MH32參考手冊》DAC章節(jié)。
學(xué)習本章時,配合《W55MH32參考手冊》DAC章節(jié)一起閱讀,效果會更佳,特別是涉及到寄存器說明的部分。
1 DAC簡介
DAC為數(shù)字/模擬轉(zhuǎn)換模塊,故名思議,它的作用就是把輸入的數(shù)字編碼,轉(zhuǎn)換成對應(yīng)的模擬電壓輸出,它的功能與ADC相反。 在常見的數(shù)字信號系統(tǒng)中,大部分傳感器信號被化成電壓信號,而ADC把電壓模擬信號轉(zhuǎn)換成易于計算機存儲、處理的數(shù)字編碼, 由計算機處理完成后,再由DAC輸出電壓模擬信號,該電壓模擬信號常常用來驅(qū)動某些執(zhí)行器件,使人類易于感知。如音頻信號的采集及還原就是這樣一個過程。
W55MH32具有片上DAC外設(shè),它的分辨率可配置為8位或12位的數(shù)字輸入信號,具有兩個DAC輸出通道,這兩個通道互不影響, 每個通道都可以使用DMA功能,都具有出錯檢測能力,可外部觸發(fā)。
2 DAC功能框圖剖析
W55MH32的DAC模塊框圖如下:
整個DAC模塊圍繞框圖下方的“數(shù)字至模擬轉(zhuǎn)換器x”展開,它的左邊分別是參考電源的引腳:VDDA、 VSSA及VREF+, 其中W55MH32的DAC規(guī)定了它的參考電壓:math:V_{ref +}輸入范圍為2.4——3.3V。 “數(shù)字至模擬轉(zhuǎn)換器x”的輸入為DAC的數(shù)據(jù)寄存器“DORx”的數(shù)字編碼,經(jīng)過它轉(zhuǎn)換得的模擬信號由圖中右側(cè)的“DAC_OUTx”輸出。 而數(shù)據(jù)寄存器“DORx”又受“控制邏輯”支配,它可以控制數(shù)據(jù)寄存器加入一些偽噪聲信號或配置產(chǎn)生三角波信號。圖中的左上角為DAC的觸發(fā)源, DAC根據(jù)觸發(fā)源的信號來進行DAC轉(zhuǎn)換,其作用就相當于DAC轉(zhuǎn)換器的開關(guān),它可以配置的觸發(fā)源為外部中斷源觸發(fā)、定時器觸發(fā)或軟件控制觸發(fā)。 如本章實驗中需要控制正弦波的頻率,就需要定時器定時觸發(fā)DAC進行數(shù)據(jù)轉(zhuǎn)換。
2.1 參考電壓
與ADC外設(shè)類似,DAC也使用VREF+引腳作為參考電壓, 在設(shè)計原理圖的時候一般把VSSA接地,把VREF+和VDDA 接3.3V, 可得到DAC的輸出電壓范圍為:0~3.3V。
如果想讓輸出的電壓范圍變寬,可以在外部加一個電壓調(diào)理電路,把0~3.3V的DAC輸出抬升到特定的范圍即可。
2.2 數(shù)模轉(zhuǎn)換及輸出通道
框圖中的“數(shù)字至模擬轉(zhuǎn)換器x”是核心部件,整個DAC外設(shè)都圍繞它而展開。它以左邊的VREF+作為參考電源, 以DAC的數(shù)據(jù)寄存器“DORx”的數(shù)字編碼作為輸入,經(jīng)過它轉(zhuǎn)換得的模擬信號由右側(cè)的“DAC_OUTx”通道輸出。其中各個部件中的“x”是指設(shè)備的標號, 在W55MH32中具有2個這樣的DAC部件,每個DAC有1個對應(yīng)的輸出通道連接到特定的引腳,即:PA4-通道1,PA5-通道2,為避免干擾,使用DAC功能時, DAC通道引腳需要被配置成模擬輸入功能(AIN)。
2.3 觸發(fā)源及DHRx寄存器
在使用DAC時,不能直接對上述DORx寄存器寫入數(shù)據(jù),任何輸出到DAC通道x的數(shù)據(jù)都必須寫入到DHRx寄存器中(其中包含DHR8Rx、DHR12Lx等, 根據(jù)數(shù)據(jù)對齊方向和分辨率的情況寫入到對應(yīng)的寄存器中)。
數(shù)據(jù)被寫入到DHRx寄存器后,DAC會根據(jù)觸發(fā)配置進行處理,若使用硬件觸發(fā),則DHRx中的數(shù)據(jù)會在3個APB1時鐘周期后傳輸至DORx, DORx隨之輸出相應(yīng)的模擬電壓到輸出通道;若DAC設(shè)置為外部事件觸發(fā),可以使用定時器(TIMx_TRGO)、 EXTI_9信號或軟件觸發(fā)(SWTRIGx)這幾種方式控制數(shù)據(jù)DAC轉(zhuǎn)換的時機,例如使用定時器觸發(fā),配合不同時刻的DHRx數(shù)據(jù),可實現(xiàn)DAC輸出正弦波的功能。
3 DAC初始化結(jié)構(gòu)體詳解
在W55MH32的標準庫中,把控制DAC相關(guān)的各種配置封裝到了結(jié)構(gòu)體DAC_InitTypeDef中, 它主要包含了DAC_CR控制寄存器的各寄存器位的配置,見代碼清單:DAC-1 :
代碼清單:DAC-1 DAC_InitTypeDef結(jié)構(gòu)體
typedef struct { /*DAC觸發(fā)方式 */ uint32_t DAC_Trigger; /*是否自動輸出噪聲或三角波 */ uint32_t DAC_WaveGeneration; /*選擇噪聲生成器的低通濾波或三角波的幅值 */ uint32_t DAC_LFSRUnmask_TriangleAmplitude; /*選擇是否使能輸出緩沖器 */ uint32_t DAC_OutputBuffer; } DAC_InitTypeDef;
各個結(jié)構(gòu)體成員的介紹如下,解說中各模式后括號內(nèi)的英文為該模式在標準庫中使用宏:
DAC_Trigger
本成員用于配置DAC的觸發(fā)模式,當DAC產(chǎn)生相應(yīng)的觸發(fā)事件時,才會把DHRx寄存器的值轉(zhuǎn)移到DORx寄存器中進行轉(zhuǎn)換。 本結(jié)構(gòu)體成員可以選擇的觸發(fā)模式如下:硬件觸發(fā)模式(DAC_Trigger_None),DHRx寄存器內(nèi)的數(shù)據(jù)會在3個APB1時鐘周期內(nèi)自動轉(zhuǎn)換至DORx進行轉(zhuǎn)換; 定時器觸發(fā)模式(DAC_Trigger_T2/4/5/6/7_TRGO),使用定時器2、4、5、6、7控制DHRx寄存器的數(shù)據(jù)按時間轉(zhuǎn)移到DORx中進行轉(zhuǎn)換, 利用這種方式可以輸出特定的波形;EXTI_9觸發(fā)方式(DAC_Trigger_Ext_IT9),當產(chǎn)生EXTI_9事件時(如GPIO中斷事件), 觸發(fā)轉(zhuǎn)換;軟件觸發(fā)模式(DAC_Trigger_Software),在本模式下,向DAC_SWTRIGR寄存器寫入配置即可觸發(fā)信號進行轉(zhuǎn)換。
DAC_WaveGeneration
本成員用于設(shè)置是否使用DAC輸出偽噪聲或三角波(DAC_WaveGeneration_None/Noise/Triangle),使用偽噪聲和三角波輸出時, DAC都會把LFSR寄存器的值疊加到DHRx數(shù)值上,產(chǎn)生偽噪聲和三角波,若希望產(chǎn)生自定義的輸出時,直接配置為DAC_WaveGeneration_None即可。
DAC_LFSRUnmask_TriangleAmplitude
本成員通過控制DAC_CR的MAMP2位設(shè)置LFSR寄存器位的數(shù)據(jù),即當使用偽噪聲或三角波輸出時要疊加到DHRx的值,非噪聲或三角波輸出模式下, 本配置無效。使用偽噪聲輸出時LFSR=0xAAA,MAMP2寄存器位可以屏蔽LFSR的某些位, 這時把本結(jié)構(gòu)體成員賦值為DAC_LFSRUnmask_Bit0~DAC_LFSRUnmask_Bit11_0等宏即可;使用三角波輸出時,本結(jié)構(gòu)體設(shè)置三角波的最大幅值, 可選擇為DAC_TriangleAmplitude_1~ DAC_TriangleAmplitude_4096等宏,見下圖,DAC輸出三角波。DAC在DHRx值的基礎(chǔ)上升,幅值達到MAMPx設(shè)置的最大幅度時下降,形成三角波的輸出。
DAC_OutputBuffer
本結(jié)構(gòu)體成員用于控制是否使能DAC的輸出緩沖(DAC_OutputBuffer_Enable/Disable), 使能了DAC的輸出緩沖后可以減小輸出阻抗,適合直接驅(qū)動一些外部負載。
4 DAC輸出正弦波實驗
這段代碼是基于 W55MH32 微控制器編寫的,其主要功能是通過 DAC(數(shù)模轉(zhuǎn)換器)輸出雙聲道的正弦波信號,并且配置了串口通信以便輸出系統(tǒng)時鐘信息。
4.1 代碼解析
1. 宏定義與全局變量
#define DAC1_DHR12RD_ADDRESS (DAC_BASE + 0x00000008 + DAC_Align_12b_R) #define DAC2_DHR12RD_ADDRESS (DAC_BASE + 0x00000014 + DAC_Align_12b_R) #define POINT_NUM 32 uint16_t Sine12bit[POINT_NUM] = { 2048, 2460, 2856, 3218, 3532, 3786, 3969, 4072, 4093, 4031, 3887, 3668, 3382, 3042, 2661, 2255, 1841, 1435, 1054, 714, 428, 209, 65, 3, 24, 127, 310, 564, 878, 1240, 1636, 2048}; uint32_t DualSine12bit[POINT_NUM];
DAC1_DHR12RD_ADDRESS 和 DAC2_DHR12RD_ADDRESS:分別定義了 DAC1 和 DAC2 的 12 位右對齊數(shù)據(jù)寄存器地址。
POINT_NUM:定義了正弦波一個周期內(nèi)的采樣點數(shù),這里為 32 個點。
Sine12bit:存儲了一個周期正弦波的 12 位采樣數(shù)據(jù)。
DualSine12bit:用于存儲雙聲道的正弦波數(shù)據(jù)。
2. 函數(shù)聲明
void UART_Configuration(uint32_t bound); void GPIO_Configuration(void); void DAC_Configuration(void); void TIM_Configuration(void); void DMA_Configuration(void);
聲明了用于配置串口、GPIO、DAC、定時器和 DMA 的函數(shù)。
3. main()函數(shù)
int main(void) { uint32_t i; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE); delay_init(); UART_Configuration(115200); RCC_GetClocksFreq(&clocks); printf("n"); printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhzn", (float)clocks.SYSCLK_Frequency / 1000000, (float)clocks.HCLK_Frequency / 1000000, (float)clocks.PCLK1_Frequency / 1000000, (float)clocks.PCLK2_Frequency / 1000000, (float)clocks.ADCCLK_Frequency / 1000000); printf("DAC Out Software Sine Wave Test.n"); GPIO_Configuration(); DAC_Configuration(); TIM_Configuration(); for (i = 0; i < POINT_NUM; i++) { DualSine12bit[i] = (Sine12bit[i] < 16) + (Sine12bit[i]); } DMA_Configuration(); while (1); }
使能 CRC 外設(shè)時鐘,初始化延時函數(shù),配置串口通信波特率為 115200,并獲取系統(tǒng)時鐘頻率信息。
打印系統(tǒng)時鐘頻率信息和測試提示信息。
依次調(diào)用 GPIO_Configuration、DAC_Configuration() 和 TIM_Configuration()函數(shù)進行 GPIO、DAC 和定時器的配置。
將單聲道的正弦波數(shù)據(jù)轉(zhuǎn)換為雙聲道數(shù)據(jù)存儲在 DualSine12bit 數(shù)組中。
調(diào)用 DMA_Configuration()函數(shù)配置 DMA 傳輸。
進入無限循環(huán),保持程序運行。
4. DMA_Configuration()函數(shù)
void DMA_Configuration(void) { DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); DMA_InitStructure.DMA_PeripheralBaseAddr = DAC2_DHR12RD_ADDRESS; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&DualSine12bit; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = POINT_NUM; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA2_Channel4, &DMA_InitStructure); DMA_Cmd(DMA2_Channel4, ENABLE); DMA_InitStructure.DMA_PeripheralBaseAddr = DAC1_DHR12RD_ADDRESS; DMA_Init(DMA2_Channel3, &DMA_InitStructure); DMA_Cmd(DMA2_Channel3, ENABLE); }
使能 DMA2 外設(shè)時鐘。
配置 DMA2 通道 4,將雙聲道正弦波數(shù)據(jù)從內(nèi)存?zhèn)鬏數(shù)?DAC2 的數(shù)據(jù)寄存器。
配置 DMA2 通道 3,將雙聲道正弦波數(shù)據(jù)從內(nèi)存?zhèn)鬏數(shù)?DAC1 的數(shù)據(jù)寄存器。
采用循環(huán)模式,使 DMA 不斷循環(huán)傳輸數(shù)據(jù)。
5. TIM_Configuration()函數(shù)
void TIM_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseStructure.TIM_Period = (20 - 1); TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); TIM_Cmd(TIM2, ENABLE); }
使能定時器 2 外設(shè)時鐘。
配置定時器 2 的周期為 20 個時鐘周期,預(yù)分頻器為 0,計數(shù)器向上計數(shù)。
選擇定時器 2 的更新事件作為觸發(fā)輸出。
使能定時器 2。
6. GPIO_Configuration()函數(shù)
void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); }
使能 GPIOA 外設(shè)時鐘。
配置 GPIOA 的引腳 4 和 5 為模擬輸入模式,速度為 50MHz。
7. DAC_Configuration()函數(shù)
void DAC_Configuration(void) { DAC_InitTypeDef DAC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO; DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_4095; DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; DAC_Init(DAC_Channel_1, &DAC_InitStructure); DAC_Init(DAC_Channel_2, &DAC_InitStructure); DAC_Cmd(DAC_Channel_1, ENABLE); DAC_Cmd(DAC_Channel_2, ENABLE); DAC_DMACmd(DAC_Channel_1, ENABLE); DAC_DMACmd(DAC_Channel_2, ENABLE); }
使能 DAC 外設(shè)時鐘。
配置 DAC 通道 1 和通道 2 的觸發(fā)源為定時器 2 的觸發(fā)輸出。
不生成波形,啟用輸出緩沖。
使能 DAC 通道 1 和通道 2,并使能 DMA 傳輸。
8. UART_Configuration()函數(shù)
void UART_Configuration(uint32_t bound) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = bound; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART_TEST, &USART_InitStructure); USART_Cmd(USART_TEST, ENABLE); }
使能 USART1 和 GPIOA 外設(shè)時鐘。
配置 GPIOA 的引腳 9 為復(fù)用推挽輸出,引腳 10 為浮空輸入。
配置 USART1 的波特率、數(shù)據(jù)位、停止位、奇偶校驗等參數(shù)。
使能 USART1。
9. SER_PutChar() 和 fputc() 函數(shù)
int SER_PutChar(int ch) { while (!USART_GetFlagStatus(USART_TEST, USART_FLAG_TC)); USART_SendData(USART_TEST, (uint8_t)ch); return ch; } int fputc(int c, FILE *f) { /* Place your implementation of fputc here */ /* e.g. write a character to the USART */ if (c == 'n') { SER_PutChar('r'); } return (SER_PutChar(c)); }
SER_PutChar():向 USART 發(fā)送一個字符,等待發(fā)送完成標志位。
fputc():重定向標準輸出函數(shù),將字符發(fā)送到 USART,遇到換行符時先發(fā)送回車符。
綜上所述,這段代碼通過配置定時器、DMA 和 DAC,實現(xiàn)了雙聲道正弦波信號的輸出,并通過串口輸出系統(tǒng)時鐘信息。
-
單片機
+關(guān)注
關(guān)注
6067文章
44960瀏覽量
648762 -
寄存器
+關(guān)注
關(guān)注
31文章
5430瀏覽量
123911 -
正弦波
+關(guān)注
關(guān)注
11文章
654瀏覽量
56474 -
dac
+關(guān)注
關(guān)注
43文章
2396瀏覽量
193298 -
定時器
+關(guān)注
關(guān)注
23文章
3297瀏覽量
117569
發(fā)布評論請先 登錄
正弦波所需的DAC數(shù)據(jù)是如何計算的
stm32用dac輸出正弦波
第二十六講 寄存器和移位寄存器

模擬電路網(wǎng)絡(luò)課件 第二十六節(jié):差分式放大電路

DAC—輸出正弦波
DAC輸出正弦波的實驗程序和工程文件免費下載
利用DAC實現(xiàn)正弦波輸出

納雷科技將攜兩大交通家族產(chǎn)品參加第二十六屆CEIC中國高速公路展
第二十六屆高交會將于11月舉辦 科技盛宴亮點紛呈

評論