keil5开发案例分享 基于STM32设计遥控小车

发布者:创意旅程最新更新时间:2023-06-05 来源: elecfans关键字:keil5  STM32  遥控小车 手机看文章 扫描二维码
随时随地手机看文章

一、环境介绍

小车主控MCU: STM32F103ZET6


STM32程序开发IDE: keil5

STM32程序风格: 采用寄存器方式开发,注释齐全,执行效率高,方便移植

手机APP: 采用QT设计,程序支持跨平台编译运行(Android、IOS、Windows、Linux都可以编译运行,对应平台上QT的环境搭建,之前博客已经发了文章讲解)

硬件包含: 淘宝购买的完整一套4轮遥控小车(采用STM32F103ZET6作为主控板)、DHT11温湿度传感器、中科微GPS模块、ESP8266

小车完整源码下载地址:https://download.csdn.net/download/xiaolong1126626497/19557040

APP完整源码下载地址: https://download.csdn.net/download/xiaolong1126626497/19557009


二、功能介绍

这是基于STM32设计的4轮遥控小车,支持通过Android手机APP、Windows上位机完成对小车遥控;支持前进、后退、左转、右转、停止等操作。

小车上会实时采集温度、湿度、GPS经纬度、通过ESP8266 WIFI上传至手机APP,手机APP收到数据之后,会将温湿度实时显示出来,经纬度收到后会调用百度地图,显示小车的位置,并且数据也会存放到数据库里,方便查看历史数据;支持范围内温湿度查询、最高温湿度、最低温湿度查询。


小车电机驱动模块采用L298N、WIFI模块采用ESP8266、MCU采用STM32F103C8T6、温湿度模块采用DTH11、GPS模块采用北斗GPS+BDS。


poYBAGDYdXCAWkKMAAAAK8RNs4s030.pngpoYBAGDYdXCAWkKMAAAAK8RNs4s030.png


poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

三、相关硬件介绍


poYBAGDYdXCAWkKMAAAAK8RNs4s030.pngpoYBAGDYdXCAWkKMAAAAK8RNs4s030.png


poYBAGDYdXCAWkKMAAAAK8RNs4s030.png


poYBAGDYdXCAWkKMAAAAK8RNs4s030.png


四、程序源码

硬件连接说明:
GPS接的串口1: PA3(RX) --5V~3.3V
WIFI接的串口3: PB10(TX)--->接ESP8266的RX PB11(RX)--->接ESP8266的TX --3.3V
DHT11温湿度接: PA7

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png


4.1 STM32小车端: main.c源码

#include "stm32f10x.h"

#include "led.h"

#include "delay.h"

#include "key.h"

#include "usart.h"

#include 

#include "timer.h"

#include "bluetooth.h"

#include "esp8266.h"

#include "dht11.h"

#include "gps.h"

#include "motor.h"


/*

硬件连接说明:  

GPS接的串口1:   PA3(RX)   --5V~3.3V

WIFI接的串口3:  PB10(TX)--->接ESP8266的RX    PB11(RX)--->接ESP8266的TX    --3.3V

DHT11温湿度接:  PA7    

*/

u8 ESP8266_SendBuff[50];

char Buffer[1024];


int main()

{

   u32 time_cnt=0;

   double Longitude=120.086199;

   double latitude=30.139219;

   u8 temp=20;

   u8 humi=70;

    

    //延时2秒保证系统稳定

   delay_ms(1000);

   delay_ms(1000);

 

   LED_Init();

   BEEP_Init();

    

   USART1_Init(115200);  //串口调试

    

   USART2_Init(9600); //接GPS模块

   TIMER2_Init(72,20000);

    

   USART3_Init(115200);   //串口-WIFI ESP8166_01默认波特率9600  ESP8266_12F默认波特率115200

   TIMER3_Init(72,20000); //超时时间20ms

   


   printf("正在初始化请稍等.rn");


   printf("DHT11_Init:%drn",DHT11_Init());//温湿度传感器初始化

   

   printf("准备检测WIFI硬件,请稍等...rn");

    //初始化WIFI硬件

   if(ESP8266_Init())printf("WIFI硬件错误.rn");

   else

   {

       printf("WIFI设备正常....rn");

      //配置WIFI的模式   192.168.4.1

      printf("WIFI配置状态:%drn",ESP8266_AP_TCP_Server_Mode("esp8266_666","12345678",8089));

   }

   

    MotorInit();  //电机初始化


   //电机脉冲控制  

   TIMER4_Init(72,1000);

    

   while(1)

   {    

       //接收到GPS的数据

       if(USART2_RX_FLAG)

       {

           USART2_RX_BUFFER[USART2_RX_CNT]='';

           //解析经纬度

           GPS_GNRMC_Decoding((char*)USART2_RX_BUFFER,&Longitude,&latitude);

           USART2_RX_CNT=0;

           USART2_RX_FLAG=0;

           //打印到串口调试助手

           printf("GPS:%f,%frn",Longitude,latitude);

       }

       

        

        //接收到WIFI的数据

        if(USART3_RX_FLAG)

        {

            USART3_RX_BUFFER[USART3_RX_CNT]='';

            printf("WIFI:%srn",USART3_RX_BUFFER);

 

            strcpy(Buffer,(char*)USART3_RX_BUFFER);

            USART3_RX_CNT=0;

            USART3_RX_FLAG=0;

                       

            BEEP=1;

            delay_ms(50);            

            BEEP=0;

            

            if(strstr((char*)Buffer,":a"))

            {

                printf("向前...rn");

                CarGo();

            }

            else if(strstr((char*)Buffer,":b"))

            {

                 printf("后退...rn");

                CarBack();

            }

            else if(strstr((char*)Buffer,":c"))

            {

                 printf("向左...rn");

                 CarLeft();

            }

            else if(strstr((char*)Buffer,":d"))

            {

                 printf("向右...rn");

                 CarRight();

            }

            else if(strstr((char*)Buffer,":e"))

            {

                 printf("停止...rn");

                 CarStop();

            }

        }

        

       time_cnt++;

       delay_ms(10);

       

       //判断轮询时间

       if(time_cnt>=100*2)

       {

            time_cnt=0;

            //读取温湿度数据

           DHT11_Read_Data(&temp,&humi);

           

           sprintf((char*)ESP8266_SendBuff,"#%d,%d,%f,%f",temp,humi,Longitude,latitude);

           //向服务器上传数据

           ESP8266_ServerSendData(0,ESP8266_SendBuff,strlen((char*)ESP8266_SendBuff));

           

           //打印到串口调试助手

           printf("ESP8266_SendBuff:%srn",(char *)ESP8266_SendBuff);

           

           //运行状态

           Motor_LED=!Motor_LED;

       }

   }

}

 

4.2 STM32小车端: 电机控制源码

#include "motor.h"



//全局变量定义

unsigned int speed_count=0;//占空比计数器 50次一周期

int front_left_speed_duty=SPEED_DUTY;

int front_right_speed_duty=SPEED_DUTY;

int behind_left_speed_duty=SPEED_DUTY;

int behind_right_speed_duty=SPEED_DUTY;



unsigned char continue_time=0;



//根据占空比驱动电机转动

void CarMove(void)

{   

BEHIND_RIGHT_EN;

//右前轮

if(front_right_speed_duty > 0)//向前

{

if(speed_count < front_right_speed_duty)

{

FRONT_RIGHT_GO;

}else                //停止

{

FRONT_RIGHT_STOP;

}

}

else if(front_right_speed_duty < 0)//向后

{

if(speed_count < (-1)*front_right_speed_duty)

{

FRONT_RIGHT_BACK;

}else                //停止

{

FRONT_RIGHT_STOP;

}

}

else                //停止

{

FRONT_RIGHT_STOP;

}

//左后轮

if(behind_left_speed_duty > 0)//向前

{

if(speed_count < behind_left_speed_duty)

{

BEHIND_LEFT_GO;

} else                //停止

{

BEHIND_LEFT_STOP;

}

}

else if(behind_left_speed_duty < 0)//向后

{

if(speed_count < (-1)*behind_left_speed_duty)

{

BEHIND_LEFT_BACK;

} else                //停止

{

BEHIND_LEFT_STOP;

}

}

else                //停止

{

BEHIND_LEFT_STOP;

}

}



//向前

void CarGo(void)

{

front_left_speed_duty=SPEED_DUTY;

front_right_speed_duty=SPEED_DUTY;

behind_left_speed_duty=SPEED_DUTY;

behind_right_speed_duty=SPEED_DUTY;

}


//后退

void CarBack(void)

{

front_left_speed_duty=-SPEED_DUTY;

front_right_speed_duty=-SPEED_DUTY;

behind_left_speed_duty=-SPEED_DUTY;

behind_right_speed_duty=-SPEED_DUTY;

}


//向左

void CarLeft(void)

{

front_left_speed_duty=-20;

front_right_speed_duty=SPEED_DUTY;

behind_left_speed_duty=-20;

behind_right_speed_duty=SPEED_DUTY+10;//增加后轮驱动力

}


//向右

void CarRight(void)

{

front_left_speed_duty=SPEED_DUTY;

front_right_speed_duty=-20;

behind_left_speed_duty=SPEED_DUTY+10;//增加后轮驱动力

behind_right_speed_duty=-20;

}


//停止

void CarStop(void)

{

front_left_speed_duty=0;

front_right_speed_duty=0;

behind_left_speed_duty=0;

behind_right_speed_duty=0;

}




/*

FRONT_LEFT_F_PIN PG13 左前前进IO

FRONT_LEFT_B_PIN PG11 左前后退IO


FRONT_RIGHT_F_PIN PC11 右前前进IO

FRONT_RIGHT_B_PIN PD0   右前后退IO


BEHIND_LEFT_F_PIN PD6     左后前进IO

BEHIND_LEFT_B_PIN PG9     左后后退IO


右后电机的两个控制IO这里改为两路使能EN1、EN2,高电平有效

BEHIND_RIGHT_F_PIN PD4     右电机使能IO

BEHIND_RIGHT_B_PIN PD2     左电机使能IO

*/

void MotorInit(void)

{

RCC->APB2ENR|=1<<8; //PG

RCC->APB2ENR|=1<<5; //PD

    RCC->APB2ENR|=1<<4; //PC

    

    GPIOG->CRH&=0xFF0F0F0F;

    GPIOG->CRH|=0x00303030;

    

    GPIOD->CRL&=0xF0F0F0F0;

[1] [2]
关键字:keil5  STM32  遥控小车 引用地址:keil5开发案例分享 基于STM32设计遥控小车

上一篇:STM32F103控制ad7606采集程序分享
下一篇:STM32嵌入式系统设计的智能控制网络终端技术

推荐阅读最新更新时间:2024-11-12 10:39

浅谈关于STM32软硬件兼容性相关的知识
Ⅰ、写在前面 很多朋友初学STM32的时候,对STM32芯片很多相关知识都不是很了解,导致了在学习的路上很迷茫,甚至半途放弃。希望本文的内容对初学的朋友有一定帮助。 常见问题: 1.我开发板是STM32F103ZE芯片,但网上找到的软件工程基于STM32F103R8芯片的,我能直接将工程下载并调试吗? 2.我有STM32F205R8的原理图和封装库,但现在需要画STM32F405RC芯片的板子,能直接替换使用吗? 以上问题在你阅读本文之后就会得到比较明确的答案。 关于本文的更多详情请往下看。 Ⅱ、本文要点 从本文的标题可以看得出来,主要是站在“STM32兼容性”的角度来分析问题。 在开发STM32项目中,往往是软件工程师、硬件
[单片机]
浅谈关于<font color='red'>STM32</font>软硬件兼容性相关的知识
STM32 SysTick小结
SysTick简介 系统定时器,24位,只能递减,存在于内核,嵌套在 NVIC 中。其大部分内容可以查看 STM32F10xxx Cortex-M3编程手册-英文版。 SysTick工作过程 1.计数器在时钟驱动下从初值开始计数直到0。 2.为0时可以产生中断或置位 COUNTFLAG 标志位。 3.如果没有关闭,则初值再次开始计数,如此循环。 计数过程中,计数器的实时值可由 STK_VAL 位得到 SysTick寄存器 STK_CTRL 控制及状态寄存器,只有四个有效位: COUNTFLAG :如果计数器计到0,此位置1;如果软件读取这个位,这个位会置0; CLKSOURCE :时钟选择位;0=AHB/8;1=AHB
[单片机]
<font color='red'>STM32</font> SysTick小结
STM32学习笔记(五)---NVIC
F407在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和中断,其中系统异常有10个,中断有82个。 一、NVIC简介 NVIC是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。 在配置中断的时候一般只用ISER、ICER和IP这三个寄存器,ISER用来使能中断,ICER用来失能中断,IP用来设置中断的优先级。 二、中断优先级 优先级定义 NVIC有一个专门的中断优先级寄存器NVIC_IPRx,来配置外部中断的优先级,IPR宽度为8bit,原则上每个外部中断可配置的优先级为0-255,数值越小,优先级越高。 F407中只使用了高4位,bit 表达优先级的这4b
[单片机]
<font color='red'>STM32</font>学习笔记(五)---NVIC
STM32 读写内部Flash
STM32F4Discovery开发帮使用的STM32F407VGT6芯片,内部FLASH有1M之多。平时写的代码,烧写完之后还有大量的剩余。有效利用这剩余的FLASH能存储不少数据。因此研究了一下STM32F4读写内部FLASH的一些操作。 【STM32F4 内部Flash的一些信息】 STM32F407VG的内部FLASH的地址是:0x08000000,大小是0x00100000。 写FLASH的时候,如果发现写入地址的FLASH没有被擦出,数据将不会写入。FLASH的擦除操作,只能按Sector进行。不能单独擦除一个地址上的数据。因此在写数据之前需要将地址所在Sector的所有数据擦除。 在STM32F4的编程手册上可找到F
[单片机]
<font color='red'>STM32</font> 读写内部Flash
MDK软件不能模拟仿真STM32的问题解决方法
引言   MDK软件在模拟仿真时,不能很好地支持各种STM32系列芯片,目前对STM32F103系列芯片支持模拟仿真,但对于其他系列芯片不支持或只是部分支持。主要存在的问题是:PC和SP不能自动装载,存储器不能访问,中断服务程序不能执行或触发,外设寄存器不能修改或观察。要解决上述问题,必须通过相应的设置和相关的操作,才能完成模拟仿真。 1 模拟仿真的实现及PC和SP的自动装载   在MDK软件中,只有部分STM32芯片支持模拟仿真(如STM32F103),大部分芯片都不支持模拟仿真。主要的问题是,当进入调试界面后,R15 (PC)的值为0x00000000,不能进行调试操作(如单步、全速等)。要能对STM32进行模拟仿真,必须使P
[单片机]
stm32通过电调带动电机(可按键调速)
这几天在做32通过电调带动电机的实验,上网一查,发现这方面的资料很少,经过自己的亲自实践,总结出以下经验,供大家参考。 论坛上也有很多人说自己在做,但是都遇到了同样的瓶颈。我想他们大多是pwm的频率和占空比没有调到合适的值吧。 首先,我在网上只找到一片很好的文章,是瑞生大神写的:http://www.rationmcu.com/lpc1114/1126.html 我的电机是银燕2212/1400kv经典电机 ,电调也是银燕40A无刷电调。 通过它知道,当pwm设置为500hz的 时候电调才能正常的工作,刚开始时高电平时间要控制在0.7-1.9左右,让电机带电自检。 通过按键控制占空比可以很好地 实现这一点。
[单片机]
stm32之CAN发送、接收详解
CAN接收报文并过滤之标识符过滤:(重点、难点)   在CAN协议里,报文的标识符不代表节点的地址,而是跟报文的内容相关的。因此,发送者以广播的形式把报文发送给所有的接收者。节点在接收报文时-根据标识符的值-决定软件是否需要该报文;如果需要,就拷贝到SRAM里;如果不需要,报文就被丢弃且无需软件的干预。   为满足这一需求,bxCAN为应用程序提供了14个位宽可变的、可配置的过滤器组(13~0),以便只接收那些软件需要的报文。硬件过滤的做法节省了CPU开销,否则就必须由软件过滤从而占用一定的CPU开销。每个过滤器组x由2个32位寄存器,CAN_FxR0和CAN_FxR1组成。这两个寄存器用途在下面有大用处; 可变的位宽
[单片机]
<font color='red'>stm32</font>之CAN发送、接收详解
STM32定时器通道独立启停控制
在main()中 ch1_open(); delay_ms(1000); ch2_open(); delay_ms(1000); ch3_open(); delay_ms(1000); ch4_open(); delay_ms(1000); 在timer.c中添加了 //开启通道一,同时关闭通道二三四 void ch1_open(void) { TIM3- CCER|=(1 1); TIM3- CCER&=~(1 4); TIM3- CCER&=~(1 8); TIM3- CCER&=~(1 12); } //开启通道二,同时关闭通道一三四 void ch2
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved