无法使用 STM32F407 上的 Chan FatFs 库通过 SPI 写入 SD 卡文件

     2023-02-19     293

关键词:

【中文标题】无法使用 STM32F407 上的 Chan FatFs 库通过 SPI 写入 SD 卡文件【英文标题】:Can't write to SD card file with SPI using Chan FatFs library on a STM32F407 【发布时间】:2017-06-19 15:46:40 【问题描述】:

我正在使用带有 STM32F407 芯片的 STM32F4 开发板。为了与 SD 卡通信,我使用 SPI1,并使用 Chan 创建的 FatFs 库。

所以问题的要点是我已经成功地在 SD 卡上创建了一个文件,我可以从中读取。但是,当我尝试写入文件时,它要么损坏文件,要么打印像“46040EDD-C”这样的垃圾数据。如果我查看内存,我可以看到我写的东西,但不知何故,它被写入了错误的内存地址。

我遇到的另一个问题是,第一次创建文件并尝试使用 f_write 对其进行写入时,我得到了回复 FR_DISK_ERR。错误来自试图创建一个集群链,当我通过代码时它工作正常。因此,可能会缺少一些延迟。下次我运行程序时它会工作,并且 f_write 返回 FR_OK。

我不确定这些问题是否相关。我一直在努力让它工作大约两个星期,并且希望能得到任何帮助。谢谢。

代码:

main.c

int main(void)

    int i;

    //SD CARD INIT

    //Fatfs object
    FATFS FatFs;
    //File object
    FIL fil;
    UINT fa;

    FRESULT res_mount, res_open, res_seek, res_write;

    delay(10ms);
    res_mount = f_mount(&FatFs, "", 1);
    if (res_mount == FR_OK) 
        GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
        delay(10ms);
        res_open = f_open(&fil, "test.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
        if (res_open == FR_OK) 
            GPIO_ToggleBits(GPIOD, GPIO_Pin_13);
            delay(10ms);
            res_seek = f_lseek(&fil, f_size(&fil));
            if(res_seek == FR_OK)
            
                delay(10ms);
                GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
                res_write = f_write(&fil, "Alpha Beta\n", 11, &fa);
                if (fa > 0 && res_write == FR_OK) 
                    GPIO_ToggleBits(GPIOD, GPIO_Pin_15);
                    f_sync(&fil);
                
            
            f_close(&fil);
        
        f_mount(0, "", 1);
    

    while(1);

    //SD CARD INIT END

我编辑的 Chans diskio.c 文件。

#include "diskio.h"     /* FatFs lower layer API */

/* Definitions of physical drive number for each drive */
#define DEV_RAM     0   /* Example: Map Ramdisk to physical drive 0 */
#define DEV_MMC     1   /* Example: Map MMC/SD card to physical drive 1 */
#define DEV_USB     2   /* Example: Map USB MSD to physical drive 2 */

static volatile DSTATUS Stat = STA_NOINIT;  /* Disk status */

static BYTE CardType;   /* Card type flags (b0:MMC, b1:SDv1, b2:SDv2, b3:Block addressing) */



/*-----------------------------------------------------------------------*/
/* Get Drive Status                                                      */
/*-----------------------------------------------------------------------*/

DSTATUS disk_status (
    BYTE pdrv       /* Physical drive nmuber to identify the drive */
)

    if(pdrv) 
        return STA_NOINIT;      // Supports only drive 0

    return Stat;




/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */
/*-----------------------------------------------------------------------*/

DSTATUS disk_initialize (
    BYTE pdrv               /* Physical drive nmuber to identify the drive */
)

    if (Stat & STA_NODISK) 
        return Stat;    /* No card in the socket? */

    //SLOW

    uint8_t ty = 0;
    ty = SD_CARD_InitialiseCard();

    CardType = ty;

    if(ty)
        Stat &= ~STA_NOINIT;

    return Stat;




/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */
/*-----------------------------------------------------------------------*/

DRESULT disk_read (
    BYTE pdrv,      /* Physical drive nmuber to identify the drive */
    BYTE *buff,     /* Data buffer to store read data */
    DWORD sector,   /* Start sector in LBA */
    UINT count      /* Number of sectors to read */
)

    //DRESULT res;
    //int result;
    if(pdrv || !count)
        return RES_PARERR;
    if (Stat & STA_NOINIT)
        return RES_NOTRDY;

    if(!(CardType & SDCARD_BLOCK))
        sector *= 512;

    if(count == 1)
    
        if((SD_CARD_Cmd(READ_SINGLE_BLOCK, sector) == 0x00) &&  SD_CARD_Read(buff, 512))
            count = 0;
    
    else
    
        if(SD_CARD_Cmd(READ_MULTIPLE_BLOCKS, sector) == 0)
        
            do
            
                if(!SD_CARD_Read(buff, 512))
                    break;
                buff += 512;
            
            while(--count);
            SD_CARD_Cmd(STOP_TRANSMISSION, 0);
        
    

    return count ? RES_ERROR : RES_OK;




/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */
/*-----------------------------------------------------------------------*/

DRESULT disk_write (
    BYTE pdrv,          /* Physical drive nmuber to identify the drive */
    const BYTE *buff,   /* Data to be written */
    DWORD sector,       /* Start sector in LBA */
    UINT count          /* Number of sectors to write */
)

    //DRESULT res;
    //int result;

    if (pdrv || !count)
        return RES_PARERR;
    if (Stat & STA_NOINIT)
        return RES_NOTRDY;
    if (Stat & STA_PROTECT)
        return RES_WRPRT;

    if(!(CardType & SDCARD_BLOCK))
        sector *= 512;

    if(count == 1)
    
        if((SD_CARD_Cmd(WRITE_SINGLE_BLOCK, sector) == 0x00) &&  SD_CARD_Write(buff, 0xFE))
            count = 0;
    
    else
    
        if (CardType & SDCARD_SDC)
            SD_CARD_Cmd(SET_WR_BLOCK_ERASE_COUNT, count);

        if(SD_CARD_Cmd(WRITE_MULTIPLE_BLOCKS, sector) == 0)
        
            do
            
                if(!SD_CARD_Write(buff, 0xFC))
                    break;

                buff += 512;
            
            while(--count);

            if (!SD_CARD_Write(0, 0xFD))    /* STOP_TRAN token */
                count = 1;
        
    

    return count ? RES_ERROR : RES_OK;




/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */
/*-----------------------------------------------------------------------*/

DRESULT disk_ioctl (
    BYTE pdrv,      /* Physical drive nmuber (0..) */
    BYTE cmd,       /* Control code */
    void *buff      /* Buffer to send/receive control data */
)

    //DRESULT res;
    //int result;

    //NOT NEEDED AT THE MOMENT

    return RES_PARERR;


DWORD get_fattime (void)

    /* Pack date and time into a DWORD variable */
    return    ((DWORD)(2017 - 1980) << 25)
            | ((DWORD)1 << 21)
            | ((DWORD)1 << 16)
            | ((DWORD)0 << 11)
            | ((DWORD)0 << 5)
            | ((DWORD)0 >> 1);

SD_CARD.c:

#include "SD_CARD.h"

/*
SPI1(GPIOA):    -   Type:   -   SD CARD:
Pin4            -   CS      -   Pin2
Pin5            -   SCLK    -   Pin5
Pin6            -   MISO    -   Pin7
Pin7            -   MOSI    -   Pin3
*/
uint8_t SD_CARD_InitialiseCard()

    INT i = 0;

    SPI1ENABLE();

    ChipSelect(SPI1, HIGH);
    for(i = 0;i < 16;i++)
        SPI_Send(SPI1, 0xFF);

    for(i = 0;i < 0xFFFF;i++);

    while(SD_CARD_Cmd(GO_IDLE_STATE, 0) != R1_IDLE_STATE); //CMD0

    uint32_t r = SD_CARD_Cmd(SEND_IF_COND, 0x1AA); //CMD8
    if(r == 0x1AA)
        return SD_CARD_InitialiseCardV2();
    else if(r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND))
        return SD_CARD_InitialiseCardV1();
    else
        return SDCARD_FAIL;


uint8_t SD_CARD_WriteRead(INT arg)

    SPI_Send(SPI1, arg);
    uint8_t test = SPI_Read(SPI1);
    return test;


uint8_t SD_CARD_InitialiseCardV1()

    uint8_t cmd;
    INT i = 0;

    if(SD_CARD_Cmd(SD_SEND_OP_COND, 0x40040000) <= 1) //ACMD41 - set to 3V, use 0x40200000 for 3V3
        cmd = SD_SEND_OP_COND;
    else
        cmd = SEND_OP_COND;

    for(i = 0; i < SD_COMMAND_TIMEOUT;i++)
    
        if(SD_CARD_Cmd(cmd, 0) == 0) //CMD1 or ACMD41
           
            // Set block length to 512 (CMD16)
            if(SD_CARD_Cmd(SET_BLOCKLEN, 512) != 0) //CMD16
                return SDCARD_FAIL;

            //Init: SEDCARD_V1
            if(cmd == SD_SEND_OP_COND)
                return SDCARD_V1;
            else
                return SDCARD_MMCV3;
        
    

    //Timeout waiting for v1.x card
    return SDCARD_FAIL;


uint8_t SD_CARD_InitialiseCardV2()

    INT i = 0;
    INT j = 0;

    for(i = 0;i < SD_COMMAND_TIMEOUT;i++)
    
        for(j = 0;j < 0xFF;j++);
        if(SD_CARD_Cmd(SD_SEND_OP_COND, 0x40040000) == 0) //ACMD41 - set to 3V, use 0x40200000 for 3V3
        
            uint32_t ocr = SD_CARD_Cmd(READ_OCR, 0); //CMD58
            return (ocr & 0x40000000) ? SDCARD_V2 | SDCARD_BLOCK : SDCARD_V2;
        
    

    //Timed out waiting for v2.x card
    return SDCARD_FAIL;


uint32_t SD_CARD_Cmd(INT cmd, INT arg)

    struct command_fields com;
    com.start_bit = 0;
    com.transmitter_bit = 1;
    com.index = cmd;
    com.argument = arg;
    if(cmd == GO_IDLE_STATE)
        com.crc = 0x4A;
    else if(cmd == SEND_IF_COND)
        com.crc = 0x43;
    else
        com.crc = 0x7F;
    com.end_bit = 1;

    if(cmd == SD_STATUS | cmd == SET_WR_BLOCK_ERASE_COUNT | cmd == SD_SEND_OP_COND) //ACMDx
        SD_CARD_Cmd(APP_CMD, 0); //CMD55

    SD_CARD_WriteCom(&com);

    if(cmd == SEND_IF_COND)
        return SD_CARD_RecieveR7();
    else if(cmd == READ_OCR)
        return SD_CARD_RecieveR3();
    else
        return SD_CARD_RecieveR1();


void SD_CARD_WriteCom(struct command_fields *com)


    ChipSelect(SPI1, LOW);
    SPI_Send(SPI1, 0xFF);
    SPI_Send(SPI1, (0xFF & ((com->start_bit << 7) | (com->transmitter_bit << 6) | com->index)));
    SPI_Send(SPI1, (0xFF & (com->argument >> 24)));
    SPI_Send(SPI1, (0xFF & (com->argument >> 16)));
    SPI_Send(SPI1, (0xFF & (com->argument >> 8)));
    SPI_Send(SPI1, (0xFF & com->argument));
    SPI_Send(SPI1, (0xFF & ((com->crc << 1) | com->end_bit)));


INT SD_CARD_Write(const BYTE *buffer, BYTE token)

    INT i = 0;
    ChipSelect(SPI1, LOW);

    while(SD_CARD_WriteRead(0xFF) != 0xFF);

    // indicate start of block
    SPI_Send(SPI1, token);

    if(token != 0xFD)
    
        // write the data
        for(i = 0;i < 512;i++)
        
            SPI_Send(SPI1, *buffer);
            buffer++;
        

        // write the checksum
        SPI_Send(SPI1, 0xFF);
        SPI_Send(SPI1, 0xFF);

        // check the repsonse token
        if(((SD_CARD_WriteRead(0xFF)) & 0x1F) != 0x05)
        
            ChipSelect(SPI1, HIGH);
            SPI_Send(SPI1, 0xFF);
            return SUCCESS;
        
    

    // wait for write to finish
    while(SD_CARD_WriteRead(0xFF) != 0xFF);

    ChipSelect(SPI1, HIGH);
    SPI_Send(SPI1, 0xFF);
    return ERROR;


INT SD_CARD_Read(BYTE *buffer, INT length)

    INT i = 0;
    ChipSelect(SPI1, LOW);

    for(i = 0; i < SD_COMMAND_TIMEOUT;i++)
    
        // read until start byte (0xFF)
        if(SD_CARD_WriteRead(0xFF) == 0xFE)
        
            // read data
            for(i = 0;i < length;i++)
                buffer[i] = SD_CARD_WriteRead(0xFF);

            SPI_Send(SPI1, 0xFF); // checksum
            SPI_Send(SPI1, 0xFF);

            ChipSelect(SPI1, HIGH);
            SPI_Send(SPI1, 0xFF);
            return SUCCESS;
        
    

    return ERROR;


uint8_t SD_CARD_RecieveR1()

    INT i;
    uint8_t response = 0xFF;
    for(i = 0;i < SD_COMMAND_TIMEOUT;i++)
    
        response = SD_CARD_WriteRead(0xFF);
        if((response == 0x00) || (response == 0x01))
        
            ChipSelect(SPI1, HIGH);
            SPI_Send(SPI1, 0xFF);
            return response;
        
    
    ChipSelect(SPI1, HIGH);
    SPI_Send(SPI1, 0xFF);
    return 0xFF;


uint32_t SD_CARD_RecieveR7()

    INT i = 0, j = 0;
    for(i = 0;i < (SD_COMMAND_TIMEOUT * 1000);i++)
    
        uint8_t response[5];
        response[0] = SD_CARD_WriteRead(0xFF);
        if(!(response[0] & 0x80))
        
                for(j = 1;j < 5;j++)
                
                    response[j] = SD_CARD_WriteRead(0xFF);
                
                ChipSelect(SPI1, HIGH);
                SPI_Send(SPI1, 0xFF);
                return ((response[1] << 24) | (response[2] << 16) | (response[3] << 8) | response[4]);
        
    
    ChipSelect(SPI1, HIGH);
    SPI_Send(SPI1, 0xFF);
    return 0xFFFFFFFF; // timeout


uint32_t SD_CARD_RecieveR3()

    uint32_t ocr = 0;
    INT response;
    for(int i=0; i < SD_COMMAND_TIMEOUT; i++)
    
        response = SD_CARD_WriteRead(0xFF);
        if(!(response & 0x80))
        
            ocr = SD_CARD_WriteRead(0xFF) << 24;
            ocr |= SD_CARD_WriteRead(0xFF) << 16;
            ocr |= SD_CARD_WriteRead(0xFF) << 8;
            ocr |= SD_CARD_WriteRead(0xFF);
            ChipSelect(SPI1, HIGH);
            SPI_Send(SPI1, 0xFF);
            return ocr;
        
    
    ChipSelect(SPI1, HIGH);
    SPI_Send(SPI1, 0xFF);
    return 0xFFFFFFFF; // timeout


INT SD_CARD_InitialiseDisk()

    if(SD_CARD_InitialiseCard() == SDCARD_FAIL)
        return SDCARD_FAIL;

    SPI_SetSpeed(SPI1, SPI_SPEED_1300KHz);
    return SUCCESS;

SPI.c:

#include "SPI.h"

void SPI1ENABLE()

    GPIO_InitTypeDef GPIO_InitStruct;
    SPI_InitTypeDef SPI_InitStruct;
    static uint8_t SPI1_ENABLED = 0;
    if(SPI1_ENABLED)
        return;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);

    GPIO_InitStruct.GPIO_Pin =  SPI1_SCLK | SPI1_MISO | SPI1_MOSI;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.GPIO_Pin =  SPI1_CS;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
    SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
    SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
    SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
    SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_Init(SPI1, &SPI_InitStruct);

    SPI_Cmd(SPI1, ENABLE);

    SPI1_ENABLED = 1;


uint8_t SPI_Read(SPI_TypeDef* SPIx)

    while(SPI1->SR & SPI_I2S_FLAG_BSY);         // wait until SPI is not busy anymore
    while(!(SPI1->SR & SPI_I2S_FLAG_RXNE));    // wait until receive complete
    return SPI_ReceiveData(SPIx);


void SPI_Send(SPI_TypeDef* SPIx, unsigned char Data)

    while(SPI1->SR & SPI_I2S_FLAG_BSY);         // wait until SPI is not busy anymore
    while(!(SPI1->SR & SPI_I2S_FLAG_TXE));    // wait until transmit complete
    SPI_SendData(SPIx, Data);
    while(!(SPI1->SR & SPI_I2S_FLAG_RXNE));    // wait until receive complete

【问题讨论】:

我认为您最好将问题发送到electronics.stackexchange.com 谢谢,会做的! 【参考方案1】:

所以我发现了我的问题。像我一样愚蠢,在我的写入函数中,我在发送 STOP_TRANs 令牌时忘记返回成功。下面是 write 函数编辑后的样子。

INT SD_CARD_Write(const BYTE *buffer, BYTE token)

    INT i = 0;
    ChipSelect(SPI1, LOW);

    while(SD_CARD_WriteRead(0xFF) != 0xFF);

    // indicate start of block
    SPI_Send(SPI1, token);

    if(token != 0xFD)
    
        // write the data
        for(i = 0;i < 512;i++)
        
            SPI_Send(SPI1, *buffer);
            buffer++;
        

        // write the checksum
        SPI_Send(SPI1, 0xFF);
        SPI_Send(SPI1, 0xFF);

        // check the repsonse token
        uint8_t resp = 0x00;
        do
        
            resp = SD_CARD_WriteRead(0xFF);
        
        while(resp == 0x00);

        if((resp & 0x1F) != 0x05)
        
            // wait for write to finish
            while(SD_CARD_WriteRead(0xFF) != 0xFF);

            SPI_Send(SPI1, 0xFF);
            ChipSelect(SPI1, HIGH);
            SPI_Send(SPI1, 0xFF);

            return SUCCESS;
        
    

    // wait for write to finish
    while(SD_CARD_WriteRead(0xFF) != 0xFF);

    SPI_Send(SPI1, 0xFF);
    ChipSelect(SPI1, HIGH);
    SPI_Send(SPI1, 0xFF);

    if(token == 0xFD)
        return SUCCESS;

    return ERROR;

【讨论】:

感谢您的回答。我试图了解为什么我的 STM32F103 项目无法将多个扇区写入 SD 卡,这个答案让我检查了 CubeMX 生成的 user_diskio.c 文件中的 xmit_datablock 函数。在您的示例中,该函数始终在 STOP_TRANS 令牌之后返回 false,因此每个多扇区写入都会失败。

stm32f407boot0在哪

参考技术A系统上的。系统上电之后,会检测两个引脚的状态,一个被标注为BOOT0,另一个是一个通用IO引脚,是可以查看到的。 查看详情

stm32f407ig开启fpu,做开方运算

STM32F407IG开启FPU,做开方运算 MDKKEIL中使用STM32F4XX芯片硬件浮点单元FPU Keil中使用STM32F4xx硬件浮点单元 STM32F4-浮点DSP库的MDK开发环境的设置 查看详情

stm32f407以太网及usbotg快速开发

...USBOTG快速开发引言想要快速完成网络协议栈和USBOTG功能,使用ST自家的工具STM32CubMx再好不过的了。如果你还不会使用,别着急下面我会一步一步的用图片告诉你如何做。软件平台:windows、STM32CubMx、keilv5硬件平台:原子的stm32f407ZGT6... 查看详情

stm32f407读保护,写保护,解锁过程芯片已设置读保护,无法读取更多信息

硬件准备:CH340USB转TTL串口一个STM32F407板子一块设置从ISP启动软件准备:1,flash_loader_demo_v2.8.0.exe或者FlashLoaderDemonstrator2.8.0.msi都可以下载地址:(两个下载地址,优选第一个,第二个备选)http://download.csdn.net/download/keith_cheung/9355... 查看详情

stm32f407开发板用户手册第10章stm32f407的flash,ram和栈使用情况(map和htm文件)

...55第10章      STM32F407的FLASH,RAM和栈使用情况(map和htm文件)本章为大家介绍编译器生成的map和htm文件进行解析,通过这两个文件可以让大家对工程代码的认识程度提升一个档次。10 查看详情

STM32F407 - SDIO | FATFS - 将文件保存到 SD 卡

...问题描述】:问题:无论卡是否存在,SD卡都已安装。我无法将文件写入sd卡。上下文:我阅读了很多书籍、文档和教程,但我找不到让它发挥作用的方法。在STMIDE调试器中,我无法像使用Python或Javascript那样得到丰富的错误。这... 查看详情

stm32f407使用keiluv5建立工程日志

目录结构Common             ——包括延时函数等公用函数STM32F4_FWLIB     ——固件库Project      &nbs 查看详情

使用 HAL 在 STM32f407 发现中将数据存储读/写到闪存中

】使用HAL在STM32f407发现中将数据存储读/写到闪存中【英文标题】:Read/writedatastorageintoFlashMemoryinSTM32f407discoveryusingHAL【发布时间】:2016-08-0413:53:08【问题描述】:我正在尝试将数据存储在闪存(非易失性存储器)中以供进一步检... 查看详情

STM32F407ZET6,DMA的多个流可以并行运行吗?

...发布时间】:2021-08-1910:52:36【问题描述】:您好,我正在使用STM32F407ZET6微控制器,我想使用DMA1的多个流。是否可以同时触发同一DMA的两个不同流将数据传输到两个不同的外围设备。(类似并行)。在高级A 查看详情

为啥我的STM32F407发现刷机软件重新插线后生效?

...效?【发布时间】:2021-05-0812:28:55【问题描述】:我正在使用Keil将软件刷新到stm32f407发现。但软件只有在我拔出JLINK电缆并重新插入时 查看详情

stm32f407开发板用户手册第13章stm32f407启动过程详解(代码片段)

...d=viewthread&tid=93255第13章      STM32F407启动过程详解本章教程主要跟大家讲STM32F407的启动过程,这里的启动过程是指从CPU上电复位执行第1条指令开始(汇编文件)到进入C程序main()函数入口之间的部分。 查看详情

stm32f407接上外部晶振后无法运行程序

...!如果总是自动重启,可能会是什么影响的? 参考技术B无法具体告知你原因,但可以试试以下方法:接上外部晶振,而在软件里面设置使用内部时钟,就写一个LED跳变程序,其它程序不要使用.看看结果如何?如果使用一步的方法,能达... 查看详情

freertos移植stm32f407(代码片段)

...基础工程1.利用Keil5创建一个STM32基础工程,建议直接使用任何一个STM32库模板。在基础工程中创建一个文件夹FREERTOS,用来存放FreeRTOS源码,该源码存放在下载的source文件夹下,然后删除不需要的 查看详情

stm32f407:usart遇到的问题

  今天初次使用STM32F407进行USART串口通讯实验,按照f103的代码写完了,发现没法发送数据,Google后发现是由于没有将端口映射到USART1,然后添加如下代码:1GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_USART1);//PB6-TX2GPIO_PinAFConfig(GPIOB,GPIO_... 查看详情

stm32f407开发板用户手册第30章stm32f407的系统bootloader之串口iap固件升级(代码片段)

...TM32F407的系统bootloader之串口IAP固件升级本章节为大家讲解使用系统bootloader做程序升级的方法,即使不依赖外部boot引脚也可以方便升级。IAP的全称是InA 查看详情

stm32f407IG SPI通信

】stm32f407IGSPI通信【英文标题】:Stm32f407IGSPIcommunication【发布时间】:2015-09-0511:42:29【问题描述】:#include<stm32f4xx.h>#include"stm32f4xx_spi.h"#include"stm32f4xx_gpio.h"#include"stm32f4xx_rcc.h"#include"config.h"voidinit_GPIO()G 查看详情

stm32f407开发板用户手册第20章stm32f407的gpio应用之无源蜂鸣器(代码片段)

...d=viewthread&tid=93255第20章      STM32F407的GPIO应用之无源蜂鸣器本章教程为大家介绍STM32F407的GPIO应用之无源蜂鸣器,蜂鸣器也是GPIO控制的经典测试例程,可以让大家对STM32F407应用有个简单 查看详情

stm32f407第3章threadxusbx协议栈移植到stm32f407(代码片段)

教程更新中:ThreadXUSBX协议栈教程更新记录贴,前5章发布(2021-10-11)-uCOS&uCGUI&emWin&embOS&TouchGFX&ThreadX-硬汉嵌入式论坛-PoweredbyDiscuz!http://www.armbbs.cn/forum.php?mod=viewthread&ti 查看详情