|
最近在研究Linux过程中有点插曲,先不表了,于是就想着把SD卡研究一下,这个以前也没有搞过,找了stm32f767的例程,在此基础上更改了一下,可以在stm32f769上使用,就开始了SD卡的研究,个人钟爱寄存器配置的,没办法,就是对ST提供的库不感冒,有相同癖好的进来探讨,闲言少叙,进入正题。! i \6 F f+ h- F8 W" ^ 看了f767板子的寄存器版本的指导书,正好也是和STM32F769DISCOVERY电路一样,都是非SPI接口的,可以参考其例程了,于是边参考st官方的例程STM32F769I-Discovery\Applications\Display\LCD_PicturesFromSDCard,边参考f767的例程,比较着修改,+ R" m2 C7 m9 N; d9 j& \0 B 先看看电路图 对应的IO分别是PG9,PG10,PB3,PB4,PD6,PD7,PI15+ `9 V' x* \, t) f 于是开始配置IO; n% L* V5 t- W5 }* B *(uint32_t *)0x40023830 |= 0x14a; //使能PORTB\D\G\I时钟 + \+ p5 \' M% }/ r9 p/ p/ P *(uint32_t *)0x40023830 |= 0x400000; //使能dma2时钟 *(uint32_t *)0x40023844 |= 0x80;//SDMMC2时钟使能- N; R3 K; g6 f% Q7 D *(uint32_t *)0x40023824 |= 0x80;//SDMMC2复位 GPIO_Set(GPIOB,PIN3|PIN4,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PB3,PB4设置 GPIO_AF_Set(GPIOB,3,10); //PB3,AF100 a' Q9 |2 F8 ^ GPIO_AF_Set(GPIOB,4,10); //PB4,AF10 GPIO_Set(GPIOD,PIN6|PIN7,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PB3,PB4设置 GPIO_AF_Set(GPIOD,6,11); //PB6,AF11 GPIO_AF_Set(GPIOD,7,11); //PB7,AF11 GPIO_Set(GPIOG,PIN9|PIN10,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PB3,PB4设置' y- ~4 x3 k( n g- g GPIO_AF_Set(GPIOG,9,11); //PB9,AF11 GPIO_AF_Set(GPIOG,10,11); //PB10,AF114 f) u5 }. _. U- Z1 H# A; d$ _5 r GPIO_Set(GPIOI,PIN15,GPIO_MODE_IN,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PI15设置 *(uint32_t *)0x40023824 &= ~(0x80);//SDMMC2复位$ p) \' Y& V1 u/ |% |2 v! D 这里是在f767的模板基础上改的,所以没有完全改成纯寄存器版本的,这个后续研究,然后再发帖。) [( J# X2 V. o! F, d k {, w$ r IO配置完成后,开始清理SDMMC的所有寄存器 //SDMMC外设寄存器设置为默认值 SDMMC2->POWER=0x00000000; SDMMC2->CLKCR=0x00000000; SDMMC2->ARG=0x00000000; SDMMC2->CMD=0x00000000;" F' } w! ~& p. C6 m SDMMC2->DTIMER=0x00000000;) v7 v8 N; U, c/ w SDMMC2->DLEN=0x00000000; SDMMC2->DCTRL=0x00000000;6 o, P, S2 x) R) \ Z6 Z, z SDMMC2->ICR=0x00C007FF; SDMMC2->MASK=0x00000000; 增加SD卡的中断配置1 m$ G# \7 L8 M7 Z% _- T7 j MY_NVIC_Init(0,0,SDMMC2_IRQn,2); //SDMMC中断配置: C* M/ i8 h* r) S. h 完成后,开始进行上电操作, SD_PowerON();( u% D. `1 U6 e7 s% e5 B1 b1 Y% A SD_InitializeCards(); //初始化SD卡3 J3 ?( z) ^! T1 z$ w/ {1 I, n SD_GetCardInfo(&SDCardInfo); //获取卡信息 SD_SelectDeselect((u32)(SDCardInfo.RCA<<16));//选中SD卡 SD_EnableWideBusOperation(1); //4位宽度,如果是MMC卡,则不能用4位模式 以上实现了检测SD卡的类型,具体设置SD卡的时钟频率。6 v4 P& u& K- [0 _ s/ [ if(SDCardInfo.CardType==STD_CAPACITY_SD_CARD_V1_1||SDCardInfo.CardType==STD_CAPACITY_SD_CARD_V2_0) { clkdiv=SDMMC_TRANSFER_CLK_DIV+2; //V1.1/V2.0卡,设置最高48/4=12Mhz }else clkdiv=SDMMC_TRANSFER_CLK_DIV; //SDHC等其他卡,设置最高48/2=24Mhz( V V/ _* U l& ?! h4 z+ R# N SDMMC_Clock_Set(clkdiv); //设置时钟频率,SDMMC时钟计算公式:SDMMC_CK时钟=SDMMCCLK/[clkdiv+2];其中,SDMMCCLK固定为48Mhz / J! F+ s) i9 B5 e6 h 暂且设置成查询模式,后续再改成中断模式. t* [6 d' K+ p$ L* g! V: f SD_SetDeviceMode(SD_POLLING_MODE);//设置为查询模式 0 [+ L& _ E7 x O) R! C 初始化完成后,在main函数下添加以下代码实现SD卡的初始化操作 while(sdcard_init())//检测不到SD卡 { P6 ?7 ~/ i$ Q# J delay_ms(500);% f4 k6 N( y) L! g9 V# z) c LED0(led0sta^=1);//DS0闪烁8 c, N" ^/ b4 ]8 i% o/ y+ s } 在while(1)添加代码,检查SD卡初始化是否完成,代码是否继续运行 { delay_ms(500); printf("\r\n sd is ok!:\r\n"); }8 X: S: ]! i- P7 }2 X* z 果然串口一直在打印输出6 Z5 b: U0 y) D8 f 说明SD卡初始化完成了 详细的代码说明,后面会陆续有新帖,喜欢寄存器配置的网友,自行关注!- B! o" v2 N+ ` 6 i" p- m5 |' y( u. B f 发帖与2018年3月9日: L1 a4 C* w7 M1 e) \& E- f' }4 F# h ( d7 p3 E# C3 Z* [% }% k : @) u1 K& {9 Y* { \$ k$ s) j G2 K 9 Z- a6 C4 q6 E% H7 Q! P, T* k 继续阅读:stm32f769 寄存器配置SD卡--打印SD卡信息! p$ g8 c9 H& n& J |
微信公众号
手机版
https://www.stmcu.org.cn/module/forum/thread-615031-1-1.html
https://www.stmcu.org.cn/module/forum/thread-615032-1-1.html