SPCE061A的I/O端口,對某一位的設(shè)定包括以下3個(gè)基本項(xiàng):數(shù)據(jù)向量Data、屬性向量Attribution和方向控制向量Direction。3個(gè)端口內(nèi)每個(gè)對應(yīng)的位組合在一起,形成一個(gè)控制字,用來定義相應(yīng)I/O口位的輸入輸出狀態(tài)和方式。例如,假設(shè)需要IOA0是下拉輸入管腳,則相應(yīng)的Data、Attribution和Direction的值均被置為“0”。如果需要IOA1是帶喚醒功能的懸浮式輸入管腳,則Data、Attribution和Direction的值被置為“010”。A口和B口的Data、Attribution和Direction的設(shè)定值均在不同的寄存器里,用戶在進(jìn)行I/O口設(shè)置時(shí)要特別注意這一點(diǎn)。
在STM32F105和STM32F107互連型系列微控制器之前,意法半導(dǎo)體已經(jīng)推出STM32基本型系列、增強(qiáng)型系列、USB基本型系列、互補(bǔ)型系列;新系列產(chǎn)品沿用增強(qiáng)型系列的72MHz處理頻率。內(nèi)存包括64KB到256KB閃存和 20KB到64KB嵌入式SRAM。新系列采用LQFP64、LQFP100和LFBGA100三種封裝,不同的封裝保持引腳排列一致性,結(jié)合STM32平臺(tái)的設(shè)計(jì)理念,開發(fā)人員通過選擇產(chǎn)品可重新優(yōu)化功能、存儲(chǔ)器、性能和引腳數(shù)量,以最小的硬件變化來滿足個(gè)性化的應(yīng)用需求。
以下是硬件電路圖,主芯片為stm32rbt6.
貼上代碼
void SPI_FLASH_Init1(void)//io初始化配置
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_9;//CS CLK
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //MOSI要用模擬輸入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//MISO
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//關(guān)鍵在讀取函數(shù)
//包括讀取和發(fā)送
u8 SPIx_FLASH_SendByte(u8 byte)
{
uint8_t i;
u8 Temp=0x00;
unsigned char SDI;
for (i = 0; i 《 8; i++)
{
GPIO_SetBits(GPIOC, GPIO_Pin_9);//sclk = 0;//先將時(shí)鐘拉高
if (byte&0x80)
{
GPIO_SetBits(GPIOC, GPIO_Pin_7); // //SO=1
}
else
{
GPIO_ResetBits(GPIOC, GPIO_Pin_7);// //SO=0
}
byte 《《= 1;
GPIO_ResetBits(GPIOC, GPIO_Pin_9);// //sclk = 1; 拉低時(shí)鐘
SDI = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_8);//判斷si是否有輸入
Temp《《=1;
if(SDI) //讀到1時(shí)
{
Temp++; //置1 即向右移動(dòng)一位同時(shí)加1 因上邊有《《=1
}
GPIO_SetBits(GPIOC, GPIO_Pin_9);//sclk = 0;// 拉高時(shí)鐘
}
return Temp; //返回讀到miso輸入的值
}
}
//下面是以讀寫spi flash為例具體的實(shí)現(xiàn)
//此函數(shù)中 時(shí)鐘機(jī)時(shí)序很重要。Cs在讀寫中只能出現(xiàn)一次,不能在sendwrite
//讀寫里邊有,被調(diào)用時(shí)還出現(xiàn),就肯定不行了。
//其它函數(shù)宏定義
#define BUFFER_1_WRITE 0x84 // buffer 1 write
#define BUFFER_2_WRITE 0x87 // buffer 2 write
#define BUFFER_1_READ 0x54 // buffer 1 read (change to 0xD4 for SPI mode 0,3)
#define BUFFER_2_READ 0x56 // buffer 2 read (change to 0xD6 for SPI mode 0,3)
#define B1_TO_PAGE_WITH_ERASE 0x83 // buffer 1 to main memory page program with built-in erase
#define B2_TO_PAGE_WITH_ERASE 0x86 // buffer 2 to main memory page program with built-in erase
#define B1_TO_PAGE_WITHOUT_ERASE 0x88 // buffer 1 to main memory page program without built-in erase
#define B2_TO_PAGE_WITHOUT_ERASE 0x89 // buffer 2 to main memory page program without built-in erase
#define PAGE_PROG_THROUGH_B1 0x82 // main memory page program through buffer 1
#define PAGE_PROG_THROUGH_B2 0x85 // main memory page program through buffer 2
#define AUTO_PAGE_REWRITE_THROUGH_B1 0x58 // auto page rewrite through buffer 1
#define AUTO_PAGE_REWRITE_THROUGH_B2 0x59 // auto page rewrite through buffer 2
#define PAGE_TO_B1_COMP 0x60 // main memory page compare to buffer 1
#define PAGE_TO_B2_COMP 0x61 // main memory page compare to buffer 2
#define PAGE_TO_B1_XFER 0x53 // main memory page to buffer 1 transfer
#define PAGE_TO_B2_XFER 0x55 // main memory page to buffer 2 transfer
#define STATUS_REGISTER 0x57
#define MAIN_MEMORY_PAGE_READ 0x52 // main memory page read (change to 0xD2 for SPI mode 0,3)
#define PAGE_ERASE 0x81 // erase a 264 byte page
#define BULK_ERASE 0x50 // erase 8 pages
#define WIP_Flag 0x80
#define Dummy_Byte 0xA5
AT45DB系列的讀寫函數(shù)
void AT45xxReadx(uint32_t Num,uint32_t PageAddr, uint32_t ByteAddr, uint8_t *
Data, uint32_t ByteNum)
{
SPIx_FLASH_PageToBuffer2(Num,PageAddr);
SPIx_FLASH_Buffer2Read(Num,Data, ByteAddr, ByteNum);
}
寫函數(shù)
void AT45xxWritex(uint32_t Num,uint32_t PageAddr, uint32_t ByteAddr, u8 *Data
, uint32_t ByteNum)
{
uint32_t i;
u8 aa[100];
if((ByteNum 《= (528 - ByteAddr))&&(ByteNum 》 0))
{
SPIx_FLASH_WaitForWriteEnd(Num);
// while(?。≧at45_status()& 0x80 )); //判斷是否忙
SPIx_FLASH_CS_LOW(Num);
SPIx_FLASH_SendByte(Num,0x82);
// SPIx_ReadWriteByte(0x82);
// SPIx_ReadWriteByte((uint8_t)(PageAddr》》6));
// SPIx_ReadWriteByte((uint8_t)((PageAddr《《2)|(ByteAddr》》8)));
// SPIx_ReadWriteByte((uint8_t)ByteAddr);
SPIx_FLASH_SendByte(Num,(uint8_t)(PageAddr》》6));
SPIx_FLASH_SendByte(Num,(uint8_t)((PageAddr《《2)|(ByteAddr》》8)));
SPIx_FLASH_SendByte(Num,(uint8_t)ByteAddr);
for(i = 0; i 《 ByteNum; i++)
{
SPIx_FLASH_SendByte(Num,Data[i]);
// SPIx_ReadWriteByte(Data[i]);
// SPIx_FLASH_SendByte(Num,Data[i]);
}
SPIx_FLASH_CS_HIGH(Num);
}
}
void SPIx_FLASH_WaitForWriteEnd(uint32_t Num)
{
unsigned char FLASH_Status = 0;
SPIx_FLASH_CS_LOW(Num);
SPIx_FLASH_SendByte(Num,STATUS_REGISTER);
do
{
FLASH_Status = SPIx_FLASH_SendByte(Num,Dummy_Byte);
}
while ((FLASH_Status & WIP_Flag) == RESET);
SPIx_FLASH_CS_HIGH(Num);
}
void SPIx_FLASH_Buffer2Read(uint32_t Num,u8* pBuffer, u32 ReadAddr, u16
NumByteToRead)
{
SPIx_FLASH_WaitForWriteEnd(Num);
// while(?。≧at45_status()& 0x80 )); //判斷是否忙
SPIx_FLASH_CS_LOW(Num);
SPIx_FLASH_SendByte(Num,BUFFER_2_READ);
SPIx_FLASH_SendByte(Num,Dummy_Byte);
SPIx_FLASH_SendByte(Num,(ReadAddr& 0xFF00) 》》 8);
SPIx_FLASH_SendByte(Num,ReadAddr & 0xFF);
SPIx_FLASH_SendByte(Num,Dummy_Byte);//
while (NumByteToRead--)
{
*pBuffer = SPIx_FLASH_SendByte(Num,Dummy_Byte);
pBuffer++;
}
SPIx_FLASH_CS_HIGH(Num);
}
void SPIx_FLASH_CS_LOW(uint32_t Num)
{
switch(Num)
{
case 0: GPIO_ResetBits(GPIOB, GPIO_Pin_12); break;
case 1: GPIO_ResetBits(GPIOA, GPIO_Pin_8); break; //U6
case 2: GPIO_ResetBits(GPIOA, GPIO_Pin_7); break; //U7
case 3: GPIO_ResetBits(GPIOA, GPIO_Pin_3); break; //U8
case 4: GPIO_ResetBits(GPIOC, GPIO_Pin_3); break; //U9
default:break;
}
}
void SPIx_FLASH_CS_HIGH(uint32_t Num)
{
switch(Num)
{
case 0: GPIO_SetBits(GPIOB, GPIO_Pin_12); break;
case 1: GPIO_SetBits(GPIOA, GPIO_Pin_8); break; //U6
case 2: GPIO_SetBits(GPIOA, GPIO_Pin_7); break; //U7
case 3: GPIO_SetBits(GPIOA, GPIO_Pin_3); break; //U8
case 4: GPIO_SetBits(GPIOC, GPIO_Pin_3); break; //U9
default:break;
}
}
評論
查看更多