本帖最后由 天使♀的☆宇★翼 于 2015-3-4 20:42 编辑 正点原子Alientec Mini STM32ALIENTEK MINISTM32 USB读卡器实验 Miniæ¿åè½å¾ USB 读卡器简介 ALIENTEK MiniSTM32 开发板板载了 SD 卡读卡器,而 STM32F103 又有 USB,且在板上+ o% `4 w/ t& W- J* B& N 带有 USB 连接头,这样我们便可以通过 STM32 的 USB 来读写 SD 卡,从而实现一个 USB 读 卡器。 USB 读卡器的实现最重要的有两个部分: USB 部分和 SD 卡部分。 USB 部分同上一节的差 不多,只是这一节我们的 STM32F103 被识别成一个大容量存储设备,而不是人体学输入设备。( W; r; ^5 G, y: M SD 卡部分,最重要的就是 2 个函数,一个 MSD_WriteBuffer 函数,用于向 SD 卡写入数据,当 你要 COPY 文件到 SD 卡的时候,就是由这个函数完成的。另外一个是 MSD_ReadBuffer 函数, 该函数用于读取 SD 卡上面的数据。4 L/ N# Q/ A: m/ z! Y 这里的数据并不需要经过文件系统处理,而是完全电脑控制,我们要做的就是读写 SD 卡 就够了。本实验我们也是参考 Mass_Storage 例程而来的,不过在 ST 提供的例程 Mass_Storage' w+ G, X4 a Q 里面,使用的是 SDIO 方式来读写 SD 卡的,而我们这里采用的是 SPI 方式读写,所以速度会4 ]# T# M, U. m. p. m0 p 比较慢一点。 3.27.2 硬件设计 本节实验功能简介:开机的时候先检测 SD 卡是否存在,如果不存在则等待 SD 卡插入, 同时在 LCD 上显示提示信息。在 SD 卡插入之后,就开始 USB 的配置,在配置成功之后既可$ ~( m, |1 k4 v 以在电脑上发现可移动磁盘了。我们用 DS1 来指示 USB 正在读写 SD 卡,并在液晶上显示出 来,同样我们还是用 DS0 来指示程序正在运行。, G' V) c2 f/ D5 [$ ]2 l0 Z- s 所要用到的硬件资源如下: 1)STM32F103RBT6。 2)DS0、DS1(外部 LED0/LED1)。9 K+ R: ~; t6 g1 A/ w( [ 3)TFTLCD 液晶模块。 9 q; @$ |! L- t$ Y; k$ `4 u 4)SD 卡。 " t4 \4 c5 w% M* g 5)USB 接口。 / a$ l* L& [; R7 t 这几个部分,在之前的实例中都已经介绍过了,我们在此就不多说了。 3.27.3 软件设计 这一节,我们在实验 20 的基础上修改,先打开实验 18 的工程, 在 HARDWARE 文件夹所8 V4 J; d$ [# g5 L4 B* i7 o 在文件夹下新建一个 USB 的文件夹,然后在 USB 文件夹下面新建 LIB 和 CONFIG 文件夹,分 别用来存放与 USB 核相关的代码以及配置部分代码。这两部分代码我们也不细说(因为 USB# x2 r# |7 @" V/ j, { 部分我也没告通,仅是移植能用而已),这些代码都是从 ST 提供的例程 Mass_Storage 里面移植) Y+ F* w9 @' ?- b5 Q; ~ 过来的。 然后,我们在工程文件里面新建 USB 和 USBCFG 组,分别加入 USB\LIB 下面的代码和1 z8 ^9 p- r r USB\CONFIG 下面的代码。然后把 LIB 和 CONFIG 文件夹加入头文件包含路径。1 R: }' U! S# ^ 在 test.c 里面,我们修改 main 函数如下: //bit0:表示电脑正在向 SD 卡写入数据 n& r* m4 J, [8 M6 o! z //bit1:表示电脑正从 SD 卡读出数据6 }& _ ^* e* Y4 k% W& Y0 R. b //bit2:SD 卡写数据错误标志位 //bit3:SD 卡读数据错误标志位 //bit4:1,表示电脑有轮询操作(表明连接还保持着) * r! Y& z, v. ^ 429 u8 Usb_Status_Reg=0; 9 n+ D, p& ?. u9 y7 D9 x1 p( e int main(void) { ! \: Y. t. l+ m u8 offline_cnt=0;5 V) Y- q- Q: p u8 tct=0; u8 USB_STA;# @0 g+ u% \+ Q1 E u8 Divece_STA;2 X$ V( z3 H7 |6 }5 G5 ` long long sd_size;//当 SD 卡容量超过 4G 的时候,u32 不足以表示其容量大小. Stm32_Clock_Init(9);//系统时钟设置! ~9 O- s, ^! K2 F) o7 h* N delay_init(72); //延时初始化! |, ^* C2 _& P0 N& E$ j1 p* c% u uart_init(72,9600); //串口 1 初始化 LCD_Init(); //初始化液晶 $ O3 |: y9 O/ O //KEY_Init(); //按键初始化 LED_Init(); //LED 初始化 POINT_COLOR=RED;//设置字体为蓝色 LCD_ShowString(60,50,"Mini STM32");* L7 Y% e8 g( B- a LCD_ShowString(60,70,"USB TEST");6 ^( A: Z1 S, W9 g3 c s. Z( p LCD_ShowString(60,90,"ATOM@ALIENTEK");+ ~- I" M' o' q LCD_ShowString(60,110,"2010/6/19");$ W3 [8 V' H" V" T while(SD_Initialize()); R4 M& e2 U! P. @ {4 I* \' m8 Y1 t3 x7 ?6 h, | LCD_ShowString(60,130,"SD Init ERR!"); delay_ms(500); LCD_ShowString(60,130,"Please Check"); S/ z! w# C9 l1 q: l5 W+ F delay_ms(500);$ X. U) y, M+ N! G } LCD_ShowString(60,130,"SD Card Ready"); //提示 SD 卡已经准备了! |+ X( m1 H! b, t0 Y: q sd_size=(long long)SD_GetSectorCount()*512; //得到 SD 卡容量,字节.$ B9 e N& P9 _/ X v9 R' I' i Mass_Memory_Size[0]=sd_size%4294967296; //当 SD 卡容量超过 4G 的时候,/ w I. A" ?2 ~. {+ Q$ C8 h# e) Y- @ //需要用到两个 u32 来表示8 r8 z; I- B: t, V- r( a Mass_Memory_Size[1]=sd_size>>32; //容量的高 32 位 Mass_Block_Size[0] =512; ) D8 P* i# V2 ?( V' h5 |9 S- U //因为我们在 Init 里面设置了 SD 卡的操作字节为 512 个,所以这里一定是 512 个字节. Mass_Block_Count[0]=sd_size/Mass_Block_Size[0]; //得到扇区数2 [% l: o( X7 \1 S9 y3 @& u LCD_ShowString(60,150,"USB Connecting..."); //提示 SD 卡已经准备了 . J8 \4 j5 D- }7 E* H+ n //USB 配置 U0 n; J# ^# }& q USB_Interrupts_Config(); Set_USBClock(); , Q& }0 O: W; R USB_Init(); while(1) {9 x4 I; b: ?5 [7 s- O7 c2 H( q delay_ms(1); 0 e2 [: W" j# E. r4 h, G 4305 F9 M5 ?: `8 o& L, ^. ^ if(USB_STA!=Usb_Status_Reg)//状态改变了 { LCD_ShowString(60,170," ");//清除5 ]9 b+ W! l1 P) T" \/ w if(Usb_Status_Reg&0x01)//正在写 {2 j4 z b8 w" Z$ @: [4 w LCD_ShowString(60,170,"USB Writing...");//提示 USB 正在写入数据 } if(Usb_Status_Reg&0x02)//正在读 {2 y+ y& H/ A- w0 X( j LCD_ShowString(60,170,"USB Reading...");//提示 USB 正在读出数据4 [* ^+ Q4 Z+ M } if(Usb_Status_Reg&0x04)LCD_ShowString(60,190,"USB Write Err "); //提示写入错误( b0 d: }( ?3 I# a, n7 s7 I else LCD_ShowString(60,190," ");//清除错误 if(Usb_Status_Reg&0x08)LCD_ShowString(60,210,"USB Read Err ");. p- I/ k, q$ I) x6 x //提示读出错误- @+ }. l/ ?, }; Y& _ else LCD_ShowString(60,210," ");//清除错误 USB_STA=Usb_Status_Reg;//记录最后的状态 } if(Divece_STA!=bDeviceState) 6 y2 N, R* y' {+ C" z0 [( A { if(bDeviceState==CONFIGURED)& N7 f6 _$ l* R, c' z) C2 ]& z3 U: { LCD_ShowString(60,150,"USB Connected ");//提示 USB 连接已经建立! t' ~1 O% {# x& S* j' {5 u# ^ else LCD_ShowString(60,150,"USB DisConnected ");//提示 USB 被拔出了 Divece_STA=bDeviceState; }5 |$ u8 E; N! k, ?0 @7 \ P tct++; if(tct==200)7 ?* P' z7 t2 e+ o& a: B8 J! O4 R2 b$ I- b {, W+ O% t/ u9 g3 l6 Y) D tct=0;8 x; y! q% z& q, \! C LED0=!LED0;//提示系统在运行 if(Usb_Status_Reg&0x10) { offline_cnt=0;//USB 连接了,则清除 offline 计数器/ c! Y- b s d bDeviceState=CONFIGURED; }else//没有得到轮询 {; Y, l& P, y# V offline_cnt++; , g' W0 Z/ c. C4 r6 b if(offline_cnt>10)bDeviceState=UNCONNECTED;) W- [/ d, d: h2 L5 P, y //2s 内没收到在线标记,代表 USB 被拔出了2 U& O! k5 ^1 \8 C4 K. D0 ? }2 k% v1 D- E/ ]+ v$ ~7 V( t Usb_Status_Reg=0;4 ~: Z( @. i: n* J# I) X. E* x; w } ) F; ~* o! H, G- Y0 l 431) i+ x7 M2 ?- |+ [0 R9 u0 q/ H$ W }; ; _, }- y9 d6 b. W; x" T9 { } 此部分代码就实现了我们之前在硬件设计部分描述的功能,这里我们用到了一个全局变量( i4 E, i: y( i: _# i# l Usb_Status_Reg,用来标记 USB 的相关状态,这样我们就可以在液晶上显示当前 USB 的状态 了。% E% R6 h5 E6 ?1 A, | ; |! ~7 q" `$ _ + w" t' }9 N* @! _1 d å®éªç»æå¨æ¾ç¤ºå±ä¸æ¾ç¤º 5 E# }3 f; n \$ c. k7 A G9 Y - G4 @% k8 C0 K: L ' `2 E& b' Y4 b% {3 h1 z! a 0 _/ `. b* z2 b5 I+ o2 I2 [; o: t |
最全USB HID开发资料,悉心整理一个月,亲自测试
USB Audio设计与实现
【MCU实战经验】+STM32F107的USB使用
圈圈发布USB图书第二版有感,以及分享一些我学习USB过程...
STM32F4-DISC 实现USB主机(U盘)和USB设备(虚拟串口)自动切换
STM32 USB-HID通信移植步骤STM32 USB HID键盘例程
【经验分享】在进行 USB CDC 类开发时,无法发送 64整数倍的数据
如何让CDC类USB设备批量接收64字节以上数据
用STM32F4实现的USB摄像头UVC,配合上位机可识别车牌
STM32 USB CDC 虚拟多串口
没事儿,都是从小白开始的,我在大一也是小白,后来对这些感兴趣,就一步一步的学习,没关心,慢慢来,相信你能行
哈哈,没关系,大家一起相互讨论,相互学习
呵呵,我就是通过外接学习的
没事儿,用ST官方的板子,可以根据电路图以及硬件的连接位置,改动一些配置函数将程序一直过去就好了,其实原理都差不多
不客气,以后多多讨论,互相学习啦
不客气,以后有好的资料会马上分享的,以后有时间也会自己原创一些帖子发上来的,一起学习吧