
本帖最后由 天使♀的☆宇★翼 于 2015-3-4 20:42 编辑 正点原子Alientec Mini STM32ALIENTEK MINISTM32 USB读卡器实验 Miniæ¿åè½å¾ ![]() USB 读卡器简介% v9 g) j1 H2 T& u# n ALIENTEK MiniSTM32 开发板板载了 SD 卡读卡器,而 STM32F103 又有 USB,且在板上 带有 USB 连接头,这样我们便可以通过 STM32 的 USB 来读写 SD 卡,从而实现一个 USB 读 卡器。 USB 读卡器的实现最重要的有两个部分: USB 部分和 SD 卡部分。 USB 部分同上一节的差- @: ^; ]( S" M( k8 b7 f; N4 _, H 不多,只是这一节我们的 STM32F103 被识别成一个大容量存储设备,而不是人体学输入设备。8 u9 k0 [- E9 ]% \3 A' [ SD 卡部分,最重要的就是 2 个函数,一个 MSD_WriteBuffer 函数,用于向 SD 卡写入数据,当 你要 COPY 文件到 SD 卡的时候,就是由这个函数完成的。另外一个是 MSD_ReadBuffer 函数,3 |" e) K7 C8 N; I1 A' \ 该函数用于读取 SD 卡上面的数据。7 ?% o5 Z2 M( V 这里的数据并不需要经过文件系统处理,而是完全电脑控制,我们要做的就是读写 SD 卡9 {4 s5 J2 j* Q9 U; D, d 就够了。本实验我们也是参考 Mass_Storage 例程而来的,不过在 ST 提供的例程 Mass_Storage 里面,使用的是 SDIO 方式来读写 SD 卡的,而我们这里采用的是 SPI 方式读写,所以速度会+ }& c, d. H# s+ I+ e7 @, E, B 比较慢一点。& S( @0 Z/ a$ X- Y' \4 a. ~ 3.27.2 硬件设计8 G' v1 i) t/ h% k 本节实验功能简介:开机的时候先检测 SD 卡是否存在,如果不存在则等待 SD 卡插入,( M% x% b4 Q7 n8 l2 N) V4 \ 同时在 LCD 上显示提示信息。在 SD 卡插入之后,就开始 USB 的配置,在配置成功之后既可 以在电脑上发现可移动磁盘了。我们用 DS1 来指示 USB 正在读写 SD 卡,并在液晶上显示出( r" Y1 ~# k! {; A [ 来,同样我们还是用 DS0 来指示程序正在运行。 所要用到的硬件资源如下:% g+ O9 V k8 |1 N: t! G0 s4 M! p1 \- U 1)STM32F103RBT6。 2)DS0、DS1(外部 LED0/LED1)。 3)TFTLCD 液晶模块。 & I8 M8 j+ K. C( u6 ] 4)SD 卡。 5)USB 接口。 ' h) G6 z, c: g& s 这几个部分,在之前的实例中都已经介绍过了,我们在此就不多说了。 3.27.3 软件设计+ O& R' I( e) h$ S) T 这一节,我们在实验 20 的基础上修改,先打开实验 18 的工程, 在 HARDWARE 文件夹所2 L6 E" X- b% N 在文件夹下新建一个 USB 的文件夹,然后在 USB 文件夹下面新建 LIB 和 CONFIG 文件夹,分, z% G9 g: R( j) \8 ]& C 别用来存放与 USB 核相关的代码以及配置部分代码。这两部分代码我们也不细说(因为 USB 部分我也没告通,仅是移植能用而已),这些代码都是从 ST 提供的例程 Mass_Storage 里面移植 过来的。 然后,我们在工程文件里面新建 USB 和 USBCFG 组,分别加入 USB\LIB 下面的代码和 USB\CONFIG 下面的代码。然后把 LIB 和 CONFIG 文件夹加入头文件包含路径。6 h- H: F3 J6 T, F8 L( ] 在 test.c 里面,我们修改 main 函数如下:+ D# E; o8 d; I% z //bit0:表示电脑正在向 SD 卡写入数据 //bit1:表示电脑正从 SD 卡读出数据+ E+ X6 i( \/ ^% k' x( R7 l //bit2:SD 卡写数据错误标志位6 {8 o* I4 z. v% k7 y# X8 k //bit3:SD 卡读数据错误标志位5 q6 Q6 m' j4 }0 R: g s //bit4:1,表示电脑有轮询操作(表明连接还保持着) ( b$ u' k, i+ ~4 w+ b- U9 Z 429& z2 a; W6 v4 [( Q3 E u8 Usb_Status_Reg=0; int main(void)% Y# G2 {( f/ P! p) X. ? x { u8 offline_cnt=0; u8 tct=0; u8 USB_STA;5 ^2 {; S7 C% ~2 B* } u8 Divece_STA; long long sd_size;//当 SD 卡容量超过 4G 的时候,u32 不足以表示其容量大小.* v2 M; s% Y* _0 _% Z Stm32_Clock_Init(9);//系统时钟设置 delay_init(72); //延时初始化* s: C3 ]- J: i* G2 Q9 ^ uart_init(72,9600); //串口 1 初始化 LCD_Init(); //初始化液晶 2 _& N! {8 X0 Q$ r! f4 Z //KEY_Init(); //按键初始化 LED_Init(); //LED 初始化 POINT_COLOR=RED;//设置字体为蓝色 ! T6 l$ Z! r) L1 _! i8 M# g( b5 W LCD_ShowString(60,50,"Mini STM32");" d+ M, G1 b" Q& z( U LCD_ShowString(60,70,"USB TEST");4 ^) E1 {; O7 t5 ^8 j LCD_ShowString(60,90,"ATOM@ALIENTEK");+ q, v! i$ G5 Y) S) U, N5 Y8 R LCD_ShowString(60,110,"2010/6/19"); while(SD_Initialize())$ v) H+ F9 p8 t/ V2 N: j { LCD_ShowString(60,130,"SD Init ERR!");& z% J8 y5 q$ _: u& ] delay_ms(500); LCD_ShowString(60,130,"Please Check"); delay_ms(500);# w/ j% c- E% M0 r } LCD_ShowString(60,130,"SD Card Ready"); //提示 SD 卡已经准备了, i e t, ?/ N, P! t: } sd_size=(long long)SD_GetSectorCount()*512; //得到 SD 卡容量,字节.9 g! x. A5 j; n+ U Mass_Memory_Size[0]=sd_size%4294967296; //当 SD 卡容量超过 4G 的时候,5 r6 M3 }8 ^ ?. W //需要用到两个 u32 来表示, G# o4 c8 z* x/ k$ ^6 { Mass_Memory_Size[1]=sd_size>>32; //容量的高 32 位 Mass_Block_Size[0] =512; //因为我们在 Init 里面设置了 SD 卡的操作字节为 512 个,所以这里一定是 512 个字节. Mass_Block_Count[0]=sd_size/Mass_Block_Size[0]; //得到扇区数) f) Y6 i0 u# ?4 c# p LCD_ShowString(60,150,"USB Connecting..."); //提示 SD 卡已经准备了 ; C9 l: \6 i7 P" B3 T; ~# M //USB 配置 USB_Interrupts_Config(); Set_USBClock(); USB_Init(); while(1)9 t! o2 c0 }6 A# ] {! C+ O: ]/ x* D. ^/ E2 S3 F: u f delay_ms(1); " X9 _0 v2 L/ j7 o6 W 430 if(USB_STA!=Usb_Status_Reg)//状态改变了 { ! w% W/ p4 C( ?1 E LCD_ShowString(60,170," ");//清除 if(Usb_Status_Reg&0x01)//正在写 { LCD_ShowString(60,170,"USB Writing...");//提示 USB 正在写入数据( q! D& a/ \& } z+ ~# v } if(Usb_Status_Reg&0x02)//正在读 { LCD_ShowString(60,170,"USB Reading...");//提示 USB 正在读出数据+ U8 }, L$ C1 \ } 4 f* Y: \6 _6 Y) {, i0 \' E if(Usb_Status_Reg&0x04)LCD_ShowString(60,190,"USB Write Err "); //提示写入错误 else LCD_ShowString(60,190," ");//清除错误 if(Usb_Status_Reg&0x08)LCD_ShowString(60,210,"USB Read Err ");+ R1 i* B4 D4 T& Q //提示读出错误 else LCD_ShowString(60,210," ");//清除错误5 u ?- Y9 l4 e+ j- }, d3 w USB_STA=Usb_Status_Reg;//记录最后的状态$ h; r7 V L$ ]3 |* | } if(Divece_STA!=bDeviceState) {' T) h: f+ |2 J' K% | if(bDeviceState==CONFIGURED)$ F* e) V- l' l0 s* ?* | LCD_ShowString(60,150,"USB Connected ");//提示 USB 连接已经建立 else LCD_ShowString(60,150,"USB DisConnected ");//提示 USB 被拔出了! O9 I7 `, e* [6 v1 } Divece_STA=bDeviceState;2 [& v! Y/ H0 x7 V$ k0 H2 |) k } tct++;2 e1 u; G9 p- U) z: q2 J8 @( m if(tct==200) A! E" _( ~- t* N5 Y+ u8 X, k, G. E {2 l' X1 M5 s9 r& u* t* l2 e* @ tct=0;0 z3 \. i) h" p$ ^6 y LED0=!LED0;//提示系统在运行 if(Usb_Status_Reg&0x10)2 p, o/ \5 B4 D" l0 ~; o { offline_cnt=0;//USB 连接了,则清除 offline 计数器 bDeviceState=CONFIGURED;( M: [7 I+ b; d* a7 s }else//没有得到轮询 {0 F: H& H% G$ i3 f' E( d; p offline_cnt++; : E: p' y, w4 M8 d4 f3 | if(offline_cnt>10)bDeviceState=UNCONNECTED;: P/ I) P7 d5 s, s4 W //2s 内没收到在线标记,代表 USB 被拔出了 }* [: g4 p; a- ^) G& z) H Usb_Status_Reg=0; } 9 y/ M* p8 F) J6 W! K$ K% N 4314 @, r6 M: I" i/ V& @! ? }; } # H ?" @0 Z: I5 S 此部分代码就实现了我们之前在硬件设计部分描述的功能,这里我们用到了一个全局变量 Usb_Status_Reg,用来标记 USB 的相关状态,这样我们就可以在液晶上显示当前 USB 的状态9 l$ D3 f3 ?7 F/ K r: o0 a+ U# O 了。 å®éªç»æå¨æ¾ç¤ºå±ä¸æ¾ç¤º ![]() ![]() ) u: ^7 O4 e2 V4 e/ V7 o# e2 o3 p& U , _* X% |) Y/ [5 ?, w 9 s( d" e$ V" _" S; e7 G# ] |
最全USB HID开发资料,悉心整理一个月,亲自测试
实战经验 | 选择USBX模块生成USB CDC ACM无PD的项目
STM32 USB HID键盘例程
刘氓兔的杂谈【001】-片上USB 高速PHY
【经验分享】在进行 USB CDC 类开发时,无法发送 64整数倍的数据
【源码】STLINK-V3MINI 高速USB仿真器,成功改刷【高速CMSIS-DAP】
在线直播|无需编写任何代码即可在STM32上实现USB-C Power Delivery
STM32 USB CDC 虚拟多串口
圈圈发布USB图书第二版有感,以及分享一些我学习USB过程...
USB Audio设计与实现
没事儿,都是从小白开始的,我在大一也是小白,后来对这些感兴趣,就一步一步的学习,没关心,慢慢来,相信你能行
哈哈,没关系,大家一起相互讨论,相互学习
呵呵,我就是通过外接学习的
没事儿,用ST官方的板子,可以根据电路图以及硬件的连接位置,改动一些配置函数将程序一直过去就好了,其实原理都差不多
不客气,以后多多讨论,互相学习啦
不客气,以后有好的资料会马上分享的,以后有时间也会自己原创一些帖子发上来的,一起学习吧