PWM.c
#include "stm32f10x.h" // Device header void PWM_Init(void) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;//GPIO初始化GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽(控制权给片上外设)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);TIM_InternalClockConfig(TIM2);//定时器2初始化TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 2000-1; //ARRTIM_TimeBaseInitStructure.TIM_Prescaler = 720-1; //PSCTIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);TIM_OCInitTypeDef TIM_OCInitTypeDefStructure1;TIM_OCStructInit(&TIM_OCInitTypeDefStructure1);TIM_OCInitTypeDefStructure1.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitTypeDefStructure1.TIM_OCPolarity = TIM_OCPolarity_High;TIM_OCInitTypeDefStructure1.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitTypeDefStructure1.TIM_Pulse = 0; //CCR值TIM_OC1Init(TIM2,&TIM_OCInitTypeDefStructure1);TIM_OCInitTypeDef TIM_OCInitTypeDefStructure2;TIM_OCStructInit(&TIM_OCInitTypeDefStructure2);TIM_OCInitTypeDefStructure2.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitTypeDefStructure2.TIM_OCPolarity = TIM_OCPolarity_High;TIM_OCInitTypeDefStructure2.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitTypeDefStructure2.TIM_Pulse = 0;TIM_OC2Init(TIM2,&TIM_OCInitTypeDefStructure2);TIM_OCInitTypeDef TIM_OCInitTypeDefStructure3;TIM_OCStructInit(&TIM_OCInitTypeDefStructure3);TIM_OCInitTypeDefStructure3.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitTypeDefStructure3.TIM_OCPolarity = TIM_OCPolarity_High;TIM_OCInitTypeDefStructure3.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitTypeDefStructure3.TIM_Pulse = 0;TIM_OC3Init(TIM2,&TIM_OCInitTypeDefStructure3);TIM_OCInitTypeDef TIM_OCInitTypeDefStructure4;TIM_OCStructInit(&TIM_OCInitTypeDefStructure4);TIM_OCInitTypeDefStructure4.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitTypeDefStructure4.TIM_OCPolarity = TIM_OCPolarity_High;TIM_OCInitTypeDefStructure4.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitTypeDefStructure4.TIM_Pulse = 0;TIM_OC4Init(TIM2,&TIM_OCInitTypeDefStructure4);TIM_Cmd(TIM2,ENABLE); //开启定时器 } void PWM_SetCompare1(uint16_t Compare) {TIM_SetCompare1(TIM2, Compare);//设置CCR1的值 } void PWM_SetCompare2(uint16_t Compare) {TIM_SetCompare2(TIM2, Compare);//设置CCR2的值 } void PWM_SetCompare3(uint16_t Compare) {TIM_SetCompare3(TIM2, Compare);//设置CCR3的值 } void PWM_SetCompare4(uint16_t Compare) {TIM_SetCompare4(TIM2, Compare);//设置CCR4的值 }
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980可以参考江科大的:PWM驱动舵机
void Servo_SetAngle1(float Angle) {PWM_SetCompare1(Angle / 180 * 2000 + 500); } void Servo_SetAngle2(float Angle) {PWM_SetCompare2(Angle / 180 * 2000 + 500); } void Servo_SetAngle3(float Angle) {PWM_SetCompare3(Angle / 180 * 2000 + 500); } void Servo_SetAngle4(float Angle) {PWM_SetCompare4(Angle / 180 * 2000 + 500); }
1234567891011121314151617181920212223具体的步态可以观看【步态详解】人人都可制作的WiFi遥控迷你四足机器人
可以根据他的步态来进行运动,下面是我按照我自己的连线以及代码来实现的状态
void servo_advance(void)//前进 {static uint8_t advanceFlag = 1;if (advanceFlag == 1){Servo_SetAngle1(135);Servo_SetAngle2(90);Servo_SetAngle3(90);Servo_SetAngle4(45);Delay_ms(speed);advanceFlag++;}else if(advanceFlag == 2){Servo_SetAngle1(135);Servo_SetAngle2(45);Servo_SetAngle3(135);Servo_SetAngle4(45);Delay_ms(speed);advanceFlag++;}else if(advanceFlag == 3){Servo_SetAngle1(90);Servo_SetAngle2(45);Servo_SetAngle3(135);Servo_SetAngle4(90);Delay_ms(speed);advanceFlag++;}else if(advanceFlag == 4){Servo_SetAngle1(90);Servo_SetAngle2(90);Servo_SetAngle3(90);Servo_SetAngle4(90);Delay_ms(speed);advanceFlag++;}else if(advanceFlag == 5){Servo_SetAngle1(90);Servo_SetAngle2(135);Servo_SetAngle3(45);Servo_SetAngle4(90);Delay_ms(speed);advanceFlag++;}else if(advanceFlag == 6){Servo_SetAngle1(45);Servo_SetAngle2(135);Servo_SetAngle3(45);Servo_SetAngle4(135);Delay_ms(speed);advanceFlag++;}else if(advanceFlag == 7){Servo_SetAngle1(45);Servo_SetAngle2(90);Servo_SetAngle3(90);Servo_SetAngle4(135);Delay_ms(speed);advanceFlag++;}else if(advanceFlag == 8){Servo_SetAngle1(90);Servo_SetAngle2(90);Servo_SetAngle3(90);Servo_SetAngle4(90);Delay_ms(speed);advanceFlag = 1;} }
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 后退void servo_retreat(void)//后退 {static uint8_t retreatFlag = 1;if (retreatFlag == 1){Servo_SetAngle1(45);Servo_SetAngle2(90);Servo_SetAngle3(90);Servo_SetAngle4(135);Delay_ms(speed);retreatFlag++;}else if(retreatFlag == 2){Servo_SetAngle1(45);Servo_SetAngle2(135);Servo_SetAngle3(45);Servo_SetAngle4(135);Delay_ms(speed);retreatFlag++;}else if(retreatFlag == 3){Servo_SetAngle1(90);Servo_SetAngle2(135);Servo_SetAngle3(45);Servo_SetAngle4(90);Delay_ms(speed);retreatFlag++;}else if(retreatFlag == 4){Servo_SetAngle1(90);Servo_SetAngle2(90);Servo_SetAngle3(90);Servo_SetAngle4(90);Delay_ms(speed);retreatFlag++;}else if(retreatFlag == 5){Servo_SetAngle1(90);Servo_SetAngle2(45);Servo_SetAngle3(135);Servo_SetAngle4(90);Delay_ms(speed);retreatFlag++;}else if(retreatFlag == 6){Servo_SetAngle1(135);Servo_SetAngle2(45);Servo_SetAngle3(135);Servo_SetAngle4(45);Delay_ms(speed);retreatFlag++;}else if(retreatFlag == 7){Servo_SetAngle1(135);Servo_SetAngle2(90);Servo_SetAngle3(90);Servo_SetAngle4(45);Delay_ms(speed);retreatFlag++;}else if(retreatFlag == 8){Servo_SetAngle1(90);Servo_SetAngle2(90);Servo_SetAngle3(90);Servo_SetAngle4(90);Delay_ms(speed);retreatFlag = 1;} }
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 右转void servo_trunright(void)//右转 {static uint8_t trunrightFlag = 1;if (trunrightFlag == 1){Servo_SetAngle1(45);Servo_SetAngle2(90);Servo_SetAngle3(90);Servo_SetAngle4(45);Delay_ms(speed);trunrightFlag++;}else if(trunrightFlag == 2){Servo_SetAngle1(45);Servo_SetAngle2(135);Servo_SetAngle3(135);Servo_SetAngle4(45);Delay_ms(speed);trunrightFlag++;}else if(trunrightFlag == 3){Servo_SetAngle1(90);Servo_SetAngle2(135);Servo_SetAngle3(135);Servo_SetAngle4(90);Delay_ms(speed);trunrightFlag++;}else if(trunrightFlag == 4){Servo_SetAngle1(90);Servo_SetAngle2(90);Servo_SetAngle3(90);Servo_SetAngle4(90);Delay_ms(speed);trunrightFlag++;trunrightFlag = 1;} }
123456789101112131415161718192021222324252627282930313233343536373839404142 左转void servo_trunleft(void)//左转 {static uint8_t trunleftFlag = 1;if (trunleftFlag == 1){Servo_SetAngle1(90);Servo_SetAngle2(135);Servo_SetAngle3(135);Servo_SetAngle4(90);Delay_ms(speed);trunleftFlag++;}else if(trunleftFlag == 2){Servo_SetAngle1(45);Servo_SetAngle2(135);Servo_SetAngle3(135);Servo_SetAngle4(45);Delay_ms(speed);trunleftFlag++;}else if(trunleftFlag == 3){Servo_SetAngle1(45);Servo_SetAngle2(90);Servo_SetAngle3(90);Servo_SetAngle4(45);Delay_ms(speed);trunleftFlag++;}else if(trunleftFlag == 4){Servo_SetAngle1(90);Servo_SetAngle2(90);Servo_SetAngle3(90);Servo_SetAngle4(90);Delay_ms(speed);trunleftFlag++;trunleftFlag = 1;} }
123456789101112131415161718192021222324252627282930313233343536373839404142 跳舞void servo_dance(void)//跳舞 {static uint8_t danceFlag = 1;if (danceFlag == 1){Servo_SetAngle1(130);Servo_SetAngle2(130);Servo_SetAngle3(50);Servo_SetAngle4(50);Delay_ms(400);danceFlag++;}else if(danceFlag == 2){Servo_SetAngle1(50);Servo_SetAngle2(50);Servo_SetAngle3(130);Servo_SetAngle4(130);Delay_ms(400);danceFlag = 1;} }
12345678910111213141516171819202122#include "stm32f10x.h" #include <stdio.h> #include <stdarg.h> char Serial_RxPacket[100]; uint8_t Serial_RxFlag; void Serial_Init(void) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = 9600;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_Init(USART1, &USART_InitStructure);USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);USART_Cmd(USART1, ENABLE); } void Serial_SendByte(uint8_t Byte) {USART_SendData(USART1, Byte);while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); } void Serial_SendArray(uint8_t *Array, uint16_t Length) {uint16_t i;for (i = 0; i < Length; i ++){Serial_SendByte(Array[i]);} } void Serial_SendString(char *String) {uint8_t i;for (i = 0; String[i] != ' '; i ++){Serial_SendByte(String[i]);} } uint32_t Serial_Pow(uint32_t X, uint32_t Y) {uint32_t Result = 1;while (Y --){Result *= X;}return Result; } void Serial_SendNumber(uint32_t Number, uint8_t Length) {uint8_t i;for (i = 0; i < Length; i ++){Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');} } int fputc(int ch, FILE *f) {Serial_SendByte(ch);return ch; } void Serial_Printf(char *format, ...) {char String[100];va_list arg;va_start(arg, format);vsprintf(String, format, arg);va_end(arg);Serial_SendString(String); } void USART1_IRQHandler(void) {static uint8_t RxState = 0;static uint8_t pRxPacket = 0;if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET){uint8_t RxData = USART_ReceiveData(USART1);if (RxState == 0){if (RxData == '@' && Serial_RxFlag == 0){RxState = 1;pRxPacket = 0;}}else if (RxState == 1){if (RxData == 'r'){RxState = 2;}else{Serial_RxPacket[pRxPacket] = RxData;pRxPacket ++;}}else if (RxState == 2){if (RxData == 'n'){RxState = 0;Serial_RxPacket[pRxPacket] = ' ';Serial_RxFlag = 1;}}USART_ClearITPendingBit(USART1, USART_IT_RXNE);} }
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147USART可以观看江科大的串口收发HEX数据包&串口收发文本数据包
(建议从9-3开始观看,有利于了解USART代码的各部分含义)
#include "stm32f10x.h" #include "delay.h" #include "Servo.h" #include "PWM.h" #include "control.h" #include "UART.h" #include <string.h> float Angle; uint8_t statu_falg=0; int main (void) {Servo_Init();Serial_Init();servo_up(); //servo_down();while(1){if(Serial_RxFlag == 1){if (strcmp(Serial_RxPacket, "advance") == 0){statu_falg=1;} if (strcmp(Serial_RxPacket,"fast") == 0){statu_falg=2;} if (strcmp(Serial_RxPacket, "ret") == 0){statu_falg=3;} if (strcmp(Serial_RxPacket, "right") == 0){statu_falg=4;}if (strcmp(Serial_RxPacket, "left") == 0){statu_falg=5;}if (strcmp(Serial_RxPacket, "down") == 0){statu_falg=6;}if (strcmp(Serial_RxPacket, "up") == 0){statu_falg=7;}if (strcmp(Serial_RxPacket, "hard") == 0){statu_falg=8;}if (strcmp(Serial_RxPacket, "dance") == 0){statu_falg=9;}if (strcmp(Serial_RxPacket, "sit") == 0){statu_falg=10;}if (strcmp(Serial_RxPacket, "sithard") == 0){statu_falg=11;}Serial_RxFlag = 0;}switch(statu_falg){case 1: servo_advance();break;case 2: servo_fastadvance();break;case 3: servo_retreat();break;case 4: servo_trunright();break;case 5: servo_trunleft();break;case 6: servo_down();break;case 7: servo_up();break;case 8: servo_hard();break;case 9: servo_dance();break;case 10: servo_sitdown();break;case 11: servo_sithard();break;}} }
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899在开始我写代码的时候,没有配置单独的关于小狗行动的标志位,直接运行行为,导致蓝牙控制下的小狗不能在指令下连续运动,经过高人指点,定义一个标志位,将持续运动的用标志位取代,用switch函数查询标志位,执行程序。(我犯了同志们就能避开了)
我使用的蓝牙是JDY-3x,蓝牙APP是B站上一位up的开源【蓝牙调试器App开源】,使用什么蓝牙APP无所谓。
连接线路如下:
RX-----P9;
TX-----P10;
GND—GND;
VCC----3.3V;
手机蓝牙app:
配置好后就可以试试能不能用蓝牙控制小狗了。我的小狗属于有线款,不能脱离面包板,条件允许,同志们可以购买这份材料清单,来源于B站up:这个橙子好辣【【教程】如何做一个可爱的桌面机器小猫小狗】
到这个地方,一个桌面宠物就算做好了。。。如果可以也能加入智能语音控制模块,对宠物进行语音控制,我尚在摸索当中,感谢。
相关知识
基于江科大的桌面宠物项目
如何制作一款电子桌宠小狗(硬件部分)开源
[DIY]用STM32实现桌面宠物功能#开源
桌宠下载
桌宠吧
桌宠软件大全
强势种草内科大萌宠——梅花鹿
桌宠
《虚拟桌宠模拟器》桌宠怎样跳舞 桌宠跳舞设置办法
《虚拟桌宠模拟器》桌宠怎么跳舞 桌宠跳舞设置方法
网址: 基于江科大STM32的桌宠小狗 https://m.mcbbbk.com/newsview997990.html
上一篇: 封面评论丨养“芒狗”热潮风靡,是 |
下一篇: 宠物大冒险怎么换阵容 阵容搭配表 |