1MM32SPIN0230的USART簡介
MM32SPIN0230通用同步/異步收發(fā)器(USART)可以靈活地與外部設(shè)備進行全雙工數(shù)據(jù)交換。通過內(nèi)置波特率(包含整數(shù)及小數(shù)設(shè)定)發(fā)生器, USART 可以支持寬范圍的波特率。
USART 支持異步模式(UART)、同步模式。其中 UART 支持單線半雙工通信, UART 和同步模式支持調(diào)制解調(diào)器(CTS/RTS)操作。
2MM32SPIN0230的USART功能框圖
USART 的功能框圖如下圖1所示,由寄存器相關(guān)的控制單元、收發(fā)數(shù)據(jù)控制器、時鐘控制器、硬件流控制單元以及引腳控制邏輯單元組成。
圖1 MM32SPIN0230 USART功能框圖
3USART的同步模式
通過配置,USART_CR1.SAS 位為‘1’來使能同步模式(時鐘引腳功能將同時有效)。
在同步模式下, USART_CR3.HDSEL 位應配置為‘0’。
同步模式支持主模式和從模式:主模式時使用內(nèi)部波特率生成器生成的時鐘,同時輸出時鐘;從模式時由 SCLK 引腳輸入時鐘。USART 在同步模式下,能與 SPI 實現(xiàn)數(shù)據(jù)通信(此時,用戶應配置 SPI 與USART 的時鐘極性、時鐘相位為一致)。
4USART的時鐘
USART的時鐘掛載在APB1總線上,由APB1總線提供工作時鐘,以配置 USART_CR2.CLKEN 位為‘1’來使能時鐘引腳功能, 同時根據(jù) USART_CR3.CKINE 位配置來選擇使用內(nèi)部波特率時鐘或從 SCLK 引腳輸入時鐘,以進行數(shù)據(jù)通信。
當選擇內(nèi)部波特率時鐘時,可通過 SCLK 引腳輸出同步時鐘。
1 幀數(shù)據(jù)的收發(fā)包含 8 個時鐘脈沖。
當 RE 和 TE 都為‘0’, 時鐘輸出會停止, 并固定在 USART_CR2.CPOL 配置的電平。
通過配置 USART_CR2.CPOL 位選擇時鐘極性。
通過配置 USART_CR2.CPHA 位選擇外部時鐘相位。
5USART時鐘同步功能
SCLK 引腳作為發(fā)送器的時鐘輸出時,僅在數(shù)據(jù)段輸出時鐘,一幀數(shù)據(jù)輸出 8 個時鐘脈沖,最后一位發(fā)送完后,通信線保持最后一位的值,時鐘輸出固定在高電平或低電平(由 CPOL 位決定)。
USART 接收器在同步模式下的工作方式與異步模式下不同。如果 RE=1,則數(shù)據(jù)在 SCLK 變化邊沿上采樣(上升或下降沿,取決于 CPOL 和 CPHA 位配置情況),而不會進行任何過采樣。此時必須確保足夠的建立時間和保持時間,以符合時序要求(類同于 SPI 協(xié)議)。
內(nèi)部時鐘源時,內(nèi)部波特率生成器生成的波特率計算公式為:
其中通信波特率的單為 MBps;PCLK 為內(nèi)部時鐘源的頻率;MFD 為 波特率寄存器 USART_BRR 中整數(shù)分頻(注意, 在同步模式下應配置 MFD ≥ 2, 且小數(shù)分頻 FFD 無效, 用戶應配置 FFD[3:0] 位為4’h0)。
使用內(nèi)部時鐘源且 MFD=2 時,同步模式的最高波特率為 PCLK/8(MBps)。
外部時鐘源時,要求外部輸入時鐘的最大頻率為 PCLK/8( MHz),此時最高波特率也為 PCLK/8(MBps)。
6USART的特性描述
如下圖2所示為USART的數(shù)據(jù)幀類型示意圖,當USART用作同步通信時,可通過配置同步時鐘引腳即USART_SCK引腳的時鐘極性和時鐘相位實現(xiàn)SPI功能的通信。此時沒有起始位,校驗位以及停止位功能,僅支持8位。通過配置時鐘極性CPOL和時鐘相位CPHA可以實現(xiàn)基于USART的SPI通信的工作模式0-3。
圖2 MM32SPIN0230 USART數(shù)據(jù)幀類型示意圖
7USART同步模式實現(xiàn)SPI通信的配置步驟
MM32SPIN0230有一路USART1,USART1同步模式實現(xiàn)SPI通信的配置步驟如下所示。
使能USART1的時鐘和用作USART1的GPIO時鐘
配置GPIO復用為USART1功能
配置一路普通GPIO為推挽輸出模式用于USART同步通信的CS引腳
配置 USART1_CR1.SAS 位為‘1’來使能同步模式(時鐘引腳功能將同時有效)
配置 USART1_CR1.MLS 位為‘0’或 為‘1’來選擇數(shù)據(jù)格式為LSB或MSB
配置 USART1_CR3.HDSEL位為‘0’來選擇數(shù)據(jù)通信為全雙工模式
配置 USART1_CR2.CPOL位為‘0’ 或 為‘1’設(shè)置時鐘空閑時為低電平或高電平
配置 USART1_CR2.CPHA位為‘0’ 或 為‘1’設(shè)置在時鐘第一個變化沿捕獲數(shù)據(jù)或在時鐘第二個變化沿捕獲數(shù)據(jù)
配置USART1_BRR波特率寄存器小數(shù)分頻FFD[3:0]為0(USART同步模式,波特率小數(shù)分頻無效)
配置USART1同步模式波特率,USART1_BRR波特率寄存器整數(shù)分頻MFD[15:0],需配置MFD>=2
使能USART1接收和發(fā)送中斷以及NVIC中斷優(yōu)先級(如有使用到USART接收和發(fā)送中斷功能)
使能USART1功能
編寫應用層USART1同步通信模式下數(shù)據(jù)接收、數(shù)據(jù)發(fā)送函數(shù)以及中斷處理接收和中斷發(fā)送函數(shù)。(如使能了接收和發(fā)送中斷功能)
8USART同步模式實現(xiàn)SPI通信
讀寫W25Q32存儲器
根據(jù)以上配置步驟USART1同步模式實現(xiàn)SPI通信的配置步驟,使用MM32SPIN0230的庫函數(shù)配置USART1為同步模式主機功能實現(xiàn)SPI通信讀寫W25Q32 Flash存儲器,分別配置GPIO PA11復用為USART1_TX功能,PA12復用為USART1_RX功能,PB2復用為USART1_SCLK功能(注:USART1用作同步模式主機功能PA11 USART1_TX當做SPI_MOSI引腳使用,PA12 USART1_RX當做SPI_MISO引腳使用,PB2 USART1_SCLK當做SPI_SCL使用)并配置GPIO PB4為推挽輸出模式當做SPI_CSS引腳使用。
USART1同步通信模式實現(xiàn)SPI通信的初始化代碼如下所示:
#defineSPI_FLASH_CS_H()GPIO_WriteBit(GPIOB,GPIO_Pin_4,Bit_SET) #defineSPI_FLASH_CS_L()GPIO_WriteBit(GPIOB,GPIO_Pin_4,Bit_RESET) uint16_tDeviceID=0;/*W25Q64DeviceID*/ uint32_tJEDEC_ID=0;/*W25Q64JEDECID*/ voidUSART_Configure(uint32_tBaudrate) { GPIO_InitTypeDefGPIO_InitStruct; NVIC_InitTypeDefNVIC_InitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART1,ENABLE); USART_SyncMasterConfig(USART1,USART_Clock_Idle_Low,USART_Clock_Phase_1Edge,Baudrate);/*USARTInitconfigureSPIMode0*/ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE); GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_5);/*PA11AFUSART_TXforSPI_MOSIfunction*/ GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_5);/*PA12AFUSART_RXforSPI_MISOfunction*/ GPIO_PinAFConfig(GPIOB,GPIO_PinSource2,GPIO_AF_6);/*PB2AFUSART_SCLKforSPI_SCLKfunction*/ GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_High; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;/*PB4forSPI_CSSfunction*/ GPIO_Init(GPIOB,&GPIO_InitStruct); SPI_FLASH_CS_H();/*SetPB4forSPI_CSSHighleve*/ GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin=GPIO_Pin_11; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_High; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_Init(GPIOA,&GPIO_InitStruct); GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin=GPIO_Pin_12; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_High; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_FLOATING; GPIO_Init(GPIOA,&GPIO_InitStruct); GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_High; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_Init(GPIOB,&GPIO_InitStruct); NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn; NVIC_InitStruct.NVIC_IRQChannelPriority=0x01; NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStruct); USART_Cmd(USART1,ENABLE); }
USART1同步通信模式中斷接收數(shù)據(jù),代碼如下所示:
voidUSART_Synchronous_RxData_Interrupt(uint8_t*Buffer,uint8_tLength) { uint8_ti=0; for(i=0;i
USART1同步通信模式中斷發(fā)送數(shù)據(jù),代碼如下所示:
voidUSART_Synchronous_TxData_Interrupt(uint8_t*Buffer,uint8_tLength) { uint8_ti=0; for(i=0;i
USART1同步通信模式讀SPI Flash,代碼如下所示:
voidSPI_FLASH_RxBuffer(uint8_t*Buffer,uint8_tLength) { if(Length) { USART_Synchronous_RxData_Interrupt(Buffer,Length); } }
USART1同步通信模式寫SPI Flash,代碼如下所示:
voidSPI_FLASH_TxBuffer(uint8_t*Buffer,uint8_tLength) { if(Length) { USART_Synchronous_TxData_Interrupt(Buffer,Length); } }
USART1同步通信模式處理中斷接收和發(fā)送命令和讀寫數(shù)據(jù),即讀寫SPI Flash,代碼如下所示:
voidUSART1_IRQHandler(void) { uint8_tRxData=0; if(RESET!=USART_GetITStatus(USART1,USART_IT_RXNE)) { RxData=USART_ReceiveData(USART1); if(0==USART_RxStruct.CompleteFlag) { USART_RxStruct.Buffer[USART_RxStruct.CurrentCount++]=RxData; if(USART_RxStruct.CurrentCount==USART_RxStruct.Length) { USART_RxStruct.CompleteFlag=1; USART_ITConfig(USART1,USART_IT_RXNE,DISABLE); USART_ITConfig(USART1,USART_IT_TXE,DISABLE); } } } if(RESET!=USART_GetITStatus(USART1,USART_IT_TXE)) { if(0==USART_TxStruct.CompleteFlag) { USART_SendData(USART1,USART_TxStruct.Buffer[USART_TxStruct.CurrentCount++]); if(USART_TxStruct.CurrentCount==USART_TxStruct.Length) { USART_TxStruct.CompleteFlag=1; } } } }
USART1同步通信模式SPI Flash寫使能,代碼如下所示:
voidSPI_FLASH_WriteEnable(void) { uint8_tCommand=0x06; SPI_FLASH_CS_L(); SPI_FLASH_TxBuffer(&Command,0x01); SPI_FLASH_CS_H(); }
USART1同步通信模式判斷SPI Flash是否處于總線忙轉(zhuǎn)態(tài),代碼如下所示:
voidSPI_FLASH_WaitBusy(void) { uint8_tStatus=0; uint8_tCommand[2]= { 0x05,0xFF }; uint32_tTimeout=0; do { SPI_FLASH_CS_L(); SPI_FLASH_TxBuffer(Command,0x02); SPI_FLASH_RxBuffer(&Status,0x01); SPI_FLASH_CS_H(); if(Timeout++>0xFFFF) { break; } } while(Status&0x01); }
USART1同步通信模式讀SPI Flash DeviceID,代碼如下所示:
voidSPI_FLASH_ReadDeviceID(void) { uint8_tCommand[4]= { 0x90,0xFF,0xFF,0x00 }; uint8_tBuffer[2]; SPI_FLASH_CS_L(); SPI_FLASH_TxBuffer(Command,0x04); SPI_FLASH_RxBuffer(Buffer,0x02); SPI_FLASH_CS_H(); DeviceID=Buffer[0]; DeviceID<<=?8; ????DeviceID??|=?Buffer[1]; }
USART1同步通信模式讀SPI Flash JEDEC ID,代碼如下所示:
voidSPI_FLASH_ReadJEDEC_ID(void) { uint8_tCommand=0x9F; uint8_tBuffer[3]; SPI_FLASH_CS_L(); SPI_FLASH_TxBuffer(&Command,0x01); SPI_FLASH_RxBuffer(Buffer,0x03); SPI_FLASH_CS_H(); JEDEC_ID=Buffer[0]; JEDEC_ID<<=?8; ????JEDEC_ID??|=?Buffer[1]; ????JEDEC_ID?<<=?8; ????JEDEC_ID??|=?Buffer[2]; }
USART1同步通信模式SPI Flash 扇區(qū)擦除,代碼如下所示:
voidSPI_FLASH_SectorErase(uint16_tIndex) { uint8_tCommand[4]= { 0x20,0x00,0x00,0x00 }; uint32_tAddress=Index*4*1024; Command[1]=(uint8_t)((Address>>16)&0x000000FF); Command[2]=(uint8_t)((Address>>8)&0x000000FF); Command[3]=(uint8_t)((Address>>0)&0x000000FF); SPI_FLASH_WriteEnable(); SPI_FLASH_CS_L(); SPI_FLASH_TxBuffer(Command,4); SPI_FLASH_CS_H(); SPI_FLASH_WaitBusy(); }
USART1同步通信模式快速讀SPI Flash,代碼如下所示:
voidSPI_FLASH_FastRead(uint32_tAddress,uint8_t*Buffer,uint32_tLength) { uint8_tCommand[5]= { 0x0B,0x00,0x00,0x00,0xFF }; Command[1]=(uint8_t)((Address>>16)&0x000000FF); Command[2]=(uint8_t)((Address>>8)&0x000000FF); Command[3]=(uint8_t)((Address>>0)&0x000000FF); SPI_FLASH_CS_L(); SPI_FLASH_TxBuffer(Command,0x05); SPI_FLASH_RxBuffer(Buffer,Length); SPI_FLASH_CS_H(); }
USART1同步通信模式頁編程SPI Flash,代碼如下所示:
voidSPI_FLASH_PageProgram(uint32_tAddress,uint8_t*Buffer,uint32_tLength) { uint8_tCommand[4]= { 0x02,0x00,0x00,0x00 }; Command[1]=(uint8_t)((Address>>16)&0x000000FF); Command[2]=(uint8_t)((Address>>8)&0x000000FF); Command[3]=(uint8_t)((Address>>0)&0x000000FF); SPI_FLASH_WriteEnable(); SPI_FLASH_CS_L(); SPI_FLASH_TxBuffer(Command,0x04); SPI_FLASH_TxBuffer(Buffer,Length); SPI_FLASH_CS_H(); SPI_FLASH_WaitBusy(); }
驗證USART1同步通信模式讀寫W25Q32 SPI Flash,本實例在MDK Keil環(huán)境下編譯驗演示,在main函數(shù)中調(diào)用讀寫W25Q32 SPI Flash的函數(shù),代碼如下所示:
intmain(void) { uint8_ti=0; uint8_tEraseBuffer[100],WriteBuffer[100],ReadBuffer[100]; USART_RxStruct.CompleteFlag=0; USART_TxStruct.CompleteFlag=1; USART_Configure(8000000);/*ConfigureUSARTRead/writeSPIFlashbaudrate8M*/ SPI_FLASH_ReadDeviceID(); SPI_FLASH_ReadJEDEC_ID(); SPI_FLASH_SectorErase(0);/*USARTerasestheSPIFlashsector*/ SPI_FLASH_FastRead(0,EraseBuffer,100); for(i=0;i100;?i++) ????{ ????????WriteBuffer[i]?=?i; ????} ????SPI_FLASH_PageProgram(0,?WriteBuffer,?100);?/*?USART?page?programming?SPI?Flash?writes?100?bytes?of?data?*/ ????SPI_FLASH_FastRead(0,?ReadBuffer,?100);?/*?The?USART?reads?100?bytes?of?data?written?to?the?SPI?Flash?*/ ????PLATFORM_DeInitUSART1(); ????PLATFORM_InitConsole(115200); ????printf(" "); ????printf(" SPI?Flash?DeviceID?:?0x%04x",?DeviceID); ????printf(" SPI?Flash?JEDEC?ID?:?0x%06x",?JEDEC_ID); ????printf(" SPI?FLASH?Sector?Erase..."); ????printf(" SPI?FLASH?Read..."); ????for?(i?=?0;?i?100;?i++) ????{ ????????if?(0?==?(i?%?10)) ????????{ ????????????printf(" "); ????????} ????????printf("0x%02x?",?EraseBuffer[i]); ????} ????printf(" SPI?FLASH?Page?Program..."); ????printf(" SPI?FLASH?Read..."); ????for?(i?=?0;?i?100;?i++) ????{ ????????if?(0?==?(i?%?10)) ????????{ ????????????printf(" "); ????????} ????????printf("0x%02x?",?ReadBuffer[i]); ????} ????while?(1) ????{ ????} }
使用MM32-LINK Mini調(diào)試下載工具連接MM32SPIN0230 MiniBoard,板子USB口連接USB串口工具連接到電腦端,打開串口調(diào)試助手,并配置串口波特率為115200,按快捷鍵F7編譯工程,編譯成功后按快捷鍵F8下載程序到MM32SPIN0230 MiniBoard,如下圖3所示,串口調(diào)試助手分別打印輸出了W25Q32 SPI Flash的DeviceID和JEDEC ID,USART1同步通信模式扇區(qū)擦除W25Q32 SPI Flash數(shù)據(jù)后讀出的100字節(jié)0xFF數(shù)據(jù)(說明擦除成功),以及USART1同步通信模式寫入到W25Q32 SPI Flash中的0-99共100字節(jié)數(shù)據(jù)(每行10字節(jié),共10行),讀出了寫入的0-99共100字節(jié)數(shù)據(jù),寫入和讀出的數(shù)據(jù)一致即0-99對應十六進制為0x00-0x63。
圖3 測試結(jié)果
審核編輯:湯梓紅
-
FlaSh
+關(guān)注
關(guān)注
10文章
1614瀏覽量
147655 -
存儲器
+關(guān)注
關(guān)注
38文章
7430瀏覽量
163514 -
SPI
+關(guān)注
關(guān)注
17文章
1688瀏覽量
91202 -
uart
+關(guān)注
關(guān)注
22文章
1219瀏覽量
101118 -
異步收發(fā)器
+關(guān)注
關(guān)注
0文章
36瀏覽量
10834
發(fā)布評論請先 登錄
相關(guān)推薦
評論