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

【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上位机中实现这个功能,那将是几乎是不可能完成的任务。
0 q" o* R) M8 K+ t2 ^
+ U; h6 E/ i( f. a; U
在ST官方例程Virtual_COM_Port中增加的函数如下: i+ p2 X  v4 g$ x
/*******************************************************************************
" U1 s- U# C$ O: {0 ?3 y* Function Name  : TIMx_Base_Configration5 \% v0 `% @5 Q" k- b
* Description    : 定时器基础应用配置* M  D* n1 i& p/ [
* Input          : TIMx,Period,TIM_Prescaler
( C7 P2 O5 ^$ }+ w) t: @6 D3 L* Output         : None.
3 r2 E% F/ h- F! @* Return         : None.
6 F! q: S* W! m- S*******************************************************************************/. u0 h5 ^8 `0 x
void TIMx_Base_Configration(TIM_TypeDef* TIMx, uint16_t Period, uint16_t TIM_Prescaler). C9 ?0 ^& \5 `1 v- p
{- a; y% x7 Y  Z* v$ d  _) v
    // TIM_Prescaler  72 分频则为1M, 计数加1为1us, 7200分频则为10K, 计数加1为100us
9 m% w7 Z5 Z( X6 y' z/ H, @" e& d    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;4 v" y5 R7 N3 {
 ; Z; l: T% N. Y4 \( S7 {
    TIM_TimeBaseStructure.TIM_Period = Period - 1;                 // 定时器计时总数,最大655355 e" a+ G1 W2 o
    TIM_TimeBaseStructure.TIM_Prescaler = TIM_Prescaler - 1;       // 定时器预分频7 g" V1 S, Z6 ^- ]' B; c
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;        // 定时器时钟输入分频
* p# P4 e# F1 C' i; V    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;    // 向上计数模式
! B( z; n8 h. f    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
3 Q) Z* M. E5 [% Y6 _    TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);                // 初始化定时器" l/ q7 v# `0 K+ D2 L% e; ~. x
 , R9 i# ^5 Q5 t9 x  `8 c. ?
    TIM_ClearFlag(TIMx, TIM_FLAG_Update);                          // 清除中断标志) H8 B0 _( `  G5 n7 m
    TIM_ITConfig(TIMx, TIM_IT_Update, ENABLE);                   // 使能定时器中断
, m1 ^. N6 M8 U( ]+ O9 ?- { + Q, O9 G: [6 @2 J1 u. A/ T
    TIM_SetCounter(TIMx, 0);  // 设置定时器初始值
- D2 P  P1 Q* x* ~0 a" W    TIM_Cmd(TIMx, ENABLE); ; X1 [9 k' F2 X& T1 G6 |! g2 O. c  v

. t3 ~. K8 Q. ? 4 F0 `! v4 v: O
 , E6 y/ y( I( g6 b/ B: }$ j; m
  /* Enable TIM2 clocks */. w5 e0 i& A7 p3 x
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能定时器2
8 O8 [3 x! N4 s6 l! Q. L6 I7 h  TIMx_Base_Configration(TIM2, 10, 7200);  // 设定周期为1ms
  f- s7 Q" _) p; T" a6 C1 w8 a ( Q9 h7 E; h' k8 q" M4 x* z  W! i+ |
 * j: Y* S5 }' o2 [
/*******************************************************************************; b/ U; t8 w% c" H: b4 W
* Function Name  : EVAL_COM1_IRQHandler
: b) f$ v6 J2 n6 ?* Description    : This function handles EVAL_COM1 global interrupt request.% W/ P, F1 U8 N" }+ p3 a
* Input          : None4 P# z# e: A1 e! ]
* Output         : None
/ ]# J' A2 ~7 S6 u$ y; ^5 |* Return         : None) t( n3 T8 y3 Y
*******************************************************************************/. Z9 T! I9 C; M
void EVAL_COM1_IRQHandler(void)1 w# ]; K  V: m/ T  u3 A
{
; _' [* W9 J: d  if (USART_GetITStatus(EVAL_COM1, USART_IT_RXNE) != RESET)
) Z. f# G# S& h  {
. P% c) ?( ]: {3 Q0 f  I    /* Send the received data to the PC Host*/
9 \$ n' M# d8 S6 J  o* ]    USART_To_USB_Send_Data();, ?) g, e4 c6 W; S  K
 
: Q# U/ Y0 C) b! K* b! Y    /*& P& M; V" X1 N2 m
    最后两个字节为0x0d,0x0a, 这是一个符合微软标准的换行字符
; z- ^. H2 M1 T7 D    如果最后两个字节不为0x0d,0x0a, 超时1毫秒则自动添加0x0d,0x0a' O' K% K% f* K) t* m# S
    */9 r, f. {: P- v  m: x: U
    last_char[0] = last_char[1];
5 d$ m4 \# }% P+ M& g    last_char[1] =  USART_Rx_Buffer[USART_Rx_ptr_in-1];; Q3 n. d  A5 H( ?1 N
    if((last_char[0] == 0x0d)&&(last_char[1] == 0x0a)){
3 u, x' n  J9 k; l        Flag_CR_CN = 0;- W% g; k) A4 O$ `; w- z
        TIM_Cmd(TIM2, DISABLE);
+ D8 N) H+ u* f+ \+ Y    }else{
# @6 W& D: d7 ^  r6 ^+ W) u        TIM_SetCounter(TIM2, 0);- x( k' y5 d0 K
        TIM_Cmd(TIM2, ENABLE);* t' l' w- E9 t) s" }2 p9 p
        Flag_CR_CN = 1;* K# z) B8 S3 r
    }, k/ ^& e. V+ }3 i; S
  }  Y* n& g1 [5 i0 S% {
 * ~+ U; o3 A5 s' {8 G  t/ ^2 P# g5 g, C, {
  /* If overrun condition occurs, clear the ORE flag and recover communication */
' w# {8 o6 G+ y8 q- T, G5 f2 }  if (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_ORE) != RESET)
6 H: X4 e" D: I6 \( [  {
/ I! v" e/ g, n' ?/ F" M$ ?    (void)USART_ReceiveData(EVAL_COM1);
- z* z6 E' V2 {  }
" N5 T7 Z3 @9 b3 c: I- k1 {}5 @1 J) Y3 }, f6 R
/*******************************************************************************; B; b  D0 l# P5 T& F
* Function Name  : TIM2_IRQHandler 
$ ^% W+ B  c4 |( Y9 b* Description    : This function handles TIM2 global interrupt request.2 _% V5 [- u' Z1 {3 K
* Input          : None
1 S* a2 ?  p: L7 _6 D: ?* Output         : None
1 u) D* x# r. e+ _/ s! {* Return         : None: r3 _1 m/ H, L6 K' d0 Z. g0 a
*******************************************************************************/
9 ?) p7 o  m( D8 _4 z7 Y% c 
0 p' t1 i4 v' @5 a" E - t" P, u3 d, {5 H
void TIM2_IRQHandler(void)5 ^- |4 T9 r) w1 r
{) Y: S, M1 Y  `1 S* B) G  F1 k
    TIM_Cmd(TIM2, DISABLE);
, r0 ]+ L) v1 W6 r( U& X( t* R5 t    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
7 Y$ P7 n. u) }' B* u: S2 h    if(Flag_CR_CN){
! \5 Y! R' E! z! t        Flag_CR_CN = 0;
8 D9 F' h$ L2 `, y- }5 f. @ 
$ u* Q3 }- {  ]- f5 }, J( h        USART_Rx_Buffer[USART_Rx_ptr_in] = 0x0d;
* d4 V; d# p) f+ u& `        USART_Rx_ptr_in++;
$ X5 |* V1 d; S5 B. y0 s        if(USART_Rx_ptr_in == USART_RX_DATA_SIZE)" b. h% y+ d* o# v
        {! p( e5 ^( R( o( p
            USART_Rx_ptr_in = 0;/ N2 o) L7 `, ?0 E
        }
8 X" d2 @9 ]/ s! s        USART_Rx_Buffer[USART_Rx_ptr_in] = 0x0a;
- O/ H$ z9 l/ L; J* v3 U& A: f4 z; r        USART_Rx_ptr_in++;" d. M+ D8 g. R6 N
        if(USART_Rx_ptr_in == USART_RX_DATA_SIZE)0 j% ?2 q; W1 ]! j1 v
        {
( L& K& l  X: \- v4 i/ b            USART_Rx_ptr_in = 0;- D' s8 u0 M6 y# p# S; l
        }( c/ c1 @4 t9 e
    }) _4 W& v* v( i" `: S# L1 p
}0 S$ e7 L9 r. p* N: m7 R; O
! u9 c6 S: U9 C6 i$ [5 I
 
; ?) y0 B1 A/ L/ }% g* v5 ?基于ST官方原版例程Virtual_COM_Port修改,添加智能换行功能
9 H2 {* S$ Z& V* B8 D8 r8 t下载地址  STM32_USB-FS-Device_Lib_V4.0.0(智能换行).rar (5.65 MB, 下载次数: 6567)
收藏 9 评论17 发布时间:2014-4-16 14:38

举报

17个回答
Aegiss 回答时间:2016-7-27 13:29:58
caizhiwei 发表于 2015-1-19 16:58
, {3 r: t/ D+ k$ A; p, M$ G* d2 j请问楼主D+的1.5K电阻能直接上拉到V3.3吗?不用IO口控制。。。
! C: U4 v4 b- ]; w2 I7 A
可以,上拉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字节,4 h2 I9 l1 Z$ M3 r9 w
可以解决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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版