SPI0驅(qū)動(dòng)FLASH芯片W25Q64,SPI1驅(qū)動(dòng)TFT屏幕(驅(qū)動(dòng)芯片ST7735),當(dāng)使用SPI0對(duì)FLASH進(jìn)行擦除、寫(xiě)入等動(dòng)作時(shí),SPI1引腳也會(huì)輸出信號(hào),但是使用SPI1對(duì)屏幕進(jìn)行寫(xiě)操作SPI0引腳正常,不會(huì)跟隨SPI1輸出,各位路過(guò)的大佬們能否幫忙看下是什么問(wèn)題。驅(qū)動(dòng)源碼如下:
/////////////////////////////////////////////////////////////分界線///////////////////////////////////////////////////////////////
SPI0驅(qū)動(dòng)FLASH程序使用官方例程,將SPI1改為SPI0:
#include "SPIFlash.H"
/********************************* 引腳定義 ************************************
*? ? PA12? <===========>? SCS
*? ? PA13? <===========>? SCK
*? ? PA13? <===========>? DI/MOSI
*? ? PA15? <===========>? DO/MISO
*******************************************************************************/
#define? SPI0_CS_LOW()? ? ? ? GPIOA_ResetBits( GPIO_Pin_12 )
#define? SPI0_CS_HIGH()? ? ? ?GPIOA_SetBits( GPIO_Pin_12 )
/*******************************************************************************
* Function Name? : ReadExternalFlashStatusReg_SPI
* Description? ? : 用來(lái)讀取狀態(tài)寄存器,并返回狀態(tài)寄存器的值
* Input? ? ? ? ? : None
* Output? ? ? ? ?: None
* Return? ? ? ? ?: ExFlashRegStatus
*******************************************************************************/
UINT8 ReadExternalFlashStatusReg_SPI( void )
{
? ? UINT8 ExFlashRegStatus;
? ??
? ??
? ? SPI0_CS_LOW();
? ? SPI0_MasterSendByte( CMD_STATUS1 );? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //發(fā)送讀狀態(tài)寄存器的命令
? ? ExFlashRegStatus = SPI0_MasterRecvByte();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //讀取狀態(tài)寄存器
? ? SPI0_CS_HIGH();
? ??
? ? return ExFlashRegStatus;
}
/*******************************************************************************
* Function Name? : WaitExternalFlashIfBusy
* Description? ? : 等待芯片空閑(在執(zhí)行Byte-Program, Sector-Erase, Block-Erase, Chip-Erase操作后)
* Input? ? ? ? ? : None
* Output? ? ? ? ?: None
* Return? ? ? ? ?: None
*******************************************************************************/
void WaitExternalFlashIfBusy( void )
{
? ? while ((ReadExternalFlashStatusReg_SPI())&0x01 == 0x01 )
? ? {
? ? ? ? ;? ? //等待直到Flash空閑
? ? }
}
/*******************************************************************************
* Function Name? : WriteExternalFlashEnable_SPI
* Description? ? : 寫(xiě)使能,同樣可以用于使能寫(xiě)狀態(tài)寄存器
* Input? ? ? ? ? : None
* Output? ? ? ? ?: None
* Return? ? ? ? ?: None
*******************************************************************************/
void WriteExternalFlashEnable_SPI( void )
{
? ? SPI0_CS_LOW();
? ? SPI0_MasterSendByte( CMD_WR_ENABLE );? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //發(fā)送寫(xiě)使能命令
? ? SPI0_CS_HIGH();
}
/*******************************************************************************
* Function Name? : EraseExternal4KFlash_SPI
* Description? ? : 擦除4K Flash? 擦除一個(gè)扇區(qū)
* Input? ? ? ? ? : Dst_Addr 0-1 ffff ffff ,清除任意地址所在的扇區(qū)。
* Output? ? ? ? ?: None
* Return? ? ? ? ?: None
*******************************************************************************/
//擦除一個(gè)扇區(qū)
//Dst_Addr:扇區(qū)地址 0~2047*1024*4 for w25q64
//擦除一個(gè)扇區(qū)的最少時(shí)間:150ms
void EraseExternal4KFlash_SPI( UINT32 Dst_Addr )
{
Dst_Addr*=4096;
? ? WriteExternalFlashEnable_SPI();
? ? WaitExternalFlashIfBusy();
? ??
? ? SPI0_CS_LOW();
? ? SPI0_MasterSendByte(CMD_ERASE_4KBYTE);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //扇區(qū)擦除命令
? ? SPI0_MasterSendByte(((Dst_Addr & 0xFFFFFF) >> 16));? ? ? ? ? ? ? ? ? ? ? ?//發(fā)送3字節(jié)地址
? ? SPI0_MasterSendByte(((Dst_Addr & 0xFFFF) >> 8));
? ? SPI0_MasterSendByte(Dst_Addr & 0xFF);
? ? SPI0_CS_HIGH();
? ??
? ? WaitExternalFlashIfBusy();
}
/*******************************************************************************
* Function Name? : EraseExternalFlash_SPI
* Description? ? : 擦除32K Flash? 擦除一個(gè)扇區(qū)
* Input? ? ? ? ? : Dst_Addr 0-1 ffff ffff ,清除任意地址所在的扇區(qū)。
* Output? ? ? ? ?: None
* Return? ? ? ? ?: None
*******************************************************************************/
void EraseExternal32KFlash_SPI( UINT32 Dst_Addr )
{
? ? WriteExternalFlashEnable_SPI();
? ? WaitExternalFlashIfBusy();
? ??
? ? SPI0_CS_LOW();
? ? SPI0_MasterSendByte(CMD_ERASE_32KBYTE);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //32K擦除命令
? ? SPI0_MasterSendByte(((Dst_Addr & 0xFFFFFF) >> 16));? ? ? ? ? ? ? ? ? ? ? ? //發(fā)送3字節(jié)地址
? ? SPI0_MasterSendByte(((Dst_Addr & 0xFFFF) >> 8));
? ? SPI0_MasterSendByte(Dst_Addr & 0xFF);
? ? SPI0_CS_HIGH();
? ??
? ? WaitExternalFlashIfBusy();
}
/*******************************************************************************
* Function Name? : PageWriteExternalFlash_SPI
* Description? ? : 頁(yè)寫(xiě);SPI在一頁(yè)(0~65535)內(nèi)寫(xiě)入少于256個(gè)字節(jié)的數(shù)據(jù)
* Input? ? ? ? ? : RcvBuffer:數(shù)據(jù)存儲(chǔ)區(qū)
*? ? ? ? ? ? ? ? ? StarAddr:開(kāi)始寫(xiě)入的地址
*? ? ? ? ? ? ? ? ? Len:要寫(xiě)入的字節(jié)數(shù)(最大256),該數(shù)不應(yīng)該超過(guò)該頁(yè)的剩余字節(jié)數(shù)!!!
* Output? ? ? ? ?: None
* Return? ? ? ? ?: None
*******************************************************************************/
void PageWriteExternalFlash_SPI(UINT32 StarAddr,UINT16 Len,PUINT8 RcvBuffer)
{
? ? UINT16 i;
? ??
? ? WriteExternalFlashEnable_SPI();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //SET WEL
? ??
? ? SPI0_CS_LOW();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? SPI0_MasterSendByte(CMD_PAGE_PROG);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //發(fā)送寫(xiě)頁(yè)命令
? ? SPI0_MasterSendByte(((StarAddr & 0xFFFFFF) >> 16));? ? ? ? ? ? ? ? ? ? ? ? //發(fā)送24bit地址
? ? SPI0_MasterSendByte(((StarAddr & 0xFFFF) >> 8));
? ? SPI0_MasterSendByte(StarAddr & 0xFF);
? ? for(i=0; i!=Len; i++)
? ? {
? ? ? ? SPI0_MasterSendByte(RcvBuffer[i]);? ? //循環(huán)寫(xiě)數(shù)
? ? }
? ? SPI0_CS_HIGH();
? ??
? ? WaitExternalFlashIfBusy();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//等待寫(xiě)入結(jié)束
}
/*******************************************************************************
* Function Name? : BlukWriteExternalFlash_SPI
* Description? ? : 無(wú)檢驗(yàn)寫(xiě)SPI FLASH
*? ? ? ? ? ? ? ? ? 必須確保所寫(xiě)的地址范圍內(nèi)的數(shù)據(jù)全部為0XFF,否則在非0XFF處寫(xiě)入的數(shù)據(jù)將失敗!
*? ? ? ? ? ? ? ? ? 具有自動(dòng)換頁(yè)功能
*? ? ? ? ? ? ? ? ? 在指定地址開(kāi)始寫(xiě)入指定長(zhǎng)度的數(shù)據(jù),但是要確保地址不越界!
* Input? ? ? ? ? : SendBuffer:數(shù)據(jù)存儲(chǔ)區(qū)
*? ? ? ? ? ? ? ? ? StarAddr:開(kāi)始寫(xiě)入的地址
*? ? ? ? ? ? ? ? ? Len:要寫(xiě)入的字節(jié)數(shù)(最大65535)
* Output? ? ? ? ?: None
* Return? ? ? ? ?: None
*******************************************************************************/
void BlukWriteExternalFlash_SPI(UINT32 StarAddr,UINT16 Len,PUINT8 SendBuffer)
{
? ? UINT16? pageremain;
? ??
? ? pageremain = 256-StarAddr%256;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//單頁(yè)剩余的字節(jié)數(shù)
? ? if(Len<=pageremain)
? ? {
? ? ? ? pageremain=Len;? ? //不大于256個(gè)字節(jié)
? ? }
? ? while(1)
? ? {
? ? ? ? PageWriteExternalFlash_SPI(StarAddr,pageremain,SendBuffer);
? ? ? ? if(Len==pageremain)
? ? ? ? {
? ? ? ? ? ? break;? ? //寫(xiě)入結(jié)束了
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? SendBuffer+=pageremain;
? ? ? ? ? ? StarAddr+=pageremain;
? ? ? ? ? ? Len-=pageremain;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//減去已經(jīng)寫(xiě)入了的字節(jié)數(shù)
? ? ? ? ? ? if(Len>256)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? pageremain=256;? ? //一次可以寫(xiě)入256個(gè)字節(jié)
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? pageremain=Len;? ? //不夠256個(gè)字節(jié)了
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
/*******************************************************************************
* Function Name? : ReadExternalFlash_SPI
* Description? ? : 讀取地址的數(shù)據(jù).
*******************************************************************************/
void ReadExternalFlash_SPI( UINT32 StarAddr, UINT16 Len, PUINT8 RcvBuffer )
{? ??
? ? SPI0_CS_LOW();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? SPI0_MasterSendByte(CMD_READ_DATA);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//讀命令
? ? SPI0_MasterSendByte(((StarAddr & 0xFFFFFF) >> 16));? ? ? ? ? ? ? ? ?//發(fā)送3字節(jié)地址
? ? SPI0_MasterSendByte(((StarAddr & 0xFFFF) >> 8));
? ? SPI0_MasterSendByte(StarAddr & 0xFF);
? ? SPI0_MasterRecv( RcvBuffer, Len );
? ? SPI0_CS_HIGH();
}
/*******************************************************************************
* Function Name? : BlukReadExternalFlash_SPI
* Description? ? : 讀取起始地址(StarAddr)內(nèi)多個(gè)字節(jié)(Len)的數(shù)據(jù).存入緩沖區(qū)RcvBuffer中
* Input? ? ? ? ? : StarAddr -Destination Address 000000H - 1FFFFFH
? ? ? ? ? ? ? ? ? ?Len 讀取數(shù)據(jù)長(zhǎng)度
? ? ? ? ? ? ? ? ? ?RcvBuffer 接收緩沖區(qū)起始地址
* Output? ? ? ? ?: None
* Return? ? ? ? ?: None
*******************************************************************************/
void BlukReadExternalFlash_SPI( UINT32 StarAddr, UINT16 Len, PUINT8 RcvBuffer )
{? ??
? ? SPI0_CS_LOW();
? ? SPI0_MasterSendByte(CMD_FAST_READ);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//高速度
? ? SPI0_MasterSendByte(((StarAddr & 0xFFFFFF) >> 16));? ? ? ? ? ? ? ? ?//發(fā)送3字節(jié)地址
? ? SPI0_MasterSendByte(((StarAddr & 0xFFFF) >> 8));
? ? SPI0_MasterSendByte(StarAddr & 0xFF);
? ? SPI0_MasterSendByte(0x00);? ??
? ? SPI0_MasterRecv( RcvBuffer, Len );
? ? SPI0_CS_HIGH();
}
/*******************************************************************************
* Function Name? : SPIFlash_ReadID
* Description? ? : SPI Flash讀取芯片ID
* Input? ? ? ? ? : None
* Output? ? ? ? ?: None
* Return? ? ? ? ?: 0XEF13,表示芯片型號(hào)為W25Q08
*? ? ? ? ? ? ? ? ? 0XEF14,表示芯片型號(hào)為W25Q16
*? ? ? ? ? ? ? ? ? 0XEF15,表示芯片型號(hào)為W25Q32
*? ? ? ? ? ? ? ? ? 0XEF16,表示芯片型號(hào)為W25Q64
*? ? ? ? ? ? ? ? ? 0XEF17,表示芯片型號(hào)為W25Q128
*******************************************************************************/
UINT16 SPIFlash_ReadID(void)
{
? ? UINT16? temp = 0;
? ??
? ? SPI0_CS_LOW();
? ? SPI0_MasterSendByte(CMD_DEVICE_ID);? ? ? ? ? ? ? ? ? ? //讀取ID命令
? ? SPI0_MasterSendByte(0x00);
? ? SPI0_MasterSendByte(0x00);
? ? SPI0_MasterSendByte(0x00);
? ? temp = SPI0_MasterRecvByte();
? ? temp = temp<<8;
? ? temp |= SPI0_MasterRecvByte();
? ? SPI0_CS_HIGH();
? ??
? ? return temp;
}
/*******************************************************************************
* Function Name? : SPI0Flash_Init
* Description? ? : SPI Flash初始化
* Input? ? ? ? ? : None
* Output? ? ? ? ?: None
* Return? ? ? ? ?: None
*******************************************************************************/
void SPIFlash_Init(void)
{
GPIOA_SetBits( GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14 );
GPIOA_ModeCfg( GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14, GPIO_ModeOut_PP_5mA );// MOSI/SCK/CS
GPIOA_SetBits( GPIO_Pin_15 );
GPIOA_ModeCfg( GPIO_Pin_15, GPIO_ModeIN_PU );// MISO
? ? SPI0_MasterDefInit();
? ? SPI0_DataMode( Mode3_HighBitINFront );
? ? SPI0_CLKCfg( 4 );
? ? printf("id:0x%04x\n", SPIFlash_ReadID() );
}
/////////////////////////////////////////////////////////////分界線///////////////////////////////////////////////////////////////
SPI1是手搓的TFT驅(qū)動(dòng)程序:
#include "ST7735.H"
//RESETPB3
//RSPB5
//SDAPA1
//SCLPA0
//CS? ? ? ? PB6
uint16_t BG_Color=WHITE;
void LCD_GPIO_Init(void)
{
GPIOA_ModeCfg(GPIO_Pin_0|GPIO_Pin_1, GPIO_ModeOut_PP_5mA);
GPIOB_ModeCfg(GPIO_Pin_3|GPIO_Pin_5|GPIO_Pin_6, GPIO_ModeOut_PP_5mA);
}
void LCD_Reset(void)
{
GPIOB_ResetBits(GPIO_Pin_3);//拉低RST
mDelaymS(20);
GPIOB_SetBits(GPIO_Pin_3);//拉高RST
mDelaymS(20);
}
void LCD_Write_REG(uint8_t Com)
{
GPIOB_ResetBits(GPIO_Pin_6);//片選
GPIOB_ResetBits(GPIO_Pin_5);//拉低->命令
SPI1_MasterSendByte(Com);//發(fā)送命令
GPIOB_SetBits(GPIO_Pin_6);//取消片選
}
void LCD_Write_Byte(uint8_t Data)
{
GPIOB_ResetBits(GPIO_Pin_6);//片選
GPIOB_SetBits(GPIO_Pin_5);//拉高->數(shù)據(jù)
SPI1_MasterSendByte(Data);//發(fā)送數(shù)據(jù)
GPIOB_SetBits(GPIO_Pin_6);//取消片選
}
void LCD_Write_Data(uint16_t Data)
{
LCD_Write_Byte(Data>>8);
LCD_Write_Byte(Data);
}