新手入门
- 积分
- 11
- 金钱
- 11
- 注册时间
- 2018-2-9
- 在线时间
- 7 小时
|
15金钱
本帖最后由 爱兜风ADF 于 2018-2-21 00:08 编辑
菜鸟自己写了个舵机程序,希望控制舵机正转,然后反转,然而将其写入串口中断函数后。
经过测试,在串口发送一个数据后,触发中断,
1.正转代码单独可运行,
2.反转代码单独可运行,
3.但将正反转代码写在一块后(即先正转,再反转),代码不能正常运行。它会不止一次地正转再反转,按我的想法他应该只有一个来回,即转过去再转回来。
4.在正反转代码之间加入正点原子提供的delay_ms(5000),舵机会转过去,停留一段时间(目测绝对没5s那么久),然后迅速进行一个角度范围比较小的来回,再停留一段时间,再转回去。
5.在4的条件下,疯狂按发送,它会转过去,停留一段时间,然后迅速进行许多个小来回,直到不按发送键,再停留一段时间,再转回去。
由于我在串口中断服务函数的开头部分熄灭了LED,结束部分点亮了LED,所以可以确定除5外代码都确实只运行了一次,5运行了很多次,因为可以看到LED灯亮了一点点然后熄灭了。
我用的舵机是辉盛SG90,信号线接PF11。
另外,串口中断服务函数里的相同代码放在按键实验的代码下却可以运行,能达到我期望的目的。
代码和源程序贴在这,求大神们看看是哪里出错了
正转部分
for(i=0;i<=10;i++){
GPIO_SetBits(GPIOF,GPIO_Pin_11);
delay_us(1500);
GPIO_ResetBits(GPIOF,GPIO_Pin_11);
delay_us(18500);
}
反转部分
for(j=0;j<=5;j++){
GPIO_SetBits(GPIOF,GPIO_Pin_11);
delay_ms(4);
GPIO_ResetBits(GPIOF,GPIO_Pin_11);
delay_ms(16);}
GPIO_ResetBits(GPIOB,GPIO_Pin_5);
GPIO_ResetBits(GPIOE,GPIO_Pin_5);
全部main.c代码
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
void USART1_Init()
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
USART_InitStruct.USART_BaudRate=115200;
USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
USART_InitStruct.USART_Parity=USART_Parity_No;
USART_InitStruct.USART_StopBits=USART_StopBits_1;
USART_InitStruct.USART_WordLength=USART_WordLength_8b;
USART_Init(USART1,&USART_InitStruct);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
USART_Cmd(USART1,ENABLE);
NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;
NVIC_Init(&NVIC_InitStruct);
}
void USART1_IRQHandler()
{
u16 t;
u8 i;
u8 j;
if(USART_GetITStatus(USART1,USART_IT_RXNE))
{
t=USART_ReceiveData(USART1);
USART_SendData(USART1,t);
GPIO_SetBits(GPIOB,GPIO_Pin_5);
GPIO_SetBits(GPIOE,GPIO_Pin_5);
for(i=0;i<=5;i++){
GPIO_SetBits(GPIOF,GPIO_Pin_11);
delay_us(1500);
GPIO_ResetBits(GPIOF,GPIO_Pin_11);
delay_us(18500);
}
delay_ms(5000);
for(j=0;j<=5;j++){
GPIO_SetBits(GPIOF,GPIO_Pin_11);
delay_ms(4);
GPIO_ResetBits(GPIOF,GPIO_Pin_11);
delay_ms(16);}
GPIO_ResetBits(GPIOB,GPIO_Pin_5);
GPIO_ResetBits(GPIOE,GPIO_Pin_5);
}
}
int main()
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
USART1_Init();
Motor_Init();
delay_init();
while(1);
}
|
最佳答案
查看完整内容[请看2#楼]
舵机控制应该用定时器输出PWM,你用延时函数来做首先精度不高,其次这样写STM32完全干不了其他事。最好不要在中断里面用延时函数,程序在中断里面那么久,很容易死机。
你这个程序应该用定时器pwm输出,串口中断进去后设置个flag,在main函数里面识别flag来控制舵机。
|