打印
[STM32F1]

ST分享大集结 stm32 SD卡分享

[复制链接]
楼主: hanzhen654
手机看帖
扫描二维码
随时随地手机跟帖
21
hanzhen654|  楼主 | 2017-11-24 22:47 | 只看该作者 回帖奖励 |倒序浏览

相互学习,大家要懂得分享。

使用特权

评论回复
22
sopc12| | 2017-11-25 09:35 | 只看该作者
感谢楼主分享!又补了一课SD卡知识

使用特权

评论回复
23
hanzhen654|  楼主 | 2017-11-26 12:04 | 只看该作者

void SPI1_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        SPI_InitTypeDef  SPI_InitStructure;

    /* SPI的IO口和SPI外设打开时钟 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

    /* SPI的IO口设置 */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_Init(GPIOA, &GPIO_InitStructure);
        GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); //PA5.6.7上拉
/***************************************************************************/
/************************* 设置SPI的参数 ***********************************/
/***************************************************************************/
       
        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//选择全双工SPI模式
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;     //主机模式
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位SPI
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;       //时钟悬空高电平
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;      //在第二个时钟采集数据
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                  //Nss使用软件控制
        /* 选择波特率预分频为256 */
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//从最高位开始传输
        SPI_InitStructure.SPI_CRCPolynomial = 7;
       
        SPI_Cmd(SPI1, ENABLE);
        SPI_Init(SPI1, &SPI_InitStructure);
}      

使用特权

评论回复
24
hanzhen654|  楼主 | 2017-11-26 12:04 | 只看该作者
void SPI2_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        SPI_InitTypeDef  SPI_InitStructure;

    /* SPI的IO口和SPI外设打开时钟 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

    /* SPI的IO口设置 */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_Init(GPIOB, &GPIO_InitStructure);

/***************************************************************************/
/************************* 设置SPI的参数 ***********************************/
/***************************************************************************/
       
        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//选择全双工SPI模式
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;     //主机模式
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位SPI
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;       //时钟悬空高电平
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;      //在第二个时钟采集数据
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                  //Nss使用软件控制
        /* 选择波特率预分频为256 */
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//从最高位开始传输
        SPI_InitStructure.SPI_CRCPolynomial = 7;
       
        SPI_Cmd(SPI2, ENABLE);
        SPI_Init(SPI2, &SPI_InitStructure);
}      

使用特权

评论回复
25
hanzhen654|  楼主 | 2017-11-26 12:06 | 只看该作者
void SPI1_SetSpeed(uint8_t speed)
{
        SPI1->CR1 &= 0xFFC7;
        SPI1->CR1 |= speed;
        SPI_Cmd(SPI1, ENABLE);
       
}

使用特权

评论回复
26
hanzhen654|  楼主 | 2017-11-26 12:06 | 只看该作者
void SPI2_SetSpeed(uint8_t Speed)
{
       
        SPI2->CR1 &= 0xFFC7;
        SPI2->CR1 |= Speed;
        SPI_Cmd(SPI2,ENABLE);
                        
}

使用特权

评论回复
27
hanzhen654|  楼主 | 2017-11-26 12:12 | 只看该作者
uint8_t SPI1_WriteReadData(uint8_t dat)
{
        uint16_t i = 0;

    /* 当发送缓冲器空 */       
        while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
        {
                i++;
                if(i > 10000)
                {
                        return 0xFF;
                }
        }
       
    /* 发送数据 */
           SPI_I2S_SendData(SPI1, dat);
       
        /* 等待接收缓冲器为非空 */
        while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
       
        /* 将读取到的数值返回 */
        return SPI_I2S_ReceiveData(SPI1);               
}

使用特权

评论回复
28
hanzhen654|  楼主 | 2017-11-26 12:13 | 只看该作者
uint8_t SPI2_WriteReadData(uint8_t dat)
{
        uint16_t i = 0;

    /* 当发送缓冲器空 */       
        while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
        {
                i++;
                if(i > 10000)
                {
                        return 0xFF;
                }
        }
       
    /* 发送数据 */
           SPI_I2S_SendData(SPI2, dat);
       
        /* 等待接收缓冲器为非空 */
        while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
       
        /* 将读取到的数值返回 */
        return SPI_I2S_ReceiveData(SPI2);               
}

使用特权

评论回复
29
hanzhen654|  楼主 | 2017-11-26 12:14 | 只看该作者
初始化SD使用的IO和SPI
static void SD_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOG, ENABLE);
       
        /* SD_CS PG14/ FLASH_CS PG13 */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_Init(GPIOG, &GPIO_InitStructure);
        GPIO_SetBits(GPIOG, GPIO_Pin_14);
        GPIO_SetBits(GPIOG, GPIO_Pin_13);
       
        /* ENC28J60_CS PB12 */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_SetBits(GPIOB, GPIO_Pin_12); //避免影响SD卡

        SPI2_Config();
}

使用特权

评论回复
30
hanzhen654|  楼主 | 2017-11-26 12:15 | 只看该作者
向SD卡发送一个命令
static uint8_t SD_WriteCmd(uint8_t cmd, uint32_t dat, uint8_t crc)
{         
        uint8_t r1 = 0;
        uint16_t i = 0;

        /* 复位SD卡,取消上次片选 */
        SD_CS_SET;
        SPI2_WriteReadData(0xFF);         //额外提供8个时钟

        SD_CS_CLR;
        while(SPI2_WriteReadData(0xFF) != 0xFF) //等待卡是否准备好
        {
                i++;
                if(i > 100)
                {
                        return 0xFF;                         //等待失败返回
                }
        }

使用特权

评论回复
31
hanzhen654|  楼主 | 2017-11-26 12:31 | 只看该作者
/* 发送数据 */
        SPI2_WriteReadData(cmd | 0x40);

        SPI2_WriteReadData(dat >> 24);     //发送Dat的最高8位
        SPI2_WriteReadData(dat >> 16);
        SPI2_WriteReadData(dat >> 8);
        SPI2_WriteReadData(dat & 0x00FF);

        SPI2_WriteReadData(crc);
        if(cmd == SD_CMD12)                 //如果是停止数据传输命令,额外多发一个时钟
        {
                SPI2_WriteReadData(0xFF);
        }

        i = 0;
        do
        {
                r1 = SPI2_WriteReadData(0xFF);       
                i++;
                if(i > 100)
                {
                        return 0xFF;
                }
        }
        while((r1 & 0x80) != 0);   //发送成功的最高位是0

        return r1;
}

使用特权

评论回复
32
hanzhen654|  楼主 | 2017-11-26 12:32 | 只看该作者
初始化SD卡.
int8_t SD_Init(void)
{
        uint8_t r1, buf[4];
        uint16_t i = 0;

        SD_GPIO_Config();
       
        /* 将SD卡通信模式转换为SPI模式,上电默认是用DAT0作数据线 */
        /* 接到CMD0时,CS信号有效,SPI模式启动 */
        for(i=0; i<0x0F; i++)//初始时,先发送至少74个时钟,这个是必须的。
        {
                SPI2_WriteReadData(0xFF);         //发送8*16个
        }

        //当读取到0x01的时候表示初始化成功
        i = 0;
        while(SD_WriteCmd(SD_CMD0, 0, 0x95) != 0x01)
        {
                i++;
                if(i > 100)
                {
                        return 0xFF;        //初始化失败返回0
                }
        }
               
        /* 发送CMD8,检测是否SD V2.0 */
        i = 0;
        do
        {
                i++;
                if(i > 100)        //若是发送超过次数跳出循环管
                {
                        break;
                }
                r1 = SD_WriteCmd(SD_CMD8, 0x01AA, 0x87);
        }
        while(r1 != 0x01); //发送CMD8
       
        if(r1 == 0x01)     //如果CMD8有回应说明是SD V2.0协议
        {
                /* 读取CMD8的返回值,检测是否支持电压 */
                /* 读取CMD8的返回值,检测是否支持电压 */
                for(i=0; i<4; i++)
                {
                        buf[i] = SPI2_WriteReadData(0xFF);
                }
               
                /* 卡电压不支持电压,返回错误 */
                if((buf[2] != 0x01) || (buf[3] != 0xAA))
                {
                        return 0xFF;
                }
               
                /* 初始化SD卡 */
                i = 0;
                do
                {
                        i++;
                        if(i > 100)
                        {
                                return 0xFF;   //返回失败
                        }

                        SD_WriteCmd(SD_CMD55, 0, 0x01);
                        r1 = SD_WriteCmd(SD_CMD41, 0x40000000, 0x01);
                }
                while(r1 != 0);

                /* 检测是SDHC卡还是SD卡 */
                i = 0;
                while(SD_WriteCmd(SD_CMD58, 0, 0x01) != 0)
                {
                        i++;
                        if(i > 100)
                        {
                                SD_TYPE = SD_TYPE_ERR;
                                break;
                        }               
                }

                /* 读取OCR */
                for(i=0; i<4; i++)
                {
                        buf[i] = SPI2_WriteReadData(0xFF);
                }

                if(buf[0] & 0x40)
                {
                        SD_TYPE = SD_TYPE_V2HC;
                }
                else
                {
                        SD_TYPE = SD_TYPE_V2;
                }       
        }
                       
        else //否则就是SD V1.0或者MMC V3
        {
                SD_WriteCmd(SD_CMD55, 0x00, 0x01);
                r1 = SD_WriteCmd(SD_CMD41, 0x00, 0x01);

                if(r1 <= 1)           //对CMD41有回应说明是SD V1.0
                {
                        SD_TYPE = SD_TYPE_V1;         //是V1.0卡
                        i = 0;
                        do
                        {
                                if(i > 100)
                                {
                                        return 0xFF;
                                }

                                SD_WriteCmd(SD_CMD55, 0x00, 0x01);
                                r1 = SD_WriteCmd(SD_CMD41, 0x00, 0x01);       
                        }
                        while(r1 != 0);       
                }

                else                  //没有回应说明是MMC V3
                {
                        SD_TYPE = SD_TYPE_MMC;         //卡类型是MMC卡
                        i = 0;
                        while(SD_WriteCmd(SD_CMD1, 0, 0x01) != 0)
                        {
                                i++;
                                if(i > 100)
                                {
                                        return 0xFF;
                                }
                        }       
                }
        }               

        SD_CS_SET;                   //取消片选
        SPI2_WriteReadData(0xFF);
//        SPI2_SetSpeed(SPI_BaudRatePrescaler_2);

        return 0;
}

使用特权

评论回复
33
hanzhen654|  楼主 | 2017-11-26 12:33 | 只看该作者
读取SD卡的内存大小
int8_t SD_ReadCapacity(uint32_t *capacity)
{
        uint8_t csdValue[16];
        uint16_t n, i = 0;

        /* 发送命令 */
        while(SD_WriteCmd(SD_CMD9, 0, 0x01) != 0);
        {
                i++;
                if(i > 100)
                {
                        return 0xFF;  //发送命令失败
                }
        }

        /* 等待起始令牌0XFE */
        i = 0;
        while(SPI2_WriteReadData(0xFF) != 0xFE)
        {
                i++;
                if(i > 500)
                {
                        return 0xFF;
                }
        }

               
        /* 读取数据 */
        for(i=0; i<16; i++)
        {
                csdValue[i] = SPI2_WriteReadData(0xFF);
        }

        /* 读取两位CRC效验 */
        SPI2_WriteReadData(0xFF);          //RCC
        SPI2_WriteReadData(0xFF);
       
        /* 取消片选 */
        SD_CS_SET;                          
        SPI2_WriteReadData(0xFF);

        /* SD V2.0的卡CSD第一个数据是0x40 */
        if((csdValue[0] & 0xC0) == 0x40)
        {
                /* 计算C_SIZE,在CSD[69:48] */
                *capacity = csdValue[9] + ((uint16_t)csdValue[8] << 8) + 1;

                /* 实际上就是乘以1024 */
                *capacity = (*capacity) << 10;//得到扇区数                       
        }
        else   
        {
                /* 内存算法是 capacity = BLOCKNR * BLOCK_LEN */
                /* BLOCKNR = (C_SIZE + 1) * MULT; */
                /* BLOCK_LEN = (READ_BL_LEN < 12) 或2^(READ_BL_LEN) */

                /* 计算BLOCK_LEN,C_SIZE_MULT在CSD[49:47];READ_BL_LEN在CSD[83:80] */
                n = (csdValue[5] & 0x0A) + ((csdValue[10] & 0x80) >> 7)
                         + ((csdValue[9] & 0x03) << 1) + 2;

                /* 计算C_SIZE,C_SIZE在CSD[73:62] */
                *capacity = (csdValue[8] >> 6) + ((uint16_t)csdValue[7] << 2)
                            + ((uint16_t)(csdValue[6] & 3) << 10) + 1;
                *capacity = (*capacity) << (n - 9);//得到扇区数       
        }

        return 0;               
}

使用特权

评论回复
34
hanzhen654|  楼主 | 2017-11-26 12:35 | 只看该作者
SD_ReadData
static int8_t SD_ReadData(uint8_t *buf)
{
        uint16_t i;

        /* 等待起始令牌0XFE */
        i = 0;
        while(SPI2_WriteReadData(0xFF) != 0xFE)
        {
                i++;
                if(i > 0x0FFF)
                {
                        return 0xFF;
                }
        }
       
        /* 接收数据 */
        for(i=0; i<512; i++)
        {
                *buf = SPI2_WriteReadData(0xFF);
                buf++;       
        }

        /* 读完数据再读两位CRC效验,但是我们可以不需要它们 */
        SPI2_WriteReadData(0xFF);
        SPI2_WriteReadData(0xFF);
       
        return 0;                                                 
}

使用特权

评论回复
35
hanzhen654|  楼主 | 2017-11-26 12:35 | 只看该作者
读取扇区的数据
int8_t SD_ReadDisk(uint8_t *buf, uint32_t sector, uint8_t num)
{
        uint16_t i;

        if(SD_TYPE != SD_TYPE_V2HC)
        {
                sector <<= 9; //转换位字节地址
        }
       
        if(num == 1)
        {
                /* 发送读取命令 */
                i = 0;
                while(SD_WriteCmd(SD_CMD17, sector, 0x01) != 0);
                {
                        i++;
                        if(i > 100)
                        {
                                return 0xFF;  //命令无反应,表明发送命令失败
                        }       
                }

                /*  接收数据  */
                if(SD_ReadData(buf) != 0)
                {
                        return 0xFF;
                }               
        }
        else
        {
                /* 发送连续读取命令 */
                i = 0;
                while(SD_WriteCmd(SD_CMD18, sector, 0x01) != 0);
                {
                        i++;
                        if(i > 100)
                        {
                                return 0xFF;  //命令无反应,表明发送命令失败
                        }       
                }
               
                /* 接收数据 */
                while(num--)
                {
                        /*  接收数据  */
                        if(SD_ReadData(buf) != 0)
                        {
                                return 0xFF;
                        }
                        buf += 512;                       
                }
                SD_WriteCmd(SD_CMD12, 0, 0x01); //发送停止信号
        }
       
        /* 取消片选 */
        SD_CS_SET;
        SPI2_WriteReadData(0xFF);       

        return 0;
}

使用特权

评论回复
36
一路向北lm| | 2017-11-26 12:51 | 只看该作者
感谢分享,SPI总线写的不错。

使用特权

评论回复
37
hanzhen654|  楼主 | 2017-11-26 22:04 | 只看该作者
static int8_t SD_WriteData(uint8_t *buf, uint8_t cmd)
{
        uint16_t i;

        /*  发送若干个时钟,等待SD卡准备好  */
        i = 0;
        while(SPI2_WriteReadData(0xFF) != 0xFF)
        {
                if(i > 0x0FFF)
                {
                        return 0xFF;       
                }       
        }

        /* 发送命令 */
        SPI2_WriteReadData(cmd);

        /* 开始写入数据 */
        for(i = 0; i<512; i++)
        {
                SPI2_WriteReadData(*buf);
                buf++;
        }

        /* 发送两位CRC效验码,随便发 */
        SPI2_WriteReadData(0xFF);
        SPI2_WriteReadData(0xFF);

        /* 读取返回值 */
        i = SPI2_WriteReadData(0xFF);

        if((i & 0x1F) != 0x05)          //判断是否写成功
        {
                 SD_CS_SET;
                SPI2_WriteReadData(0xFF);
                return 0xFF;
        }

        return 0;
}

使用特权

评论回复
38
hanzhen654|  楼主 | 2017-11-26 22:05 | 只看该作者
写多个扇区
int8_t SD_WriteDisk(uint8_t *buf, uint32_t sector, uint8_t num)
{
        uint8_t i;

        if(SD_TYPE != SD_TYPE_V2HC)
        {
                sector <<= 9; //转换位字节地址
        }
       
        /* - 只写一个扇区 - */
        if(num == 1)
        {
                /* 发送写命令 */
                i = 0;
                while(SD_WriteCmd(SD_CMD24, sector, 0x01) != 0);
                {
                        i++;
                        if(i > 100)
                        {
                                return 0xFF;  //命令无反应,表明发送命令失败
                        }       
                }
       
                if(SD_WriteData(buf, 0xFE) != 0)
                {
                        return 0xFF;       
                }
        }

        /* - 写多个扇区 - */
        else
        {
                if(SD_TYPE == SD_TYPE_MMC)                  //如果是MMC卡
                {
                        SD_WriteCmd(SD_CMD55, 0, 0X01);       
                        SD_WriteCmd(SD_CMD23, num, 0X01); //写入前先擦除num个扇区里面的数据       
                }
                /* 发送连续写命令 */
                i = 0;
                while(SD_WriteCmd(SD_CMD25, sector, 0x01) != 0);
                {
                        i++;
                        if(i > 100)
                        {
                                return 0xFF;  //命令无反应,表明发送命令失败
                        }       
                }

                /* - 开始写数据 - */
                while(num--)
                {
                        if(SD_WriteData(buf, 0xFC) != 0)
                        {
                                return 0xFF;       
                        }
                        buf += 512;       
                }

                /*  发送若干个时钟,等待SD卡准备好  */
                i = 0;
                while(SPI2_WriteReadData(0xFF) != 0xFF)
                {
                        if(i > 0x0FFF)
                        {
                                return 0xFF;       
                        }       
                }
       
                /* 发送结束命令 */
                SPI2_WriteReadData(0xFD);

        }

        SD_CS_SET;
        SPI2_WriteReadData(0xFF);

        return 0;
}

使用特权

评论回复
39
hanzhen654|  楼主 | 2017-11-26 22:06 | 只看该作者
void USART1_Config(uint16_t baudRate)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;

        /* 打开RCC时钟 */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

        /* 设置TXD的GPIO参数 */
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;               //复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                     //串口输出PA9

        /* 初始化串口输入IO */
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        /* 设置RXD的GPIO参数 */
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;          //模拟输入
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                     //串口输入PA10

        GPIO_Init(GPIOA, &GPIO_InitStructure);

        /* 设置USART的参数 */
        USART_InitStructure.USART_BaudRate = baudRate;                  //波特率
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;     //数据长8位
        USART_InitStructure.USART_StopBits = USART_StopBits_1;          //1位停止位
        USART_InitStructure.USART_Parity = USART_Parity_No;             //无效验
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//失能硬件流
        USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //开启发送和接受模式
       
    /* 初始化USART1 */
        USART_Init(USART1, &USART_InitStructure);
       
        /* 使能USART1 */
        USART_Cmd(USART1, ENABLE);
#ifdef USE_USART1RX_INTERRUPT  
    USART1_NVIC_RxConfig();
    USART_ITConfig(USART1, USART_IT_RXNE ,ENABLE);
#endif                
}

使用特权

评论回复
40
hanzhen654|  楼主 | 2017-11-26 22:07 | 只看该作者
串口2初始化
void USART2_Config(uint16_t baudRate)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;

        /* 打开RCC时钟 */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

        /* 设置TXD的GPIO参数 */
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;               //复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                     //串口输出PA9

        /* 初始化串口输入IO */
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        /* 设置RXD的GPIO参数 */
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;          //模拟输入
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;                      //串口输入PA10

        GPIO_Init(GPIOA, &GPIO_InitStructure);

        /* 设置USART的参数 */
        USART_InitStructure.USART_BaudRate = baudRate;                  //波特率
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;     //数据长8位
        USART_InitStructure.USART_StopBits = USART_StopBits_1;          //1位停止位
        USART_InitStructure.USART_Parity = USART_Parity_No;             //无效验
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//失能硬件流
        USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //开启发送和接受模式
       
    /* 初始化USART1 */
        USART_Init(USART2, &USART_InitStructure);
       
        /* 使能USART1 */
        USART_Cmd(USART2, ENABLE);
#ifdef USE_USART2RX_INTERRUPT   
    USART2_NVIC_RxConfig();
    USART_ITConfig(USART2, USART_IT_RXNE ,ENABLE);
#endif                
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则