|
本帖最后由 天使♀的☆宇★翼 于 2015-3-4 20:42 编辑 正点原子Alientec Mini STM32ALIENTEK MINISTM32 USB读卡器实验 Miniæ¿åè½å¾
USB 读卡器简介1 u% V6 l: W9 Z9 _2 y- \ ALIENTEK MiniSTM32 开发板板载了 SD 卡读卡器,而 STM32F103 又有 USB,且在板上 带有 USB 连接头,这样我们便可以通过 STM32 的 USB 来读写 SD 卡,从而实现一个 USB 读 卡器。9 U# R0 K. ^9 l( V5 Z) r2 ~ USB 读卡器的实现最重要的有两个部分: USB 部分和 SD 卡部分。 USB 部分同上一节的差 不多,只是这一节我们的 STM32F103 被识别成一个大容量存储设备,而不是人体学输入设备。 SD 卡部分,最重要的就是 2 个函数,一个 MSD_WriteBuffer 函数,用于向 SD 卡写入数据,当 你要 COPY 文件到 SD 卡的时候,就是由这个函数完成的。另外一个是 MSD_ReadBuffer 函数,+ I& @# M R; {# [, \ 该函数用于读取 SD 卡上面的数据。 这里的数据并不需要经过文件系统处理,而是完全电脑控制,我们要做的就是读写 SD 卡0 L; b! {1 q* {6 D& ^9 W 就够了。本实验我们也是参考 Mass_Storage 例程而来的,不过在 ST 提供的例程 Mass_Storage 里面,使用的是 SDIO 方式来读写 SD 卡的,而我们这里采用的是 SPI 方式读写,所以速度会 比较慢一点。 3.27.2 硬件设计 本节实验功能简介:开机的时候先检测 SD 卡是否存在,如果不存在则等待 SD 卡插入,! c3 b' @6 I* N* d }- _ 同时在 LCD 上显示提示信息。在 SD 卡插入之后,就开始 USB 的配置,在配置成功之后既可 以在电脑上发现可移动磁盘了。我们用 DS1 来指示 USB 正在读写 SD 卡,并在液晶上显示出" [" u1 h2 b% Z# [" Y. g 来,同样我们还是用 DS0 来指示程序正在运行。 所要用到的硬件资源如下:# A+ [* j* l! J3 E: i 1)STM32F103RBT6。1 u# V% `( i( V" ? 2)DS0、DS1(外部 LED0/LED1)。! k0 ]) e7 T+ ~2 P: ~+ d 3)TFTLCD 液晶模块。 6 t5 B- o ^- {; {9 w+ q 4)SD 卡。 5)USB 接口。 这几个部分,在之前的实例中都已经介绍过了,我们在此就不多说了。% |# S+ r5 P4 V 3.27.3 软件设计& V6 G2 Q8 ~3 A1 c4 x/ E 这一节,我们在实验 20 的基础上修改,先打开实验 18 的工程, 在 HARDWARE 文件夹所7 E) Y9 B: K# N+ u4 P4 j$ @! i0 c 在文件夹下新建一个 USB 的文件夹,然后在 USB 文件夹下面新建 LIB 和 CONFIG 文件夹,分) l5 i7 M: v" U1 D* L 别用来存放与 USB 核相关的代码以及配置部分代码。这两部分代码我们也不细说(因为 USB 部分我也没告通,仅是移植能用而已),这些代码都是从 ST 提供的例程 Mass_Storage 里面移植 过来的。 然后,我们在工程文件里面新建 USB 和 USBCFG 组,分别加入 USB\LIB 下面的代码和& E# G; B+ b, V3 T, z- A/ \ USB\CONFIG 下面的代码。然后把 LIB 和 CONFIG 文件夹加入头文件包含路径。: `, s4 U+ j0 e9 H& r 在 test.c 里面,我们修改 main 函数如下:% n6 b' M1 G4 |" K. h8 x4 ^+ y. I: f //bit0:表示电脑正在向 SD 卡写入数据 //bit1:表示电脑正从 SD 卡读出数据: X: A$ W9 x% p5 X1 L/ C; b* n //bit2:SD 卡写数据错误标志位& z/ \, F7 ]% E+ w' e //bit3:SD 卡读数据错误标志位2 X( Y; r0 {9 l //bit4:1,表示电脑有轮询操作(表明连接还保持着) 429 u8 Usb_Status_Reg=0; 6 t' f0 [( t+ P int main(void)9 C# n6 \4 L E7 J; Z% |5 Q { % G4 ^" K p: X( o8 {8 R u8 offline_cnt=0;5 Y; ^& `# X; C+ \: E9 K u8 tct=0; u8 USB_STA; u8 Divece_STA; long long sd_size;//当 SD 卡容量超过 4G 的时候,u32 不足以表示其容量大小.8 @- @" |) W! E, @! }- V) D Stm32_Clock_Init(9);//系统时钟设置, r5 R# n: p% U delay_init(72); //延时初始化" L# }- j0 [0 z- W uart_init(72,9600); //串口 1 初始化 . [- j6 X) G9 l" y LCD_Init(); //初始化液晶 //KEY_Init(); //按键初始化 LED_Init(); //LED 初始化" H* H& ~5 E2 A* V L" m POINT_COLOR=RED;//设置字体为蓝色 : d% l+ ]' I( `) V LCD_ShowString(60,50,"Mini STM32");8 n* L- a' y5 x$ O: E% w5 Y LCD_ShowString(60,70,"USB TEST"); LCD_ShowString(60,90,"ATOM@ALIENTEK"); LCD_ShowString(60,110,"2010/6/19");( O( q2 S6 F- s( N T while(SD_Initialize()) {, f7 j5 E( c2 I$ B6 R LCD_ShowString(60,130,"SD Init ERR!");$ n. I% Y. `1 y8 H/ a; [" x" u% g delay_ms(500); LCD_ShowString(60,130,"Please Check");( b3 M7 j$ M* @7 x+ X delay_ms(500); } LCD_ShowString(60,130,"SD Card Ready"); //提示 SD 卡已经准备了 sd_size=(long long)SD_GetSectorCount()*512; //得到 SD 卡容量,字节.! [' T u) n/ N& c Mass_Memory_Size[0]=sd_size%4294967296; //当 SD 卡容量超过 4G 的时候, //需要用到两个 u32 来表示6 _: p7 R. ]- t; [4 Q* D Mass_Memory_Size[1]=sd_size>>32; //容量的高 32 位 Mass_Block_Size[0] =512; 0 @6 V( ?/ [0 g/ G //因为我们在 Init 里面设置了 SD 卡的操作字节为 512 个,所以这里一定是 512 个字节.* |9 R; W' Z/ Z* a$ O/ l9 j Mass_Block_Count[0]=sd_size/Mass_Block_Size[0]; //得到扇区数 LCD_ShowString(60,150,"USB Connecting..."); //提示 SD 卡已经准备了 ; b( [; w3 y2 ] z( j //USB 配置+ ]$ f; ]+ r. z6 i: b; U+ q! J6 i USB_Interrupts_Config(); : Q2 _9 j' G F. b& t) V Set_USBClock(); 5 ^5 g _- ] n; N8 J" D6 e USB_Init(); while(1) { delay_ms(1); 430 if(USB_STA!=Usb_Status_Reg)//状态改变了0 q7 O. J6 k8 _. E! ]8 l. h { LCD_ShowString(60,170," ");//清除% v# _3 d( f" e) l5 {; |/ Y if(Usb_Status_Reg&0x01)//正在写 {$ @1 F- p! D* M5 j5 }7 l LCD_ShowString(60,170,"USB Writing...");//提示 USB 正在写入数据' f, N( R; o% d! w9 V/ l } if(Usb_Status_Reg&0x02)//正在读2 C) l- J( A' C5 Z0 S { LCD_ShowString(60,170,"USB Reading...");//提示 USB 正在读出数据* j7 r8 B- z) M/ o& l1 p9 ?( O } if(Usb_Status_Reg&0x04)LCD_ShowString(60,190,"USB Write Err "); //提示写入错误0 Z9 m1 |* u o0 b' N" n else LCD_ShowString(60,190," ");//清除错误# u! I/ c9 X+ I3 X! y o if(Usb_Status_Reg&0x08)LCD_ShowString(60,210,"USB Read Err "); //提示读出错误9 N! m! O( a! p- N else LCD_ShowString(60,210," ");//清除错误 USB_STA=Usb_Status_Reg;//记录最后的状态* l- n } Z% q7 `9 e% H& q7 Z } if(Divece_STA!=bDeviceState) ; |8 K) u! [7 h1 }) V+ f" b& I { if(bDeviceState==CONFIGURED) LCD_ShowString(60,150,"USB Connected ");//提示 USB 连接已经建立 O% }. L: K+ n# m& Q, s7 E$ y else LCD_ShowString(60,150,"USB DisConnected ");//提示 USB 被拔出了, M7 Y+ o; ]4 }+ [5 u: a Divece_STA=bDeviceState; } tct++;7 s0 F. E/ Q( U if(tct==200) { tct=0;( Z9 p% M' `+ ^( o LED0=!LED0;//提示系统在运行( o" H) _6 t7 C1 x2 U* M if(Usb_Status_Reg&0x10) {0 A; S6 |9 w r offline_cnt=0;//USB 连接了,则清除 offline 计数器 bDeviceState=CONFIGURED;/ \6 D( ~# Q, o8 c' g6 e* M* m }else//没有得到轮询 {/ O/ u: J* t- d offline_cnt++; ' v2 _* q- A* a4 N O4 ] if(offline_cnt>10)bDeviceState=UNCONNECTED;+ _ C: P; Q3 W //2s 内没收到在线标记,代表 USB 被拔出了 } Usb_Status_Reg=0;7 i9 `* K! f5 a$ ]7 [; G0 I* I, _" q } 431$ Y! x4 q: |) _ }; 6 q, A# K, Q I } 此部分代码就实现了我们之前在硬件设计部分描述的功能,这里我们用到了一个全局变量 Usb_Status_Reg,用来标记 USB 的相关状态,这样我们就可以在液晶上显示当前 USB 的状态4 U0 }' S: f; j( W1 G 了。 - Q3 m# @4 @. L4 C3 d* M å®éªç»æå¨æ¾ç¤ºå±ä¸æ¾ç¤º
* f5 |/ T7 ` h$ F; P- z; o3 s 3 @3 v3 D" V3 r& V4 X- \$ }: ~ |
最全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官方的板子,可以根据电路图以及硬件的连接位置,改动一些配置函数将程序一直过去就好了,其实原理都差不多
不客气,以后多多讨论,互相学习啦
不客气,以后有好的资料会马上分享的,以后有时间也会自己原创一些帖子发上来的,一起学习吧