stm32f103c8t6控制五个舵机,前三个舵机由一个按键开关控制,后面两个舵机都分别通过两个按键进行左右运动的控制的代码
时间: 2024-01-05 19:02:53 浏览: 99
基于STM32控制的舵机代码
以下是一个示例代码,用于控制五个舵机:
```c
#include "stm32f10x.h"
// 定义舵机的引脚
#define SERVO1_PIN GPIO_Pin_0
#define SERVO2_PIN GPIO_Pin_1
#define SERVO3_PIN GPIO_Pin_2
#define SERVO4_PIN GPIO_Pin_3
#define SERVO5_PIN GPIO_Pin_4
// 定义按键的引脚
#define KEY1_PIN GPIO_Pin_5
#define KEY2_PIN GPIO_Pin_6
#define KEY3_PIN GPIO_Pin_7
// 定义舵机的角度范围
#define SERVO_MIN_ANGLE 0
#define SERVO_MAX_ANGLE 180
// 定义按键的状态
#define KEY_PRESSED 0
#define KEY_RELEASED 1
// 定义舵机的初始角度
uint16_t servo1_angle = 90;
uint16_t servo2_angle = 90;
uint16_t servo3_angle = 90;
uint16_t servo4_angle = 90;
uint16_t servo5_angle = 90;
// 函数声明
void GPIO_Configuration(void);
void TIM_Configuration(void);
void delay_ms(uint32_t ms);
uint8_t read_key(uint16_t pin);
int main(void)
{
// 初始化GPIO和定时器
GPIO_Configuration();
TIM_Configuration();
while(1)
{
// 读取按键状态
uint8_t key1_state = read_key(KEY1_PIN);
uint8_t key2_state = read_key(KEY2_PIN);
uint8_t key3_state = read_key(KEY3_PIN);
// 控制前三个舵机的角度
if(key1_state == KEY_PRESSED)
servo1_angle = (servo1_angle + 10) % 181;
if(key2_state == KEY_PRESSED)
servo2_angle = (servo2_angle + 10) % 181;
if(key3_state == KEY_PRESSED)
servo3_angle = (servo3_angle + 10) % 181;
// 控制后面两个舵机的角度
if(key1_state == KEY_PRESSED)
servo4_angle = (servo4_angle + 10) % 181;
if(key2_state == KEY_PRESSED)
servo4_angle = (servo4_angle - 10) % 181;
if(key3_state == KEY_PRESSED)
servo5_angle = (servo5_angle + 10) % 181;
// 更新舵机的角度
TIM_SetCompare1(TIM2, servo1_angle);
TIM_SetCompare2(TIM2, servo2_angle);
TIM_SetCompare3(TIM2, servo3_angle);
TIM_SetCompare4(TIM2, servo4_angle);
TIM_SetCompare1(TIM3, servo5_angle);
// 延时一段时间
delay_ms(100);
}
}
// 初始化GPIO
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// 打开GPIOA和GPIOB的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
// 配置PA0、PA1和PA2为推挽输出,用于控制舵机
GPIO_InitStructure.GPIO_Pin = SERVO1_PIN | SERVO2_PIN | SERVO3_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置PB3和PB4为推挽输出,用于控制舵机
GPIO_InitStructure.GPIO_Pin = SERVO4_PIN | SERVO5_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 配置PA5、PA6和PA7为上拉输入,用于读取按键
GPIO_InitStructure.GPIO_Pin = KEY1_PIN | KEY2_PIN | KEY3_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
// 初始化定时器
void TIM_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// 打开TIM2和TIM3的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE);
// 初始化TIM2,用于控制前三个舵机
TIM_TimeBaseStructure.TIM_Period = 19999;
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// 初始化TIM3,用于控制后面两个舵机
TIM_TimeBaseStructure.TIM_Period = 19999;
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// 配置TIM2的四个通道为PWM输出
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 1500;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC4Init(TIM2, &TIM_OCInitStructure);
// 配置TIM3的一个通道为PWM输出
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 1500;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
// 启动TIM2和TIM3
TIM_Cmd(TIM2, ENABLE);
TIM_Cmd(TIM3, ENABLE);
}
// 延时函数,单位为毫秒
void delay_ms(uint32_t ms)
{
while(ms--)
{
uint16_t i = 8000;
while(i--);
}
}
// 读取按键状态,返回值为KEY_PRESSED或KEY_RELEASED
uint8_t read_key(uint16_t pin)
{
if(GPIO_ReadInputDataBit(GPIOA, pin) == 0)
return KEY_PRESSED;
else
return KEY_RELEASED;
}
```
在这个示例代码中,我们使用了两个定时器(TIM2和TIM3)来控制五个舵机的角度。前三个舵机的角度由一个按键开关控制,后面两个舵机都分别通过两个按键进行左右运动的控制。我们还定义了一些常量,如舵机的引脚、按键的引脚、舵机的角度范围等等。在程序的主循环中,我们读取按键状态,根据按键状态来控制舵机的角度,并使用定时器更新舵机的角度。我们还定义了一个延时函数,用于延时一段时间,避免舵机运动过快。最后,我们定义了一个读取按键状态的函数,用于判断按键是否被按下。
阅读全文