Good afternoon, I would like to ask for some help on the matter of PWM on new boards. This question appeared after a long time of me trying to find some >information on this issue or a manual. The question is well described for the old boards but the situation is a bit different with the new ones. I have taken it the way that I would have control of the motor if PWM_ENABLE is set to 0, PWM_B_DIRECT and PWM_A_DIRECT to 1, PWM_PERIOD to 5000 and DUTY_DIR_B and DUTY_DIR_A changing oppositely from 0 to 1 depending on polarity of width and DUTY is set to any width less than period, it will work somehow. Apparently, it doesn't. I would appreciate any hints or a manual. Thank you in advance.
-- Sincerely yours, Aleksandra Pereverzeva
Hello, in order to make motor spin, try to set CR register to zero (especially PWM_x_DIRECT to zero). I think these bits are used to generate your own signal without PWM_DUTY register. The rest should be correct. Jaroslav Klapálek
On 12/30/2017 02:25 PM, klapajar@fel.cvut.cz wrote:
Good afternoon, I would like to ask for some help on the matter of PWM on new boards. This question appeared after a long time of me trying to find some
information on this issue or a manual. The question is well described for the old boards but the situation is a bit different with the new ones. I have taken it the way that I would have control of the motor if PWM_ENABLE is set to 0, PWM_B_DIRECT and PWM_A_DIRECT to 1, PWM_PERIOD to 5000 and DUTY_DIR_B and DUTY_DIR_A changing oppositely from 0 to 1 depending on polarity of width and DUTY is set to any width less than period, it will work somehow. Apparently, it doesn't. I would appreciate any hints or a manual. Thank you in advance.
-- Sincerely yours, Aleksandra Pereverzeva
Hello, in order to make motor spin, try to set CR register to zero (especially PWM_x_DIRECT to zero). I think these bits are used to generate your own signal without PWM_DUTY register. The rest should be correct.
I have not tested it yet, so the following is only my understanding of the documentation [1]. If PWM_ENABLE is 0 the PWM is controlled directly by PWM_B_DIRECT and PWM_A_DIRECT. It means that the functions for generating PWM signal needs to be written manually. If PWM_ENABLE is 1 the PWM is controlled by PWM generator - PWM_PERIOD defines how long is the PWM period (should be 20kHz, see [1]). Speed of the motor is then defined by PWM_DUTY register. The question is how easy is PWM_ENABLE = 0 approach compared to PWM_ENABLE = 1. # References [1]: http://rtime.felk.cvut.cz/psr/cviceni/semestralka/ Have a nice day, Jiri Hubacek
On Saturday 30 of December 2017 14:25:19 klapajar@fel.cvut.cz wrote:
Good afternoon, I would like to ask for some help on the matter of PWM on new boards. This question appeared after a long time of me trying to find some >information on this issue or a manual. The question is well described for the old boards but the situation is a bit different with the new ones. I have taken it the way that I would have control of the motor if PWM_ENABLE is set to 0, PWM_B_DIRECT and PWM_A_DIRECT to 1, PWM_PERIOD to 5000 and DUTY_DIR_B and DUTY_DIR_A changing oppositely from 0 to 1 depending on polarity of width and DUTY is set to any width less than period, it will work somehow. Apparently, it doesn't. I would appreciate any hints or a manual. Thank you in advance.
-- Sincerely yours, Aleksandra Pereverzeva
Hello, in order to make motor spin, try to set CR register to zero (especially PWM_x_DIRECT to zero). I think these bits are used to generate your own signal without PWM_DUTY register. The rest should be correct.
You need to set PWM_ENABLE (control register bit 6) to 1 to control "dcsimpledrv" output peripherals by PWM state machine implemented in VHDL code. The option to control PWM outputs directly by control register bits PWM_A_DIRECT and PWM_B_DIRECT is there mostly for testing. The PWM_A_DIRECT and PWM_B_DIRECT controls outputs only when PWM_ENABLE (bit 6 of the control register) is set to zero (0). But for reasonable filtering of PWM signals by an inductance of motor windings and to suppress audible noise, the frequency of PWM should be at least 20 kHz. Because pulse duty cycle should be controlled at least at granularity of 1%, then software timing precision about 500 ns is required to set and clear PWM_A_DIRECT and PWM_B_DIRECT bits. Such accuracy is very hard to achieve even in simple MCU with a single task or direct response to interrupt event. If there should be another task running, then some task delay function has to to be used, but granularity of VxWorks timing functions is defined by tick time, 200 usec min on Zynq. So the task to generate PWM signal with required parameters by software is not achievable. That is why "dcsimpledrv" peripheral provides hardware to generate periodic PWM signal PWM_PERIOD defines period of the signal with the granularity 10 nsec given by peripheral AXI bus clock 100 Mhz. Then the duty cycle is controlled by bits 0 to 29 of PWM_DUTY register. A bit DUTY_DIR_B (bit 31) and DUTY_DIR_B (bit 30) then controls to which half of H-bridge is the generated PWM signal fed. If both signals are enabled then both outputs change synchronously and difference voltage is zero so the effect on motor is same as if both halves are switched off except for switching power loses caused by semiconductors and wiring capacitances and need to drive MOSFET gate and overcome Miller charge. Usable combinations are "0,0" for zero action, "0,1" for one direction and "1,0" for another. For those who like more complete source code than the description there are complete VHDL sources of the "dcsimpledrv" peripheral peripheral which can be found on branch "microzed_apo_psr" of the "canbench-sw" repository git clone git://rtime.felk.cvut.cz/fpga/zynq/canbench-sw.git git checkout microzed_apo_psr the "dcsimpledrv" peripheral AXI bus component is located in subdirectory "/system/ip/dcsimpledrv_1.0/hdl". You can browse it directory on the web https://rtime.felk.cvut.cz/gitweb/fpga/zynq/canbench-sw.git/tree/refs/heads/... Registers which are writable and have effect on the peripheral state are routed out from AXI peripheral by assignments starting from the line 450 450 -- CR 451 irc_reset <= slv_reg0(8); 452 pwm_direct_a <= slv_reg0(4); 453 pwm_direct_b <= slv_reg0(5); 454 pwm_enable <= slv_reg0(6); 455 456 slv_reg0_wmask <= x"00000170"; 457 458 -- STAT 459 slv_reg1 <= (8 => irc_a_mon, 9 => irc_b_mon, 10 => irc_irq_mon, others => '0'); 460 461 -- PWM_PER 462 pwm_period <= slv_reg2; 463 464 slv_reg2_wmask <= x"3fffffff"; 465 466 -- PWM_DUTY 467 pwm_duty <= slv_reg3; 468 469 -- IRC_POS 470 slv_reg4 <= irc_pos; 471 -- User logic ends Actual PWM A and B signals (for positive and negative H-bridge output polarity) are controlled by section 271 PWM_A <= (pwm_direct_a and not pwm_enable) or pwm_a_gen; 272 PWM_B <= (pwm_direct_b and not pwm_enable) or pwm_b_gen; in the component top level VHLD file https://rtime.felk.cvut.cz/gitweb/fpga/zynq/canbench-sw.git/blob/refs/heads/... If a "pwm_enable" signal is negated then direct signals are fed to outputs and PWM state machine is forced to reset state. When "pwm_enable" signal is asserted then PWM state machine controls outputs. There is mapping of the PWM state machine to the signals of the top level source 249 bidir_pwm_inst: bidir_pwm 250 generic map ( 251 pwm_width => 30 252 ) 253 port map( 254 clock => fsm_clk, 255 reset => pwm_reset_rq, 256 pwm_period => pwm_period(29 downto 0), 257 pwm_duty => pwm_duty(29 downto 0), 258 dir_a => pwm_duty(30), 259 dir_b => pwm_duty(31), 260 pwm_a => pwm_a_gen, 261 pwm_b => pwm_b_gen 262 ); The PWM state machine is implemented in the file https://rtime.felk.cvut.cz/gitweb/fpga/zynq/canbench-sw.git/blob/refs/heads/... The "dir_a" and "dir_b" signals are kept together with the "pwm_duty(29 downto 0)" in the single peripheral register to enable atomic change of the duty value and direction (enable bits). Actual state machine is implemented such way that if duty is changed asynchronously to the signal generation then if change is done during active time interval of the pulse then pulse can be prolonged or shortened (even cut) immediately. If the direction is changed then the signal output is negated immediately and the correct signal starts with proper direction in the next period. This solution requires more hardware resources than solution with simple value match/equality compare (n x 2-input xor and n-input nor) because full adder (in the fact substract) unit has to be used. But if the equality comparison is used then the the duty and directions (and ideally even period) has to be stored at each period start to ensure that the value is not changed to the value below actual counter state because in such case the match is missed and instead of shorter pulse full fill is generated for that one period. The registering of requested values is no problem for serious design where complete motor control is synchronized with PWM timing. But for the case, when there are expected users experimenting with PWM period registers and duty register and flexibility of PWM period register allows to set period to maximal value of 10 seconds (2^30)/100e6 then keeping single parameters for whole period can lead to confussion. Best wishes, Pavel Pisa
participants (3)
-
Jiri Hubacek
-
klapajar@fel.cvut.cz
-
Pavel Pisa