开源!自制一个桌面宠物(STM32CUBEMX HAL库 PWM波 小项目)

慈云数据 2024-05-11 技术支持 80 0
原视频:好,自制一个桌面宠物!_哔哩哔哩_bilibili
基础所需:基础电路认识,C语言,STM32开发,STM32CUBEIDE或CUBEMX和Keil使用(重要),一点点艺术细胞、一点点耐心。
CAUTION:本文重点在代码部分的开源,是基于HAL库。硬件手工部分不出教程(没必要)可以直接看视频P2,文末附步态参考出处,接线图,舵机安排。

硬件配置

主控:STM32F103C8T6 粉色沉金板(也可以用C6T6,价格便宜一半)

舵机:SG90 *4

屏幕:1.3寸OLED (IIC驱动

供电:锂电池 (3.7V 30mm*40mm 800mah,建议购买尺寸合适的飞控专用锂电池或两块普通锂电池并联,输出功率大,不需要后续拆保护板) + 锂电池充放电模块(不会自动断电、适配3.7V锂电池、输出5V、充放电同口)

蓝牙:低功耗蓝牙(BLE,串口透传,便宜又好用)

软件配置

手机app开发:appinventor制作(这里不附教程,因为我也不熟,唯一有用的建议是我的蓝牙模组要用BLE而不是普通蓝牙,需另外下载并配置,建议另寻他佬教程

单片机开发:

平台:STM32CUBEIDE(等效STM32CUBEMX+Keil)

软件开源:  

提纲:

1.定时器pwm波输出

2.串口信息交互

3.OLED显示  

CUBEMX配置:

(这里没有配置驱动屏幕的IIC,选择直接软件模拟,文末会附驱动代码。

1.RCC时钟配置:

(无脑选择外部时钟,无脑拉最高频。

2.定时器配置PWM输出模式:

(一个定时器直接开四个PWM通道即可,并关注输出引脚是否正确。根据舵机参数,配置PWM频率为50Hz。通道一为前右脚,通道二为后右脚,通道三为前左脚,通道四为后左脚,脚的位置和角度见文末图,是参考文末大佬的视频的

注意引脚为PA0,PA1,PA2,PA3。

3.配置串口

(也很无脑,但要根据蓝牙模块的参数配置传输速率(Baud Rate),我是115200。

并且开中断NVIC,优先级按经验来填2就可。

考虑到单片机引脚位置,需要把串口引脚重定向到PB6和PB7。 

4.IIC引脚配置(软件模拟IIC,引脚任意两个IO就可以,要命名成这个是因为和驱动代码匹配)

小Tip:

经验所得,把系统滴答时钟的优先级拉最高可以防止卡死在HAL_Delay里面。

5.最后生成工程,用keil的这里改成MDK_ARM

推荐打勾这个,为每个外设建.c和.h文件,使工程结构更清晰。

最后直接ctrl+s即可生成工程(用STM32CUBEMX+Keil的点Generate code建立工程)

代码部分:(最后会附完整代码,其中LED的控制可有可无

(即“HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);”)。
1.PWM波输出(姿态
uint16_t angle(uint8_t angle) //角度CCR值转换
{
	return angle*2000/180+500;
}
void Rbt_Init(void) //立正
{
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(90));
	HAL_Delay(100);
}
void move_forward(void) //前进
{
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(135));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(45));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(45));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(135));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(90));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(90));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(135));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(45));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(45));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(135));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(90));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(90));
	HAL_Delay(move_delay);
}
void move_behind(void) //后退
{
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(45));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(135));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(135));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(45));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(90));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(90));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(45));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(135));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(135));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(45));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(90));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(90));
	HAL_Delay(move_delay);
}
void move_right(void) //右转
{
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(45));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(45));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(135));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(135));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(90));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(90));
	HAL_Delay(move_delay);
}
void move_left(void) //左转
{
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(135));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(135));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(45));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(45));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(90));
	HAL_Delay(move_delay);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(90));
	HAL_Delay(move_delay);
}
void move_swing(void) //摇摆
{
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(130));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(130));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(50));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(50));
	HAL_Delay(250);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(50));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(50));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(130));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(130));
	HAL_Delay(250);
}
void move_stretch(void){ //伸懒腰+坐下招手
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_3,angle(90));
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4,angle(90));
	if(TIM2->CCR1CCR3>angle(25)){
		for(uint8_t i=0;iangle(25)){
		for(uint8_t i=0;i
微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon