中职网站建设与维护考试题,公司起名字大全免费2021,wordpress 电商主题,十大app软件下载入口sdio移植
st官网给的标准库有给一个用于st出的评估板的sdio外设实现#xff0c;但一是文件结构有点复杂#xff0c;二是相比于国内正点原子和野火的板子也有点不同#xff0c;因此还是需要移植下才能使用。当然也可以直接使用正点原子或野火提供的实例#xff0c;但为了熟…sdio移植
st官网给的标准库有给一个用于st出的评估板的sdio外设实现但一是文件结构有点复杂二是相比于国内正点原子和野火的板子也有点不同因此还是需要移植下才能使用。当然也可以直接使用正点原子或野火提供的实例但为了熟悉下sdio的一些知识本人还是决定从st标准库移植一次。下面就是移植的过程。
硬件差异
st官方提供的10E评估板和本人使用的野火stm32f103zet6开发板可以兼容。但在TF卡插入检测有所不同。st官方的stm3210e评估板使用PF11用于卡插入检测而stm32f103zet6开发板没有提供此检测引脚功能。
移植内容
复制STM32F10x_StdPeriph_Lib_V3.5.0/Utilities/STM32_EVAL/Common/stm32_eval_sdio_sd.c和STM32F10x_StdPeriph_Lib_V3.5.0/Utilities/STM32_EVAL/Common/stm32_eval_sdio_sd.h到自己的项目中自己项目中新建一个sdio_gpio.c和sdio_gpio.h。复制STM32F10x_StdPeriph_Lib_V3.5.0/Utilities/STM32_EVAL/STM3210E_EVAL/stm3210e_eval.c中的几个函数实现到sdio_gpio.c文件中。这里就列出sdio_gpio.h头文件具体函数就自己复制了。
#ifndef __SDIO_GPIO_H
#define __SDIO_GPIO_H#include stm32f10x_conf.h// 这里的个宏是驱动中会使用到的都是官方实例中复制出来的
#define SDIO_FIFO_ADDRESS ((uint32_t)0x40018080)
/*** brief SDIO Intialization Frequency (400KHz max)*/
#define SDIO_INIT_CLK_DIV ((uint8_t)0xB2)
/*** brief SDIO Data Transfer Frequency (25MHz max)*/
#define SDIO_TRANSFER_CLK_DIV ((uint8_t)0x00)// 头文件中只是这几个函数的声明函数的具体内容要复制到sd_gpio.c文件中
void SD_LowLevel_DeInit(void);
void SD_LowLevel_Init(void);
void SD_LowLevel_DMA_TxConfig(uint32_t *BufferSRC, uint32_t BufferSize);
void SD_LowLevel_DMA_RxConfig(uint32_t *BufferDST, uint32_t BufferSize);
uint32_t SD_DMAEndOfTransferStatus(void);
// 这里中断初始化改了一个名字防止和别的外设中断初始化重名
void sdio_NVIC_Configuration(void)#endif复制好函数体后删除sdio_gpio.c文件中出现DETECT的地方原因就是因为官方评估板中有DETECT引脚而本人板子实际没有DETECT引脚更改一些stm32_eval_sdio_sd.c文件中的内容
static SD_Error CmdResp2Error(void);
//这里注释了因为在sd_gpio.c中定义了不再是私有函数
//static uint32_t SD_DMAEndOfTransferStatus(void);
static SD_Error CmdResp6Error(uint8_t cmd, uint16_t *prca);// SD_Init()函数中加入中断初始化
SD_Error SD_Init(void)
{SD_Error errorstatus SD_OK;/* SDIO Peripheral gpio 初始化 */SD_LowLevel_Init();SDIO_DeInit();// 中断初始化sdio_NVIC_Configuration();errorstatus SD_PowerON();...
}// SD_GetState()删除detect内容
/*** brief Returns the current cards state.* brief 因为采用data3信号线作为插入检测因此此处不能使用SD_Detect()函数* param None* retval SDCardState: SD Card Error or SD Card Current State.*/
SDCardState SD_GetState(void)
{uint32_t resp1 0;/*if(SD_Detect() SD_PRESENT)*//*{*/if (SD_SendStatus(resp1) ! SD_OK){return SD_CARD_ERROR;}else{return (SDCardState)((resp1 9) 0x0F);}/*}*//*else*//*{*//*return SD_CARD_ERROR;*//*}*/
}// SD_Detect()函数全部注释了
/*** brief Detect if SD card is correctly plugged in the memory slot.* brief 因为没有单独的插入检测因此不使用此函数* param None* retval Return if SD is detected or not*/
/*uint8_t SD_Detect(void)*/
/*{*//*__IO uint8_t status SD_PRESENT;*//*[! Check GPIO to detect SD ]*//*if (GPIO_ReadInputDataBit(SD_DETECT_GPIO_PORT, SD_DETECT_PIN) ! Bit_RESET)*//*{*//*status SD_NOT_PRESENT;*//*}*//*return status;*/
/*}*/// SD_WriteMultiBlocks()中加入一个命令书中说加入有用具体不清楚
SD_Error SD_WriteMultiBlocks(uint8_t *writebuff, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks)
{SD_Error errorstatus SD_OK;__IO uint32_t count 0;TransferError SD_OK;TransferEnd 0;StopCondition 1;SDIO-DCTRL 0x0;if (CardType SDIO_HIGH_CAPACITY_SD_CARD){BlockSize 512;WriteAddr / 512;}/*! 根据正点原子代码加入说明是为了防止DMA检测卡死 */SDIO_CmdInitStructure.SDIO_Argument (uint32_t) BlockSize;SDIO_CmdInitStructure.SDIO_CmdIndex SD_CMD_SET_BLOCKLEN;SDIO_CmdInitStructure.SDIO_Response SDIO_Response_Short;SDIO_CmdInitStructure.SDIO_Wait SDIO_Wait_No;SDIO_CmdInitStructure.SDIO_CPSM SDIO_CPSM_Enable;SDIO_SendCommand(SDIO_CmdInitStructure);errorstatus CmdResp1Error(SD_CMD_SET_BLOCKLEN);if (errorstatus ! SD_OK){return(errorstatus);}...
}还有一个sdio的中断函数还要忘记了放在stm32f10x_it.c或main.c都一样的。
/** 函数名SDIO_IRQHandler* 描述 在SDIO_ITConfig(这个函数开启了sdio中断 数据传输结束时产生中断* 输入 无* 输出 无*/
void SDIO_IRQHandler(void)
{/* Process All SDIO Interrupt Sources */SD_ProcessIRQSrc();
}改好后项目中加入sdio_gpio.h和stm32_eval_sdio_sd.h头文件。就可以试着编译下了
加入测试代码
因为本人之前的项目中使用的freertos且已经调通uart0串口。st官方实例是使用几个LED灯指示测试结果本人开发板上没有这么多的灯就直接使用串口的printf显示了一样的方便。下面就是main.c文件。
#include stm32f10x_conf.h//extern __IO uint16_t ADCConvertedValue;
extern __IO uint16_t ADC_DualConvertedValueTab[4];
extern QueueHandle_t command_buf;typedef enum {FAILED 0, PASSED !FAILED} TestStatus;
#define BLOCK_SIZE 512 /* Block Size in Bytes */#define NUMBER_OF_BLOCKS 32 /* For Multi Blocks operation (Read/Write) */
#define MULTI_BUFFER_SIZE (BLOCK_SIZE * NUMBER_OF_BLOCKS)#define SD_OPERATION_ERASE 0
#define SD_OPERATION_BLOCK 1
#define SD_OPERATION_MULTI_BLOCK 2
#define SD_OPERATION_END 3uint8_t Buffer_Block_Tx[BLOCK_SIZE], Buffer_Block_Rx[BLOCK_SIZE];
uint8_t Buffer_MultiBlock_Tx[MULTI_BUFFER_SIZE], Buffer_MultiBlock_Rx[MULTI_BUFFER_SIZE];void SD_EraseTest(void);
void SD_SingleBlockTest(void);
void SD_MultiBlockTest(void);
void Fill_Buffer(uint8_t *pBuffer, uint32_t BufferLength, uint32_t Offset);
TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint32_t BufferLength);
TestStatus eBuffercmp(uint8_t* pBuffer, uint32_t BufferLength);
SD_Error Status SD_OK;
volatile TestStatus EraseStatus FAILED, TransferStatus1 FAILED, TransferStatus2 FAILED;
__IO uint32_t SDCardOperation SD_OPERATION_ERASE;void sdio_test_task(void *pvParameter)
{if((Status SD_Init()) ! SD_OK)printf(sdio init error);while(Status SD_OK SDCardOperation ! SD_OPERATION_END){switch(SDCardOperation){case SD_OPERATION_ERASE:SD_EraseTest();SDCardOperation SD_OPERATION_BLOCK;break;case SD_OPERATION_BLOCK:SD_SingleBlockTest();SDCardOperation SD_OPERATION_MULTI_BLOCK;break;case SD_OPERATION_MULTI_BLOCK:SD_MultiBlockTest();SDCardOperation SD_OPERATION_END;break;}}while(1){}
}void dac_task(void *pvParameter){static unsigned short num 0xffff;for(;;){DAC_SetChannel1Data(DAC_Align_12b_L, num);DAC_SoftwareTriggerCmd(DAC_Channel_1, ENABLE);num - 0x2;if(num 0xff)num 0xffff;vTaskDelay(2);}
}void system_init(void *pvParameter){SystemInit();dac_init();serial_init();//single_adc_init();muiltichannel_adc_init();command_buf xQueueCreate(100, sizeof(struct command_t));vTaskDelete(NULL);
}void print_test_task(void *pvParameter){for(;;){printf(This just test for uart\r\n);vTaskDelay(500);}
}//void adc_task(void *pvParameter){
// // 软件开启ADC1转换
// ADC_SoftwareStartConvCmd(ADC1, ENABLE);
// for(;;){
// printf(Current ADC voltage is %f\r\n, ADCConvertedValue * 3.3/4096);
// vTaskDelay(5);
// }
//}void muiltichannel_adc_task(void *pvParameter){muiltichannel_adc_enable();for(;;){printf(PA1 voltage is %.2f\r\n, ADC_DualConvertedValueTab[0] * 3.3 / 4096);printf(PA2 voltage is %.2f\r\n, ADC_DualConvertedValueTab[1] * 3.3 / 4096);printf(PA3 voltage is %.2f\r\n, ADC_DualConvertedValueTab[2] * 3.3 / 4096);printf(PA5 voltage is %.2f\r\n, ADC_DualConvertedValueTab[3] * 3.3 / 4096);vTaskDelay(2);}
}int main(void)
{xTaskCreate(system_init, system init task, 500, NULL, 2, NULL);//xTaskCreate(print_test_task, uart print test, 200, NULL, 1, NULL);/*xTaskCreate(dac_task, dac task for led breath, 1000, NULL, 1, NULL);*///xTaskCreate(adc_task, adc test task, 1000, NULL, 1, NULL);/*xTaskCreate(muiltichannel_adc_task, mNuiltichannel adc test task, 1000, NULL, 1, NULL);*/xTaskCreate(sdio_test_task, sdio test, 200, NULL, 1, NULL);vTaskStartScheduler();
}#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{while (1){printf(Assert error in %s, line %d\r\n,file, line);}
}
#endifvoid vApplicationStackOverflowHook( TaskHandle_t xTask,char * pcTaskName ){while (1){printf(Malloc error for %s\r\n,pcTaskName);}
}void SD_EraseTest(void)
{if (Status SD_OK){/* Erase NumberOfBlocks Blocks of WRITE_BL_LEN(512 Bytes) */Status SD_Erase(0x00, (BLOCK_SIZE * NUMBER_OF_BLOCKS));}if (Status SD_OK){Status SD_ReadMultiBlocks(Buffer_MultiBlock_Rx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS);/* Check if the Transfer is finished */Status SD_WaitReadOperation();/* Wait until end of DMA transfer */while(SD_GetStatus() ! SD_TRANSFER_OK);}/* Check the correctness of erased blocks */if (Status SD_OK){EraseStatus eBuffercmp(Buffer_MultiBlock_Rx, MULTI_BUFFER_SIZE);}if(EraseStatus PASSED){printf(sdio erase test passed\r\n);}else{printf(sdio erase test failed\r\n);}
}void SD_SingleBlockTest(void)
{/* Fill the buffer to send */Fill_Buffer(Buffer_Block_Tx, BLOCK_SIZE, 0x320F);if (Status SD_OK){/* Write block of 512 bytes on address 0 */Status SD_WriteBlock(Buffer_Block_Tx, 0x00, BLOCK_SIZE);/* Check if the Transfer is finished */Status SD_WaitWriteOperation();while(SD_GetStatus() ! SD_TRANSFER_OK);}if (Status SD_OK){/* Read block of 512 bytes from address 0 */Status SD_ReadBlock(Buffer_Block_Rx, 0x00, BLOCK_SIZE);/* Check if the Transfer is finished */Status SD_WaitReadOperation();while(SD_GetStatus() ! SD_TRANSFER_OK);}/* Check the correctness of written data */if (Status SD_OK){TransferStatus1 Buffercmp(Buffer_Block_Tx, Buffer_Block_Rx, BLOCK_SIZE);}if(TransferStatus1 PASSED){printf(sdio single block test passed\r\n);}else{printf(sdio single block test failed\r\n);}
}void SD_MultiBlockTest(void)
{/*--------------- Multiple Block Read/Write ---------------------*//* Fill the buffer to send */Fill_Buffer(Buffer_MultiBlock_Tx, MULTI_BUFFER_SIZE, 0x0);if (Status SD_OK){/* Write multiple block of many bytes on address 0 */Status SD_WriteMultiBlocks(Buffer_MultiBlock_Tx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS);/* Check if the Transfer is finished */Status SD_WaitWriteOperation();while(SD_GetStatus() ! SD_TRANSFER_OK);}if (Status SD_OK){/* Read block of many bytes from address 0 */Status SD_ReadMultiBlocks(Buffer_MultiBlock_Rx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS);/* Check if the Transfer is finished */Status SD_WaitReadOperation();while(SD_GetStatus() ! SD_TRANSFER_OK);}/* Check the correctness of written data */if (Status SD_OK){TransferStatus2 Buffercmp(Buffer_MultiBlock_Tx, Buffer_MultiBlock_Rx, MULTI_BUFFER_SIZE);}if(TransferStatus2 PASSED){printf(sdio muilti block test passed\r\n);}else{printf(sdio muilti block test error\r\n);}
}TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint32_t BufferLength)
{while (BufferLength--){if (*pBuffer1 ! *pBuffer2){return FAILED;}pBuffer1;pBuffer2;}return PASSED;
}void Fill_Buffer(uint8_t *pBuffer, uint32_t BufferLength, uint32_t Offset)
{uint16_t index 0;/* Put in global buffer same values */for (index 0; index BufferLength; index){pBuffer[index] index Offset;}
}TestStatus eBuffercmp(uint8_t* pBuffer, uint32_t BufferLength)
{while (BufferLength--){/* In some SD Cards the erased state is 0xFF, in others its 0x00 */if ((*pBuffer ! 0xFF) (*pBuffer ! 0x00)){return FAILED;}pBuffer;}return PASSED;
}
以上的大部分内容都是复制的STM32F10x_StdPeriph_Lib_V3.5.0/Project/STM32F10x_StdPeriph_Examples/SDIO/uSDCard/main.c的内容。只是在此基础上加入了freertos的格式将测试最后通过和出错的提示方式全部使用串口打印出来。 下面是串口显示的打印结果
sdio erase test passed
sdio single block test passed
sdio muilti block test passed至此sdio基本驱动移植成功可以移植fatfs了。