OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8566|回复: 9

【ALIENTEK 战舰STM32开发板例程系列连载+教学】第五十五章 USB读卡器实验

[复制链接]

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2013-4-22 21:09:12 | 显示全部楼层 |阅读模式
 

第五十五章 USB读卡器实验

    上一章我们向大家介绍了如何利用STM32USB来做一个触控USB鼠标,本章我们将利用STM32USB来做一个USB读卡器。本章分为如下几个部分:

55.1 USB读卡器简介

55.2 硬件设计

55.3 软件设计

55.4 下载验证


55.1 USB读卡器简介

ALIENTEK 战舰STM32开发板板载了一个SD卡插槽,可以用来接入SD卡,另外战舰STM32开发板板载了一个8M字节的SPI FLASH芯片,通过STM32USB接口,我们可以实现一个简单的USB读卡器,来读写SD卡和SPI FLASH

本章我们还是通过移植官方的USB Mass_Storage例程来实现,该例程在MDK的安装目录下可以找到(..\MDK\ARM\Examples\ST\STM32F10xUSBLib\Demos\Mass_Storage)。

USB Mass Storage类支持两个传输协议:

1Bulk-Only 传输(BOT

2Control/Bulk/Interrupt传输(CBI

Mass Storage类规范定义了两个类规定的请求:Get_Max_LUNMass Storage Reset,所有的Mass Storage类设备都必须支持这两个请求。

Get_Max_LUNbmRequestType= 10100001b and bRequest= 11111110b)用来确认设备支持的逻辑单元数。Max LUN的值必须是0~15。注意:LUN是从0开始的。主机不能向不存在的LUN发送CBW,本章我们定义Max LUN的值为1,即代表2个逻辑单元。

Mass Storage ResetbmRequestType=00100001b and bRequest= 11111111b)用来复位Mass Storage设备及其相关接口。

支持BOT传输的Mass Storage设备接口描述符要求如下:

接口类代码bInterfaceClass=08h,表示为Mass Storage设备;

接口类子代码bInterfaceSubClass=06h,表示设备支持SCSI Primary Command-2SPC-2);

协议代码bInterfaceProtocol3种:0x000x010x50,前两种需要使用中断传输,最后一种仅使用批量传输(BOT)。

支持BOT的设备必须支持最少3endpointControl, Bulk-InBulk-OutUSB2.0的规范定义了控制端点0Bulk-In端点用来从设备向主机传送数据(本章用端点1实现)。Bulk-Out端点用来从主机向设备传送数据(本章用端点2实现)。

ST官方的例程是通过USB来读写SD卡(SDIO方式)和NAND FALSH,支持2个逻辑单元,我们在官方例程的基础上,只需要修改SD驱动部分代码(改为SPI),并将对NAND FLASH的操作修改为对SPI FLASH的操作。只要这两步完成了,剩下的就比较简单了,对底层磁盘的读写,都是在mass_mal.c文件实现的,所以我们只需要修改该函数的MAL_InitMAL_WriteMAL_ReadMAL_GetStatus4个函数,使之与我们的SD卡和SPI FLASH对应起来即可。

本章我对SD卡和SPI FLASH的操作都是采用SPI方式,所以速度相对SDIOFSMC控制的NAND FLASH来说,相对会慢一些。

55.2 硬件设计

本节实验功能简介:开机的时候先检测SD卡和SPI FLASH是否存在,如果存在则获取其容量,并显示在LCD上面(如果不存在,则报错)。之后开始USB配置,在配置成功之后就可以在电脑上发现两个可移动磁盘。我们用DS1来指示USB正在读写SD卡,并在液晶上显示出来,同样我们还是用DS0来指示程序正在运行。

所要用到的硬件资源如下:

1)  指示灯DS0 DS1

2)  串口

3)  TFTLCD模块

4)  SD

5)  SPI FLASH

6)  USB接口

这几个部分,在之前的实例中都已经介绍过了,我们在此就不多说了。不过还是要注意一下P13的连接,要和上一章一样!

55.3 软件设计

本章,我们在第四十四章实验(实验39)的基础上修改,先打开实验39 的工程,在HARDWARE文件夹所在文件夹下新建一个USB的文件夹,然后在USB文件夹下面新建LIBCONFIG文件夹,分别用来存放与USB核相关的代码以及配置部分代码。这两部分代码我们也不细说(详见光盘本例程源码),其中USB文件夹里面的代码同上一章的一模一样,而CONFIG文件夹里面的源码则来自MDK自带的Mass_Storage例程: X:\Keil3.80A\ARM\

Examples\ST\STM32F10xUSBLib\Demos\Mass_Storage下的sourceinclude文件夹(X为你安装MDK的磁盘)。

然后,我们在工程文件里面新建USBUSBCFG组,分别加入USB\LIB下面的代码和USB\CONFIG下面的代码。然后把LIBCONFIG文件夹加入头文件包含路径。

test.c里面,我们修改main函数如下:

//设置USB 连接/断线

//enable:0,断开

//      1,允许连接        

void usb_port_set(u8 enable)

{

       RCC->APB2ENR|=1<<2;    //使能PORTA时钟           

       if(enable)_SetCNTR(_GetCNTR()&(~(1<<1)));//退出断电模式

       else

       {      

              _SetCNTR(_GetCNTR()|(1<<1));  // 断电模式

              GPIOA->CRH&=0XFFF00FFF;

              GPIOA->CRH|=0X00033000;

              PAout(12)=0;                      

       }

}

int main(void)

{                                         

       u8 offline_cnt=0;

       u8 tct=0;

       u8 USB_STA;

       u8 Divece_STA;

     Stm32_Clock_Init(9);    //系统时钟设置

       delay_init(72);                     //延时初始化

       uart_init(72,9600);       //串口1初始化      

       LCD_Init();                  //初始化液晶

       LED_Init();            //LED初始化

       KEY_Init();                  //按键初始化                

       usmart_dev.init(72);      //usmart初始化           

      POINT_COLOR=RED;  //设置字体为蓝色    

       LCD_ShowString(60,50,200,16,16,"WarShip STM32");   

       LCD_ShowString(60,70,200,16,16,"USB Card Reader TEST");

       LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");

       LCD_ShowString(60,110,200,16,16,"2012/9/25");    

      SPI_Flash_Init();

       if(SD_Initialize())LCD_ShowString(60,130,200,16,16,"SD Card Error!");     

//检测SD卡错误

       else //SD 卡正常

       {                                                                                                              

              LCD_ShowString(60,130,200,16,16,"SD Card Size:     MB");

          Mass_Memory_Size[0]=(long long)SD_GetSectorCount()*512;

//得到SD卡容量(字节),当容量超过4G的时候,需要用到两个u32来表示

           Mass_Block_Size[0] =512;

//因为在Init里面设置了SD卡的操作字节为512,所以这里一定是512个字节.

           Mass_Block_Count[0]=Mass_Memory_Size[0]/Mass_Block_Size[0];

             LCD_ShowNum(164,130,Mass_Memory_Size[0]>>20,5,16);//显示SD卡容量

      }

       if(SPI_FLASH_TYPE!=W25Q64)LCD_ShowString(60,130,200,16,16,"W25Q64 Error!");       //检测SD卡错误

       else //SPI FLASH 正常

       {                                                                                                              

           Mass_Memory_Size[1]=1024*1024*6;//6M字节

           Mass_Block_Size[1] =512;

//因为在Init里面设置了SD卡的操作字节为512,所以这里一定是512个字节.

           Mass_Block_Count[1]=Mass_Memory_Size[1]/Mass_Block_Size[1];

              LCD_ShowString(60,150,200,16,16,"SPI FLASH Size:6144KB");  

       }

       delay_ms(1800); usb_port_set(0);        //USB先断开

       delay_ms(300); usb_port_set(1);          //USB再次连接

      LCD_ShowString(60,170,200,16,16,"USB Connecting...");//提示SD卡已经准备了     

     //USB配置

      USB_Interrupts_Config();   

      Set_USBClock();  

      USB_Init();             

       while(1)

       {    

              delay_ms(1);                         

              if(USB_STA!=USB_STATUS_REG)//状态改变了

              {                                                

                     LCD_Fill(60,190,240,190+16,WHITE);//清除显示                           

                     if(USB_STATUS_REG&0x01)//正在写               

                     {

                            LCD_ShowString(60,190,200,16,16,"USB Writing...");//USB正在写入数据                     }

                     if(USB_STATUS_REG&0x02)//正在读

                     {

                            LCD_ShowString(60,190,200,16,16,"USB Reading...");//USB正在读数据                        }                                                                           

                     if(USB_STATUS_REG&0x04)LCD_ShowString(60,210,200,16,16,"USB Write

Err ");//提示写入错误

                     else LCD_Fill(60,210,240,210+16,WHITE);//清除显示      

                     if(USB_STATUS_REG&0x08)LCD_ShowString(60,230,200,16,16,"USB Read

  Err ");//提示读出错误

                     else LCD_Fill(60,230,240,230+16,WHITE);//清除显示   

                     USB_STA=USB_STATUS_REG;//记录最后的状态

              }

              if(Divece_STA!=bDeviceState)

              {

                     if(bDeviceState==CONFIGURED)LCD_ShowString(60,170,200,16,16,"USB

Connected    ");//提示USB连接已经建立

                     else LCD_ShowString(60,170,200,16,16,"USB DisConnected ");//USB被拔出了

                     Divece_STA=bDeviceState;

              }

              tct++;

              if(tct==200)

              {

                     tct=0; LED0=!LED0;//提示系统在运行

                     if(USB_STATUS_REG&0x10)

                     {

                            offline_cnt=0;//USB连接了,则清除offline计数器

                            bDeviceState=CONFIGURED;

                     }else//没有得到轮询

                     {

                            offline_cnt++; 

                            if(offline_cnt>10)bDeviceState=UNCONNECTED;

//2s内没收到在线标记,代表USB被拔出了

                     }

                     USB_STATUS_REG=0;

              }

       };                                                                                              

此部分代码除了main函数,还有一个usb_port_set函数,usb_port_set函数我们在上一章已经介绍过了,这里就不多说。我们将SPI FLASH的最开始6M地址范围用作SPI FLASH Disk,也就是文件系统管理的范围大小,这个我们在之前的SPI FLASH也介绍过。

通过此部分代码就可以实现了我们之前在硬件设计部分描述的功能,这里我们用到了一个全局变量Usb_Status_Reg,用来标记USB的相关状态,这样我们就可以在液晶上显示当前USB的状态了。

软件设计部分就为大家介绍到这里。

55.4 下载验证

在代码编译成功之后,我们通过下载代码到战舰STM32开发板上,在USB配置成功后(假设已经插入SD卡,注意:USB数据线,要插在USB口!不是USB_232端口!),LCD显示效果如图55.4.1所示:


55.4.1 USB连接成功

此时,电脑提示发现新硬件如图55.4.2所示:


55.4.2 USB读卡器被电脑找到

    USB配置成功后,DS1不亮,DS0闪烁,并且在电脑上可以看到我们的磁盘,如图55.4.3所示:


55.4.3 电脑找到USB读卡器的两个盘符

我们打开设备管理器,在通用串行总线控制器里面可以发现多出了一个USB Mass Storage Device,同时看到磁盘驱动器里面多了2个磁盘,如图55.4.4所示:


55.4.4 通过设备管理器查看磁盘驱动器

此时,我们就可以通过电脑读写SD卡或者SPI FLASH里面的内容了。在执行读写操作的时候,就可以看到DS1亮,并且会在液晶上显示当前的读写状态。

注意,在对SPI FLASH操作的时候,最好不要频繁的往里面写数据,否则很容易将SPI FLASH写爆!!

 

《STM32开发指南》第五十五章 USB读卡器实验.rar

568.74 KB, 下载次数: 748

实验50 USB读卡器实验.rar

275.97 KB, 下载次数: 846

我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
28
金钱
28
注册时间
2015-4-6
在线时间
0 小时
发表于 2015-4-6 16:56:28 | 显示全部楼层

原子哥,为什么我移植之后,电脑能识别,出现了图标,但是就是查看不了内容

回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
 楼主| 发表于 2015-4-6 18:54:25 | 显示全部楼层
回复【2楼】caomufei:
---------------------------------
说明还有bug呢。得再看看代码。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
28
金钱
28
注册时间
2015-4-6
在线时间
0 小时
发表于 2015-4-6 22:30:37 | 显示全部楼层
sd卡属性,容量显示为0,这样的话,该重点看那部分呢,会不会是 sd卡那块代码的问题
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
 楼主| 发表于 2015-4-7 00:02:49 | 显示全部楼层
回复【4楼】caomufei:
---------------------------------
看sd卡初始化部分是否成功了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

34

帖子

0

精华

高级会员

Rank: 4

积分
517
金钱
517
注册时间
2014-5-17
在线时间
79 小时
发表于 2015-4-24 17:49:28 | 显示全部楼层
原子哥,你在最后说:“注意,在对SPI FLASH操作的时候,最好不要频繁的往里面写数据,否则很容易将SPI FLASH写爆!!”
你的意思是FLASH内数据装不下,还是写的次数太多把把芯片写坏(看到手册写擦写次数可以10W次)?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
 楼主| 发表于 2015-4-24 23:01:56 | 显示全部楼层
回复【6楼】zhangfj2010:
---------------------------------
擦除次数过多。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
101
金钱
101
注册时间
2013-10-18
在线时间
20 小时
发表于 2017-3-17 10:33:42 | 显示全部楼层
电脑认出flash 但是在从电脑向flash复制文件 提示“无法复制  路径太深”
回复 支持 反对

使用道具 举报

1

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
101
金钱
101
注册时间
2013-10-18
在线时间
20 小时
发表于 2017-3-17 10:38:44 | 显示全部楼层
[img][/img]
20170317103410.png
回复 支持 反对

使用道具 举报

1

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
101
金钱
101
注册时间
2013-10-18
在线时间
20 小时
发表于 2017-3-17 10:39:21 | 显示全部楼层
在flash上 可以新建 txt   word
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 20:25

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表