單芯片解決方案,開啟全新體驗——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)模組等場景,軟件使用方法一致。更多信息和資料請進入http://www.w5500.com/網(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)頁:http://www.w5500.com/,我們期待與您共同探索W55MH32的無限可能。
第九章 RCC——使用HSE/HSI配置時鐘
本章參考資料:《W55MH32參考手冊》RCC章節(jié)。
學(xué)習(xí)本章時,配合《W55MH32參考手冊》RCC章節(jié)一起閱讀,效果會更佳,特別是涉及到寄存器說明的部分。
RCC :reset clock control 復(fù)位和時鐘控制器。本章我們主要講解時鐘部分, 特別是要著重理解時鐘樹,理解了時鐘樹,W55MH32的一切時鐘的來龍去脈都會了如指掌。
1 RCC主要作用——時鐘部分
設(shè)置系統(tǒng)時鐘SYSCLK、設(shè)置AHB分頻因子(決定HCLK等于多少)、設(shè)置APB2分頻因子(決定PCLK2等于多少)、 設(shè)置APB1分頻因子(決定PCLK1等于多少)、設(shè)置各個外設(shè)的分頻因子;控制AHB、APB2和APB1這三條總線時鐘的開啟、 控制每個外設(shè)的時鐘的開啟。對于SYSCLK、HCLK、PCLK2、PCLK1這四個時鐘的配置一般是: PCLK2 = HCLK = SYSCLK=PLLCLK = 72M, PCLK1=HCLK/2 = 36M。這個時鐘配置也是庫函數(shù)的標準配置,我們用的最多的就是這個。
2 RCC框圖剖析——時鐘部分
1. 當(dāng) HSI 被用于作為 PLL 時鐘的輸入時,系統(tǒng)時鐘能得到的最大頻率是 108MHz。
2. 對于內(nèi)部和外部時鐘源的特性,請參考相應(yīng)產(chǎn)品數(shù)據(jù)手冊中“電氣特性”章節(jié)。
用戶可通過多個預(yù)分頻器配置 AHB、高速 APB(APB2)和低速 APB(APB1)域的頻率。AHB 和 APB2 域的最大頻率是 216MHz。APB1 域的最大允許頻率是 108MHz。SDIO 接口的時鐘頻率固定為 HCLK/2。RCC 通過 AHB 時鐘(HCLK)8 分頻后作為 Cortex 系統(tǒng)定時器(SysTick)的外部時鐘。通過對 SysTick控制與狀態(tài)寄存器的設(shè)置,可選擇上述時鐘或 Cortex(HCLK)時鐘作為 SysTick 時鐘。ADC 時鐘由高速 APB2 時鐘經(jīng) 2、4、6 或 8 分頻后獲得。
定時器時鐘頻率分配由硬件按以下 2 種情況自動設(shè)置:
1. 如果相應(yīng)的 APB 預(yù)分頻系數(shù)是 1,定時器的時鐘頻率與所在 APB 總線頻率一致。
2. 否則,定時器的時鐘頻率被設(shè)為與其相連的 APB 總線頻率的 2 倍。
FCLK 是 Cortex?-M3 的自由運行時鐘。詳情見 ARM 的 Cortex?-M3 技術(shù)參考手冊。RCC時鐘樹如下:
2.1 系統(tǒng)時鐘
2.1.1 HSE高速外部時鐘信號
HSE是高速的外部時鐘信號,可以由有源晶振或者無源晶振提供,頻率從4-16MHZ不等。當(dāng)使用有源晶振時, 時鐘從OSC_IN引腳進入,OSC_OUT引腳懸空,當(dāng)選用無源晶振時,時鐘從OSC_IN和OSC_OUT進入,并且要配諧振電容。
HSE最常使用的就是8M的無源晶振。當(dāng)確定PLL時鐘來源的時候,HSE可以不分頻或者2分頻, 這個由時鐘配置寄存器CFGR的位17:PLLXTPRE設(shè)置,我們設(shè)置為HSE不分頻。
PLL時鐘源
內(nèi)部 PLL 可以用來倍頻 HSIRC 的輸出時鐘或 HSE 晶體輸出時鐘。參考圖 7 和時鐘控制寄存器。
PLL 的設(shè)置(選擇 HIS 振蕩器除 2 或 HSE 振蕩器為 PLL 的輸入時鐘,和選擇倍頻因子)必須在其被激活前完成。一旦 PLL 被激活,這些參數(shù)就不能被改動。
如果 PLL 中斷在時鐘中斷寄存器里被允許,當(dāng) PLL 準備就緒時,可產(chǎn)生中斷申請。
如果需要在應(yīng)用中使用 USB 接口,PLL 必須被設(shè)置為輸出 48 或 72MHZ 時鐘,用于提供 48MHz 的USBCLK 時鐘。
PLL時鐘PLLCLK
通過設(shè)置PLL的倍頻因子,可以對PLL的時鐘來源進行倍頻,倍頻因子可以是:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16], 具體設(shè)置成多少,由時鐘配置寄存器CFGR的位21-18:PLLMUL[3:0]設(shè)置。我們這里設(shè)置為9倍頻, 因為上一步我們設(shè)置PLL的時鐘來源為HSE=8M,所以經(jīng)過PLL倍頻之后的PLL時鐘:PLLCLK = 8M *9 = 72M。 72M是ST官方推薦的穩(wěn)定運行時鐘,如果你想超頻的話,增大倍頻因子即可,最高為128M。 我們這里設(shè)置PLL時鐘:PLLCLK = 8M *9 = 72M。
系統(tǒng)時鐘(SYSCLK)選擇
系統(tǒng)復(fù)位后,HSI 振蕩器被選為系統(tǒng)時鐘。當(dāng)時鐘源被直接或通過 PLL 間接作為系統(tǒng)時鐘時,它將不能被停止。
只有當(dāng)目標時鐘源準備就緒了(經(jīng)過啟動穩(wěn)定階段的延遲或 PLL 穩(wěn)定),從一個時鐘源到另一個時鐘源的切換才會發(fā)生。在被選擇時鐘源沒有就緒時,系統(tǒng)時鐘的切換不會發(fā)生。直至目標時鐘源就緒,才發(fā)生切換。
在時鐘控制寄存器(RCC_CR)里的狀態(tài)位指示哪個時鐘已經(jīng)準備好了,哪個時鐘目前被用作系統(tǒng)時鐘。
AHB總線時鐘HCLK
系統(tǒng)時鐘SYSCLK經(jīng)過AHB預(yù)分頻器分頻之后得到時鐘叫APB總線時鐘,即HCLK,分頻因子可以是:[1,2,4,8,16,64,128,256,512], 具體的由時鐘配置寄存器CFGR的位7-4 :HPRE[3:0]設(shè)置。片上大部分外設(shè)的時鐘都是經(jīng)過HCLK分頻得到, 至于AHB總線上的外設(shè)的時鐘設(shè)置為多少,得等到我們使用該外設(shè)的時候才設(shè)置, 我們這里只需粗線條的設(shè)置好APB的時鐘即可。
APB2總線時鐘PCLK2
APB2總線時鐘PCLK2由HCLK經(jīng)過高速APB2預(yù)分頻器得到,分頻因子可以是:[1,2,4,8,16],具體由時鐘配置寄存器CFGR的位13-11:PPRE2[2:0]決定。 PCLK2屬于高速的總線時鐘,片上高速的外設(shè)就掛載到這條總線上,比如全部的GPIO、USART1、SPI1等。至于APB2總線上的外設(shè)的時鐘設(shè)置為多少, 得等到我們使用該外設(shè)的時候才設(shè)置,我們這里只需粗線條的設(shè)置好APB2的時鐘即可。
APB1總線時鐘PCLK1
APB1總線時鐘PCLK1由HCLK經(jīng)過低速APB預(yù)分頻器得到,分頻因子可以是:[1,2,4,8,16],具體的由時鐘配置寄存器CFGR的位10-8:PRRE1[2:0]決定。 PCLK1屬于低速的總線時鐘,最高為36M,片上低速的外設(shè)就掛載到這條總線上,比如USART2/3/4/5、SPI2/3,I2C1/2等。 至于APB1總線上的外設(shè)的時鐘設(shè)置為多少,得等到我們使用該外設(shè)的時候才設(shè)置,我們這里只需粗略的設(shè)置好APB1的時鐘即可。
2.1.2 設(shè)置系統(tǒng)時鐘庫函數(shù)
上面的7個步驟對應(yīng)的設(shè)置系統(tǒng)時鐘庫函數(shù)如下,該函數(shù)截取自固件庫文件system_w55mh32.c。為了方便閱讀, 我已把互聯(lián)型相關(guān)的代碼刪掉,把英文注釋翻譯成了中文,并把代碼標上了序號,總共七個步驟。該函數(shù)是直接操作寄存器的, 有關(guān)寄存器部分請參考數(shù)據(jù)手冊的RCC的寄存器描述部分。
代碼清單:RCC-1 設(shè)置系統(tǒng)時鐘庫函數(shù)
static void SetSysClockTo72(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; // ① 使能HSE,并等待HSE穩(wěn)定 RCC->CR |= ((uint32_t)RCC_CR_HSEON); // 等待HSE啟動穩(wěn)定,并做超時處理 do { HSEStatus = RCC->CR & RCC_CR_HSERDY; StartUpCounter++; } while ((HSEStatus == 0) &&(StartUpCounter !=HSE_STARTUP_TIMEOUT)); if ((RCC->CR & RCC_CR_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } // HSE啟動成功,則繼續(xù)往下處理 if (HSEStatus == (uint32_t)0x01) { //----------------------------------------------------------- // 使能FLASH 預(yù)存取緩沖區(qū) */ FLASH->ACR |= FLASH_ACR_PRFTBE; // SYSCLK周期與閃存訪問時間的比例設(shè)置,這里統(tǒng)一設(shè)置成2 // 設(shè)置成2的時候,SYSCLK低于48M也可以工作,如果設(shè)置成0或者1的時候, // 如果配置的SYSCLK超出了范圍的話,則會進入硬件錯誤,程序就死了 // 0:0 < SYSCLK <= 24M // 1:24< SYSCLK <= 48M // 2:48< SYSCLK <= 72M */ FLASH-?>ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; //------------------------------------------------------------ // ② 設(shè)置AHB、APB2、APB1預(yù)分頻因子 // HCLK = SYSCLK RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; //PCLK2 = HCLK RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; //PCLK1 = HCLK/2 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; // ③ 設(shè)置PLL時鐘來源,設(shè)置PLL倍頻因子,PLLCLK = HSE * 9 = 72 MHz RCC->CFGR &= (uint32_t)((uint32_t) ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); // ④ 使能 PLL RCC->CR |= RCC_CR_PLLON; // ⑤ 等待PLL穩(wěn)定 while ((RCC->CR & RCC_CR_PLLRDY) == 0) { } // ⑥ 選擇PLL作為系統(tǒng)時鐘來源 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; // ⑦ 讀取時鐘切換狀態(tài)位,確保PLLCLK被選為系統(tǒng)時鐘 while ((RCC->CFGR&(uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){ } } else {// 如果HSE啟動失敗,用戶可以在這里添加錯誤代碼出來 } }
2.2 其他時鐘
通過對系統(tǒng)時鐘設(shè)置的講解,整個時鐘樹我們已經(jīng)把握的有六七成,剩下的時鐘我們講解幾個重要的部分。
2.2.1 USB時鐘
USB時鐘是由PLLCLK經(jīng)過USB預(yù)分頻器得到,分頻因子可以是:[1,1.5],具體的由時鐘配置寄存器CFGR的位22:USBPRE配置。 USB的時鐘最高是48M,根據(jù)分頻因子反推過來算,PLLCLK只能是48M或者是72M。一般我們設(shè)置PLLCLK=72M,USBCLK=48M。 USB對時鐘要求比較高,所以PLLCLK只能是由HSE倍頻得到,不能使用HSI倍頻。
2.2.2 Cortex系統(tǒng)時鐘
Cortex系統(tǒng)時鐘由HCLK 8分頻得到,等于9M, Cortex系統(tǒng)時鐘用來驅(qū)動內(nèi)核的系統(tǒng)定時器SysTick,SysTick一般用于操作系統(tǒng)的時鐘節(jié)拍,也可以用做普通的定時。
2.2.3 ADC時鐘
ADC時鐘由PCLK2經(jīng)過ADC預(yù)分頻器得到,分頻因子可以是[2,4,6,8],具體的由時鐘配置寄存器CFGR的位15-14:ADCPRE[1:0]決定。 很奇怪的是怎么沒有1分頻。ADC時鐘最高只能是14M,如果采樣周期設(shè)置成最短的1.5個周期的話,ADC的轉(zhuǎn)換時間可以達到最短的1us。 如果真要達到最短的轉(zhuǎn)換時間1us的話,那ADC的時鐘就得是14M,反推PCLK2的時鐘只能是:28M、56M、84M、112M。
2.2.4 RTC時鐘、獨立看門狗時鐘
RTC時鐘可由HSE/128分頻得到,也可由低速外部時鐘信號LSE提供,頻率為32.768KHZ,也可由低速內(nèi)部時鐘信號LSI提供, 具體選用哪個時鐘由備份域控制寄存器BDCR的位9-8:RTCSEL[1:0]配置。獨立看門狗的時鐘由LSI提供, 且只能是由LSI提供,LSI是低速的內(nèi)部時鐘信號,頻率為30~60KHZ直接不等,一般取40KHZ。
2.2.5 MCO時鐘輸出
MCO是microcontroller clock output的縮寫,是微控制器時鐘輸出引腳,在W55MH32系列中 由 PA8復(fù)用所得, 主要作用是可以對外提供時鐘,相當(dāng)于一個有源晶振。MCO的時鐘來源可以是:PLLCLK/2、HSI、HSE、SYSCLK, 具體選哪個由時鐘配置寄存器CFGR的位26-24:MCO[2:0]決定。除了對外提供時鐘這個作用之外, 我們還可以通過示波器監(jiān)控MCO引腳的時鐘輸出來驗證我們的系統(tǒng)時鐘配置是否正確。
3 時鐘配置
3.1RCC_HSIConfig
1. 頭文件包含與全局定義
#include #include #include #include "delay.h" #include "w55mh32.h" #include "wiz.h" USART_TypeDef *USART_TEST = USART1;
頭文件:包含標準庫和硬件相關(guān)頭文件(w55mh32.h)、延時函數(shù)(delay.h)、自定義硬件抽象層(wiz.h)。
全局變量:定義串口外設(shè)指針 USART_TEST 指向 USART1。
2. 函數(shù)聲明
void UART_Configuration(uint32_t bound); void RCC_ClkConfiguration(void);
UART_Configuration:配置串口通信。
RCC_ClkConfiguration:配置系統(tǒng)時鐘(RCC,復(fù)位與時鐘控制)。
3. main ()函數(shù):系統(tǒng)初始化與主邏輯
int main(void) { RCC_ClocksTypeDef clocks; RCC_ClkConfiguration(); // 配置系統(tǒng)時鐘 delay_init(); // 初始化延時函數(shù) UART_Configuration(115200); // 配置串口(波特率 115200) printf("RCC HSI Config Test.n"); RCC_GetClocksFreq(&clocks); // 獲取系統(tǒng)時鐘頻率 // 打印各時鐘頻率 printf("nSYSCLK: %3.1fMhz, nHCLK: %3.1fMhz, nPCLK1: %3.1fMhz, nPCLK2: %3.1fMhz, nADCCLK: %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); while (1) {} // 主循環(huán)(空,等待事件) }
功能:
初始化系統(tǒng)時鐘(HSI + PLL)。
初始化串口,通過 printf 輸出時鐘頻率信息。
進入無限循環(huán),程序無實際業(yè)務(wù)邏輯,僅驗證時鐘和串口配置。
4. RCC_ClkConfiguration ()函數(shù):系統(tǒng)時鐘配置
void RCC_ClkConfiguration(void) { RCC_DeInit(); // 復(fù)位 RCC 到默認狀態(tài) // 啟用 HSI(高速內(nèi)部時鐘,默認 16MHz) RCC_HSICmd(ENABLE); while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); // 等待 HSI 就緒 // 配置 PLL(PLL 輸入 = HSI/2,PLL 倍頻 = 32) RCC_PLLCmd(DISABLE); // 先禁用 PLL WIZ_RCC_PLLConfig( RCC_PLLSource_HSI_Div2, // PLL 時鐘源:HSI/2(8MHz) RCC_PLLMul_32, // PLL 倍頻:32(8MHz × 32 = 256MHz) 1 // 保留參數(shù)(未使用) ); RCC_PLLCmd(ENABLE); // 啟用 PLL while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); // 等待 PLL 就緒 // 設(shè)置系統(tǒng)時鐘源為 PLL(256MHz) RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // 配置總線時鐘分頻 RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK(256MHz) RCC_PCLK1Config(RCC_HCLK_Div2); // PCLK1 = HCLK/2(128MHz) RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK(256MHz) // 啟用 LSI(低速內(nèi)部時鐘,默認 40kHz) RCC_LSICmd(ENABLE); while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); // 重復(fù)啟用 HSI(冗余代碼,HSI 已啟用) RCC_HSICmd(ENABLE); while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); }
時鐘配置流程:
復(fù)位 RCC:重置所有時鐘配置。
啟用 HSI:使用內(nèi)部 16MHz 時鐘。
配置 PLL:輸入:HSI/2 = 8MHz。
輸出:8MHz × 32 = 256MHz(系統(tǒng)時鐘 SYSCLK)。
選擇 PLL 作為系統(tǒng)時鐘源。
總線分頻:
HCLK(AHB 總線):256MHz(不分頻)。
PCLK1(APB1 總線):128MHz(HCLK/2)。
PCLK2(APB2 總線):256MHz(不分頻)。
啟用 LSI:用于獨立看門狗或 RTC(未在代碼中使用)。
冗余操作:重復(fù)啟用 HSI(無實際意義,HSI 已就緒)。
注意:
PLL 輸出頻率需符合芯片規(guī)格(如 W55MH32 的最大 SYSCLK 為 256MHz)。
WIZ_RCC_PLLConfig ()是自定義函數(shù)(來自 wiz.h),用于擴展 PLL 配置。
5. UART_Configuration ()函數(shù):串口初始化
void UART_Configuration(uint32_t bound) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; // 使能串口和 GPIO 時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 配置 TX 引腳(PA9):復(fù)用推挽輸出 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); // 配置 RX 引腳(PA10):浮空輸入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // 串口參數(shù)配置 USART_InitStructure.USART_BaudRate = bound; // 波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 8 位數(shù)據(jù) USART_InitStructure.USART_StopBits = USART_StopBits_1; // 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; // 收發(fā)模式 USART_Init(USART_TEST, &USART_InitStructure); // 初始化串口 USART_Cmd(USART_TEST, ENABLE); // 使能串口 }
功能:
使能 USART1 和 GPIOA 時鐘。
配置 PA9(TX)為復(fù)用推挽輸出,PA10(RX)為浮空輸入。
初始化串口參數(shù)(波特率、數(shù)據(jù)位、停止位等)。
使能串口。
6. 串口輸出函數(shù)
int SER_PutChar(int ch) { while (!USART_GetFlagStatus(USART_TEST, USART_FLAG_TC)); // 等待發(fā)送完成 USART_SendData(USART_TEST, (uint8_t)ch); // 發(fā)送字符 return ch; } int fputc(int c, FILE *f) { if (c == 'n') SER_PutChar('r'); // 換行符添加回車(適配終端) return SER_PutChar(c); // 重定向 printf 到串口 }
核心功能:
系統(tǒng)時鐘配置:
使用 HSI(16MHz)作為 PLL 輸入,PLL 倍頻 32 倍,生成 256MHz 系統(tǒng)時鐘。
總線分頻:HCLK=256MHz,PCLK1=128MHz,PCLK2=256MHz。
串口通信:配置 USART1 為 115200 波特率,用于printf輸出。
測試驗證:打印系統(tǒng)各時鐘頻率,驗證時鐘配置正確性。
3.1.1 實驗現(xiàn)象
把編譯好的程序下載到開發(fā)板,可以看到設(shè)置不同的系統(tǒng)時鐘:
3.2 RCC_HighFrequencyConfig
程序運行:
1. 頭文件與全局變量
引入了標準庫的頭文件以及自定義的delay.h、w55mh32.h、wiz.h頭文件,為程序提供所需的函數(shù)和數(shù)據(jù)類型。
定義全局變量USART_TEST并將其指向USART1,用于后續(xù)的串口通信操作。
2. 函數(shù)聲明
對UART_Configuration()和RCC_ClkConfiguration()函數(shù)進行聲明,前者用于配置串口,后者用于配置系統(tǒng)時鐘。
主函數(shù)main():
int main(void) { RCC_ClocksTypeDef clocks; RCC_ClkConfiguration(); delay_init(); UART_Configuration(115200); printf("RCC Clock Config Test.n"); RCC_GetClocksFreq(&clocks); printf("n"); printf("SYSCLK: %3.1fMhz, nHCLK: %3.1fMhz, nPCLK1: %3.1fMhz, nPCLK2: %3.1fMhz, nADCCLK: %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); while (1) { } }
初始化完成之后,使用printf()函數(shù)打印輸出系統(tǒng)時鐘、AHB 總線時鐘、APB1 總線時鐘、APB2 總線時鐘和 ADC 時鐘的頻率信息,隨后進入無限循環(huán),使程序持續(xù)運行。
4. RCC_ClkConfiguration()函數(shù)的主要流程:
復(fù)位 RCC 寄存器,為后續(xù)的時鐘配置做準備。
使能外部高速時鐘(HSE),并等待其穩(wěn)定。
禁用 PLL,重新配置 PLL 的時鐘源和倍頻系數(shù)。
使能 PLL,并等待其穩(wěn)定。
把系統(tǒng)時鐘源設(shè)置為 PLL 輸出。
配置 AHB、APB1 和 APB2 總線的時鐘分頻系數(shù)。
使能內(nèi)部低速時鐘(LSI)和內(nèi)部高速時鐘(HSI),并等待它們穩(wěn)定。
5. UART_Configuration()函數(shù)
使能 USART1 和 GPIOA 的時鐘。
配置 USART1 的發(fā)送引腳(PA9)為復(fù)用推挽輸出模式,接收引腳(PA10)為浮空輸入模式。
配置 USART1 的波特率、數(shù)據(jù)位、停止位、奇偶校驗位等參數(shù)。使能 USART1。
6. SER_PutChar()函數(shù):此函數(shù)用于向串口發(fā)送一個字符,會等待發(fā)送完成后再發(fā)送下一個字符。
7. fputc()函數(shù):重定向標準輸出函數(shù),把字符發(fā)送到串口。若遇到換行符n,會先發(fā)送回車符r。
3.2.1 實驗現(xiàn)象
WIZnet 是一家無晶圓廠半導(dǎo)體公司,成立于 1998 年。產(chǎn)品包括互聯(lián)網(wǎng)處理器 iMCU?,它采用 TOE(TCP/IP 卸載引擎)技術(shù),基于獨特的專利全硬連線 TCP/IP。iMCU? 面向各種應(yīng)用中的嵌入式互聯(lián)網(wǎng)設(shè)備。
WIZnet 在全球擁有 70 多家分銷商,在香港、韓國、美國設(shè)有辦事處,提供技術(shù)支持和產(chǎn)品營銷。
香港辦事處管理的區(qū)域包括:澳大利亞、印度、土耳其、亞洲(韓國和日本除外)。
審核編輯 黃宇
-
WIZnet
+關(guān)注
關(guān)注
3文章
20瀏覽量
42461 -
RCC
+關(guān)注
關(guān)注
0文章
95瀏覽量
27606 -
HSI
+關(guān)注
關(guān)注
0文章
13瀏覽量
8818 -
HSE
+關(guān)注
關(guān)注
0文章
18瀏覽量
9679
發(fā)布評論請先 登錄
Sklearn與TensorFlow機器學(xué)習(xí)實用指南——第九章習(xí)題答案
編寫HSE/HSI配置系統(tǒng)時鐘函數(shù)
CH32V103基礎(chǔ)教程103-RCC—HSE/HSI時鐘配置
功率放大電路問答第九章
振幅調(diào)制與解調(diào) 第九章
單片機c語言教程第九章--C51運算符和表達式(指針和地址運

STM32使用HSE、HSI作為系統(tǒng)時鐘的來源
【正點原子FPGA連載】第九章按鍵控制LED燈實驗 -摘自【正點原子】新起點之FPGA開發(fā)指南_V2.1

第九章 數(shù)模和模數(shù)轉(zhuǎn)換

評論