zoukankan      html  css  js  c++  java
  • C8051F340之USB简介

    背景

    需求为实现一个键盘产品,于是将C8051F340作为主控制器。本篇记录C8051F340USB控制器相关知识点,阅读本篇文章需要读者具有最基本的USB相关知识。

    正文

    1. C8051F340结构
      C8051F340,以下简称F340,为silicon公司出品的8位单片机,具有USB接口,可支持USB全速/低速两种模式,USB功能控制器包括一个串行接口引擎(SIE),一个USB收发器,1k FIFO块,该控制器物理层遵循USB2.0通信协议,架构图如下:

      此处可以将USB看做一个独立于F340的外设, F340通过USB控制器提供的寄存器来控制USB控制器,其内部共含有4个物理端点,端点0可同时含有IN/OUT双向通道,端点1-端点3为单向通道,但可将对应的3个端点模拟为双向通道,只需将对应端点的FIFO部分配置为两部分——IN/OUT,在USB运行中,改变对应方向寄存器即可。
      F340只能作为USB从设备。

    2. C8051F340之USB寄存器读写方式
      USB所有的寄存器都通过两组特殊功能寄存器(SFR)访问:
      USB0 Address(USB0ADR):对应的要读写寄存器的地址;
      USB0 Data(USB0DAT):对应寄存器读或写的数据。
      即先将要访问的寄存器地址写入USB0ADR,下一步操作USB0DAT则完成对对应寄存器读/写操作,对应读写宏定义如下:

    #define POLL_READ_BYTE(addr, target) while(USB0ADR & 0x80); 
                                         READ_BYTE(addr, target);
    #define READ_BYTE(addr, target) USB0ADR = (0x80 | addr); 
                                    while (USB0ADR & 0x80); target = USB0DAT
    
    #define POLL_WRITE_BYTE(addr, data) while(USB0ADR & 0x80);  
                                        WRITE_BYTE(addr, data);
    #define WRITE_BYTE(addr, data) USB0ADR = (addr); USB0DAT = data;
    
    1. C8051F340 USB时钟配置
      USB可通过寄存器USB0XCN配置USB为全速/低速模式。当选择为低速模式时,USB0的时钟必须为6MHZ,当工作在全速模式时,USB0必须工作在48MHZ,时钟的配置方法在另一篇博客Silicon C8051F340之时钟系统中已详述。注意配置CLKREC(Clock Recovery Control)寄存器,Clock Recovery circuitry的作用是用来将USB数据流与控制器内部时钟相同步,使USB控制器能准确读取到USB主机输入的USB数据流,配置方法文档内已说的很明白,不再重复。以下为配置USB为全速模式的示例代码:
    void USB0_Init (void)
    {
       POLL_WRITE_BYTE (POWER, 0x08);      // Force Asynchronous USB Reset
       POLL_WRITE_BYTE (IN1IE, 0x07);       // Enable Endpoint 0-1 in interrupts
       POLL_WRITE_BYTE (OUT1IE,0x07);      // Enable Endpoint 0-1 out interrupts
       POLL_WRITE_BYTE (CMIE, 0x07);       // Enable Reset, Resume, and Suspend interrupts
       USB0XCN = 0xE0;                     // Enable transceiver; select full speed
       POLL_WRITE_BYTE (CLKREC,0x89);      // Enable clock recovery, 
                                           // single-step mode disabled
       EIE1 |= 0x02;                       // Enable USB0 Interrupts
                                           // Enable USB0 by clearing the USB
       POLL_WRITE_BYTE (POWER, 0x01);      // Inhibit Bit and enable suspend
                                           // detection
    }
    
    1. C8051F340 USB中断
      作为一个用户(单片机的编程者),在USB0中断中,我们只需要关心3大类中断寄存器即可,CMINT(Common interrupt)(公共中断寄存器),IN1INT(输入端点中断寄存器),OUT1INT(输出端点中断寄存器)。USB的通信协议规定,端点0通常用来传递配置信息,其他端点根据端点类型(大容量或是中断或是同步)来传递不同的端点数据,USB通信细节本篇不再赘述,会在博客USB通信详解系列中详述。以下贴出USB0中断处理代码,会更加直观些:
    void Usb_ISR (void) interrupt 8        // USB中断入口
    {
    
    	unsigned char bCommon, bIn, bOut;
    	POLL_READ_BYTE (CMINT, bCommon);	// USB0公共中断寄存器
    	POLL_READ_BYTE (IN1INT, bIn);		// USB0输入端点中断寄存器
    	POLL_READ_BYTE (OUT1INT, bOut);		// USB0输出端点中断寄存器
    	{
    		if (bCommon & rbRSUINT) {		// 恢复
    			Usb_Resume ();
    		}
    		if (bCommon & rbRSTINT) {		// 复位
    			Usb_Reset ();
    		}
    		if (bCommon & rbSUSINT)  {		// 挂起
    			Usb_Suspend ();
    		}
    		if (bIn & rbEP0) {				// 端点0中断处理
    			Handle_Control ();			
    		}
    		if (bIn & rbIN1) {          	// 端点1输入中断处理
    			Handle_In1 ();				
    		}
    		if (bOut & rbOUT1) {			// 端点1输出中断处理
    			Handle_Out1 ();				
    		}
    	}
    }
    

    从以上代码可以看出,当有数据来或是需要写的时候,使能了对应中断,则SIE即会产生相关中断,通知MCU来处理对应的USB数据。具体如何处理对应的数据会在博客USB通信详解系列中详述。

    至此,记录完毕。

    参考链接:

    C8051F340数据手册。

    记录时间:2017-4-6
    记录地点:深圳WZ

  • 相关阅读:
    vue路由篇(动态路由、路由嵌套)----动态路由下再嵌套子路由
    文件、I/O重定向、文本
    Linux基础命令
    Chrome开发者工具(DevTools)使用技巧
    Grid网格布局知识点整理
    Javascript常见数组、字符串API整理
    css 实现瀑布流布局效果
    实时校验输入框内容
    app里遇见的小问题总结
    修复bug: iOS特性会滚动会引起白屏 ,使用 will-change: transform;
  • 原文地址:https://www.cnblogs.com/ChYQ/p/6675112.html
Copyright © 2011-2022 走看看