[Purpose] In order to demonstrate CAN dual-signal communication, AT32F425 is needed as the receiver to drive the servo to work.
[Idea] In the previous example, CH582 uses Bluetooth to control the servo's timer PWM to drive the servo. The timing required to drive the servo.
The control line is used to transmit angle control signals. This angle is determined by the duration of the control signal pulse, which is called pulse code modulation (PCM). The control of the servo generally requires a time base pulse of about 20ms. The high level part of the pulse is generally in the range of 0.5ms-2.5ms, and the total interval is 2ms. The width of the pulse will determine the distance the motor rotates. For example: with a 1.5 millisecond pulse, the motor will turn to the 90-degree position (usually called the neutral position, for a 180° servo, it is the 90° position). If the pulse width is less than 1.5 milliseconds, the motor axis is facing the 0-degree direction. If the pulse width is greater than 1.5 milliseconds, the axis is facing the 180-degree direction. Taking a 180-degree servo as an example, the corresponding control relationship is as follows:
0.5ms————-0度;
1.0ms————45度;
1.5ms————90度;
2.0ms———–135度;
2.5ms———–180度;
I use TMR1 here to implement it. The code is as follows:
#include "at32f425_board.h"
#include "at32f425_clock.h"
/** @addtogroup 舵机驱动
* @{
*/
gpio_init_type gpio_init_struct = {0};
tmr_output_config_type tmr_output_struct;
crm_clocks_freq_type crm_clocks_freq_struct = {0};
uint16_t timer_period = 0;
uint16_t channel1_pulse = 0;
/**
* [url=home.php?mod=space&uid=159083]@brief[/url] main function.
* @param none
* @retval none
*/
int main(void)
{
system_clock_config();
at32_board_init();
/* get system clock */
crm_clocks_freq_get(&crm_clocks_freq_struct);
/* enable tmr1/gpioa/gpiob clock */
crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
/* timer1 output pin Configuration */
gpio_init_struct.gpio_pins = GPIO_PINS_8 ;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init(GPIOA, &gpio_init_struct);
gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE8, GPIO_MUX_2);
/* compute the value to be set in arr regiter to generate signal frequency at 17.57 khz */
timer_period = (crm_clocks_freq_struct.sclk_freq/12000) - 1;
//channel1_pulse = 219 + 799; //180
channel1_pulse = 219;//0度
tmr_base_init(TMR1, timer_period, 239);
tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);
/* channel 1, 2, 3 and 4 configuration in output mode */
tmr_output_default_para_init(&tmr_output_struct);
tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_B;
tmr_output_struct.oc_output_state = TRUE;
tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_LOW;
tmr_output_struct.oc_idle_state = TRUE;
tmr_output_struct.occ_output_state = TRUE;
tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
tmr_output_struct.occ_idle_state = FALSE;
/* channel 1 */
tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_1, &tmr_output_struct);
tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_1, channel1_pulse);
/* output enable */
tmr_output_enable(TMR1, TRUE);
/* enable tmr1 */
tmr_counter_enable(TMR1, TRUE);
while(1)
{
delay_ms(1000);
channel1_pulse = 219;
tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_1, channel1_pulse);
delay_ms(1000);
channel1_pulse = 219 + 799; //180
tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_1, channel1_pulse);
}
}
After debugging, 219 for channel1_pulse is zero degree, and 219+799 is 180 degrees.
The experimental phenomenon is that the servo goes back and forth from 0 degrees to 180 degrees. It should be noted that the servo should be supplied with 5V power separately.
The next step is to use N32G45 to communicate with AT32F425 via CAN to display temperature and humidity, and control the servo with buttons.
|