你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【MCU实战经验】+ 利用ST官方STM32_USB-FS-Device_Lib_V4.0.0例程实现USB-TO-TTL232的数据包添加智能换行的功能。  

[复制链接]
wjandsq 发布时间:2014-4-16 14:38
STM32的USB中断是1ms执行一次,ST官方的代码并不立即将收到的数据发往USB主机,而是定义了一个接收缓冲,接收缓冲的存在就是避免漏接字符,在回调函数中5ms发送一次数据到USB主机,这个时间间隔使得STM32有足够的时间向USB主机传输数据。RS485的情况需另行考虑。注意这是在STM32中实现超时自动添加换行字符,由于Windows并非实时系统,想要在Windows上位机中实现这个功能,那将是几乎是不可能完成的任务。9 E: |- k" Y9 n' l! ^

3 S1 Y6 r* F2 d
在ST官方例程Virtual_COM_Port中增加的函数如下
" W3 C% i* n6 p1 U" E5 v' P/*******************************************************************************$ B/ `! V& N. P/ q
* Function Name  : TIMx_Base_Configration/ ~4 |9 l2 S9 ?2 g9 r  f# L0 T) \4 u$ K
* Description    : 定时器基础应用配置
: S( k& X0 B6 C  j3 M; h, n9 i* Input          : TIMx,Period,TIM_Prescaler' T- @; _; f! [% Q9 F9 h) b
* Output         : None.
; R. i  r" P( U# H* Return         : None.7 z- H5 ]4 B/ V, P" @2 z: Y
*******************************************************************************/
+ ~7 X5 s3 e" P. H4 c  cvoid TIMx_Base_Configration(TIM_TypeDef* TIMx, uint16_t Period, uint16_t TIM_Prescaler)
# F  l/ u; q- L, [! T{
: X% f5 ]6 |1 E% K; ~4 J    // TIM_Prescaler  72 分频则为1M, 计数加1为1us, 7200分频则为10K, 计数加1为100us
( A/ o" P; e2 M2 [4 f+ B5 r    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;0 {4 T( k$ i! i  U1 [
 
4 v/ w; X7 G8 F  l/ p1 d    TIM_TimeBaseStructure.TIM_Period = Period - 1;                 // 定时器计时总数,最大655355 y2 |7 v& q2 P1 c/ {1 f% {
    TIM_TimeBaseStructure.TIM_Prescaler = TIM_Prescaler - 1;       // 定时器预分频  o+ m9 V/ ]% F/ }$ m0 Z
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;        // 定时器时钟输入分频
. Z4 g1 @: K2 E% t. J5 |, ]    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;    // 向上计数模式8 n/ i6 e: N- a" b# }
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
2 H0 j, k6 _. l: p    TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);                // 初始化定时器& V- P6 D# \9 o+ c
 " ]: `: h5 E  ]7 }
    TIM_ClearFlag(TIMx, TIM_FLAG_Update);                          // 清除中断标志
# d. O  U* Q7 ~- x* E! Z- X" B    TIM_ITConfig(TIMx, TIM_IT_Update, ENABLE);                   // 使能定时器中断9 c! u+ t. Y9 u4 \- L
 
/ x+ q. O! p9 v  X9 a    TIM_SetCounter(TIMx, 0);  // 设置定时器初始值
" s1 {' ~6 O2 z$ d) c    TIM_Cmd(TIMx, ENABLE); " X" E) X3 r4 @6 e! }* H5 b
} 
2 ]# W' P. ?( A7 m) d5 b, a 
8 X2 @+ R8 k9 E' h9 c 
' D( G  z3 c1 b. J: v  /* Enable TIM2 clocks */
' B( p! E0 ^: S3 s  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能定时器2
2 L# ~+ g) B: e  _2 O0 m  TIMx_Base_Configration(TIM2, 10, 7200);  // 设定周期为1ms$ Q5 s' Y' _2 b" w- z
 
7 b- z7 _7 _  q  `, _/ K 
8 E/ A$ A3 D& T# t1 ]& O/*******************************************************************************8 o2 f4 C. t) Q
* Function Name  : EVAL_COM1_IRQHandler
8 r$ {% d5 x1 g* Description    : This function handles EVAL_COM1 global interrupt request.
4 O  z" ?- e9 g/ R% u' S* Input          : None
7 C. r+ }2 m' J' D5 x6 X! N7 Y* Output         : None
! n6 r2 L) Z% @, j" o* Return         : None2 R: x8 {$ x9 P% n4 {, O4 ?
*******************************************************************************/
1 O) @. ?" [) B! t: P/ Svoid EVAL_COM1_IRQHandler(void)( |, }$ F/ d5 M: j
{; {; Y- [! R8 |6 {
  if (USART_GetITStatus(EVAL_COM1, USART_IT_RXNE) != RESET)& e; Y2 O" C" K8 T
  {
6 |$ W' k# J& U6 g( k) @% a. E, f    /* Send the received data to the PC Host*/
6 j! P. t, P- }! T: }    USART_To_USB_Send_Data();
9 Q  Z- Y" j, i. Q1 @% C& R 
7 x5 S0 c1 N- x1 g9 H& F    /*( R3 j  i' V  v7 X
    最后两个字节为0x0d,0x0a, 这是一个符合微软标准的换行字符
" O2 c* r9 L$ j  V    如果最后两个字节不为0x0d,0x0a, 超时1毫秒则自动添加0x0d,0x0a* |. u1 u9 v& s
    */( v9 ]/ J( l/ X8 t) y. D
    last_char[0] = last_char[1];
* k7 m8 o  _, d5 [0 P, j    last_char[1] =  USART_Rx_Buffer[USART_Rx_ptr_in-1];
7 F3 e. t9 f, q. ^5 ~! h    if((last_char[0] == 0x0d)&&(last_char[1] == 0x0a)){6 w, Z  {  {  i
        Flag_CR_CN = 0;
8 ~1 U  h  M. z$ h/ L4 H" C        TIM_Cmd(TIM2, DISABLE);: `" g) @. T1 y8 b! E$ |- E
    }else{
, C5 _+ l! w( @+ d* F0 \( x        TIM_SetCounter(TIM2, 0);' {4 \5 Q; n& T. V+ `
        TIM_Cmd(TIM2, ENABLE);
1 R! a0 G; g% S        Flag_CR_CN = 1;5 c5 `5 ?: y/ C: Y
    }
! a0 S3 e) d/ ?0 m* h" o  }8 U$ h/ c) X6 K, t
 1 H" w5 ]2 V; z" ~) L
  /* If overrun condition occurs, clear the ORE flag and recover communication */3 n, U& k8 A0 J
  if (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_ORE) != RESET)0 a& d  g$ l/ k1 t; j
  {% e) J; w: a4 L0 i/ c
    (void)USART_ReceiveData(EVAL_COM1);
6 z- p$ K: M! P5 _6 j) X, ^  }- P& h$ Y  Z3 r$ |
}* ^- v; m* n4 Q5 |8 z
/*******************************************************************************( Z0 h3 w2 o; v' T4 W4 n
* Function Name  : TIM2_IRQHandler 
' d7 H: k* v& J6 t; e/ T( t* Description    : This function handles TIM2 global interrupt request.# E0 S2 [' D0 I4 _
* Input          : None8 d: x- W# p: I& a
* Output         : None9 G- P- b, A8 D0 S) `4 M$ a
* Return         : None4 w9 M4 A& ~0 R5 j  Y& C
*******************************************************************************/
# c3 B' }8 p7 ^1 T ! r  G  q1 Q. |. D' r, y
 
. _) W6 z$ G8 cvoid TIM2_IRQHandler(void)
9 F, c3 j' |9 v7 {, M" L{7 [7 P; A8 H- R4 m* P
    TIM_Cmd(TIM2, DISABLE);
' ]  Q! m+ x2 f; S' v4 v    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
2 K$ C+ ]+ p7 @$ c    if(Flag_CR_CN){+ m7 `8 i7 [5 W" n
        Flag_CR_CN = 0;7 x- L/ x4 W! N0 t
 & c. }. |0 D+ a4 H5 x" ?
        USART_Rx_Buffer[USART_Rx_ptr_in] = 0x0d;# J1 J8 c! V6 t+ O
        USART_Rx_ptr_in++;1 ], M! i7 f. N: S
        if(USART_Rx_ptr_in == USART_RX_DATA_SIZE)
& H( r7 ]) `# O) v* x1 L! N9 R; e        {5 k+ v7 z3 d( \3 c0 {$ A
            USART_Rx_ptr_in = 0;
( \* v+ m/ f  @/ l8 l% O5 H' H/ @        }
7 B2 T# N4 O" O$ l9 Y1 E: }- w; |        USART_Rx_Buffer[USART_Rx_ptr_in] = 0x0a;
* @+ G# |( K( m& d  P5 x; s, ?        USART_Rx_ptr_in++;
( E3 {- Y' Q# y3 j3 |. y        if(USART_Rx_ptr_in == USART_RX_DATA_SIZE)
+ ?4 F! V4 G3 e        {' U; z/ r1 T8 u: ]$ Q
            USART_Rx_ptr_in = 0;1 l3 I; ?: H  m% B5 k' M
        }
' g  ]3 `1 t6 M* k" U    }
8 d6 p" k- u5 J}
: \, O$ I  h0 v3 K" W) r
2 V+ l  n# ^# T) Y$ E- ^ + W) _$ a- y. @( v, j1 b9 s
基于ST官方原版例程Virtual_COM_Port修改,添加智能换行功能
" [( E8 j! Z6 J7 O) B下载地址:  STM32_USB-FS-Device_Lib_V4.0.0(智能换行).rar (5.65 MB, 下载次数: 6727)
赞 收藏 9 评论17 发布时间:2014-4-16 14:38

举报

17个回答
Aegiss 回答时间:2016-7-27 13:29:58
caizhiwei 发表于 2015-1-19 16:58
$ X0 \1 Y9 m, Q, X, h请问楼主D+的1.5K电阻能直接上拉到V3.3吗?不用IO口控制。。。
$ x& x! E) o' f* @5 q$ W
可以,上拉D+为全速设备,上拉D-为低速设备,要作为高速设备使用时,才需要使用三极管控制上拉
fafa1 回答时间:2017-3-3 10:54:12
在研究一个使用STM32F101接收扫描枪输入的东西,学习一下,谢谢分享!
caizhiwei 回答时间:2015-1-19 16:58:12
请问楼主D+的1.5K电阻能直接上拉到V3.3吗?不用IO口控制。。。
tianyu22 回答时间:2014-9-17 23:34:01

回复:【MCU实战经验】+ 利用ST官方STM32_USB-FS-Device_Lib_V4.0.0例程实现USB-TO-TTL232的数据包添加智能换行的功能

我也在搞虚拟串口。。。老出问题。。。想找个新点的库
wjandsq 回答时间:2014-9-18 18:08:10

将64字节的定义改为63字节,可以解决64字节不响应的bug,以上所有例程都有这个bug

将USB通讯数据包64字节大小的定义改为63字节,
- f. \" w3 N8 A1 a! L, w9 r4 M8 K7 k" {可以解决64字节不响应的bug,以上所有例程都有这个bug
zhangkun2609 回答时间:2015-7-7 18:06:13
good
风之谷-2040681 回答时间:2016-1-28 09:31:02
谢谢楼主分享
alft 回答时间:2016-5-23 09:25:19
大爱楼主!!!!!!
一叶清风 回答时间:2017-9-9 15:33:27
谢谢
ToDo 回答时间:2017-12-20 21:14:33
謝謝樓主!最近也想嘗試STM的HID
路平 回答时间:2018-4-27 10:53:17
学习中
xheng 回答时间:2018-4-28 10:10:30
非常感谢了。
静水-394928 回答时间:2018-5-22 17:27:31
学习一下,不错的资源
a914002128 回答时间:2018-7-16 13:44:02
mask!!!!
12下一页

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版