STM32 USB转串口程序解读
- 格式:pdf
- 大小:177.81 KB
- 文档页数:11
的三极管_config.h 中有下列定义:
#define RCC_APB2Periph_GPIO_DISCONNECT
RCC_APB2Periph_GPIOD
它将这个设为端口 D。所以这个 USB 断开引脚到底是由谁来控制的还未确定。这里留下一
接下来配置 PA10 为输入浮空,配置 PA9 为 PP 输出。这两个脚是串口。这个是正确的。我 们几孚所有的板子都用 UART0,它就是这两个脚的。 至此这个部分结束了。
2
下面再来看第 2 个函数 Set_USBClock()-------两句话:
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5); /* Enable USB clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); 72M 除 1。5=48 然后允许 USB 的时钟。 这个要看一下数据手册。从数据手册比较好理解。 它是直接从 PCLK 中除一个数,可以除 1 也可以除 1.5..这段还是比较好理解的。
然后,我们要允许 GPIOA,GPIOB 和串口的时钟。因为我们只用到了这几个资源。当然 USB
是另外的,我想总会在某个地方允许的。
下面这个就不好理解了:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_DISCONNECT, ENABLE);这个叫允许 USB
断开线。从原理图上看好象是 PE7 来控制的。因为 PE7 连接到一个 DP+的一个上拉电阻控制
pInformation = &Device_Info; 这个是设备资料部分,里面的全部变量,静态的。 pInformation->ControlState = 2; pInformation 是一个指向 Device_Info 的指针。不知为什么要这样大费周折。不可以直接这 样写吗:
Device_Info.ControlState = 2;
接下来:
pProperty = &Device_Property;
pUser_Standard_Requests = &User_Standard_Requests;
pProperty 是一个指针,指向 DEVICE_PROP
这个是设备属性部分
设备属性部分包含一些方法,即函数。也包括两个参数,一个是接收区的缓冲区地址,一个
buffer_in[count_in] = USART_ReceiveData(USART1); } count_in++; UserToPMABufferCopy(buffer_in, ENDP1_TXADDR, count_in); SetEPTxCount(ENDP1, count_in); SetEPTxValid(ENDP1); }
个问号,等以后再解决。
接下来,将 USB 的断开脚配置成上拉的。这也就意味着在开始时,这个上拉电阻使得三极 管导通,从而使这个 DP 脚被加了一个 1.5K 的电阻,可以开始枚举的。 再看这个断开脚指的是哪一个脚,它不是 PD9 就是 PB14。怎么也没有 PE7 的说法(原理图)。 所以这里就有点不知所以然了。难道这个原理图与程序有冲突?
if (USART_ART_WordLength == USART_WordLength_8b) {
buffer_in[count_in] = USART_ReceiveData(USART1) & 0x7F; } else if (USART_ART_WordLength == USART_WordLength_9b) {
总是先从 main 开始
Set_System();
///设置系统
Set_USBClock();
///设置 USB 时钟
USB_Interrupts_Config();
///配置 USB 中断
USB_Init();
///USB 初始化
while (1)
{
if ((count_out != 0) && (bDeviceState == CONFIGURED))
▉接下来,再一次清除中断标志,然后使能中断(CNTR_CTRM | CNTR_SOFM | CNTR_RESETM )
这几个中断就是复位中断,正确传输中断,SOF 中断
▉配置串口至缺省状态---在这里波特率被设为 9600,并且允许了接收中断。发送中断没有
允许。
▉将当前的状态定义为未连接状态。bDeviceState = UNCONNECTED;什么时候连接不知道。
是最大的包的长度。都是用字节表示的。
这个属性是一个通用的属性,它指以相当于实例化套到 USB 这个头上去。故我们在这里看
上 去 运 行 一 个 pProperty->Init(); 实 际 上 运 行 的 是 DEVICE_PROP 中 的
Virtual_Com_Port_init()这个函数。
我们看在这个函数中做了什么:
▉Get_SerialNum(); 设置芯片序列号,将描述符中的例如 STM 等字符串修改没太大意义。
▉PowerOn(void)
先使能芯片(三极管 B 极变高) 强迫 USB 复位。再将全部 USB 中
断都屏蔽后,将中断清除,最后再允许以下中断:CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;
/* Transmit Data */ USARTx->DR = (Data & (u16)0x01FF); }
先从简单的看起,串口的接收中断,它在哪里呢? 发现它在 stm32f10x_it.c 中有如下:
USART_To_USB_Send_Data(); 表示从串口向 USB 端发送数据。
再看这个定义如下: void USART_To_USB_Send_Data(void) {
开始日期:2012 年 11 月 8 日,预计完成日期 2012 年 11 月 15 日。实际完成 11 月 9 日
说明: 1.跳过驱动。使用低速传输。最大可以设为 921000 即 100KB/S。应该也差不多了。只传一 些简单的东西。因为我们工作的重点是工业控制,无需高速,而我们是以完成任务为主要目 的。而不是非要学什么东西,完成任务才是第一重要的。 2.由于例程中没有操作系统支持,也许以后可以用 keil 的操作系统。比较简单,最重要的是 ucOS 不支持 M4 的浮点运算。当然对于 M3 我们可以将 USB 部分移到 ucOS 上。而对于 M4,我们直接用 Keil OS,不想花很大力气去做 OS 移植了。 3.打字错别字较多还请谅解。
4
void USB_LP_CAN_RX0_IRQHandler(void) {
3
至此,初始化结束。我们现在要看的是中断函数了。中断函数不外于一个是串口的接收中断。 串口的发送中断是没有允许的。 串口是如何发送的呢?它直接写串口寄存器,显然如果有大量数据发送时就会出问题的。因 为它根本不判断是否发送缓冲区为空。因此,感觉这个程序要进行大量的数据交互不可能, 最多是敲打一下键盘可能还差不多。 看它的库中的函数:直接发送,也不管是否空。难道它有 16 字节缓冲吗?没有。 void USART_SendData(USART_TypeDef* USARTx, u16 Data) {
STM32 USB 转串口程序解读
前言:了解 USB 虚拟串口,为了在项目中用一下这个 USB,调试方便一些,供电可直供。 公司以后的产品开发就基于 STM32 这个平台,从 contex_M3 到 contex-M4。不管速度、功 耗、价格、采购的方便性都有竞争力,不想再修改了(除非它无法满足要求)。STM32 基本 上都带有 USB 串口。如果不把它用上而另外加一个 USB 转串口单元,未免显得太落后了而 且也是一种资源的浪费。顺便说一下,根据公司的状况,合适的才是好的。以前一直用 TI 的,从 430 到 ARM 到 28XX。这个 ST 的包含了以前的所有,TI 的 ARM 速度比较慢,而 它的普通的 DSP 的速度与 M4 相当,有些还比不过 M4,耗电却惊人,何况 M4 带了浮点后 比定点在某些地方要快很多。难怪 TI 在推 M4 时故意将频率放慢,DSP 功能减少,我想各 个公司都有自已的考虑吧。而 ST 就把 CMOS 传感器接口也放进去。赶明儿啥时有空了再做 块 PCB 试试。ST 最让人不爽的是它的开发例程做的太浅,例如超速 USB2。0, CMOS 接口 资料几乎没有,TCP/IP 也浅尝即止,网页也设计得世界上最烂,让人找个芯片,找个资料 很累。在应用上比 NXP 差远了,毕竟有个 ZLG 帮忙,FREESCALE 在网络通讯方面的应用 做得最好,看他们的 TCP/IP 源代码是一种享受。看来做芯片是 ST 的强项,做应用还非常 有待加强。
{
USB_To_USART_Send_Data(&buffer_out[0], count_out); //如果有数据 将它发送到串
口中去
count_out = 0;
/////发送完后这个清零
}
1
}
初看一下,还算比较好理解,但是由于这个例子好象只有发,没有收。我想它的收大约在中 断中进行的(也就是串口向 USB 发的过程,估计在串口中断中进行,后面我们可以再分析, 不行可能需要自行加上这部分代码,希望不要这样)
再看第 3 个函数 USB_Interrupts_Config()-------配置 USB 中断 在该函数中使能了两个中断,一个是 USB,一个是串口。至于中断放在 RAM 或 FLASH 当 然一般是后者,所以在这也就没有什么意义了。串口优先级为 1,USB 为 0。中断分组中我 们将一位作为可重入的优先组,另 3 位作为优先级组。由于一个为 0 一个为 1,故这两个中 断都不会相互被另一个中断打断。 现在既然允许了两个中断,估计在中断中将做很多事情,大多数事情都在中断中完成的。 这个中断程序等一会马上就来解读。 最后是 USB_Init()这个函数了。 在这是里先看到: