精华内容
下载资源
问答
  • 基于STM32单片机项目设计目录-加油吧(更新完成)

    千次阅读 多人点赞 2021-08-18 19:10:14
    目录★♥基于STM32单片机项目小设计√♥※1、基于STM32的音乐喷泉2、STM32的智能浇水补光系统3、基于STM32的手机通过wifi控LED灯4、基于STM32的电子打铃器5、基于STM32的智能手环6、基于STM32的电子秤设计7、基于STM...
    展开全文
  • STM32单片机现已火遍大江南北,各种教程资料也是遍布各大网站论坛,可谓一抓一大把,但大部分都差不多。今天总结了几篇电路城上关于STM32的制作,不能说每篇都是经典,但都是在其他地方找不到的,很有学习参考意义的...
  • STM32状态机思路展示,备注详细,采用事件驱动型
  • STM32单片机PID加温项目的调试经验与代码分享 简单的叙述一下PID的加热原理 1:当目标温度接近设定温度(我设计的是相差5)开启PID运算 2:定时器1每隔2秒中产生一次PID运算(这个时间实际情况调整) 3:定时器2每隔10ms...
  • STM32单片机开发环境搭建

    千次阅读 2021-12-09 21:42:12
    进入ST官网:意法半导体STM | STM32/STM8微控制器 | MCU单片机 点击注册: 进入注册界面: 登录: 账号:18487123540 密码:13988097944why 下载芯片参考手册 到此,STMF407参考手册...

    学习过程中不能追求大而全,掌握大部分就可以。

    注册ST账号

    进入ST官网:意法半导体STM | STM32/STM8微控制器 | MCU单片机

    点击注册:

    进入注册界面:

     

     

     

     

    登录:

     

    账号:18487123540

    密码:13988097944why

    下载芯片参考手册

     

     

     

     

    到此,STMF407参考手册下载完成。

    stm32是主流的32位高性能单片机。

    stm32的特点:高性价比、内部外设丰富、高MIPS(兆指令每秒)、广大的群众基础。

    ARM Cortex M内核是arm公司设计的,st公司在此基础上,封装各种外设,做出stm32单片机。

    ch340驱动官方下载

    首页 - 南京沁恒微电子股份有限公司

     

     安装CH340驱动

    将USB线连接开发板和电脑,会听到电脑发出“咚”的声音。

    可通过上述官网下载的文件进行安装,也可以通过51单片机开发板中的资料进行下载安装。

    找到此软件,双击打开软件,点击安装即可。 

     

     

    注意:安装CH340驱动安装是不需要给单片机上电的。 

    安装mdk

    进入官网:

    Keil Embedded Development Tools for Arm, Cortex-M, Cortex-R4, 8051, C166, and 251 processor families.

     

     点击:

    选择MDK ARM:

     

    填写相关信息: 

    注册:

     

    进入邮箱获取下载链接:

     

    下载:

     

     

    下载中:

    注意:在实际下载过程中,可能由于网络问题,导致下载失败。

    也可以通过迅雷来下载,下载速度就会快很多了。

    下面以keil mdk5.36为例,进行安装演示。

     

     

    保持默认配置:

     

     

    安装中:

     

     

    直接关闭即可。

     

    此时,系统同时安装了keil4和keil mdk 5,前提是先安装keil4,然后安装keil5。能够同时开发51单片机和stm32单片机。

    keil5破解:keil5和破解软件均需要以管理员权限运行。(与keil4的破解类似)

    未激活前:

     

    破解成功: 

     

    注意:keil4软件和mdk,其实都是属于keil软件,只不过一个拿来开发51单片机,一个拿来开发STM32单片机。

    安装芯片支持器件包:安装过程中注意软件适配问题,一般各个软件选择最新版的进行安装都没有问题。

    进入官网页面:MDK5 Device List

     

     

     

     

    下载完成后,双击安装即可。

     

    安装中:

     

     

    仿真器和调试器

    • 仿真器:用来模拟硬件,可以调试硬件。
    • 调试器:用来调试CPU。
    • stm32调试接口:

    JTAG:5根线

    SWD:2根线

    • 常用调试器:

    JLINK

    STLINK:用来调试stm32和stm8。

    • 安装stlink驱动

    双击安装:

     

     

     

     

    将stlink一端插入电脑中,另外义端可以不接开发板:

    安装成功:

    实际使用过程中,使用SWD模式进行程序下载:

    stlink外形:

    引脚顺序:

     

    具体引脚定义:

     

    最终接法:对应顺序接好就行。

     

    打开keil5进行下载演示:

    以跑马灯为例:

     

    为开发板上电:

     

    此时说明已经设别到stlink。

    编译下载程序:

    烧录成功,但是程序复位不成功,需要手工按下复位按键进行复位。

    stm32的标准库和HAL库

    • 三种对STM32编程方法:

    寄存器方式:每个单片机的寄存器都是不同的,必须对寄存器的每个细节都了解到,才能写程序,容易出错。

    标准库:由CPU官方将不同单片机的寄存器的差异对开发者屏蔽了,开发者不用关心底层寄存器的细节实现,调用库函数即可。但是缺点是只是提供了内部外设的标准库。

    HAL库:集成了文件系统,LWIP协议栈等扩展功能等。也是屏蔽了底层硬件的不同。学会使用即可。HAL以用为主,不用研究其是怎么实现的。

    当然,三种方法的本质都是寄存器操作。

    标准库在弱化,HAL是未来的趋势。

    • 相关库获取

    进入官网:Home - STMicroelectronics

     

    选择工具和软件à嵌入式软件àstm32嵌入式软件

    stm32标准外设库:

     

    点击对应系列:

    这里选择F4系列:

    点击下载最新版:

     

    开始下载:

     

    安装cubemx软件

    选择工具和软件à软件开发工具àstm32软件开发工具

    往下滑动:

     

    点击cubemx进入:

     

    继续点击:

     

    下载最新版本:

     

     

    进入邮箱,点击下载:

     

    下载中:

     

    安装准备:

    安装cubemx之前需要安装一个java环境。

    双击安装: 

     

     

     

     

     

     

    保持默认配置:

    安装中:

    cubemx启动:

    设置器件包存放路径:

    点击帮助菜单中的更新设置:

    安装器件包(又叫芯片补丁包):

    点击帮助菜单中的管理嵌入式软件包选项:

    安装中:

    安装完成:

    展开全文
  • STM32单片机的编程也是一样的,虽然支持汇编,但基本上没有人用,STM32程序都是基于C语言编程的。 编程序代码可读性差,不方便移植,所以逐步的被淘汰,单片机目前基本上都是支持C语言程序编程。 如何学习STM32...

    在大学刚开始接触51单片机的时候,我们学习的都是汇编指令,再到后来学习了C语言,用C语言代替汇编指令来开发编程单片机。

    STM32单片机的编程也是一样的,虽然支持汇编,但基本上没有人用,STM32程序都是基于C语言编程的。

    编程序代码可读性差,不方便移植,所以逐步的被淘汰,单片机目前基本上都是支持C语言程序编程。

    如何学习STM32单片机开发?

    1. 选择一款合适的开发板

    想学好单片机,我们拥有一个开发板是必不可少的,单片机开发学习最要紧的就是要实操,配套开发板学习,很多程序代码通过开发板来验证,才能找到程序编程的感觉和兴趣。

    STM32单片机,我们推荐大家选择从STM32F103开始学习,性价比高,应用比较广。

    当然,我更倾向于通过项目去学习STM32,通过项目可以一步到位,如果通过开发板学习,你会发下,学完以后还是不知道怎么做项目。

    无际单片机编程提供的STM32实战项目学习,通过项目实战学习单片机开发可以帮助大家更高效的学习并掌握单片机编程开发。

    2.搭建开发环境

    STM32单片机开发学习的第一件事情,就是要搭建单片机的开发环境。

    STM32单片机最常用的开发环境有Keil和IAR,两个各有优势,目前选择使用Keil的人更多一点,所以Keil更通用,也推荐大家使用Keil软件。

    Keil软件有多个版本,包括Keil C51,KeilMDK等,STM32单片机需要安装KeilMDK版本,正式版本是需要收费的,如果大家是学习,大家可以在网上搜索Keil注册机破解。

    除了安装Keil,还需要下载并安装STM32F10x_StdPeriph_Lib_V3.5.0,STM32单片机编程用到的库文件都来自这个文件。

    关于软件的安装,在这里就给大家不介绍了,网上有大把的资料。

    搭建好Keil开发环境之后,还需要掌握STM32单片机的烧录。

    关于STM32单片机程序的烧录有三种方式:分别是ST-Link,J-Link和ISP(串口下载.)

    如果是长时间开发使用,建议大家选择ST-Link,ST-Link不仅可以下载程序,也可以方便大家调试仿真,使用非常方便。

    ST-Link烧录工具,某宝上大把,我们可以选择价格比较合适的购买即可,不过一般开发板都会自带ST-Link烧录工具,不需要大家重新购买。

    3.收集开发资料

    “STM32 参考手册”、“Cortex-M3 权威指南”、“STM32 不完全手册-库函数版本”这三个资料是STM32单片机最官方,最权威的资料,而且以上的资料都是有中文版本的。 大家在初学阶段,要学会参看和利用这些资料。

    这些资料网上大把的,大家百度直接可以下载就可以了,少啰嗦,我们直接开始动手学习STM32单片机,直接在开发板上实战学习STM32单片机的实验。

    4.动手开始学习STM32单片机

    学习板一般会带配套的学习教程,我们跟着开发板的教程学习就可以。

    刚开始学习的时候做的第一个实验就是点亮第一个LED灯,这个小实验的代码量比较小,也可以让大家动手实现单片机编程,并达到实验效果的感觉还是特别激动的。

    单片机的学习碰到问题如果不能解决,容易产生枯燥,烦躁,不耐烦的情绪,大家一定要多点耐心,学习一定是通过我们不断努力积累的。

    5.掌握调试技巧

    刚开始敲代码实战的时候,编译经常会出现很多错误和警号,我们要学会处理这些警号和错误的能力。

    处理程序编译的时候提示错误和警号是STM32单片机程序编程必须要掌握的技能之一,最常用的方法有:

    ①双击编译提示的错误语句,程序会自动的跳转到错误处,然后再跳转的地方的前后查找问题

    ②刚开始写代码,最常见的错误包括:大括号不对应,语句的后面忘记写分号,分号写成了中文格式,函数未声明,变量未定义等。

    ③对于一些不能处理的警号或错误,可以复制错误提示,然后百度,大多数的错误都可以通过这个方法处理

    有时候我们写的代码,没有错误和警号,但就是不能实现功能,这个时候我们就需要通过单片机的仿真功能来寻找代码的问题。

    成为高手,就是不断看,不断改,然后再自己重写的过程。

    展开全文
  • 基于STM32F103单片机智能电表交流电压电流设计 包含: 实物图 原理图 源程序 模块框图 ElectricEnergyMeter_STM32_986-V2.0.1
  • 其余硬件设备均固定到机器人底盘上,包括电池座、红外避障传感器、wifi模块、摄像头、STM32单片机主控模块和L298N电机驱动芯片。机器人底盘俯视图示意图如图: 【4】系统硬件设计 硬件系统主要由 单片机主控...

    【1】背景意义

    近些年随着国民生活水平的提升,以小车为载体的轮式机器人进入了我们的生活,尤其是在一些布线复杂困难的安全生活区和需要监控的施工作业场合都必须依赖轮式机器人的视频监控技术。因此,基于嵌入式技术的无线通信视频监控轮式机器人应运而生。由于它们与人类工作相比具有成本低廉、安全稳定的优点,目前已经在许多危险作业以及工业场合得到了广泛应用而且轮式机器人不需要像人那样采取过多的保护措施,因此轮式机器人更适合在危险困难的工作环境中工作。然而轮式机器人在行驶中所能碰到的障碍很多,例如前部凸出物的碰触,后部凸出物的拖托,中部凸出物的顶举,特别还有垂直障碍和壕沟等,所以必须对轮式机器人的越障问题进行研究来解决类似问题。

    针对复杂地形环境的巡检作业,设计一种基于wifi视频监控的智能小车。基于STM32F103主控板搭建智能小车的控制系统,并采用模块化的设计思想编写控制系统程序,为能够在复杂地形下进行巡检作业的轮式机器人研究提供理论依据。

    【2】总设计方案

    本课题利用STM32作为智能小车的主控制器来驱动智能小车的直流电机工作,电机驱动芯片采用L298N微型集成电路电机驱动芯片,配合STM32核心板使用实现四个直流电机运行和pwm软件调速,通过改变直流电机占空比的电压来改变平均电压的数值,从而改变电机的转速变化来驱动轮式机器人运行。轮式机器人行驶的状态有:前进、后退、左转、右转和停止。当轮式机器人在行驶过程中遇到障碍物,红外避障检测模块检测周围障碍物,轮式机器人自动停止或转向。通过WIFI无线信号作为传输媒介,以上位机或手机作为控制端来控制机器人的运动以及将摄像头所拍摄的视频信息在控制端界面中显示,这样便可观察轮式机器人周围的环境并对机器人进行实时监控。主要设计步骤有:

    (1)根据提出方案的功能需求对智能小车进行结构设计。
    (2)根据主控制器的基本结构和特点,设计总体硬件电路模块。总体硬件电路模块的设计包括电机驱动电路设计、红外避障电路设计、无线传输电路设计等。
    (3)选择符合系统设计需求的系统软件,并在该软件的基础上编写驱动代码和应用软件代码。针对系统功能的具体要求,从系统信号稳定传输的角度出发,对电机驱动、调速、无线路由器系统的改造、视频信息的接受与发送、红外避障模块的改造和控制端界面的设计等进行详细的分析与设计,并完成代码的编写与调试。
    (4)把硬件开发板和软件平台结合起来,对视频监控智能小车整个系统进行了整体测试。对测试中出现的问题进行相关的改进工作,进一步提高系统工作的可靠性和稳定性。

    【3】结构设计

    根据提出方案的功能需求,对轮式机器人的整体结构进行设计,采用双面覆铜加硬的PCB板料作为轮式机器人的底盘,其优点是:不易变形、不易折断、轻量化、不易造成短路;选用抗干扰TT马达,其加入压敏抗组的转子可抵抗电机突然启动产生的火花干扰,避免触发信号错误,可有效降低马达启动噪音,并在启动时可提供更大电流,使马力更强;使用航模级抗滑橡胶轮胎内带海绵表面平整不易变形,在避障行走时刹车不易撞上障碍物。马达用马达锁片固定到机器人底盘上,轮子通过轴与马达相连。
    在这里插入图片描述在这里插入图片描述
    其余硬件设备均固定到机器人底盘上,包括电池座、红外避障传感器、wifi模块、摄像头、STM32单片机主控模块和L298N电机驱动芯片。机器人底盘俯视图示意图如图:
    在这里插入图片描述

    【4】系统硬件设计

    硬件系统主要由单片机主控模块、电源模块、电机驱动模块、红外避障模块控制终端模块和无线视频监控模块组成。硬件系统框图如图:
    在这里插入图片描述
    (1)主控模块
    主控模块采用STM32F103为主控制器,STM32F103属于中低端的32位ARM微控制器,该系列芯片是意法半导体(ST)公司出品,其内核是Cortex-M3。该系列芯片按片内Flash的大小可分为三大类:小容量(16K和32K)、中容量(64K和128K)、大容量(256K、384K和512K)。芯片集成定时器,CAN,ADC,SPI,I2C,USB,UART,等多种功能。STM32F103可使用keil C语言编译,支持STLink-SWD在线调试,主要用于收集信息、处理数据、协调系统中的每个功能模块预计要完成的任务。在这里插入图片描述
    (2)电源模块
    电源模块在机器人的运行过程中,需要给单片机、电机、各大模块及传感器供电。为了保证系统的可靠供电,所以选择可充电的18650锂电池,如图3.5所示。**18650是锂离子电池的鼻祖–日本SONY公司当年为了节省成本而定下的一种标准性的锂离子电池型号,其中18表示直径为18mm,65表示长度为65mm,0表示为圆柱形电池。**常见的18650电池分为锂离子电池、磷酸铁锂电池。锂离子电池电压为标称电压为3.7v,充电截止电压为4.2v,磷酸铁锂电池标称电压为3.2V,充电截止电压为3.6v容量通常为1200mAh-3350mAh,常见容量是2200mAh-2600mAh。
    在这里插入图片描述
    (3)电机驱动模块
    电机驱动模块采用L298N为电机驱动芯片,其原理图如图3.6所示。L298N是ST公司生产的一种高电压、大电流电机驱动芯片。该芯片采用15脚封装。主要特点是:工作电压高,最高工作电压可达46V;输出电流大,瞬间峰值电流可达3A,持续工作电流为2A;额定功率25W。内含两个H桥高电压大电流全桥式驱动器,可以用来驱动直流电动机和步进电动机、继电器线圈等感性负载;采用标准逻辑电平信号控制;具有两个使能控制端,在不受输入信号影响的情况下允许或禁止器件工作有一个逻辑电源输入端,使内部逻辑电路部分在低电压下工作;可以外接检测电阻, 将变化量反馈给控制电路。使用L298N芯片驱动电机,该芯片可以驱动一台两相步进电机或四相步进电机,也可以驱动两台直流电机,并联时可以驱动四台电机。此次研究将L298N配合STM32核心板无缝对插使用,实现无损扩展并对四个马达进行驱动和PWM调速。

    在这里插入图片描述
    (4)红外避障模
    红外避障模块选用不怕光的HJ-IR2传感器,如图3.7所示,它相当于一个红外电子开关,检测到障碍输出低电平,一般情况下为高电平。当前方有障碍物时,红外管发出的红外信号经红外接收管接收回来后,经集成的芯片放大,比较后,输出一低电平,点亮模块上的LED发光管,同时可以输出一个低平信号,信号可以作为单片机的信号输入检测控制外部各种驱动模块之用。HJ-IR2传感器具有模块三线制的特点,VCC为电源+5V,OUT为信号输出端,GND接电源负极。探测距离大概为1~30CM(探测距离的长短和供电电压、 电流还有周围环境有关)。工作电压为5V,工作电流为18-30ma左右。
    在这里插入图片描述
    (5)控制终端模块
    控制终端模块有PC上位机和安卓手机两种,两种控制界面都能实现对于智能小车的各种运动状态的控制。

    (6)无线视频监控模块
    本模块采用720p高清USB摄像头,可以对轮式机器人的运动状态以及周围环境进行视频采集,然后将采集的视频数据通过无线信号返回到控制界面显示,以达到实时监控的目的。**USB接口是目前应用比较广泛的一种接口模式,几乎所有的产品都能支持,即插即用,具有强大的扩充能力,用起来十分方便。**依靠USB连接无线路由器获得的电压就能否满足摄像头正常工作需求的电压,这样就不用再接外部电压,使得电路设计更加简单方便。USB摄像头虽然在采集动态画面与成像清晰度上仍然无法与接口摄像头相比,但是其接口简单,即插即用,己经成为设计者的首选。本模块主要是用来完成轮式机器人与各个控制界面之间的通信,由于机器人移动性的特点,所以系统选用无线通信进行数据传输。无线通信的实现主要由无线路由器实现,通过无线路由器可以搭建一个局域网,并且在这局域网的基础上可以运行多种底层协议。控制终端与轮式机器人进行信号的控制和交互就是采用这种传输模式。首先运行于控制终端的网络程序通过局域网与轮式机器人建立起连接,待连接建立成功后,用户就可以使用控制终端的用户界面软件向轮式机器人发送各种控制指令和获取摄像头视频信息等数据。本系统设计将数字摄像头的驱动加载在无线路由器固件当中,当主控制器发出采集视频指令,摄像头开始工作。

    【5】系统软件设计

    软件的设计包括:主程序的设计、电机驱动程序设计、红外循障程序设计、视频采集程序设计、无线数据传输程序设计

    (1)电机驱动程序
    电机的驱动主要是对L298N驱动芯片的操作,运用PWM调速方法完成对电机进行驱动控制。脉冲宽度调制(PWM),简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。PWM波的产生可以通过时钟频率、自动重装值等参数进行设置,从而调节PWM波的占空比和输出频率,即对脉冲宽度的控制,PWM原理如图:

    在这里插入图片描述

    由图我们先假定定时器工作正处于向上计数PWM模式,且当CNT小于CCRx 时,输出0,当CNT大于等于CCRx 时输出 1。那么就可以得到如上的PWM示意图:当CNT值小于CCRx的时候,IO输出低电平(0),当CNT值大于等于CCRx的时候,IO输出高电平(1),当CNT达到ARR值的时候,重新归零,然后重新向上计数,依次循环改变CCRx的值,就可以改变PWM输出的占空比,改变ARR的值,就可以改变PWM输出的频率,这就是PWM输出的原理。由此可知PWM 技术就是把直流电压斩成一系列脉冲,通过改变脉冲的占空比获得所需的输出电压。

    由图L298N芯片的原理图,引脚A,B可用于输入PWM脉宽调制信号对电机进行调速控制。如果无须调速可将两引脚接5V,使电机工作在最高速状态,既将短接帽短接。假设驱动的两台直流电机分别为M1和M2,当输入信号端IN1接高电平输入端IN2接低电平时,电机M1正转。当信号端IN1接低电平,IN2接高电平,电机M1反转。控制另一台电机是同样的方式,输入信号端IN3接高电平,输入端IN4接低电平,电机M2正转(反之则反转)。PWM信号端A控制M1调速,PWM信号端B控制M2调速 。可通过单片机IO口状态来控制小车运行,电机具体运行方式如图

    在这里插入图片描述
    电机驱动程序使用了单片机定时器的PWM功能,通过输出频率及占空比可变的PWM波来驱动电机。具体实现方法为:首先,使能定时器和相关IO口时钟。其次,对定时器进行初始化并设置其自动重转载值和预分频值,将计数模式设置为向上计数模式。最后,再使能预装载寄存器,使能定时器,通过改变比较值CCRX,达到不同的占空比效果。智能小车电机驱动程序流程图如图所示(以M1为例):
    在这里插入图片描述

    电机驱动部分代码

    
    
    /*电机宏定义*/
    #define left1on GPIO_SetBits(GPIOD,GPIO_Pin_6)
    #define left1off GPIO_ResetBits(GPIOD,GPIO_Pin_6)
    
    #define left2on GPIO_SetBits(GPIOG,GPIO_Pin_9)
    #define left2off GPIO_ResetBits(GPIOG,GPIO_Pin_9)
    
    #define right1on GPIO_SetBits(GPIOC,GPIO_Pin_11)
    #define right1off GPIO_ResetBits(GPIOC,GPIO_Pin_11)
    
    #define right2on GPIO_SetBits(GPIOD,GPIO_Pin_0)
    #define right2off GPIO_ResetBits(GPIOD,GPIO_Pin_0)
    
    
    extern volatile u32 time;
    u8 start=0;
    u16 time1,time2;
    volatile u8 motor0_angel=90,motor1_angel=90,motor2_angel=90,motor3_angel=90,motor4_angel=90,motor5_angel=90;
    
    void TIM2_IRQHandler(void)
    {
    	if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET ) 
    	{	
    		TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);  
    		time1++;
    		time2++;
    		if(time1==50)
    		{  
    			time1=0;
    	  		time++;
    			if(time>9)
    				time=0;
    			if(ina1>time)
    				left1on;
    			else 	
    				left1off;
    			if(ina2>time)
    				left2on;
    			else 	
    				left2off;
    			if(inb1>time)
    				right1on;
    			else 	
    				right1off;
    			if(inb2>time)
    				right2on;
    			else 	
    				right2off;
    		}
    		if(time2>1818)
    			time2=0;
    		if(time2<motor0)
    			motor0on;
    		else
    			motor0off;
    		if(time2<motor1)
    			motor1on;
    		else
    			motor1off;
    		if(time2<motor2)
    			motor2on;
    		else
    			motor2off;
    		if(time2<motor3)
    			motor3on;
    		else
    			motor3off;
    		if(time2<motor4)
    			motor4on;
    		else
    			motor4off;
    		if(time2<motor5)
    			motor5on;
    		else
    			motor5off;
    	}		 	
    }
    
    void USART3_IRQHandler(void)
    {
    	unsigned char rec_data;
    	if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
    	{
    		USART_ClearITPendingBit(USART3, USART_IT_RXNE);
    		/* Read one byte from the receive data register */
    		rec_data = USART_ReceiveData(USART3);
    		if(start!=0&&rec_data!=0xff)						//如果已收到包头并且当前收到的不是包尾
    		{
    			buf[start-1]=rec_data;							//缓存数据
    			start++;
    		}
    		else if(start!=0&&rec_data==0xff)					//如果收到包尾
    		{
    			mode[0]=buf[0];									//给状态存储数组赋值
    			mode[1]=buf[1];
    			mode[2]=buf[2];
    			start=0;
    			mode1=1;										//指示主函数循环检测一次
    		}
    		else if(rec_data==0xff&&start==0)					//如果收到的是包头
    			start++;	
    	}
    }
    
    void dianji(u8 i)
    {
    	switch(i)
    	{
    		case 1:					   //前进
    		speed_right=4;
    		speed_left=4;
    		break;
    
    		case 2:					   //后退
    		speed_right=-4;
    		speed_left=-4;
    		break;
    
    		case 3:					   //左转
    		speed_right=-2;
    		speed_left=4;
    		break;
    
    		case 4:					   //右转
    		speed_right=4;
    		speed_left=-2;
    		break;
    
    		case 0:					   //停止
    		speed_right=0;
    		speed_left=0;
    		break;
    
    		case 5:					   //左前
    		speed_right=2;
    		speed_left=5;
    		break;
    
    		case 6:					   //右前
    		speed_right=5;
    		speed_left=1;
    		break;
    
    		case 7:					   //左后
    		speed_right=-2;
    		speed_left=-5;
    		break;
    
    		case 8:					   //右后
    		speed_right=-5;
    		speed_left=-2;
    		break;
    	}
    }
    
    
    

    舵机程序:

    /*舵机宏定义*/
    #define motor0on GPIO_SetBits(GPIOA,GPIO_Pin_0)
    #define motor0off GPIO_ResetBits(GPIOA,GPIO_Pin_0)
    
    #define motor1on GPIO_SetBits(GPIOA,GPIO_Pin_1)
    #define motor1off GPIO_ResetBits(GPIOA,GPIO_Pin_1)
    
    #define motor2on GPIO_SetBits(GPIOA,GPIO_Pin_2)
    #define motor2off GPIO_ResetBits(GPIOA,GPIO_Pin_2)
    
    #define motor3on GPIO_SetBits(GPIOF,GPIO_Pin_8)
    #define motor3off GPIO_ResetBits(GPIOF,GPIO_Pin_8)
    
    #define motor4on GPIO_SetBits(GPIOF,GPIO_Pin_9)
    #define motor4off GPIO_ResetBits(GPIOF,GPIO_Pin_9)
    
    #define motor5on GPIO_SetBits(GPIOF,GPIO_Pin_10)
    #define motor5off GPIO_ResetBits(GPIOF,GPIO_Pin_10)
    
    void duoji(u8 i)
    {
    	if(mode[2]>180)
    		mode[2]=180;
    	switch(i)
    	{
    		case 1:					   
    		motor0_angel=mode[2];				  //取角度
    		break;
    
    		case 2:					   
    		motor1_angel=mode[2];		
    		break;
    
    		case 3:					
    		motor2_angel=mode[2];		   
    		break;
    
    		case 4:					   
    		motor3_angel=mode[2];		
    		break;
    
    		case 5:					   
    		motor4_angel=mode[2];		
    		break;
    
    		case 6:					   
    		motor5_angel=mode[2];		
    		break;
    	}
    }
    

    中断部分:

    void USART3Conf(u32 baudRate)
    {
    	NVIC_InitTypeDef 	NVIC_InitStruct;//定义一个设置中断的结构体	
    	USART_InitTypeDef USART_InitSturct;//定义串口1的初始化结构体
    	GPIO_InitTypeDef GPIO_InitStruct;//定义串口对应管脚的结构体
    
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3 , ENABLE);//打开串口管脚时钟
    	//USART3_Tx_Pin Configure 
    	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;//输出引脚
    	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;//设置最高速度50MHz
    	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//推挽复用输出
    	GPIO_Init(GPIOB , &GPIO_InitStruct);//将初始化好的结构体装入寄存器
    
    //USART3_Rx_Pin Configure
      GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//GPIO模式悬浮输入
      GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;//输入引脚
      GPIO_Init(GPIOB, &GPIO_InitStruct);//将初始化好的结构体装入寄存器
    
    //USART3 Configure	
    	USART_InitSturct.USART_BaudRate = baudRate;//波特率9600
    	USART_InitSturct.USART_WordLength = USART_WordLength_8b;//数据宽度8位
    	USART_InitSturct.USART_StopBits = USART_StopBits_1;//一个停止位
    	USART_InitSturct.USART_Parity = USART_Parity_No;//无奇偶校验
    	USART_InitSturct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    	USART_InitSturct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//使能发送与接收
    	USART_Init(USART3 , &USART_InitSturct);//将初始化好的结构体装入寄存器	
    	//USART1_INT Configure
    	USART_ITConfig(USART3 , USART_IT_RXNE , ENABLE);//使能接收中断
    //	USART_ITConfig(USART3 , USART_IT_TXE , ENABLE);
    	USART_Cmd(USART3 , ENABLE);//打开串口
    	USART_ClearFlag(USART3 , USART_FLAG_TC);//解决第一个数据发送失败的问题
    	
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    	NVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn;
    	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
    	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
    	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//打开该中断
    	NVIC_Init(&NVIC_InitStruct);
    	
    }
    

    (2)红外避障控制程序
    红外避障模块选用的红外避障传感器由发射管与接收管组成的,发射管发射红外线,当检测到障碍物时,接收管接受到红外线反射信号,经过比较器后,输出一个低电平信号送给单片机利用物体的反射性质,在一定范围内,如果没有障碍物,发射出去的红外线,因为传播距离越远而逐渐减弱,最后消失;如果有障碍物,红外线遇到障碍物,被反射到达传感器接收头,传感器检测到这一信号,就可以确认正前方有障碍物,并送给单片机,单片机进行一系列的处理分析,协调小车两轮工作,完成一个躲避障碍物动作。红外避障的控制程序的基本原理为首先检测是否有障碍物。当检测到有障碍物时,判断是做左边的传感器检测都到的还是右边的传感器检测到的,若是左边,则小车需先后退,然后右转。如过是右边的传感器检测到的,则小车应该先后退再左转。其算法流程图如图所示:

    在这里插入图片描述

    //GPIOÅäÖú¯Êý
    void MotorGPIO_Configuration(void)
    {		
    	GPIO_InitTypeDef GPIO_InitStructure;
    	GPIO_InitStructure.GPIO_Pin = FRONT_LEFT_F_PIN;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 	
    	GPIO_Init(FRONT_LEFT_F_GPIO, &GPIO_InitStructure);    
    	
    	GPIO_InitStructure.GPIO_Pin = FRONT_LEFT_B_PIN;	
    	GPIO_Init(FRONT_LEFT_B_GPIO, &GPIO_InitStructure); 
    	
    	GPIO_InitStructure.GPIO_Pin = FRONT_RIGHT_F_PIN;	
    	GPIO_Init(FRONT_RIGHT_F_GPIO, &GPIO_InitStructure); 
    	
    	GPIO_InitStructure.GPIO_Pin = FRONT_RIGHT_B_PIN;	
    	GPIO_Init(FRONT_RIGHT_B_GPIO, &GPIO_InitStructure); 
    	
    	GPIO_InitStructure.GPIO_Pin = BEHIND_LEFT_F_PIN;	
    	GPIO_Init(BEHIND_LEFT_F_GPIO, &GPIO_InitStructure);  
    	
    	GPIO_InitStructure.GPIO_Pin = BEHIND_LEFT_B_PIN;	
    	GPIO_Init(BEHIND_LEFT_B_GPIO, &GPIO_InitStructure);  
    	
    	GPIO_InitStructure.GPIO_Pin = BEHIND_RIGHT_F_PIN;	
    	GPIO_Init(BEHIND_RIGHT_F_GPIO, &GPIO_InitStructure);  
    	
    	GPIO_InitStructure.GPIO_Pin = BEHIND_RIGHT_B_PIN;	
    	GPIO_Init(BEHIND_RIGHT_B_GPIO, &GPIO_InitStructure);  
    	
    }
    
    //¸ù¾ÝÕ¼¿Õ±ÈÇý¶¯µç»úת¶¯
    void CarMove(void)
    {   
    	
    	 BEHIND_RIGHT_EN;
    	
     /* //×óÇ°ÂÖ
    	if(front_left_speed_duty > 0)//ÏòÇ°
    	{
    		if(speed_count < front_left_speed_duty)
    		{
    			FRONT_LEFT_GO;
    		}else
    		{
    			FRONT_LEFT_STOP;
    		}
    	}
    	else if(front_left_speed_duty < 0)//Ïòºó
    	{
    		if(speed_count < (-1)*front_left_speed_duty)
    		{
    			FRONT_LEFT_BACK;
    		}else
    		{
    			FRONT_LEFT_STOP;
    		}
    	}
    	else                //Í£Ö¹
    	{
    		FRONT_LEFT_STOP;
    	}*/
    	
    		//ÓÒÇ°ÂÖ
    	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;
    	}
    	
    /*		//ÓÒºóÂÖ
    	if(behind_right_speed_duty > 0)//ÏòÇ°
    	{
    		if(speed_count < behind_right_speed_duty)
    		{
    			BEHIND_RIGHT_GO;
    		}	else                //Í£Ö¹
    		{
    			BEHIND_RIGHT_STOP;
    		}
    	}
    	else if(behind_right_speed_duty < 0)//Ïòºó
    	{
    		if(speed_count < (-1)*behind_right_speed_duty)
    		{
    			BEHIND_RIGHT_BACK;
    		}	else                //Í£Ö¹
    		{
    			BEHIND_RIGHT_STOP;
    		}
    	}
    	else                //Í£Ö¹
    	{
    		BEHIND_RIGHT_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;
    }
    
    void MotorInit(void)
    {
    	MotorGPIO_Configuration();
    	CarStop();
    }
    
    
    

    (3)无线视频采集程序
    摄像头的工作原理其实就是将光学信号转换电信号的过程,通过图像传感器将物镜转换为电信号,然后再经过A/D转换成数字图像信号,最后将数字图像信号发送给摄像头内部DSP(数字信号处理)处理芯片进程处理。本系统设计将数字摄像头的驱动加载在无线路由器固件当中,当主控制器发出采集视频指令,摄像头开始工作,并将釆集回来的视频信息通过TCP协议利用WIFI无线路由器连接的信号发送到显示界面显示出来无线视频采集程序流程图如图所示:

    在这里插入图片描述
    (4)主程序
    系统主程序主要完成子程序调用和各种初始化操作,首先系统上电后,启动初始化程序,判断有无避障中断发送,发生避障中断时,执行避障子程序。执行完子程序后,发送电机控制信号。主程序流程图如图:
    在这里插入图片描述

    int main(void)
    {
    	/* 配置系统时钟为 72M */  
    	SystemInit();	
    	/* led 端口配置 */ 
    	ALL_GPIO_Config();	
    	/*usart3 串口配置 */
    	USART3Conf(9600);
    	TIM2_NVIC_Configuration();
    	//NVIC_Configuration();
    	TIM2_Configuration();	
    	/* TIM2 开始计时 */
    	START_TIME;	
    	while(1)
    	{
    		if(mode1==1)						//每次收到指令执行一次
    		{
    			mode1=0;
    			if(mode[0]==0)					//判断操作对象
    				dianji(mode[1]);
    			else if(mode[0]==1)
    				duoji(mode[1]);
    			else if(mode[0]>=2&&mode[0]<=4)
    				other(mode[0]);
    		}
    	}
    }
    /*************************************************************************************
    协议规定:
    包头   类型位  数据位   数据位    结束位
    0XFF   0X**     OX**    0X**      0XFF
    
    各命令说明:
    类型位    数据位   数据位    功能
    0X00       0X01      0X00    前进
    0X00       0X02      0X00    后退
    0X00       0X03      0X00    左转
    0X00       0X04      0X00    右转
    0X00       0X00      0X00    停止
    0X00       0X05      0X00    左前
    0X00       0X06      0X00    右前
    0X00       0X07      0X00    左后
    0X00       0X08      0X00    右后
    
    0X01       0X01      角度    舵机1
    0X01       0X02       .      舵机2
    0X01       0X03       .      舵机3
    0X01       0X04       .      舵机4
    0X01       0X05       .      舵机5
    0X01       0X06       .      舵机6
    
    
    0X02       0X00      0X00    车灯亮
    0X02       0X01      0X00    车灯灭
    
    0X03       0X00      0X00    喇叭开
    0X03       0X01      0X00    喇叭关
    
    0X04       0X00      0X00   自定义开
    0X04       0X01      0X00   自定义关
    *****************************************************/
    

    【6】实现效果

    运用STM32F103 单片机为控制器,采用 C 语言在Keil 软件进行编程,来控制小车则完成前进、后退、左拐、右拐等动作。实现由红外传感器来检测信号,将检测到的信号送到单片机,由单片机处理后控制小车的行驶状态。实现由视频监控模块对轮式机器人的运动状态以及周围环境进行视频采集,然后将采集的视频数据通过无线信号返回到控制界面显示,以达到实时监控的目的。实现由无线路由模块来完成智能小车与各个控制界面之间的通信。最终实现了一个集视频监控、自动避障、wifi控制等功能于一体的智能小车控制系统系统。
    在这里插入图片描述

    展开全文
  • STM32单片机+音乐灯

    2020-02-27 16:05:45
    最近用STM32单片机做了一个音乐灯,灯的亮灭强度随着音乐播放的高低变化,晚上放自己的车上效果挺好的。 最近用STM32单片机做了一个音乐灯,灯的亮灭强度随着音乐播放的高低变化,晚上放自己的车上效果挺好的。
  • 出自某校博士,充电管理,电压电流管理,速度电流双闭环,室内地图创建和使用,防撞保护。总体写的不错,有可借鉴之处。
  • 最近工作中的项目需要LCD显示二维码,目前的需求较为简单,只需要显示一个二维码演示功能。短期内由上位机提供图片内容,所以单片机只需要...上传的工程是单片机STM32ZET6用红牛开发板显示的,工程用MDK4.72编译OK。
  • 基于STM32F407ZGT6开发的一款单片机程序,实现了按键和红外遥控的双重控制,配套正点原子的探索者开发板可不用修改直接使用。程序中贪吃蛇的难易程度分为三种,可供用户选择使用。
  • 小小的单片机实践项目,对于做毕设的可能有些帮助,如果需要其他资源请留言
  • 基于STM32F103单片机的liteos移植项目keil5,包含完整项目,打开即用,需要安装keil5以及STM32F103程序包
  • 经过前两章节对STM32的简单介绍,在接下来的几个章节中开始进行STM32单片机的软件开发实践,所使用到的工具有Keil5、STM32CubeMX以及串口软件。对于STM32F1系列的单片机,其存储器有4GB的空间,包含了程序存储器、...
  • 基于STM32单片机的精彩设计实例合集

    万次阅读 多人点赞 2018-09-18 21:35:28
    STM32系列给MCU用户带来了... stm32的学习资料多是零零散散的,电路城先将stm32资料做了一个整合,也将于STM32单片机的精彩设计实例做了一个汇总,适合新手迅速上手,也适合高手做创作。 1、(毕设)基于STM32多功能M...
  • STM32单片机在线升级设计及实现.pdf
  • STM32单片机开发

    2019-02-28 11:52:35
    关于工业制碱项目程序的开发,使用STM32嵌入式单片机开发。
  • 基于STM32系列单片机的智能清扫机器人的设计 该项目包括原理图电路图 程序源码 演示视频讲解文档全套资料 三分拿去 超值了
  • 关于STM32单片机本人在半年前就已初步接触并已经实现了一个以矩阵键盘为输入源的简易计算器小项目,但觉得先前学得过浅,于是这个假期重新从计算机原理及单片机原理开始学习,一个小阶段下来收获颇丰,经过复盘,...
  • stm32单片机学习秘籍(完整版)

    千次阅读 2021-12-10 15:10:41
    大家好,我是华维麦琪,今天来分享下我们华维团队十年经验总结,如何能快速学好stm32单片机
  • 本文主要针对STM32项目中在USART、调试及编程中遇到的问题进行了描述并给出了相应的解决办法。
  • 该系统利用STM32的RTC功能显示指针盘式时钟,可现实秒,分,小时,周和日期年份。LCD彩屏实时显示钟表转盘,并有指示灯指示。
  • STM32单片机WS2812B驱动程序灯效程序

    热门讨论 2017-06-06 17:13:31
    代码主要是基于stm32开发,包括两路ws2812b初始化代码,以及呼吸灯、跑马灯、彩虹灯等灯效程序,均是用pwm+dma的方式发送数据,不占用内存,本程序已用在项目中,可稳定运行。
  • 万物互联-stm32单片机简介、烧录、编程 前言:stm32单片机这里给出简单介绍,给不了解的朋友普及下硬件端的基本知识,叙述的较为简单,想深入研究的朋友可以去一些官方网站、论坛、博客汲取知识。最下端会给出几个...
  • 易上手的STM32项目(22个)

    万次阅读 多人点赞 2021-05-30 19:50:15
    1、(大赛作品)STM32F072RB NUCLEO智能家居控制.zip 2、STM32数字示波器源码+数字信号处理教程、配套实例.zip 3、低功耗STM32F411开发板(原理图+ PCB源文件+官方例程+驱动等) .zip 4、基于stm32 nucleo_ L476的智能灯...
  • 为有效预防和监控电动车充电桩的实际应用环境中的火灾情况,文章设计了一种以STM32F103C8T6单片机平台为核心,通过系统处理显示具体环境,当传感器模块获得的信息值超过系统设定的安全阈值,驱动模块会通过液晶显示屏...
  • 学习STM32单片机,从菜鸟到牛人就是这样简单

    万次阅读 多人点赞 2017-11-29 11:09:34
    我想说,为了学习单片机而去学习单片机的思路不对。  你问,如何系统地入门学习stm32?  本身就是一个错误的问题。假如你会使用8051 , 会写C语言,那么STM32本身并不需要刻意的学习。  你要考虑的是, 我可以...
  • STM32项目快递存取柜

    2020-10-11 15:44:37
    快递存取柜项目是基于STM32实现的,所用模块如下: STM32F103ZE最小开发板 OV7670摄像头 GSM模块(sim900a) 16路PWM(PCF8574) 5个舵机(可增加) WIFI模块(ESP8266) MP3模块(VS1053) SD卡 触摸屏(R61509V)
  • keil平台用c语言编写的基于stm32的模拟交通灯项目,有源码+文档+ppt,可应付大学操作系统等课程的期末设计

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,243
精华内容 4,097
关键字:

stm32单片机项目