|
哈喽大家好,这里是没什么人爱看的USB系列。USB系列停了几天,今天继续。这次说下如何通过STM32CubeMX软件,在5分钟的时间内,把你的单片机变成一个迷你优盘。
. |: h `. }# D4 d/ T y$ I - F! v+ j: D0 B. V$ Z. D5 |
GPIO、RCC、SYS、Connectivity
+ l e h7 a( K首先,通过STM32CubeMX软件配置单片机外设。型号依然是STM32F013C8T6,GPIO、RCC、SYS、Connectivity部分和之前的[color=var(--weui-LINK)]USB鼠标设置一样,参照前面的部分。% D9 I1 w* i( |+ I" ~
' F' t& l. j- `' h- P* S
; @, J" q) s+ a( S. T
中间件 * h( W- I5 `. a$ f: v
6 c' B' F# b: ]) h" Y* l8 P% g, n F
其次,中间件,也就是Middleware部分,修改一下。一个是Class For FS IP,这里选择:Mass Storge Class,然后是下面的Class Parameters这里,之前的值是512,现在改为1024.为什么是1024,后面会说。- O3 ?/ `% k8 C6 f, b
4 k! c5 J* A+ W. W+ {. ^; M F
除此之外,VID和PID要和之前的不一样,然后配置一下时钟。/ m+ e. {9 R5 _4 O, G( S" a$ J& X
- D9 u5 h7 \. }) Q4 \
4 k% ]: U3 R/ _ y) D! L
堆栈设置
4 {. F& z, a8 J, e
0 N0 X3 S2 I0 z# s
第三,修改堆栈上限。之前的值是0x200,0x400,因为要模拟优盘,操作大量数据,这部分空间已经不够了,全部改为0x1000. 然后就可以生成工程了。
% X0 `) ~% @# {: N, c# ]9 l* R
3 B% A: I4 s( k! v
优盘空间设置
) q1 W4 _3 o. p# d& }& }
1 X o) x4 r8 c6 l9 q% s0 K+ x
第四,添加自定义部分代码,下面的操作都在文件usbd_storage_if.c内。
# d8 S5 x+ C6 w: Q) A% R* y! {& ~- /* USER CODE BEGIN PRIVATE_DEFINES */# K: Z; \" X) G- X8 D3 |
- #define FLASH_START_ADDR 0x08004000 //
, k- z) d( {. \7 Q& k& Y% I - #define FLASH_PAGE_NBR 48 // 48K1 R5 H! r& F% N* q% }- J. O
- /* USER CODE END PRIVATE_DEFINES */
复制代码 8 P+ e' i6 i3 G+ F% \0 A
8 Y* K* P7 I: J( r" d: [2 U
主要有两个内容,一个是flash的起始地址,另一个是扇区的个数。 因为本工程代码不多,编译完成后代码量在12K左右,所以给程序文件预留16K的空间足够了。同时,STM32F103C8T6的flash总共64K,所以还剩48K。而STM32F103C8T6的flash,一个扇区大小是1024字节。这就是为什么第二步那里,Class Parameters的值要改成1024. 所以根据这些信息,可以知道优盘空间的起始地址是0x08004000,扇区个数是48.
9 D4 j7 D0 [9 b2 o' u" N/ r: m
容量获取函数
* }) I! Q- x5 Q2 q7 l
, [$ L; m) Y1 y/ D" j
第五,修改容量获取函数。如下,这里的FLASH_PAGE_SIZE是一个宏定义,可以找到定义值:0x400. - % E) w, W* i+ H4 H, {" M& W- k
- int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
( U4 G8 t% D% a- p. F; } - {, ~+ w: }) E1 a* z3 c* {
- /* USER CODE BEGIN 3 */
1 M! [* s7 A5 w2 y0 n" D: U - *block_num = FLASH_PAGE_NBR;1 _0 y+ l2 Q) x4 ~2 G$ b* [
- *block_size = FLASH_PAGE_SIZE;1 z; [$ ?, Y1 E( I& f- d7 ^, s; w6 a+ v
- return (USBD_OK);
0 ~2 W' F- @# s/ `2 | - /* USER CODE END 3 */
* R( X8 w2 m5 M5 f - }
复制代码
/ R& R- `) I! b" z% O; @/ Y7 e! B" Z+ @/ R" l. p, C
- U, c% n0 l$ W( I- k/ w1 p
读优盘函数
7 j" S- o E! h$ y0 {6 q3 n2 d, w4 Z! L
第六,修改读优盘函数。如下,把目标flash地址中的数据拷贝到buf中。 - 1 N1 t( s: q; t5 C' I" }' s
- int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)6 L: ~( S( O% m
- {9 a( Q. O* b, N. C* [, F6 k
- /* USER CODE BEGIN 6 */1 r7 X" ]9 _/ {) E
- if(lun == 0)+ J& Z, ^- O2 P! i, n: p
- {
+ q5 D. p1 S( q( `! L - memcpy(buf,(uint8_t *)(FLASH_START_ADDR + blk_addr*FLASH_PAGE_SIZE),blk_len*FLASH_PAGE_SIZE);
$ ? p! w9 Y; {" v - return USBD_OK;
F2 F6 q; E- \( _ - }
6 j, Q# @7 K# L+ n5 H' B, d - return USBD_FAIL;
. _# U# H6 c( V5 t( { - /* USER CODE END 6 */
* H/ E( s% Q+ W8 ` - }
复制代码
3 [5 I& O/ T$ y, ?/ f3 U) C, h
8 H: n' o0 F3 N6 H$ v* B" V
9 ]4 t7 y, [; i$ q" o& i
/ T/ O U; @6 u# D
写优盘函数 % }6 ~; q4 ]" W% r- v6 F3 J6 c5 v/ U
1 P+ o6 o1 e0 J, F
4 `: Z9 H5 ? g/ }0 O8 Q
7 \% u# o" t6 ?& I. T) n0 E 第七,修改写优盘函数。如下,把buf中的数据写入到目标flash地址中。 - / E2 I9 p& U9 I; n8 B" S
- int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
- ]1 z! I! E0 P+ ?4 ` - {( h' W0 I4 k0 d) T1 t
- /* USER CODE BEGIN 7 */
7 p; p0 U. S6 P2 f& k' P - if(lun == 0)
, O) S$ u; H* M2 f* N4 m& X - {9 X# @! n4 r# A$ U2 B
- uint16_t i;% Q1 {3 L& n* V' w h; W* f7 }# c
- HAL_FLASH_Unlock();
+ ^0 b+ ~; V+ ^- i+ P5 _ - 4 f( z# R9 o: R& r$ x3 e
- FLASH_EraseInitTypeDef f;" C9 z: F* |3 @ ~" @2 \
- f.TypeErase = FLASH_TYPEERASE_PAGES;, a1 ^, }$ X- [
- f.PageAddress = FLASH_START_ADDR + blk_addr*FLASH_PAGE_SIZE ;
! [$ h b' B, Q2 i ^3 B - f.NbPages = blk_len;
% c0 a, _/ V) M ]7 R - uint32_t PageError = 0;
. `$ {2 U4 z* p- O - HAL_FLASHEx_Erase(&f, &PageError);; g% Y" M. k7 q. M* H6 H
- 5 B1 V1 f3 L5 F
- for(i=0;i<blk_len*FLASH_PAGE_SIZE;i+=4)
$ _* s. x& Z- `/ X) t& ?$ T6 s8 g - HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,FLASH_START_ADDR + blk_addr*FLASH_PAGE_SIZE + i , *(uint32_t *)(&buf[i]));" U6 ?& s- x5 B2 w" |
1 ?8 j4 Q- t6 w x9 g; W- HAL_FLASH_Lock();
9 n+ P& r {% u3 O# H - return USBD_OK;
. ]' W$ i f; ? J5 B - }7 K; @4 T) \0 G, v) M1 w# D
- return USBD_FAIL;5 v0 D- L0 y% w5 t6 w1 Z4 Q0 ^
- /* USER CODE END 7 */
* h6 {4 q) s+ @ - }
复制代码 7 P) Q1 C" Y2 n* R7 Y% N" \3 @
& \" C7 F8 k& a- F3 {2 {, E
好了,保存,编译、下载、上电。 5 P1 b* C& x! O8 q$ {: B/ O
把USB线插入电脑,首先会弹出一个提示框,要求你格式化优盘: 点击:格式化磁盘。弹出“格式化 可移动磁盘”的对话框,磁盘容量是48K,跟我们当初计算的大小一样。没有问题,点击:开始。 很快,格式化完成了,点确定即可。 这时,你会在你的电脑上看到一个容量28K的可移动磁盘。刚才还48,现在怎么一下子缩水成28? 其实,是因为格式化的时候,电脑要向磁盘写入FAT文件系统,而文件系统要占用一定的磁盘容量。有了文件系统,我们就能方便的操作优盘,而不像操作EEPROM那样费劲。 这时,你可以打开优盘,创建一个TXT文件: 保存,关闭。弹出优盘,再插上,你会发现你之前创建的TXT文件还在,说明优盘创建成功!
6 \% w) P" Q! t3 T' D. S5 L
至此,优盘的例程操作完了。其实,单片机内部的flash空间是很小的,虽然能模拟成优盘,但存不了什么东西。所以这一例程的意义在于,我们熟悉了如何使用STM32CubeMX软件来把一些存储设备模拟成优盘,方便使用。例如,我们可以把外部的TF卡或者外部flash模拟成优盘,这样使用起来非常方便。 . x/ d* ^- M |: f5 ?5 U
脑洞一下:如果你有喜欢的人,做这样一个优盘给她,里面写一封表白的信,然后想办法把写优盘函数搞一下,无法擦除,这就是一封删不掉的信........... |