最新日志

发表于:2008-4-26 18:42:47
标签:STM32  USB  Joystick  程序设计  

0

STM32 USB joystick程序 --hw_config.c

hw_config.c  提供了STM32的初始化函数和实际硬件需要的操作函数,Joystick_Send()通过函数UserToPMABufferCopy 和 SetEPTxValid 将坐标值发给了USB端口。这个文件算是USB代码中最易懂的一个了。

void Joystick_Send(u8 Keys)
{
  u8 Mouse_Buffer[4] = {0, 0, 0, 0};      //前后固定为0,中间2位代表X,Y
  s8 X = 0, Y = 0;

  switch (Keys)
  {
    case LEFT:
      X -= CURSOR_STEP;
      break;
    case RIGHT:

      X += CURSOR_STEP;
      break;
    case UP:
      Y -= CURSOR_STEP;
      break;
    case DOWN:
      Y += CURSOR_STEP;
      break;
    default:
      return;
  }

  /* prepare buffer to send */
  Mouse_Buffer[1] = X;
  Mouse_Buffer[2] = Y;
  /*copy mouse position info in ENDP1 Tx Packet Memory Area*/
  UserToPMABufferCopy(Mouse_Buffer, GetEPTxAddr(ENDP1), 4);  //把设备的数据发往主机
  /* enable endpoint for transmission */
  SetEPTxValid(ENDP1);
}

点击此处查看原文 >>

系统分类: ARM   |    用户分类:    |    来源: 原创

评论(1) | 阅读(233)
发表于:2008-4-26 18:39:38
标签:STM32  USB  Joystick  程序设计  

0

STM32 USB joystick程序 --usb_prop.c

usb_prop.c  提供了Device_Property, Device_Table & USER_STANDARD_REQUEST 结构描述,这3个东东定义于usb_core.c。

在ST的例子中,USER_STANDARD_REQUESTS里面的成员全部定义为了空函数DEVICE_PROP的成员有具体的定义,详细的解读会再以后给出。

DEVICE Device_Table =
  {
    EP_NUM,   // defined in usb_conf.h  EP_NUM=2 代表USB应用使用的端点数量
    1         // 代表USB应用使用的配置数量
  };

DEVICE_PROP Device_Property =    //这些函数具体的描述在后面
  {
    Joystick_init,  //USB IP的初始化
    Joystick_Reset,
    Joystick_Status_In,  //回调函数,进入某个阶段状态结束时调用,用于执行类或应用相关的过程,本例中为空函数
    Joystick_Status_Out, //回调函数,退出某个阶段状态结束时调用,本例中为空函数
    Joystick_Data_Setup, //回调函数,
    Joystick_NoData_Setup, //回调函数
    Joystick_Get_Interface_Setting,  //回调函数,检测收到的设置接口的标准请求
    Joystick_GetDeviceDescriptor,    //内核获取设备描述符
    Joystick_GetConfigDescriptor,    //内核获取配置描述符
    Joystick_GetStringDescriptor,    //内核获取字符串描述符
    0,
    0x40 /*MAX PACKET SIZE*/
  };

//下面的ONE_DESCRIPTOR 即指向usb_desc.c中定义的各种描述符

ONE_DESCRIPTOR Device_Descriptor =     //设备描述符
  {
    (u8*)Joystick_DeviceDescriptor,     //描述符均在usb_desc中定义
    JOYSTICK_SIZ_DEVICE_DESC
  };

ONE_DESCRIPTOR Config_Descriptor =      //配置描述符
  {
    (u8*)Joystick_ConfigDescriptor,
    JOYSTICK_SIZ_CONFIG_DESC
  };

ONE_DESCRIPTOR Joystick_Report_Descriptor =  //报告描述符
  {
    (u8 *)Joystick_ReportDescriptor,
    JOYSTICK_SIZ_REPORT_DESC
  };

ONE_DESCRIPTOR Mouse_Hid_Descriptor =      //HID描述符
  {
    (u8*)Joystick_ConfigDescriptor + JOYSTICK_OFF_HID_DESC,
    JOYSTICK_SIZ_HID_DESC
  };

ONE_DESCRIPTOR String_Descriptor[4] =        //字符串描述符 defined in usb_desc.c
  {
    {(u8*)Joystick_StringLangID, JOYSTICK_SIZ_STRING_LANGID},
    {(u8*)Joystick_StringVendor, JOYSTICK_SIZ_STRING_VENDOR},
    {(u8*)Joystick_StringProduct, JOYSTICK_SIZ_STRING_PRODUCT},
    {(u8*)Joystick_StringSerial, JOYSTICK_SIZ_STRING_SERIAL}
  };

点击此处查看原文 >>

系统分类: ARM   |    用户分类:    |    来源: 原创

评论(0) | 阅读(213)
发表于:2008-4-26 18:30:19
标签:STM32  USB  Joystick  程序设计  

0

STM32 USB joystick程序 -- usb_desc.c

usb_desc.c  提供了设备、端点、接口、字符串、群组、制造商描述符。因为joystick是HID设备,所以多了报告描述符。我加了一些注释如下。我的目标是先搞懂其大致的结构,至于细节可以慢慢再学习。

/* USB Standard Device Descriptor 设备描述符*/
const u8 Joystick_DeviceDescriptor[JOYSTICK_SIZ_DEVICE_DESC] =
  {
    0x12,                       /*bLength Byte0: the length of bytes is 0x12*/
    USB_DEVICE_DESCRIPTOR_TYPE, /*Byte1: 0x01, type of descriptor:Device bDescriptorType*/
    0x00,                       /*bcdUSB compatible with USB2.0 */
    0x02,                       /* 0x00,0x01 means compatible with USB1.0 */
    0x00,                       /*bDeviceClass 群组码*/
    0x00,                       /*bDeviceSubClass 设备次群组*/
    0x00,                       /*bDeviceProtocol 0表示无特定设备协议*/
    0x40,                       /*bMaxPacketSize 最大封包0x40*/
    0x83,                       /*idVendor 制造商ID(0x0483)*/
    0x04,
    0x10,                       /*idProduct 产品ID 0x5710*/
    0x57,
    0x00,                       /*bcdDevice rel. 2.00 以BCD表示设备发行序号*/
    0x02,
    1,                          /*Index of string descriptor describing
                                              manufacturer */
    2,                          /*Index of string descriptor describing
                                             product*/
    3,                          /*Index of string descriptor describing the
                                             device serial number */
    0x01                        /*bNumConfigurations 配置数目为1,接下来只有1个配置描述符*/
  }
  ; /* Joystick_DeviceDescriptor */

/* USB Configuration Descriptor 配置,接口,端点,群组,制作商描述符*/
/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
const u8 Joystick_ConfigDescriptor[JOYSTICK_SIZ_CONFIG_DESC] =
  {
    0x09, /* bLength: Configuation Descriptor size 配置描述符 长度为9字节*/
    USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
    JOYSTICK_SIZ_CONFIG_DESC,         //JOYSTICK_SIZ_CONFIG_DESC 34
    0x00,    //34=09+09+09+07
    /* 34 0x00 总长度为0x34字节,包括配置,接口,端点,bytes与群组描述符。
       注意低字节在前。wTotalLength: Bytes returned */
    0x01,         /*bNumInterfaces: 1 interface,因此接下来只有1个接口描述符*/
    0x01,         /*bConfigurationValue: Configuration value 接口配置值*/
    0x00,         /*iConfiguration: Index of string descriptor describing
                                 the configuration*/
    0xC0,         /*bmAttributes: self powered */
    0x32,         /*MaxPower 100 mA: this current is used for detecting Vbus*/

    /************** Descriptor of Joystick Mouse interface ****************/
    /* 09 接口描述符*/
    0x09,         /*bLength: Interface Descriptor size*/
    USB_INTERFACE_DESCRIPTOR_TYPE,/*0x04, 代表接口 bDescriptorType: Interface descriptor type*/
    0x00,         /*bInterfaceNumber: Number of Interface,接口数目以0为基值*/
    0x00,         /*bAlternateSetting: Alternate setting 交互设置值*/
    0x01,         /*bNumEndpoints 端点数目1*/
    0x03,         /*bInterfaceClass: 群组类型:HID*/
    0x01,         /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
    0x02,         /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
    0,            /*iInterface: Index of string descriptor 0个字符串描述符*/
   
    /******************** Descriptor of Joystick Mouse HID **********/
    /* 18 */         //群组描述符
    0x09,         /*bLength: HID Descriptor size*/
    HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
    0x00,        
    0x01,         /*bcdHID: HID Class Spec release number*/
    0x00,         /*bCountryCode: Hardware target country,无区域为0*/
    0x01,         /*bNumDescriptors: Number of HID class descriptors to follow,至少为1*/
    0x22,         /*bDescriptorType,描述符类型为报告*/
    JOYSTICK_SIZ_REPORT_DESC,/*wItemLength: Total length of Report descriptor报告描述符的长度*/
    0x00,
   
    /******************** Descriptor of Joystick Mouse endpoint ********************/
    /* 27 */       //端点描述符
    0x07,          /*bLength: Endpoint Descriptor size*/
    USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/

    0x81,          /*bEndpointAddress: Endpoint Address (IN) bit0 为1表示IN,端点地址*/
    0x03,          /*bmAttributes: Interrupt endpoint 中断传输*/
                   //0 控制;1 等时 2 批量 3 中断
    0x04,          /*wMaxPacketSize: 4 Byte max */
    0x00,
    0x20,          /*bInterval: Polling Interval (32 ms) 以ms为单位,查询间隔*/
    //USB的中断并非一般意义的中断,而是查询
    /* 34 */
  }
  ; /* MOUSE_ConfigDescriptor  报告描述符*/
const u8 Joystick_ReportDescriptor[JOYSTICK_SIZ_REPORT_DESC] =
  {
    0x05,          /*Usage Page(Generic Desktop)*/
    0x01,
    0x09,          /*Usage(Mouse)*/
    0x02,
    0xA1,          /*Collection(Logical)*/
    0x01,
    0x09,          /*Usage(Pointer)*/
    0x01,
    /* 8 */
    0xA1,          /*Collection(Linked)*/
    0x00,
    0x05,          /*Usage Page(Buttons)*/
    0x09,
    0x19,          /*Usage Minimum(1)*/
    0x01,
    0x29,          /*Usage Maximum(3)*/
    0x03,
    /* 16 */
    0x15,          /*Logical Minimum(0)*/
    0x00,
    0x25,          /*Logical Maximum(1)*/
    0x01,
    0x95,          /*Report Count(3)*/
    0x03,
    0x75,          /*Report Size(1)*/
    0x01,
    /* 24 */
    0x81,          /*Input(Variable)*/
    0x02,
    0x95,          /*Report Count(1)*/
    0x01,
    0x75,          /*Report Size(5)*/
    0x05,
    0x81,          /*Input(Constant,Array)*/
    0x01,
    /* 32 */
    0x05,          /*Usage Page(Generic Desktop)*/
    0x01,
    0x09,          /*Usage(X axis)*/
    0x30,
    0x09,          /*Usage(Y axis)*/
    0x31,
    0x09,          /*Usage(Wheel)*/
    0x38,
    /* 40 */
    0x15,          /*Logical Minimum(-127)*/
    0x81,
    0x25,          /*Logical Maximum(127)*/
    0x7F,
    0x75,          /*Report Size(8)*/
    0x08,
    0x95,          /*Report Count(3)*/
    0x03,
    /* 48 */
    0x81,          /*Input(Variable, Relative)*/
    0x06,
    0xC0,          /*End Collection*/
    0x09,
    0x3c,
    0x05,
    0xff,
    0x09,
    /* 56 */
    0x01,
    0x15,
    0x00,
    0x25,
    0x01,
    0x75,
    0x01,
    0x95,
    /* 64 */
    0x02,
    0xb1,
    0x22,
    0x75,
    0x06,
    0x95,
    0x01,
    0xb1,
    /* 72 */
    0x01,
    0xc0
  }
  ; /* Joystick_ReportDescriptor */

//字符串描述符
/* USB String Descriptors (optional) */
const u8 Joystick_StringLangID[JOYSTICK_SIZ_STRING_LANGID] =
  {
    JOYSTICK_SIZ_STRING_LANGID,
    USB_STRING_DESCRIPTOR_TYPE,
    0x09,
    0x04
  }
  ; /* LangID = 0x0409: U.S. English */

最后还有几个字符描述符,这里就不copy了。

点击此处查看原文 >>

系统分类: ARM   |    用户分类:    |    来源: 原创

评论(0) | 阅读(392)
发表于:2008-4-24 22:27:41
标签:模拟  抗干扰  方法  

1

关于抗干扰的一些经验,也许有误,欢迎讨论和补充。

供大家参考,也许有误,欢迎讨论。

1。减小信号环路面积,根据电磁波的公式,面积越小,耦合

进来的噪声越小。

2。讲传输导线加宽,因为噪声信号会沿最小阻抗形成环路,

足够宽的导线使得噪声就地形成环路。??

3。电流传输抗噪声能力强于电压传输。如何理解呢?一直没

有在网上找到答案。和兄弟讨论了一下,认为电流信号通路

是低阻抗,而电压通路是高阻抗。设信号电流为mA级,信号

电压为mV级,同样的一个uA级噪声电流叠加在mA上关系不大

但是叠加在高阻抗的电压回路上也可能会产生mV的电压。所

以很多地方使用了电流传输信号而非电压。

点击此处查看原文 >>

系统分类: 模拟技术   |    用户分类:    |    来源: 原创

评论(1) | 阅读(176)
发表于:2008-4-24 12:35:56
标签:无标签

0

看的别人写的一段,仿“爱在西元前”,很有才气啊

         欧几里德留下了几何原本,传抄在雪白的羊皮纸上,距今已有两千三百多年;阿波罗尼生于帕加,凝视着永恒的圆锥曲线;丢番图却在静静的欣赏不定方程的解,微分、级数、离散、收敛是谁的发现?
  喜欢你在连续之中逼近我的极限,经过剑桥三一学院,我以牛顿之名许愿,思念就像傅利叶级数一样蔓延,当空间只剩下拓扑的语言,映射就成了永垂不朽的诗篇,我给你的爱写在Banach空间,深埋在康托尔集合里面,用超越数去超越永远,那一绝对收敛的数列,一万年都不变!

点击此处查看原文 >>

系统分类: 自由话题   |    用户分类: 无分类    |    来源: 无分类

评论(0) | 阅读(194)
发表于:2008-4-23 19:16:04
标签:STM32  USB  Joystick  

1

STM32 USB joystick程序

痛下决心一定要把USB的程序搞懂,也许表述有很多错误的地方,欢迎指正。

USB需要一个主机host和设备device。

USB设备和主机的通信需要先建立virtual pipeline,然后设备传回描述符给主机。joystick属于HID设备,工作在中断方式。但并非通常单片机所谓的中断,而实际上是查询的方式。

USB采用NRZI编码,而且需要位填塞,但是这些工作通过硬件SIE serial interface engine完成,编程不用关心。

USB数据是由二进制数字串构成的,首先数字串构成域(有七种),域再构成包,包再构成事务(IN、OUT、SETUP),事务最后构成传输(中断传输、并行传输、批量传输和控制传输)。什么封包格式等好像程序没有涉及。

而描述符就需要程序来提供了。

usb_desc.c  提供了设备、端点、接口、字符串、群组、制造商描述符

usb_prop.c  提供了Device_Property, Device_Table & USER_STANDARD_REQUEST 结构描述,这3个东东定义于usb_core.c。

hw_config.c  提供了实际硬件需要的操作函数,Joystick_Send()通过函数UserToPMABufferCopy 和 SetEPTxValid 将坐标值发给了USB端口。

stm32f10x_it.c  里面有

void USB_LP_CAN_RX0_IRQHandler(void)
{
    USB_Istr();       //定义于usb_istr.c
}

点击此处查看原文 >>

系统分类: ARM   |    用户分类:    |    来源: 原创

评论(0) | 阅读(230)
发表于:2008-4-16 19:17:49
标签:分频  

1

(zz)任意分频的verilog语言实现

网上看到的,很有帮助,zz与此

现来说说分频原理吧,原理通了,什么都好办了。

1. 偶数倍(2N)分频

使用一模N计数器模块即可实现,即每当模N计数器上升沿从0开始计数至N时,输出时钟进行翻转,同时给计数器一复位信号使之从0开始重新计数,以此循环即可。偶数倍分频原理示意图见图1

2. 奇数倍(2N+1)分频

1)占空比为X/(2N+1)或(2N1-X/2N+1)分频,用模(2N1)计数器模块可以实现。取02N之间一数值X(0,当计数器时钟上升沿从0开始计数到X值时输出时钟翻转一次,在计数器继续计数达到2N1时,输出时钟再次翻转并对计数器置一复位信号,使之从0开始重新计数,即可实现。

2)占空比为50%的分频,设计思想如下:基于(1)中占空比为非50%的输出时钟在输入时钟的上升沿触发翻转;若在同一个输入时钟周期内,此计数器的两次输出时钟翻转分别在与(1)中对应的下降沿触发翻转,输出的时钟与(1)中输出的时钟进行逻辑或,即可得到占空比为50%的奇数倍分频时钟。当然其输出端再与偶数倍分频器串接则可以实现偶数倍分频。奇数倍分频原理示意图见图2。(这也是许多公司常出的面试题,^_^,是不是很简单?)

3. N-0.5倍分频

采用模N计数器可以实现。具体如下:计数器从0开始上升沿计数,计数达到N-1上升沿时,输出时钟需翻转,由于分频值为N-0.5,所以在时钟翻转后经历0.5个周期时,计数器输出时钟必须进行再次翻转,即当CLK为下降沿时计数器的输入端应为上升沿脉冲,使计数器计数达到N而复位为0重新开始计数同时输出时钟翻转。这个过程所要做的就是对CLK进行适当的变换,使之送给计数器的触发时钟每经历N-0.5个周期就翻转一次。N-0.5倍:取N=3,分频原理示意图见图3

 

对于任意的NA/B倍分频(NABZAB

 

分别设计一个分频值为N和分频值N1的整数分频器,采用脉冲计数来控制单位时间内两个分频器出现的次数,从而获得所需要的小数分频值。可以采取如下方法来计算个子出现的频率:

 

N出现的频率为a,则N×a+(N+1)×(B-a)=N×BA 求解aB-A; 所以N1出现的频率为A.例如实现72/5分频,取a3,即7×38×2就可以实现。但是由于这种小数分频输出的时钟脉冲抖动很大,现实中很少使用。

 

点击此处查看原文 >>

系统分类: CPLD/FPGA   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(678)
发表于:2008-4-16 19:12:38
标签:C  extern  

0

(zz) 解析“extern”

解析“extern

1 声明外部变量

现代编译器一般采用按文件编译的方式,因此在编译时,各个文件中定义的全局变量是互相透明的,也就是说,在编译时,全局变量的可见域限制在文件内部。下面举一个简单的例子。创建一个工程,里面含有A.cppB.cpp两个简单的C++源文件:

//A.cpp

int i;

 

void main()

{

}

 

 

 

 

 

//B.cpp

int i;

 

 

   

这两个文件极为简单,在A.cpp中我们定义了一个全局变量i,在B中我们也定义了一个全局变量i

我们对AB分别编译,都可以正常通过编译,但是进行链接的时候,却出现了错误,错误提示如下:

Linking...

B.obj : error LNK2005: "int i" (?i@@3HA) already defined in A.obj

Debug/A.exe : fatal error LNK1169: one or more multiply defined symbols found

Error executing link.exe.

 

A.exe - 2 error(s), 0 warning(s)

 

 

 

 

 

    这就是说,在编译阶段,各个文件中定义的全局变量相互是透明的,编译A时觉察不到B中也定义了i,同样,编译B时觉察不到A中也定义了i

但是到了链接阶段,要将各个文件的内容“合为一体”,因此,如果某些文件中定义的全局变量名相同的话,在这个时候就会出现错误,也就是上面提示的重复定义的错误。

    因此,各个文件中定义的全局变量名不可相同。

 

   

    在链接阶段,各个文件的内容(实际是编译产生的obj文件)是被合并到一起的,因而,定义于某文件内的全局变量,在链接完成后,它的可见范围被扩大到了整个程序。

    这样一来,按道理说,一个文件中定义的全局变量,可以在整个程序的任何地方被使用,举例说,如果A文件中定义了某全局变量,那么B文件中应可以该变量。修改我们的程序,加以验证:

//A.cpp

 

void main()

{

    i = 100; //试图使用B中定义的全局变量

}

 

 

 

 

 

//B.cpp

int i;

 

 

 

    编译结果如下:

 

   

Compiling...

A.cpp

C:\Documents and Settings\wangjian\桌面\try extern\A.cpp(5) : error C2065: 'i' : undeclared identifier

Error executing cl.exe.