OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3721|回复: 6

关于一个自写的控制舵机程序,求大神赐教

[复制链接]

3

主题

19

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2018-2-9
在线时间
7 小时
发表于 2018-2-21 00:04:46 | 显示全部楼层 |阅读模式
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);                                
}



ST_Project.zip

12.8 MB, 下载次数: 407

最佳答案

查看完整内容[请看2#楼]

舵机控制应该用定时器输出PWM,你用延时函数来做首先精度不高,其次这样写STM32完全干不了其他事。最好不要在中断里面用延时函数,程序在中断里面那么久,很容易死机。 你这个程序应该用定时器pwm输出,串口中断进去后设置个flag,在main函数里面识别flag来控制舵机。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

28

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
319
金钱
319
注册时间
2017-6-19
在线时间
64 小时
发表于 2018-2-21 00:04:47 | 显示全部楼层
       舵机控制应该用定时器输出PWM,你用延时函数来做首先精度不高,其次这样写STM32完全干不了其他事。最好不要在中断里面用延时函数,程序在中断里面那么久,很容易死机。
       你这个程序应该用定时器pwm输出,串口中断进去后设置个flag,在main函数里面识别flag来控制舵机。
      
回复

使用道具 举报

3

主题

19

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2018-2-9
在线时间
7 小时
 楼主| 发表于 2018-2-21 19:11:19 | 显示全部楼层
求版主大大快点审核通过呀。。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2018-2-25 02:34:05 | 显示全部楼层
仿真找bug
回复

使用道具 举报

3

主题

19

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2018-2-9
在线时间
7 小时
 楼主| 发表于 2018-2-25 14:29:09 | 显示全部楼层
仿真不太会操作。。。
回复

使用道具 举报

4

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1046
金钱
1046
注册时间
2017-5-19
在线时间
335 小时
发表于 2018-2-25 14:54:18 | 显示全部楼层
粗看,中断函数没有清掉中断标志位
回复

使用道具 举报

3

主题

19

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2018-2-9
在线时间
7 小时
 楼主| 发表于 2018-2-27 13:01:10 | 显示全部楼层
wxjhby 发表于 2018-2-25 14:54
粗看,中断函数没有清掉中断标志位

谢谢谢谢 采纳了2楼和6楼的建议 程序好多了(虽然仍然有好多BUG
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 14:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表