|
本帖最后由 wjandsq 于 2018-1-10 19:44 编辑 7 ?3 z0 _3 o# U4 D) r2 h 4 w! l( B3 W; O 使用STM32F407的TIM3、TIM4精确发送固定个数脉冲,PC6、PB6两路500KHz PWM,用于控制两路伺服电机。0 J2 q7 X6 I' s/ n8 E 6 W+ ^- B" k3 ]( L 一、本例程的主要功能: / i9 R/ `7 s9 H2 y* v8 @" w 1.USB-CDC 功能(使用USART1-PA9 USART1-PA10)。 PC机通过USB通讯发送控制命令到STM32,命令还可以通过USART1-PA9转发出去。5 i! b& i# y' y, b! C2 F0 G# i / l; n4 D7 ^4 f$ @: P 2.使用TIM3 CH1通道发送精确个数脉冲(使用PC6)。( h) W+ O' D, K) `) n& `6 _ L, x Z " |$ v* h0 A s 发送精确个数脉冲,需要启用TIM3 的DMA通讯,在每个脉冲周期结束时,: m# h) x5 h* G& z! r$ L DMA自动将内存中的占空比数据传输至CCR1,DMA传输的次数到达设定值N, 则进入DMA传输完毕中断,此时已发送N-1个脉冲,因此在该中断中, 设置TIM3 为单脉冲模式,脉冲发送自动停止。5 j9 V5 H: J1 V {) a3 K7 S 总脉冲个数 = DMA传输次数(N) * DMA通讯中断次数(M) 目前发现的bug描述: (1) 首次启动时,如果发送多个脉冲,则会出现多发1个脉冲的情况。& R. x; i, C; Q1 U (2) 首次启动时,如果发送单个脉冲,再发送多个脉冲,不会出现该bug。; j! Z7 M; I" E4 v1 ~ 临时解决方案:. O' V* L' y$ T% H8 m' P( v: m 启动时将一个特殊标志初始化为1。 如果启动后就发送多个脉冲,则将脉冲数量减去1,然后将特殊标志清0。6 H8 h. o. _6 s 如果启动后发送单个脉冲,不会出现bug,所以要将那个特殊标志清0。 7 M5 o1 H& `. ~* e" K4 R; K7 v/ `+ a 3.使用TIM4 CH1通道发送精确个数脉冲(使用PB6)。7 V* e) t9 i6 _, |' G* I8 x 同上。 6 t+ |+ G( ?6 Z4 [7 B 4.在RAM进行硬件仿真调试的说明" K0 o! @7 K) @: t6 |0 z0 V2 \ 本例程成功地验证了STM32F407可以在内部RAM中进行硬件仿真调试。 k0 i. v7 L0 J4 D/ }/ J- T 注意DMA等的初始化,内存到外设的传输宽度为16位,只有设置正确, 才能进入DMA传输完毕中断。$ E- n2 X$ V$ Z9 D5 x( @ 三、本例程软件改动如下: 1.在usb_conf.h的第179行,注释掉了 VBUS_SENSING_ENABLED 宏定义。 2.stm324xg_eval.h中增加USART1相关的宏定义:0 V$ { ~6 }# Q1 A+ I #ifdef VBUS_SENSING_ENABLED #define EVAL_COM1 USART3 #define EVAL_COM1_CLK RCC_APB1Periph_USART3) r v/ W& I( M7 r #define EVAL_COM1_TX_PIN GPIO_Pin_10 t/ D0 g/ L1 l4 W; A #define EVAL_COM1_TX_GPIO_PORT GPIOC1 p ]5 W5 z9 J7 O! J7 E #define EVAL_COM1_TX_GPIO_CLK RCC_AHB1Periph_GPIOC #define EVAL_COM1_TX_SOURCE GPIO_PinSource10 #define EVAL_COM1_TX_AF GPIO_AF_USART3' G' _" V0 e, g4 ?5 x #define EVAL_COM1_RX_PIN GPIO_Pin_11 #define EVAL_COM1_RX_GPIO_PORT GPIOC #define EVAL_COM1_RX_GPIO_CLK RCC_AHB1Periph_GPIOC: I5 `+ |- b" e1 T #define EVAL_COM1_RX_SOURCE GPIO_PinSource11' F6 ^- \# G- m" T, ?1 r #define EVAL_COM1_RX_AF GPIO_AF_USART3 #define EVAL_COM1_IRQn USART3_IRQn4 E$ j# r [& R# g- H4 G1 p" M #else #define EVAL_COM1 USART1 i+ y6 {( V0 U, _+ {1 F& r #define EVAL_COM1_CLK RCC_APB2Periph_USART1$ V1 K/ U6 o( Z9 n) j #define EVAL_COM1_TX_PIN GPIO_Pin_9 #define EVAL_COM1_TX_GPIO_PORT GPIOA #define EVAL_COM1_TX_GPIO_CLK RCC_AHB1Periph_GPIOA #define EVAL_COM1_TX_SOURCE GPIO_PinSource9 #define EVAL_COM1_TX_AF GPIO_AF_USART1. R" A7 ` m; V. o' [7 j2 z #define EVAL_COM1_RX_PIN GPIO_Pin_10) d6 |# G; n, u6 J" a #define EVAL_COM1_RX_GPIO_PORT GPIOA #define EVAL_COM1_RX_GPIO_CLK RCC_AHB1Periph_GPIOA; }% h+ V. V9 n. V9 c3 U #define EVAL_COM1_RX_SOURCE GPIO_PinSource10# ^) s: `4 |/ K8 p8 g8 B9 u0 t, T #define EVAL_COM1_RX_AF GPIO_AF_USART12 Y* Q; [( k' y6 P# Z #define EVAL_COM1_IRQn USART1_IRQn #endif 3. usbd_cdc_vcp.h中,增加USART1相关的宏定义6 |; I$ |: k) x8 \% D' w7 j7 X #ifdef USE_STM3210C_EVAL% t7 L- L% D6 h3 J+ ], I* |7 h% u #define EVAL_COM_IRQHandler USART2_IRQHandler #else5 e) M, u1 Q/ e1 z# |/ w #ifdef VBUS_SENSING_ENABLED% x, Z, ]; ^6 h #define EVAL_COM_IRQHandler USART3_IRQHandler2 W5 ]6 z3 O+ A% D #else #define EVAL_COM_IRQHandler USART1_IRQHandler #endif" l) O) C, c* R9 V$ j9 S- A% O #endif /* USE_STM322xG_EVAL */* ]9 {, Q4 m1 W& v$ l( B ; g+ w" N. {* L% `% ^ 4.USB内部或外部上拉电阻关闭与延迟打开的函数修改: {4 |3 r3 a2 e. d5 u# M ; z' Y+ K% {$ x8 I( N4 q" f7 g1 p9 F void usb_start_delay(void)! C& z- G0 H' B3 r" L {& K) l* j1 ?- P4 x% s+ y5 k uint16_t i,j; #ifdef VBUS_SENSING_ENABLED GPIOD->BSRRL = GPIO_Pin_6; /* 不启用外部USB上拉电阻 */ for(i = 0; i < 10000; ++i){5 c0 z! L# v4 l0 s! j4 k0 L1 Y for(j = 0; j < 6000; ++j){4 c, O# G# A: b; T* v8 ~ 1 S0 U5 Q4 g" _9 i } }" H! N1 C8 H, }/ b5 ^ GPIOD->BSRRH = GPIO_Pin_6; /* 启用外部USB上拉电阻 */8 m, J; X, u' {1 P& z: p #else' g" p# x$ J5 ?" b+ V1 o6 q" ] GPIOD->BSRRL = GPIO_Pin_6; /* 不启用外部USB上拉电阻 */ DCD_DevDisconnect(&USB_OTG_dev); /* 不启用内部上拉电阻 */ for(i = 0; i < 10000; ++i){ for(j = 0; j < 6000; ++j){ 3 [+ s9 \5 M2 h } } DCD_DevConnect(&USB_OTG_dev); /* 启用内部上拉电阻 */ Q! Y9 v& v% }# I7 `% ~ ^! j" K #endif9 Z% G& `0 a, @9 m. l, Y . z* S; ]) z9 w; B }0 S- t1 c- m- z3 j 5.USB虚拟串口的DTR RTS Break控制修改 可用DTR信号控制1路伺服电机正转还是反转。 RTS信号无效,这是由于Windows USB驱动的问题造成的,ST依靠微软的USB驱动, 所以一直没有解决这个问题。" k F k. `8 O2 G' ]/ P0 Q" W 6.精确个数脉冲发送 在TIM3-CH1上(PC6)实现精确个数脉冲发送,用于控制第一路伺服电机 在TIM4-CH1上(PB6)实现精确个数脉冲发送,用于控制第二路伺服电机5 ?, ~# F0 l1 L 四、工程包下载 + I0 z# e7 v% ^" H, N ! ~" @8 I& j4 M9 m 五、解压工具! p1 R7 W; }3 z 下载最新的7z工具,7z938.exe,X86或X64均可。0 X/ H5 c# @5 ~+ J, E a5 V/ W . ^3 a+ Y3 R A* x1 [: [ 六、调试说明" \' \. U2 \+ k8 B7 ?1 P 1.点击载入配置按钮,选择测试的配置文件, 多字符串发送功能区的字符串列表自动更新。 2 d$ [: C; R8 g/ x8 y6 S% g 2.选择STM32的虚拟串口号,由于是USB通信, 可以不用理会波特率等参数,那是串口对外发送的" ]) U0 u8 R0 m0 b 波特率,这里通过USB传给STM32,通过串口向外发送的代码可以关掉,也可以保留。6 ~* R, _8 p& T. x$ ` 3.点击启动发送,自动循环发送1-10个脉冲, 示波器测量PC6(第一路),可以看到脉冲数量的变化。 P1 I3 X6 G: I - U v5 D& b* @) I3 @% i7 i- S ; l. g* g, `/ l( T1 B" y5 c8 H |
USB串å£å·¥å ·åéå½ä»¤
【福利三:雨露均沾·逢7狂欢】之四:用一个定时器同步另外两个定时器输出PWM
【逢7发帖赢大礼】STM32开发之WIFI实时时钟
【逢7发帖赢大礼】STM32开发之指纹识别!
【逢7发帖赢大礼】STM32开发之环境空气质量监测
【逢7发帖赢大礼】STM32开发之人体实时运动信息监测!
【逢7发帖赢大礼】STM32开发之IC门禁卡UID读取方法!
【逢7发帖赢大礼】全网最简单的Arduino_STM32开发环境搭建教程!
STM32F4中文用户手册
STM32F400、STM32F402 Cortex-M4超值单片机
SPI 高温读错最后一位?STM32F42xx 官方根治方案
微信公众号
手机版
请不要随意伸手……