本帖最后由 sh007 于 2011-11-17 13:07 编辑
拿到板子 本来想尽快学习使用,但是工作实在忙得没能按计划进行。最近也用到SPI FLASH,所以就先忽悠这个吧。
板子上的串口 看来挺多人跟我一样 打印不了的。我用的是USBTOCOM的线,看资料调了一下串口,居然没反应,再我插拔串口线时,数据出来了,很奇怪,看了原理图后发现,串口的三个控制端也都引出,而且DTR还接了复位信号控制。但拔出来后DTR脚接触不好时,通讯就正常了。所以就先把R5,R6先焊掉,以后再研究串口控制。先不说上代码先。
SPI_PDMA_W25Q16BV.C主控函数文件
设置主频50MHz,SPI 12MHz,然后对SPI FLASH 擦除,写和读进行操作- /*---------------------------------------------------------------------------------------------------------*/
- /* */
- /* Copyright(c) 2011 Nuvoton Technology Corp. All rights reserved. */
- /*---------------------------------------------------------------------------------------------------------*/
- #include <stdio.h>
- #include "NUC1xx.h"
- #include "DrvUART.h"
- #include "DrvSYS.h"
- #include "DrvSPI.h"
- #include "DrvPDMA.h"
- #include "SPI_FLASH_PDMA.h"
- #include "Driver\DrvGPIO.h"
- #define RW_LEN 80
- uint8_t SPI_PDMA_RXBuf[RW_LEN];
- uint8_t SPI_PDMA_TXBuf[RW_LEN];
- void RCC_Config(void);
- void UART_Config(void);
- int main()
- {
- uint16_t writenum,readnum;
- RCC_Config();
- UART_Config();
- SPI_Init();
- PDMA_Init(RW_LEN);
- printf("\n");
- printf("+----------------------------------------------------------------------+\n");
- printf("| NUC120助学板之SPI PDMA FLASH---W25Q16BV |\n");
- printf("+----------------------------------------------------------------------+\n");
- printf("***NUC120***配置主频为: %2d MHz.\n",DrvSYS_GetHCLKFreq()/1000000);
- printf("---SPI1主机模式,频率为: %2d MHz.\n", DrvSPI_GetClock1Freq(eDRVSPI_PORT1)/1000000);
- printf("开始擦除整片FLASH...\n");
- SPIFlash_ChipErase();
- SPIFlash_WaitReady();
- printf("整片FLASH擦除完成。\n");
- for(writenum=0;writenum<RW_LEN;writenum++)
- {
- SPI_PDMA_TXBuf[writenum]= writenum;
- SPI_PDMA_RXBuf[writenum]= 0;
- }
- DrvSYS_Delay(500000);
- printf("开始写入数据:\n");
- // Trigger PDMA specified Channel
- DrvPDMA_CHEnableTransfer(eDRVPDMA_CHANNEL_1);
- SPIFlash_PDMA_PageProgram(0x0);
- for(writenum=0;writenum<RW_LEN;writenum++)
- {
- if(writenum%16 == 0 ) printf("\n");
- printf("0x%x,", SPI_PDMA_TXBuf[writenum]);
- }
- DrvSYS_Delay(500000);
- printf("开始读出数据:\n");
- // Trigger PDMA specified Channel
- DrvPDMA_CHEnableTransfer(eDRVPDMA_CHANNEL_0);
- SPIFlash_PDMA_Read(0x0);
- for(readnum=0;readnum<RW_LEN;readnum++)
- {
- if(readnum%16 == 0 ) printf("\n");
- printf("0x%x,", SPI_PDMA_RXBuf[readnum]);
- }
- while(1)
- {}
- }
- void RCC_Config(void)
- {
- UNLOCKREG();
- SYSCLK->WRCON.XTL12M_EN = 1;
- // Waiting for 12M Xtal stalble
- DrvSYS_Delay(5000);
- //HCLK 为外部12M 通过PLL倍频到 50MHz.
- DrvSYS_Open(50000000);
- DrvSYS_Delay(5000);
- LOCKREG();
- }
- void UART_Config()
- {
- STR_UART_T sParam;
- // Set UART I/O
- DrvGPIO_InitFunction(E_FUNC_UART0);
- //Select UART Clock Source From 12MHz
- DrvSYS_SelectIPClockSource(E_SYS_UART_CLKSRC, 0);
- // UART Setting
- sParam.u32BaudRate = 9600;
- sParam.u8cDataBits = DRVUART_DATABITS_8;
- sParam.u8cStopBits = DRVUART_STOPBITS_1;
- sParam.u8cParity = DRVUART_PARITY_NONE;
- sParam.u8cRxTriggerLevel= DRVUART_FIFO_1BYTES;
- // Set UART Configuration
- DrvUART_Open(UART_PORT0, &sParam);
- }
SPI_FLASH_PDMA.c SPI 利用PDMA进行读写的操作函数。
- #include <stdio.h>
- #include "NUC1xx.h"
- #include "DrvUART.h"
- #include "DrvSYS.h"
- #include "DrvSPI.h"
- #include "DrvGPIO.h"
- #include "DrvPDMA.h"
- #include "SPI_FLASH_PDMA.h"
- #define Enable_SPI1_W25Q16BV (GPIOA->DOUT &= ~(1 << 14))
- #define Disable_SPI1_W25Q16BV (GPIOA->DOUT |= (1 << 14))
- void PDMA0_Callback(void);
- void PDMA1_Callback(void);
- volatile uint32_t PDMA0_INT_Flag, PDMA1_INT_Flag;
- STR_PDMA_T sPDMA;
- uint32_t SPIPort;
- uint32_t u32ByteCount, u32FlashAddress, u32PageNumber;
- extern uint8_t SPI_PDMA_RXBuf[];
- extern uint8_t SPI_PDMA_TXBuf[];
- void SPI_Init(void)
- {
-
- //SPI1 GPIO Init
- DrvGPIO_InitFunction(E_FUNC_SPI1);
- //Initialize SPI
- // Configure SPI0 as a master, 32-bit transaction
- DrvSPI_Open(eDRVSPI_PORT1, eDRVSPI_MASTER, eDRVSPI_TYPE1, 32,FALSE);
- // MSB first
- DrvSPI_SetEndian(eDRVSPI_PORT1, eDRVSPI_MSB_FIRST);
- // Set the active level of slave select.
- DrvSPI_SetSlaveSelectActiveLevel(eDRVSPI_PORT1, eDRVSPI_ACTIVE_LOW_FALLING);
- // SPI clock rate 12MHz
- DrvSPI_SetClockFreq(eDRVSPI_PORT1,12000000, 0);
- //设置PA14为输出,PA14为W25Q16BV的位选
- DrvGPIO_Open(E_GPA, 14, E_IO_OUTPUT);
-
- }
- void PDMA_Init(uint16_t RW_LEN)
- {
- /* -------------------------------------------- */
- /* Configure PDMA Channel 0 to receive SPI1 Rx0 */
- /* -------------------------------------------- */
- // PDMA Init
- DrvPDMA_Init();
- // SPI Port = SPI1 Rx0
- SPIPort = SPI1_BASE + 0x10;
- // PDMA Setting
- DrvPDMA_SetCHForAPBDevice(eDRVPDMA_CHANNEL_0, eDRVPDMA_SPI1, eDRVPDMA_READ_APB);
- // CH0 RX Setting
- sPDMA.sSrcCtrl.u32Addr = SPIPort; //源地址
- sPDMA.sDestCtrl.u32Addr = (uint32_t)SPI_PDMA_RXBuf;//目标地址,这里是内部RAM的一块区域
- sPDMA.u8TransWidth = eDRVPDMA_WIDTH_8BITS;
- sPDMA.u8Mode = eDRVPDMA_MODE_APB2MEM;
- sPDMA.sSrcCtrl.eAddrDirection = eDRVPDMA_DIRECTION_FIXED;
- sPDMA.sDestCtrl.eAddrDirection = eDRVPDMA_DIRECTION_INCREMENTED;
- sPDMA.i32ByteCnt = RW_LEN;
- DrvPDMA_Open(eDRVPDMA_CHANNEL_0, &sPDMA);
- // Enable INT
- DrvPDMA_EnableInt(eDRVPDMA_CHANNEL_0, eDRVPDMA_BLKD);
- // Install Callback function
- DrvPDMA_InstallCallBack(eDRVPDMA_CHANNEL_0, eDRVPDMA_BLKD, (PFN_DRVPDMA_CALLBACK) PDMA0_Callback );
-
- /* -------------------------------------------- */
- /* Configure PDMA Channel 1 to receive SPI1 Tx0 */
- /* -------------------------------------------- */
- // SPI Port = SPI1 Tx0
- SPIPort = SPI1_BASE + 0x20;
- // PDMA Setting
- DrvPDMA_SetCHForAPBDevice(eDRVPDMA_CHANNEL_1, eDRVPDMA_SPI1, eDRVPDMA_WRITE_APB);
- // CH0 TX Setting
- sPDMA.sSrcCtrl.u32Addr = (uint32_t)SPI_PDMA_TXBuf;
- sPDMA.sDestCtrl.u32Addr = SPIPort;
- sPDMA.u8TransWidth = eDRVPDMA_WIDTH_8BITS;
- sPDMA.u8Mode = eDRVPDMA_MODE_MEM2APB;
- sPDMA.sSrcCtrl.eAddrDirection = eDRVPDMA_DIRECTION_INCREMENTED;
- sPDMA.sDestCtrl.eAddrDirection = eDRVPDMA_DIRECTION_FIXED;
- sPDMA.i32ByteCnt = RW_LEN;
- DrvPDMA_Open(eDRVPDMA_CHANNEL_1, &sPDMA);
- // Enable INT
- DrvPDMA_EnableInt(eDRVPDMA_CHANNEL_1, eDRVPDMA_BLKD);
- // Install Callback function
- DrvPDMA_InstallCallBack(eDRVPDMA_CHANNEL_1, eDRVPDMA_BLKD, (PFN_DRVPDMA_CALLBACK) PDMA1_Callback );
- }
- void SPIFlash_PDMA_PageProgram(uint32_t StartAddr)
- {
- uint32_t au32SourceData;
-
- // configure transaction length as 8 bits
- DrvSPI_SetBitLength(eDRVSPI_PORT1, 8);
- //CS =0 使能W25Q16BV
- Enable_SPI1_W25Q16BV;
-
- // send Command: 0x06, Write enable
- au32SourceData = 0x06;
- DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
-
- // wait
- while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
-
- //CS =1 禁止W25Q16BV
- Disable_SPI1_W25Q16BV;
- //CS =0 使能W25Q16BV
- Enable_SPI1_W25Q16BV;
-
- // send Command: 0x02, Page program
- au32SourceData = 0x02;
- DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
-
- // wait
- while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
-
- // configure transaction length as 24 bits
- DrvSPI_SetBitLength(eDRVSPI_PORT1, 24);
-
- // send 24-bit start address
- au32SourceData = StartAddr;
- DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
-
- // wait
- while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
-
- // configure transaction length as 8 bits
- DrvSPI_SetBitLength(eDRVSPI_PORT1, 8);
-
- // enable SPI PDMA
- DrvSPI_SetPDMA(eDRVSPI_PORT1, eDRVSPI_TX_DMA, TRUE);
- // SPI go
- PDMA1_INT_Flag = 0;
- DrvSPI_SetGo(eDRVSPI_PORT1);
-
- // wait PDMA1 done
- while (1)
- {
- if (PDMA1_INT_Flag)
- {
- PDMA1_INT_Flag = 0;
- break;
- }
- }
-
- //CS =1 禁止W25Q16BV
- Disable_SPI1_W25Q16BV;
- }
- void SPIFlash_PDMA_Read(uint32_t StartAddr)
- {
- uint32_t au32SourceData;
-
- // configure transaction length as 8 bits
- DrvSPI_SetBitLength(eDRVSPI_PORT1, 8);
- //CS =0 使能W25Q16BV
- Enable_SPI1_W25Q16BV;
- // send Command: 0x03, Read data
- au32SourceData = 0x03;
- DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
- // wait
- while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
-
- // configure transaction length as 24 bits
- DrvSPI_SetBitLength(eDRVSPI_PORT1, 24);
- // send 24-bit start address
- au32SourceData = StartAddr;
- DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
- // wait
- while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
-
- // configure transaction length as 8 bits
- DrvSPI_SetBitLength(eDRVSPI_PORT1, 8);
- // enable SPI PDMA
- DrvSPI_SetPDMA(eDRVSPI_PORT1, eDRVSPI_RX_DMA, TRUE);
- // SPI go
- PDMA0_INT_Flag = 0;
- DrvSPI_SetGo(eDRVSPI_PORT1);
-
- // wait PDMA0 done
- while (1)
- {
- if (PDMA0_INT_Flag)
- {
- PDMA0_INT_Flag = 0;
- break;
- }
- }
- //CS =1 禁止W25Q16BV
- Disable_SPI1_W25Q16BV;
-
- }
- uint32_t SPIFlash_ReadStatusReg(void)
- {
- uint32_t au32SourceData;
- uint32_t au32DestinationData;
- // configure transaction length as 16 bits
- DrvSPI_SetBitLength(eDRVSPI_PORT1, 16);
-
- //CS =0 使能W25Q16BV
- Enable_SPI1_W25Q16BV;
-
- // send Command: 0x05, Read status register 1
- au32SourceData = 0x0500;
- DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
-
- // wait
- while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
-
- //CS =1 禁止W25Q16BV
- Disable_SPI1_W25Q16BV;
- // dump Rx register
- DrvSPI_DumpRxRegister(eDRVSPI_PORT1, &au32DestinationData, 1);
- return (au32DestinationData & 0xFF);
- }
- void SPIFlash_WaitReady(void)
- {
- uint32_t ReturnValue;
-
- do{
- ReturnValue = SPIFlash_ReadStatusReg();
- ReturnValue = ReturnValue & 1;
- }while(ReturnValue!=0); // check the BUSY bit
-
- }
- void SPIFlash_ChipErase(void)
- {
-
- uint32_t au32SourceData;
- // configure transaction length as 8 bits
- DrvSPI_SetBitLength(eDRVSPI_PORT1, 8);
- //CS =0 使能W25Q16BV
- Enable_SPI1_W25Q16BV;
- // send Command: 0x06, Write enable
- au32SourceData = 0x06;
- DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
- // wait
- while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
- //CS =1 禁止W25Q16BV
- Disable_SPI1_W25Q16BV;
- //CS =0 使能W25Q16BV
- Enable_SPI1_W25Q16BV;
- // send Command: 0xC7, Chip Erase
- au32SourceData = 0xc7;
- DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
- // wait
- while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
- //CS =1 禁止W25Q16BV
- Disable_SPI1_W25Q16BV;
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* PDMA Callback function */
- /*---------------------------------------------------------------------------------------------------------*/
- void PDMA0_Callback(void)
- {
- PDMA0_INT_Flag = 1;
- }
- void PDMA1_Callback(void)
- {
- PDMA1_INT_Flag = 1;
- }
|
|