平衡小车

126 阅读3分钟

PWM程序

单片机的IO口输出的是数字信号,IO口只能输出高电平和低电平。假设高电平为5V 低电平则为0V 那么我们要输出不同的模拟电压,就要用到PWM,通过改变IO口输出的方波的占空比从而获得使用数字信号模拟成的模拟电压信号。电压是以一种连接1或断开0的重复脉冲序列被夹到模拟负载上去的,连接即是直流供电输出,断开即是直流供电断开。通过对连接和断开时间的控制,理论上来讲,可以输出任意不大于最大电压值的模拟电压,比方说占空比为50%那就是高电平时间一半,低电平时间一半,在一定的频率下,就可以得到模拟的2.5V输出电压;那么75%的占空比得到的电压就是3.75V。

#include "stm32f10x.h"
#include "config.h"
#include "stdlib.h"

int main(void)
{	
    char recv[GATEWAY_QUEUE_MSG_LEN];
SystemInit();	 
//iwdg_init(4,625);/* Tout=((4*2^prer)*rlr)/40=(64*625)/40=1000ms不够约1秒就会复位 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//优先级组别
uart_init(115200);
ultrasonic_io_init();	
tim1_init(5000-1,7200-1);//最长一次计时不超过500ms,计一个数是100us,
debug("booting\n");
motor_gpio_config();
tim2_pwm_init(1000);
SysTick_Init(5000);

while(1){
        //delay_soft_ms(300);
        //ultrasonic_start_measure();
        if(get_queue(recv) == 0){
	debug("debug = %s\n",recv); 		
	if(strcmp(recv,"forward") == 0){
                debug("forward\n");
                moto_ops(1,1);
	}else if(strcmp(recv,"reverse") == 0){		
                debug("reverse\n");
                moto_ops(-1,-1);				
	}else if(strcmp(recv,"stop") == 0){		
                debug("stop\n");
                moto_ops(0,0);				
	}else if(strcmp(recv,"stop2") == 0){		
                debug("stop2\n");
                GPIO_ResetBits(GPIOB, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15 );
	}else if(strncmp(recv,"pwm",3) == 0){		
                debug("pwm1 = %d,pwm2 = %d\n",atoi(recv+3),atoi(recv+7));
                tim2_pwm_change(atoi(recv+3),atoi(recv+7));
	}else if(strncmp(recv,"freq",4) == 0){		
                debug("freq = %d\n",atoi(recv+4));
                TIM_PrescalerConfig(TIM2,atoi(recv+4),TIM_PSCReloadMode_Immediate);
	}
        }
}
 }

霍尔码盘测速

霍尔码盘分为霍尔传感器和码盘,中间的码盘是一块磁铁根据磁极分布,霍尔传感器也带磁极,转动中就会发生吸引和排斥,再从传感器的脉冲处发出,就得到转一圈经过N的次数,S极转一圈会有16个脉冲,精度很低。为了提高精度,我们要把码盘安装在直流电机上,后面的减速器比值是1\30,轴就转了1630圈,精度就相当于提高了30倍,而由于使用了两个霍尔传感器,精度就要再2,所以轮子转一圈电机就转了21630=960圈。

代码:

#include "stm32f10x.h"
#include "config.h"
#include "stdlib.h"

int main(void)
{	
    char recv[GATEWAY_QUEUE_MSG_LEN];
SystemInit();	 
//iwdg_init(4,625);/* Tout=((4*2^prer)*rlr)/40=(64*625)/40=1000ms不喂狗约1秒就会复位 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//优先级组别
uart_init(115200);
ultrasonic_io_init();	
tim1_init(5000-1,7200-1);//最长一次计时不超过500ms,计一个数是100us,
debug("booting\n");
motor_gpio_config();
tim2_pwm_init(1000);
tim3_encoder_init();
tim4_encoder_init();
SysTick_Init(5000);

while(1){
        delay_soft_ms(300);
        printf("left_speed = %d,right_speed = %d\n",left_speed,right_speed);
        //ultrasonic_start_measure();
        if(get_queue(recv) == 0){
	debug("debug = %s\n",recv); 		
	if(strcmp(recv,"forward") == 0){
                debug("正转\n");
                moto_ops(1,1);
            }else if(strcmp(recv,"reverse") == 0){		
                debug("反转\n");
                moto_ops(-1,-1);				
            }else if(strcmp(recv,"stop") == 0){		
                debug("停止\n");
                moto_ops(0,0);				
            }else if(strcmp(recv,"stop2") == 0){		
                debug("停止2\n");
                GPIO_ResetBits(GPIOB, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15 );
            }else if(strncmp(recv,"pwm",3) == 0){		
                debug("pwm1 = %d,pwm2 = %d\n",atoi(recv+3),atoi(recv+7));
                tim2_pwm_change(atoi(recv+3),atoi(recv+7));
            }else if(strncmp(recv,"freq",4) == 0){		
                debug("freq = %d\n",atoi(recv+4));
                TIM_PrescalerConfig(TIM2,atoi(recv+4),TIM_PSCReloadMode_Immediate);
            }
        }
    }
}