当前位置:   article > 正文

【正点原子STM32连载】 第五十三章 USB读卡器(Slave)实验 摘自【正点原子】APM32E103最小系统板使用指南

【正点原子STM32连载】 第五十三章 USB读卡器(Slave)实验 摘自【正点原子】APM32E103最小系统板使用指南

1)实验平台:正点原子APM32E103最小系统板
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/docs/boards/xiaoxitongban

第五十三章 USB读卡器(Slave)实验

本章将介绍使用APM32E103作为USB从设备,模拟出USB读卡器,使得PC与APM32E103通过USB连接后,能够访问与APM32E103连接的SD中的数据。通过本章的学习,读者将学习到APM32E103作为USB从设备模拟出USB读卡器的使用。
本章分为如下几个小节:
53.1 硬件设计
53.2 程序设计
53.3 下载验证

53.1 硬件设计
53.1.1 例程功能

  1. 程序运行后,模拟出USB读卡器,此时使用USB数据线与PC进行连接,连接成功后LCD上会有相应的提示信息,并且PC上会识别出一个名为“ALIENTEK SD Disk USB Device”的磁盘驱动器,可使用PC对SD卡进行读写操作
  2. LED1亮起,提示正在访问SD卡
  3. LED0闪烁,指示程序正在运行
    53.1.2 硬件资源
  4. LED
    LED0 - PB5
    LED1 - PE5
  5. 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
  6. SD卡(SDIO驱动)
  7. USBD
    53.1.3 原理图
    本章实验使用USB接口与PC进行连接,开发板板载了一个USB SLAVE接口,用于连接其他USB设备,USB SLAVE接口与MCU的连接原理图,如下图所示:
    在这里插入图片描述

图53.1.3.1 USB SLAVE接口与MCU的连接原理图
53.2 程序设计
53.2.1 Geehy的USB_D驱动库
Geehy针对APM32E103的USB驱动库为USB_Device_Lib,该驱动库由Geehy提供,下载链接为https://www.geehy.com/apm32?id=45,也可以在A盘8,APM32参考资料中找到。
USB_Device_Lib的根目录下包含了两个文件夹,如下表所示:
文件夹 描述
Core_Device 示例工程中与硬件相关的驱动包
Driver 驱动库本体
表53.2.1.1 USB_Device_Lib根目录文件夹描述
可见最最重要的是Library文件夹,该文件夹的文件结构,如下图所示:
在这里插入图片描述

图53.2.1.1 Libraries文件夹结构
从上图中可以看出,Geehy的USB驱动针对USB的主模式和从模式都提供了驱动,本书主要介绍USB从模式的应用,因此主要关注“Core_Device”和“Driver”文件夹。
“Driver”文件夹中就是USB的基本驱动文件,是无论作何应用都需要使用到的驱动文件。
“Core_Device”文件夹中有包含了“Class”和“Standard”两个文件夹,其中“Standard”文件夹中是与USB协议有关的驱动,而“Class”文件夹中是与具体应用有关的驱动文件,例如本章要实现的USB读卡器就需要用到“MSC”文件夹中的驱动文件,后续的USB虚拟串口实验就需要使用到“CDC”文件夹中的驱动文件,而“HID”文件夹中包含的驱动是与人体学接口设备相关应用中需要使用的驱动文件,例如鼠标、键盘等。
APM32E103的USB驱动就介绍这么多,若读者想更加深入地了解USB的驱动,需要先具备一定的USB相关知识。
53.2.2 实验应用代码
本章实验的应用代码,如下所示:

extern volatile uint8_t g_usb_state_reg;              /* USB状态标志 */
extern volatile uint8_t g_device_state;               /* USB连接状态 */

int main(void)
{
    uint8_t t = 0;
    uint8_t usb_sta;
    uint8_t device_sta;
    uint8_t offline_cnt = 0;
    
    NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_4);  /* 设置中断优先级分组为组4 */
    sys_apm32_clock_init(15);                         /* 配置系统时钟 */
    delay_init(120);                                  /* 初始化延时功能 */
    usart_init(115200);                               /* 初始化串口 */
    led_init();                                       /* 初始化LED */
    lcd_init();                                       /* 初始化LCD */
    
    lcd_show_string(30, 50, 200, 16, 16, "APM32", RED);
    lcd_show_string(30, 70, 200, 16, 16, "USB Card Reader TEST", RED);
    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    
    if (sd_init() != SD_OK)                           /* 检测SD卡错误 */
    {
        lcd_show_string(30, 130, 200, 16, 16, "SD Card Error!", RED);
    }
    else                                              /* SD卡正常 */
    {
        lcd_show_string(30, 130, 200, 16, 16, "SD Card Size:     MB", RED);
        lcd_show_num(134, 130, g_sd_card_info.CardCapacity >> 20, 5, 16, RED);
}

    /* 提示正在建立USB连接 */
    lcd_show_string(30, 170, 200, 16, 16, "USB Connecting...", RED);
    
    MSC_Init();
    
    while (1)
    {
        t++;
        
        if (usb_sta != g_usb_state_reg)               /* 状态改变了 */
        {
            lcd_fill(30, 190, 240, 190 + 16, WHITE);  /* 清除显示 */

            if (g_usb_state_reg & 0x01)               /* 正在写入 */
            {
                LED1(0);
                lcd_show_string(30, 190, 200, 16, 16, "USB Writing...", RED);
            }

            if (g_usb_state_reg & 0x02)               /* 正在读取 */
            {
                LED1(0);
                lcd_show_string(30, 190, 200, 16, 16, "USB Reading...", RED);
            }

            if (g_usb_state_reg & 0x04)               /* 写入错误 */ 
            {
                lcd_show_string(30, 210, 200, 16, 16, "USB Write Err ", RED);
            }
            else
            {
                lcd_fill(30, 210, 240, 230 + 16, WHITE);
            }
            
            if (g_usb_state_reg & 0x08)               /* 读取错误 */
            {
                lcd_show_string(30, 230, 200, 16, 16, "USB Read  Err ", RED);
            }
            else
            {
                lcd_fill(30, 230, 240, 250 + 16, WHITE);
            }
            
            usb_sta = g_usb_state_reg;  
        }
        
        if (device_sta != g_device_state)
        {
            if (g_device_state == 1)                  /* USB连接建立 */
            {
                lcd_show_string(30, 170, 200, 16, 16, "USB Connected", RED);
            }
            else                                      /* USB连接断开 */
            {
                lcd_show_string(30, 170, 200, 16, 16, "USB DisConnected ", RED);
            }
            
            device_sta = g_device_state;
        }
        
        if (t == 200)
        {
            LED1(1);
            LED0_TOGGLE();
            
            if (g_usb_state_reg & 0x10)
            {
                offline_cnt = 0;
                g_device_state = 1;
            }
            else
            {
                offline_cnt++;
                if (offline_cnt > 10)
                {
                    g_device_state = 0;
                }
            }
            g_usb_state_reg = 0;
            
            t = 0;
        }
        
        delay_ms(1);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117

从上面的代码中可以看出,在调用完USB驱动库中的MSC初始化函数MSC_Init()后并不断地获取USB的读写状态和连接状态,并在LCD上进行显示。
在调用完函数MSC_Init()后,USB驱动库便会自动模拟出一个USB读卡器,当然也需要实现配置好USB读卡器模拟出的设备信息,以及读写、初始化SD卡等的操作,这些操作全部在usbd_storage_disk.c文件中完成了,请读者自行参考该文件。
53.3 下载验证
在完成编译和烧录操作后,将SD卡正确插入开发板板载的SD卡卡座,可以看到LCD上显示了SD卡的容量信息以及USB的连接状态,若开发板还未通过USB SLAVE接口与PC进行连接,那么LCD上会有USB连接断开的提示,此时可以将开发板通过USB SLAVE接口与PC进行连接,稍等一会后,可以看到LCD上显示了USB已连接的提示,并且PC上也多出了一个磁盘,磁盘中的文件就是SD卡中的文件,并且在PC上也可以直接对SD卡中的文件进行读写操作。

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号