|
本帖最后由 天使♀的☆宇★翼 于 2015-3-4 20:42 编辑 t& M/ S/ S1 E; J# U, a+ W4 B$ m ! ~, Y# t) G1 N8 E1 v; W 正点原子Alientec Mini STM32ALIENTEK MINISTM32 USB读卡器实验 Miniæ¿åè½å¾
USB 读卡器简介 ALIENTEK MiniSTM32 开发板板载了 SD 卡读卡器,而 STM32F103 又有 USB,且在板上1 Y4 ]% R2 G; v" d n 带有 USB 连接头,这样我们便可以通过 STM32 的 USB 来读写 SD 卡,从而实现一个 USB 读 卡器。+ X: q) m O, j. O+ q% D8 O. v USB 读卡器的实现最重要的有两个部分: USB 部分和 SD 卡部分。 USB 部分同上一节的差& ?/ q; O8 i! S V- f. X& Z- I6 i( Z 不多,只是这一节我们的 STM32F103 被识别成一个大容量存储设备,而不是人体学输入设备。 SD 卡部分,最重要的就是 2 个函数,一个 MSD_WriteBuffer 函数,用于向 SD 卡写入数据,当 你要 COPY 文件到 SD 卡的时候,就是由这个函数完成的。另外一个是 MSD_ReadBuffer 函数, 该函数用于读取 SD 卡上面的数据。 这里的数据并不需要经过文件系统处理,而是完全电脑控制,我们要做的就是读写 SD 卡 就够了。本实验我们也是参考 Mass_Storage 例程而来的,不过在 ST 提供的例程 Mass_Storage 里面,使用的是 SDIO 方式来读写 SD 卡的,而我们这里采用的是 SPI 方式读写,所以速度会 比较慢一点。 3.27.2 硬件设计) p( m" B4 E. v; ?2 d8 v! q/ D 本节实验功能简介:开机的时候先检测 SD 卡是否存在,如果不存在则等待 SD 卡插入, 同时在 LCD 上显示提示信息。在 SD 卡插入之后,就开始 USB 的配置,在配置成功之后既可+ @2 q5 p$ B( _5 U5 }, Y& u+ I 以在电脑上发现可移动磁盘了。我们用 DS1 来指示 USB 正在读写 SD 卡,并在液晶上显示出 来,同样我们还是用 DS0 来指示程序正在运行。$ c$ P: \/ h7 X( b5 x+ r; ` 所要用到的硬件资源如下: 1)STM32F103RBT6。: o5 R1 F6 b5 ]4 \- | 2)DS0、DS1(外部 LED0/LED1)。 3)TFTLCD 液晶模块。 5 x- P( N/ H& ^+ s; v, U5 R 4)SD 卡。 4 u4 P5 q% |+ H- l+ @! J3 m& ] 5)USB 接口。 这几个部分,在之前的实例中都已经介绍过了,我们在此就不多说了。 3.27.3 软件设计 这一节,我们在实验 20 的基础上修改,先打开实验 18 的工程, 在 HARDWARE 文件夹所4 e$ }6 m" D, Z: [ 在文件夹下新建一个 USB 的文件夹,然后在 USB 文件夹下面新建 LIB 和 CONFIG 文件夹,分# e3 E& M- a. B( n" `; X X 别用来存放与 USB 核相关的代码以及配置部分代码。这两部分代码我们也不细说(因为 USB 部分我也没告通,仅是移植能用而已),这些代码都是从 ST 提供的例程 Mass_Storage 里面移植3 i4 a# C$ m2 `) q6 m! q 过来的。! d- O5 z) i5 e 然后,我们在工程文件里面新建 USB 和 USBCFG 组,分别加入 USB\LIB 下面的代码和 USB\CONFIG 下面的代码。然后把 LIB 和 CONFIG 文件夹加入头文件包含路径。 在 test.c 里面,我们修改 main 函数如下:& c+ I ] H0 B: D- C //bit0:表示电脑正在向 SD 卡写入数据 //bit1:表示电脑正从 SD 卡读出数据 //bit2:SD 卡写数据错误标志位 //bit3:SD 卡读数据错误标志位 //bit4:1,表示电脑有轮询操作(表明连接还保持着) ' L; o1 B( w7 }$ V9 k, B- M" [ U 429 u8 Usb_Status_Reg=0; int main(void) { 3 c5 P% Y( s+ m6 C% u u8 offline_cnt=0; u8 tct=0;# O' _ q& F# }; Z u8 USB_STA; u8 Divece_STA;# c! g) h# S( A4 p8 J& E long long sd_size;//当 SD 卡容量超过 4G 的时候,u32 不足以表示其容量大小. Stm32_Clock_Init(9);//系统时钟设置 delay_init(72); //延时初始化 uart_init(72,9600); //串口 1 初始化 0 [; P+ t2 F3 ~- S0 W LCD_Init(); //初始化液晶 //KEY_Init(); //按键初始化 LED_Init(); //LED 初始化: M: p R, f# V: _9 |' @7 g* y POINT_COLOR=RED;//设置字体为蓝色 LCD_ShowString(60,50,"Mini STM32");2 M& L. l; o S& ~' T' ?5 ?* H LCD_ShowString(60,70,"USB TEST");5 k$ {; \/ h, s& s- v: \2 U LCD_ShowString(60,90,"ATOM@ALIENTEK"); LCD_ShowString(60,110,"2010/6/19");6 ?% W$ ]0 ^" d8 y& g) i; r while(SD_Initialize()) {: K# d+ Q/ c; ~ LCD_ShowString(60,130,"SD Init ERR!"); delay_ms(500); LCD_ShowString(60,130,"Please Check");& {" P+ D* h4 O7 ~ delay_ms(500);6 ?* J& Z8 D' w4 p. H } LCD_ShowString(60,130,"SD Card Ready"); //提示 SD 卡已经准备了 sd_size=(long long)SD_GetSectorCount()*512; //得到 SD 卡容量,字节. Mass_Memory_Size[0]=sd_size%4294967296; //当 SD 卡容量超过 4G 的时候,7 ]' j0 r }, e1 O$ { //需要用到两个 u32 来表示 Mass_Memory_Size[1]=sd_size>>32; //容量的高 32 位 Mass_Block_Size[0] =512; ; T+ i/ e0 J ^9 {2 t: Y7 ^ //因为我们在 Init 里面设置了 SD 卡的操作字节为 512 个,所以这里一定是 512 个字节. Mass_Block_Count[0]=sd_size/Mass_Block_Size[0]; //得到扇区数% [ W, J% \- L, E- _) c LCD_ShowString(60,150,"USB Connecting..."); //提示 SD 卡已经准备了 , o) ~4 F9 \% |+ _/ M //USB 配置 USB_Interrupts_Config(); ! M. u, e! b0 B6 b Set_USBClock(); ' M; ^' A9 Y4 A- v: [+ p A9 T9 c USB_Init(); while(1) {) k5 p4 b4 V5 [& f4 M delay_ms(1); 430, y: W# E; L! j. F if(USB_STA!=Usb_Status_Reg)//状态改变了 { * R8 b O* I7 n) r6 l LCD_ShowString(60,170," ");//清除 if(Usb_Status_Reg&0x01)//正在写! G7 b3 t; J! Z* S( U: I {. U& `- M5 ]' |; T LCD_ShowString(60,170,"USB Writing...");//提示 USB 正在写入数据3 z$ \' N6 h2 D } if(Usb_Status_Reg&0x02)//正在读 { LCD_ShowString(60,170,"USB Reading...");//提示 USB 正在读出数据8 X" U$ f0 R6 P4 t6 C2 H! W) l6 Z } ' g* Q$ J) H D4 Z- K1 V5 [$ W if(Usb_Status_Reg&0x04)LCD_ShowString(60,190,"USB Write Err ");, X+ z2 Y* }4 Z& }/ K/ Y3 u //提示写入错误 else LCD_ShowString(60,190," ");//清除错误2 \( f' Q* y" |) {* |" Z D% j if(Usb_Status_Reg&0x08)LCD_ShowString(60,210,"USB Read Err "); //提示读出错误# V+ P4 O) T8 p$ t( c/ _ else LCD_ShowString(60,210," ");//清除错误- r G6 |. r: C( C, V2 E9 _, ?7 F USB_STA=Usb_Status_Reg;//记录最后的状态 }; ], a; ^/ g; E( \ z if(Divece_STA!=bDeviceState) { if(bDeviceState==CONFIGURED)6 i4 } J# B( B LCD_ShowString(60,150,"USB Connected ");//提示 USB 连接已经建立 else LCD_ShowString(60,150,"USB DisConnected ");//提示 USB 被拔出了 Divece_STA=bDeviceState;- L4 a4 J% o) _# c2 x } ]+ Y, n: G5 [ T tct++; if(tct==200)+ b* i' |0 N7 L, y8 ]7 x: w { tct=0; LED0=!LED0;//提示系统在运行 if(Usb_Status_Reg&0x10)+ R: K2 m* y k9 y4 e6 |% }+ P4 e { offline_cnt=0;//USB 连接了,则清除 offline 计数器 a1 d. T, E2 Z, Y bDeviceState=CONFIGURED;$ r% P( _' |, u/ u$ w7 |0 ? }else//没有得到轮询 {$ K! X' ~! @' p b offline_cnt++; # r2 a! T: m( e! l6 _$ J" m' { H if(offline_cnt>10)bDeviceState=UNCONNECTED; //2s 内没收到在线标记,代表 USB 被拔出了0 R( T' b+ L/ |8 K& h } Usb_Status_Reg=0;' z' U4 A& `; u' Z& R2 F& ]9 R } 2 {- ?$ K7 C8 L5 X+ O$ ~( j 431' C k U6 k, R3 s# F9 F }; % C* j; k% _: E3 ^/ c* k8 a } 2 e+ ^+ b# s3 a; Z3 y# D {! Y 此部分代码就实现了我们之前在硬件设计部分描述的功能,这里我们用到了一个全局变量 Usb_Status_Reg,用来标记 USB 的相关状态,这样我们就可以在液晶上显示当前 USB 的状态 \, e6 `1 r# j: } ]" Z. U, { 了。# Z2 n: S7 ~# g% c: @7 d ; |- _: _0 \- Q8 ]% O( X5 @ å®éªç»æå¨æ¾ç¤ºå±ä¸æ¾ç¤º
& c9 I& E1 o/ H6 @ q. V& T ' X9 v5 M& ]9 D: {& f ; C0 E1 W, h7 I " q6 P6 u3 x# a5 G9 X# J |
最全USB HID开发资料,悉心整理一个月,亲自测试
【源码】STLINK-V3MINI 高速USB仿真器,成功改刷【高速CMSIS-DAP】
STM32 USB CDC 虚拟多串口
实战经验 | 选择USBX模块生成USB CDC ACM无PD的项目
STM32 USB HID键盘例程
刘氓兔的杂谈【001】-片上USB 高速PHY
【经验分享】在进行 USB CDC 类开发时,无法发送 64整数倍的数据
在线直播|无需编写任何代码即可在STM32上实现USB-C Power Delivery
圈圈发布USB图书第二版有感,以及分享一些我学习USB过程...
USB Audio设计与实现
微信公众号
手机版
没事儿,都是从小白开始的,我在大一也是小白,后来对这些感兴趣,就一步一步的学习,没关心,慢慢来,相信你能行
哈哈,没关系,大家一起相互讨论,相互学习
呵呵,我就是通过外接学习的
没事儿,用ST官方的板子,可以根据电路图以及硬件的连接位置,改动一些配置函数将程序一直过去就好了,其实原理都差不多
不客气,以后多多讨论,互相学习啦
不客气,以后有好的资料会马上分享的,以后有时间也会自己原创一些帖子发上来的,一起学习吧