單芯片解決方案,開啟全新體驗——W55MH32 高性能以太網單片機
W55MH32是WIZnet重磅推出的高性能以太網單片機,它為用戶帶來前所未有的集成化體驗。這顆芯片將強大的組件集于一身,具體來說,一顆W55MH32內置高性能Arm? Cortex-M3核心,其主頻最高可達216MHz;配備1024KB FLASH與96KB SRAM,滿足存儲與數據處理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP協議棧、內置MAC以及PHY,擁有獨立的32KB以太網收發緩存,可供8個獨立硬件socket使用。如此配置,真正實現了All-in-One解決方案,為開發者提供極大便利。
在封裝規格上,W55MH32 提供了兩種選擇:QFN100和QFN68。
W55MH32L采用QFN100封裝版本,尺寸為12x12mm,其資源豐富,專為各種復雜工控場景設計。它擁有66個GPIO、3個ADC、12通道DMA、17個定時器、2個I2C、5個串口、2個SPI接口(其中1個帶I2S接口復用)、1個CAN、1個USB2.0以及1個SDIO接口。如此豐富的外設資源,能夠輕松應對工業控制中多樣化的連接需求,無論是與各類傳感器、執行器的通信,還是對復雜工業協議的支持,都能游刃有余,成為復雜工控領域的理想選擇。 同系列還有QFN68封裝的W55MH32Q版本,該版本體積更小,僅為8x8mm,成本低,適合集成度高的網關模組等場景,軟件使用方法一致。更多信息和資料請進入網站或者私信獲取。
此外,本W55MH32支持硬件加密算法單元,WIZnet還推出TOE+SSL應用,涵蓋TCP SSL、HTTP SSL以及 MQTT SSL等,為網絡通信安全再添保障。
為助力開發者快速上手與深入開發,基于W55MH32L這顆芯片,WIZnet精心打造了配套開發板。開發板集成WIZ-Link芯片,借助一根USB C口數據線,就能輕松實現調試、下載以及串口打印日志等功能。開發板將所有外設全部引出,拓展功能也大幅提升,便于開發者全面評估芯片性能。
若您想獲取芯片和開發板的更多詳細信息,包括產品特性、技術參數以及價格等,歡迎訪問官方網頁,我們期待與您共同探索W55MH32的無限可能。
第二十九章 讀寫內部FLASH
1 W55MH32的內部FLASH簡介
在W55MH32芯片內部有一個FLASH存儲器,它主要用于存儲代碼,我們在電腦上編寫好應用程序后,使用下載器把編譯后的代碼文件燒錄到該內部FLASH中, 由于FLASH存儲器的內容在掉電后不會丟失,芯片重新上電復位后,內核可從內部FLASH中加載代碼并運行, 見下圖,W55MH32的內部框架圖:
除了使用外部的工具(如下載器)讀寫內部FLASH外,W55MH32芯片在運行的時候,也能對自身的內部FLASH進行讀寫,因此, 若內部FLASH存儲了應用程序后還有剩余的空間,我們可以把它像外部SPI-FLASH那樣利用起來,存儲一些程序運行時產生的需要掉電保存的數據。
由于訪問內部FLASH的速度要比外部的SPI-FLASH快得多,所以在緊急狀態下常常會使用內部FLASH存儲關鍵記錄;為了防止應用程序被抄襲, 有的應用會禁止讀寫內部FLASH中的內容,或者在第一次運行時計算加密信息并記錄到某些區域,然后刪除自身的部分加密代碼,這些應用都涉及到內部FLASH的操作。
1.1 內部FLASH的構成
W55MH32的內部FLASH包含主存儲器、系統存儲器以及選項字節區域, 它們的地址分布及大小見下表,W55MH32大容量產品內部FLASH的構成:
模塊 | 名稱 | 地址 | 大小 |
主存儲塊 | 頁 0 | 0x0800 0000 - 0x0800 07FF | 2K |
頁 1 | 0x0800 0800 - 0x0800 0FFF | 2K | |
頁 2 | 0x0800 1000 - 0x0800 17FF | 2K | |
頁 3 | 0x0800 1800 - 0x0800 1FFF | 2K | |
… | … | … | |
頁 255 | 0x0807 F800 - 0x0807 FFFF | 2K | |
信息塊 | 系統存儲器 | 0x1FFF F000 - 0x1FFF F7FF | 2K |
選擇字節 | 0x1FFF F000 - 0x1FFF F7FF | 16 | |
閃存存儲器接口寄存器 | FLASH_ACR | 0x4002 2000 - 0x4002 2003 | 4 |
FALSH_KEYR | 0x4002 2004 - 0x4002 2007 | 4 | |
FLASH_OPTKEYR | 0x4002 2008 - 0x4002 200B | 4 | |
FLASH_SR | 0x4002 200C - 0x4002 200F | 4 | |
FLASH_CR | 0x4002 2010 - 0x4002 2013 | 4 | |
FLASH_AR | 0x4002 2014 - 0x4002 2017 | 4 | |
保留 | 0x4002 2018 - 0x4002 201F | 4 | |
FLASH_OBR | 0x4002 201C - 0x4002 201F | 4 | |
FLASH_WRPR | 0x4002 2020 - 0x4002 2023 | 4 |
主存儲
型號 | W55MH32L | W55MH32Q |
Flash (KB) | 1024 | 1024 |
SRAM (KB) | 96 | 96 |
定時器 | ||
高級 | 2 | 2 |
通用 | 10 | 10 |
基本 | 2 | 2 |
通信接口 | ||
SPI | 2 | 2 |
I2C | 2 | 2 |
USART/UART | 5 | 3 |
USB | 1 | 1 |
CAN | 1 | 1 |
SDIO | 1 | - |
Ethernet | 1 | 1 |
GPIO 端口 | 66 | 36 |
12 位 ADC (通道數) | 3(12 個通道) | 3(12 個通道) |
12 位 DAC (通道數) | 2(2 個通道) | 2(2 個通道) |
隨機數模塊 | 支持 | 支持 |
硬件加密算法單元 | 支持 | 支持 |
頁大小 (K 字節) | 4 | 4 |
CPU 頻率 | 216M | 216M |
工作電壓 | 2.0-3.6V | 2.0-3.6V |
工作溫度 | -40-+85℃ | -40-+85℃ |
系統存儲區
系統存儲區是用戶不能訪問的區域,它在芯片出廠時已經固化了啟動代碼,它負責實現串口、USB以及CAN等ISP燒錄功能。
選項字節
選項字節用于配置FLASH的讀寫保護、待機/停機復位、軟件/硬件看門狗等功能,這部分共16字節。可以通過修改FLASH的選項控制寄存器修改。
2 對內部FLASH的寫入過程
2.1 解鎖
由于內部FLASH空間主要存儲的是應用程序,是非常關鍵的數據,為了防止誤操作修改了這些內容,芯片復位后默認會給控制寄存器FLASH_CR上鎖, 這個時候不允許設置FLASH的控制寄存器,從而不能修改FLASH中的內容。
2.2 頁擦除
在寫入新的數據前,需要先擦除存儲區域,W55MH32提供了頁(扇區)擦除指令和整個FLASH擦除(批量擦除)的指令,批量擦除指令僅針對主存儲區。
頁擦除的過程如下:
檢查 FLASH_SR 寄存器中的“忙碌寄存器位 BSY”,以確認當前未執行任何 Flash 操作;
在 FLASH_CR 寄存器中,將“激活頁擦除寄存器位PER ”置 1;
用FLASH_AR寄存器選擇要擦除的頁;
將 FLASH_CR 寄存器中的“開始擦除寄存器位 STRT ”置 1,開始擦除;
等待 BSY 位被清零時,表示擦除完成。
2.3 寫入數據
擦除完畢后即可寫入數據,寫入數據的過程并不是僅僅使用指針向地址賦值,賦值前還還需要配置一系列的寄存器,步驟如下:
檢查 FLASH_SR 中的 BSY 位,以確認當前未執行任何其它的內部 Flash 操作;
將 FLASH_CR 寄存器中的 “激活編程寄存器位PG” 置 1;
向指定的FLASH存儲器地址執行數據寫入操作,每次只能以16位的方式寫入;
等待 BSY 位被清零時,表示寫入完成。
3 查看工程的空間分布
由于內部FLASH本身存儲有程序數據,若不是有意刪除某段程序代碼,一般不應修改程序空間的內容, 所以在使用內部FLASH存儲其它數據前需要了解哪一些空間已經寫入了程序代碼,存儲了程序代碼的扇區都不應作任何修改。 通過查詢應用程序編譯時產生的“*.map”后綴文件,可以了解程序存儲到了哪些區域, 它在工程中的打開方式見下圖,打開工程的map文件 , 也可以到工程目錄中的“Listing”文件夾中找到,關于map文件的詳細說明可參考《MDK的編譯過程及文件類型》章節。
3.1 程序ROM的加載與執行空間
上述說明中有兩段分別以“Load Region LR_ROM1”及“Execution Region ER_IROM1”開頭的內容, 它們分別描述程序的加載及執行空間。 在芯片剛上電運行時,會加載程序及數據,例如它會從程序的存儲區域加載到程序的執行區域,還把一些已初始化的全局變量從ROM復制到RAM空間, 以便程序運行時可以修改變量的內容。加載完成后,程序開始從執行區域開始執行。
在上面map文件的描述中,我們了解到加載及執行空間的基地址(Base)都是0x08000000,它正好是W55MH32內部FLASH的首地址, 即W55MH32的程序存儲空間就直接是執行空間;它們的大小(Size)分別為0x000017a8及0x0000177c, 執行空間的ROM比較小的原因就是因為部分RW-data類型的變量被拷貝到RAM空間了; 它們的最大空間(Max)均為0x00080000,即512K字節,它指的是內部FLASH的最大空間。
計算程序占用的空間時,需要使用加載區域的大小進行計算,本例子中應用程序使用的內部FLASH是從0x08000000至(0x08000000+0x000017a8)地址的空間區域。
3.2 ROM空間分布表
在加載及執行空間總體描述之后,緊接著一個ROM詳細地址分布表,它列出了工程中的各個段(如函數、常量數據)所在的地址BaseAddr及占用的空間Size, 列表中的Type說明了該段的類型,CODE表示代碼,DATA表示數據,而PAD表示段之間的填充區域,它是無效的內容, PAD區域往往是為了解決地址對齊的問題。
觀察表中的最后一項,它的基地址是0x0800175c,大小為0x00000020,可知它占用的最高的地址空間為0x0800177c,跟執行區域的最高地址0x0000177c一樣, 但它們比加載區域說明中的最高地址0x80017a8要小,所以我們以加載區域的大小為準。 對比表 W55MH32大容量產品內部FLASH的構成 的內部FLASH頁地址分布表, 可知僅使用頁0至頁2就可以完全存儲本應用程序,所以從頁3(地址0x08001800)后的存儲空間都可以作其它用途,使用這些存儲空間時不會篡改應用程序空間的數據。
4 操作內部FLASH的庫函數
為簡化編程,W55MH32標準庫提供了一些庫函數,它們封裝了對內部FLASH寫入數據操作寄存器的過程。
4.1 FLASH解鎖、上鎖函數
對內部FLASH解鎖、上鎖的函數見代碼清單:FLASH-2:
代碼清單:FLASH-2 FLASH解鎖、上鎖
#define FLASH_KEY1 ((uint32_t)0x45670123) #define FLASH_KEY2 ((uint32_t)0xCDEF89AB) /** * @brief 對FLASH控制寄存器解鎖,使能訪問 * @param None * @retval None */ void FLASH_Unlock(void) { if ((FLASH->CR & FLASH_CR_LOCK) != RESET) { /* 寫入確認驗證碼 */ FLASH->KEYR = FLASH_KEY1; FLASH->KEYR = FLASH_KEY2; } } /** * @brief 對FLASH控制寄存器上鎖,禁止訪問 * @param None * @retval None */ void FLASH_Lock(void) { /* 設置FLASH寄存器的LOCK位 */ FLASH->CR |= FLASH_CR_LOCK; }
解鎖的時候,它對FLASH_KEYR寄存器寫入兩個解鎖參數,上鎖的時候,對FLASH_CR寄存器的FLASH_CR_LOCK位置1。
4.2 設置操作位數及頁擦除
解鎖后擦除扇區時可調用FLASH_EraseSector完成,見代碼清單:FLASH-3:
代碼清單:FLASH-3 擦除扇區
/** * @brief 擦除指定的頁 * @param Page_Address: 要擦除的頁地址. * @retval FLASH Status: 可能的返回值: FLASH_BUSY, FLASH_ERROR_PG, * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. */ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) { FLASH_Status status = FLASH_COMPLETE; /* 檢查參數 */ assert_param(IS_FLASH_ADDRESS(Page_Address)); /*...此處省略XL超大容量芯片的控制部分*/ /* 等待上一次操作完成 */ status = FLASH_WaitForLastOperation(EraseTimeout); if (status == FLASH_COMPLETE) { /* 若上次操作完成,則開始頁擦除 */ FLASH->CR|= CR_PER_Set; FLASH->AR = Page_Address; FLASH->CR|= CR_STRT_Set; /* 等待操作完成 */ status = FLASH_WaitForLastOperation(EraseTimeout); /* 復位 PER 位 */ FLASH->CR &= CR_PER_Reset; } /* 返回擦除結果 */ return status; }
本函數包含一個輸入參數用于設置要擦除的頁地址,即目標頁的在內部FALSH的首地址,函數獲取地址后,根據前面的流程檢查狀態位、 向控制寄存器FLASH_CR及地址寄存器FLASH_AR寫入參數,配置開始擦除后,需要等待一段時間,函數中使用使用FLASH_WaitForLastOperation()等待, 擦除完成的時候才會退出FLASH_EraseSector()函數。
4.3 寫入數據
對內部FLASH寫入數據不像對SDRAM操作那樣直接指針操作就完成了,還要設置一系列的寄存器, 利用FLASH_ProgramWord()和FLASH_ProgramHalfWord()函數可按字、半字的單位單位寫入數據, 見代碼清單:FLASH-4:
代碼清單:FLASH-4 寫入數據
/** * @brief 向指定的地址寫入一個字的數據(32位) * @param Address: 要寫入的地址 * @param Data: 要寫入的數據 * @retval FLASH Status: 可能的返回值: FLASH_ERROR_PG, * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. */ FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data) { FLASH_Status status = FLASH_COMPLETE; __IO uint32_t tmp = 0; /* 檢查參數 */ assert_param(IS_FLASH_ADDRESS(Address)); /*...此處省略XL超大容量芯片的控制部分*/ /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(ProgramTimeout); if (status == FLASH_COMPLETE) { /* 若上次操作完成,則開始頁入低16位的數據(輸入參數的第1部分) */ FLASH->CR |= CR_PG_Set; *(__IO uint16_t*)Address = (uint16_t)Data; /* 等待上一次操作完成 */ status = FLASH_WaitForLastOperation(ProgramTimeout); if (status == FLASH_COMPLETE) { /* 若上次操作完成,則開始頁入高16位的數據(輸入參數的第2部分) */ tmp = Address + 2; *(__IO uint16_t*) tmp = Data >> 16; /* 等待操作完成 */ status = FLASH_WaitForLastOperation(ProgramTimeout); /* 復位 PG 位 */ FLASH->CR &= CR_PG_Reset; } else { /* 復位 PG 位 */ FLASH->CR &= CR_PG_Reset; } } /* 返回寫入結果 */ return status; }
從函數代碼可了解到,它設置FLASH->CR 寄存器的PG位允許寫入后,使用16位的指針往指定的地址寫入數據,由于每次只能按16位寫入, 所以這個按字寫入的過程使用了兩次指針賦值,分別寫入指定數據的低16位和高16位,每次賦值操作后,調用FLASH_WaitForLastOperation()函數等待寫操作完畢。 標準庫里還提供了FLASH_ProgramHalfWord()函數用于每次寫入半個字,即16位,該函數內部的執行過程類似。
5 讀寫內部FLASH
5.1 代碼分析
1.宏定義
#define FLASH_TEST_ADDR (0x0800F400) // 測試用Flash地址(32KB處)
地址選擇:需確保該地址未被程序代碼占用,且屬于可擦寫區域。
2.主函數邏輯
int main(void) { // 初始化系統時鐘、串口等 delay_init(); UART_Configuration(115200); printf("系統時鐘信息..."); while (1) { FLASH_EraseProgram(number++); // 執行擦除編程測試 if (number == 0xFFFFFFFF) // 防止溢出,結束測試 { printf("Test Endn"); while (1); } } }
無限循環:持續測試,直到number溢出。
3.FLASH 擦除與編程函數
void FLASH_EraseProgram(uint32_t number) { // 1. 擦除頁測試 SYSTICK_Reset(); FLASH_ErasePage(FLASH_TEST_ADDR); if (擦除成功) printf("擦除時間:%d msn", 計算時間); else 進入死循環; // 2. 編程半字測試 SYSTICK_Reset(); for (i = 0; i < 512; i++) FLASH_ProgramHalfWord(地址+i*2, 0x5A5A); if (編程成功) printf("編程時間:%d msn", 計算時間); else 進入死循環; }
擦除操作:使用FLASH_ErasePage擦除整頁(通常為 2KB)。
編程操作:逐個半字寫入0x5A5A,驗證寫入正確性。
4.時間測量函數
void SYSTICK_Reset(void) { SysTick->CTRL = 0; // 停止定時器 SysTick->LOAD = 0xFFFFFF; // 最大計數值 SysTick->VAL = 0; // 清零當前值 SysTick->CTRL = 0x05; // 使能定時器,選擇HCLK時鐘 }
時間計算:通過0xFFFFFF - SysTick->VAL得到操作耗時(單位:時鐘周期)。
5. 串口配置函數
void UART_Configuration(uint32_t bound) { // 使能USART1和GPIOA時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); // 配置TX引腳(PA9)為復用推挽輸出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化USART1參數(波特率、數據位等) USART_Init(USART_TEST, &USART_InitStructure); USART_Cmd(USART_TEST, ENABLE); }
功能:配置 USART1 為 115200 波特率,用于調試輸出。
5.2 下載驗證
6 FLASH_Eeprom
6.1 代碼分析
1.主函數 main()
int main(void) { uint8_t datatemp[SIZE], i; delay_init(); UART_Configuration(115200); // 打印系統時鐘信息 RCC_GetClocksFreq(&clocks); printf("SYSCLK: %3.1fMhz...n", ...); printf("FLASH EEPROM Tset.n"); // 循環讀寫FLASH while (1) { WIZFLASH_Write(FLASH_SAVE_ADDR, (u16 *)TEXT_Buffer, SIZE); // 寫入數據 WIZFLASH_Read(FLASH_SAVE_ADDR, (u16 *)datatemp, SIZE); // 讀取數據 // 打印錯誤(應逐個字符處理) for (i = 0; i < SIZE; i++) { printf("%sn", datatemp); } memset(datatemp, 0x00, sizeof(datatemp)); // 清空數組 delay_ms(1000); // 延時 } }
2.串口配置 UART_Configuration
void UART_Configuration(uint32_t bound) { // 使能時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); // 配置串口引腳 GPIO_Init(GPIOA, &GPIO_InitStructure); // PA9(發送)復用推挽,PA10(接收)浮空輸入 // 配置串口參數:115200波特率、8位數據等 USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); // 使能串口 }
配置 USART1,用于輸出調試信息。
3.串口重定向
int SER_PutChar(int ch) { while (!USART_GetFlagStatus(USART1, USART_FLAG_TC)); // 等待發送完成 USART_SendData(USART1, (uint8_t)ch); return ch; } int fputc(int c, FILE *f) { if (c == 'n') SER_PutChar('r'); // 換行處理 return SER_PutChar(c); // 實現printf通過串口輸出 }
4. FLASH 操作
依賴eeprom.h的WIZFLASH_Write和WIZFLASH_Read,需確保其實現 FLASH 底層操作(擦除、讀寫等)。
地址:FLASH_SAVE_ADDR 0X08008000,需在可用 FLASH 空間內。
6.2 下載驗證
-
單片機
+關注
關注
6065文章
44946瀏覽量
648081 -
FlaSh
+關注
關注
10文章
1672瀏覽量
151184 -
存儲器
+關注
關注
38文章
7641瀏覽量
166654 -
定時器
+關注
關注
23文章
3297瀏覽量
117454
發布評論請先 登錄
【ZYNQ Ultrascale+ MPSOC FPGA教程】第二十九章PL端AXI GPIO的使用

《DNK210使用指南 -CanMV版 V1.0》第二十九章 音頻錄制實驗
PCB設計規范2010最新版
眾想科技-劉洋邊講邊寫STM32視頻教程 15.RS232串口通訊實驗
《BOSCH汽車電氣與電子 》(中文第一版)(完整版)
「正點原子Linux連載」第二十九章LCD背光調節實驗
「正點原子STM32Mini板資料連載」第二十九章 無線通信實驗
「正點原子NANO STM32F103開發板資料連載」第二十九章 內存管理實驗
「ALIENTEK 探索者 STM32F407 開發板資料連載」第二十九章 IIC 實驗
模擬數字轉換器ADC編程指南
CH32V103基礎教程30-ADC(多通道DMA讀取方式)
模擬電路網絡課件 第二十九節:專用型集成電路運算放大器

蔡司亮相第二十九屆中國國際口腔設備材料展覽會,邀您共探口腔行業未來

評論