基于51单片机的蓝牙舵机控制超声波模块测距开发(一)

蓝牙舵机篇  

引语  本系列博客将分为三篇来讲解,第一篇讲解如何通过HC-05蓝牙模块控制舵机,第二篇会介绍HC-SR04超声波模块的测距程序,第三篇会将两者组装在一起。


最终目的:通过手机连接蓝牙向单片机发送信号,单片机收到信号后向舵机发送pwm信号,让舵机达到相应的角度。

实现效果需要达到的目标:

1.会使用HC-05蓝牙模块,了解51单片机的串口通信。

2.会用51单片机输出pwm波控制舵机,并校正舵机的误差。

材料:51单片机最小系统、HC-05蓝牙模块、舵机、杜邦线、数据传输线。

51单片机最小系统:如图:

基于51单片机的蓝牙舵机控制超声波模块测距开发(一)_第1张图片

HC-05

基于51单片机的蓝牙舵机控制超声波模块测距开发(一)_第2张图片

如上图所示为蓝牙模块与51单片机的连接方式

那么如何让手机控制单片机呢?

这里我们需要下载一个app,如图基于51单片机的蓝牙舵机控制超声波模块测距开发(一)_第3张图片


我们可以在聊天栏中,向单片机发送信息,手机将信息分解为ASCII码发给单片机。单片机接受到的也是ASCII码,因此在下面的程序中的case语句中是以16进制来分情况的。

舵机:我们这里所使用的是SG-90舵机 如图

基于51单片机的蓝牙舵机控制超声波模块测距开发(一)_第4张图片

将舵机的橙线连接到P1.2接口

              红线连接到VCC口

              棕色连接到GND

想要控制舵机,那么我们就需要一个周期T = 20ms,高电平的时间(t)等于0.5ms-2.5ms之间的这样一个信号。 
以下是高电平持续的时间(t)与舵机的关系。


t = 0.5ms——————-舵机会转动 0 ° 
t = 1.0ms——————-舵机会转动 45° 
t = 1.5ms——————-舵机会转动 90° 
t = 2.0ms——————-舵机会转动 135° 

t = 2.5ms——————-舵机会转动180° 

但是在实际的应用中,我发现每一个舵机都存在误差,也就是说输出对应空占比的pwm信号,舵机不会精确地转动到相应的度数。因此我将在下面的程序中加以校正。

以下是代码

#include //注意这里的头文件为 

#define SEH_PWM P1_2//舵机PWM口定义

unsigned char SEH_count=5;
unsigned char count=0;


unsigned char T0RH = 0xff;  //T0重载值的高字节
unsigned char T0RL = 0xa3;  //T0重载值的低字节
unsigned char RxdByte = 0;  //串口接收到的字节

void ConfigTimer0();
void ConfigUART(unsigned int baud);

void PWM(unsigned char x)
{
	SEH_count=x;
}

void main()
{
    EA = 1;       //使能总中断
;
    ConfigTimer0();   //配置T0定时1ms
    ConfigUART(9600);  //配置波特率为9600
    
    while (1)
    {  
					switch(RxdByte)
				{
					case 0x31:{
											PWM(5);//手机向单片机发送‘0’,舵机转到0度    
										};break;
					case 0x32:{
										PWM(10);//手机向单片机发送‘1’,舵机转到45度  
										};break;
					case 0x33:{
										PWM(15);//手机向单片机发送‘2’,舵机转到90度  
										};break;
					case 0x34:{
										PWM(20);//手机向单片机发送‘3’,舵机转到135度  
										};break;
					case 0x35:{
										PWM(25);//手机向单片机发送‘4’,舵机转到180度  
										};break;
					case 0x36:{
										;//														
										};break;
					case 0x37:{
									   ;//																
										};break;
					case 0x38:;break;
				}
    }
}
/* 配置并启动T0,ms-T0定时时间 */
void ConfigTimer0()
{
  


    TMOD &= 0xF0;   //清零T0的控制位
    TMOD |= 0x01;   //配置T0为模式1
    TH0 = T0RH;     //加载T0重载值
    TL0 = T0RL;
    ET0 = 1;        //使能T0中断
    TR0 = 1;        //启动T0
}
/* 串口配置函数,baud-通信波特率 */
void ConfigUART(unsigned int baud)
{
    SCON  = 0x50;  //配置串口为模式1
    TMOD &= 0x0F;  //清零T1的控制位
    TMOD |= 0x20;  //配置T1为模式2
    TH1 = 256 - (11059200/12/32)/baud;  //计算T1重载值
    TL1 = TH1;     //初值等于重载值
    ET1 = 0;       //禁止T1中断
    ES  = 1;       //使能串口中断
    TR1 = 1;       //启动T1
}

/* T0中断服务函数,完成LED扫描 */
void InterruptTimer0() interrupt 1
{
    TH0 = T0RH;  //重新加载重载值
    TL0 = T0RL;
	  if(count <= SEH_count) 
    {
     
        SEH_PWM = 1;
    }
    else
    {
        SEH_PWM = 0;
    }

    
    count++;
    if (count >= 200) 
    {
        count = 0;
			
    }
	
}
/* UART中断服务函数 */
void InterruptUART() interrupt 4
{
    if (RI)  //接收到字节
    {
        RI = 0;  //手动清零接收中断标志位
        RxdByte = SBUF;  //接收到的数据保存到接收字节变量中
        SBUF = RxdByte;  //接收到的数据又直接发回,叫作-"echo",
                         //用以提示用户输入的信息是否已正确接收
    }
    if (TI)  //字节发送完毕
    {
        TI = 0;  //手动清零发送中断标志位
    }
}

你可能感兴趣的:(基于51单片机的蓝牙舵机控制超声波模块测距开发(一))