SD card project part2 以STM32F407VG 寫入與讀取SD卡資料 Initsys.c & Initsys.h
Initsys 包含系統硬體的起使設定其中有 USART2的設定和SPI2的設定 *注意這裡的SPI設定是適用於SD卡的若要使用在其他裝置上需要看裝置的datasheet以修改內部參數
Initsys.h 部分
#include <stm32f4xx.h>
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_spi.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_usart.h"
#include "initsys.h"
SPI_InitTypeDef SPI_InitStruct;
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
uint8_t sdcard_blocksize;
---------------------------------------------------------------------------------
delay function
void delay_ms(uint32_t nms){
volatile uint32_t temp,tempval;
SysTick->LOAD=(uint32_t)nms*21000;//168000000/8
SysTick->VAL =0x00;
SysTick->CTRL=0x01 ;
do
{
temp=SysTick->CTRL;
tempval=SysTick->VAL;
}
while(temp==1);
SysTick->CTRL=0x00;
SysTick->VAL =0X00;
}
---------------------------------------------------------------------------------
SPI2 用來與SD卡溝通設定數入參數為SPI時脈的 prescaler
void Spi2_Init(uint16_t prescaler){
//ENABLE SPI2 clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
//ENABLE SPI related GPIO clock PB13 = SPI2_SCK PB14 = SPI2_MISO PB15 = SPI2_MOSI PB10
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
//DEFINE structure
GPIO_InitTypeDef GPIO_InitStruct;
//GPIO setting SPI MOSI MISO CLK part
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2);
//GPIO CS pin PD8
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOD,&GPIO_InitStruct);
GPIO_SetBits(GPIOD,GPIO_Pin_8);
//SPI2 setting [sd card use SPI mode 0 (CPHA = 0 ,CPOL =0)]
//SD card in spi mode start clock must <400kHz
SPI_InitStruct.SPI_BaudRatePrescaler = prescaler;//clock = 42mhz/128 =328.125khz
SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStruct.SPI_CRCPolynomial = 7;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
SPI_Init(SPI2,&SPI_InitStruct);
SPI_Cmd(SPI2,ENABLE);
}
---------------------------------------------------------------------------------
USART2 的設定方便用來DEBUG沒有此段對於程式執行沒有影響但要把程式內的所有USART_puts()這個function comment 不然編譯不過
void Usart2_Int(){
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
//Enable the preiph clock for USART2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
//Enable the GPIO clock
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
//setup the GPIO pin for Tx and Rx
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2);
//USART2 setting
USART_InitStructure.USART_BaudRate=115200;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_Parity=USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
USART_Init(USART2,&USART_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_Cmd(USART2,ENABLE);
}
---------------------------------------------------------------------------------
USART_puts 用來輸出文字到序列附上方便使用電腦debug
void USART_puts(USART_TypeDef* USARTx,volatile char *str){
while(*str)
{
while(!(USARTx->SR&0x040));
USART_SendData(USARTx, *str);
*str++;
}
}
---------------------------------------------------------------------------------
SPI2_send 用來與SD卡傳值和收值
uint8_t SPI2_send(uint8_t data){
SPI2->DR = data; // write data to be transmitted to the SPI data register
while( !(SPI2->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete
while( !(SPI2->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive complete
while( SPI2->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore
return SPI2->DR; // return received data from SPI data register
}
---------------------------------------------------------------------------------
Initsys.h部分
沒什麼好說的就是一些定義
#ifndef _INITSYS_H_
#define _INITSYS_H_
#include <stm32f4xx.h>
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_spi.h"
#include "stm32f4xx_gpio.h"
void delay_ms(uint32_t nms);
void Spi2_Init(uint16_t prescaler);
void USART_puts(USART_TypeDef* USARTx,volatile char *str);
uint8_t SPI2_send(uint8_t data);
#endif
留言
張貼留言