难点:1、串口定时器T1,和T0定时器优先级

2、pwm频率与占空比的设置

按键控制

按键1——前进

按键2——后退

按键3——加速

按键4——减速

(板子上只有四个按键)

串口控制

‘1’——前进

‘2’——后退

‘3’——加速

‘4’——减速

‘5’——左转

‘6’——右转

源码:

#include <reg52.h>

typedef unsigned char u8;
typedef unsigned int u16;

//L298N引脚定义
sbit ena = P0^0;
sbit in1 = P0^1;
sbit in2 = P0^2;
sbit in3 = P0^3;
sbit in4 = P0^4;
sbit enb = P0^5;

//按键
sbit key1 = P3^3;    //模拟前进
sbit key2 = P3^4;         //模拟后退
sbit key3 = P3^6;         //模拟加速
sbit key4 = P3^7;   //模拟减速
 
u16 MA = 0,MB = 0;      //pwm控制用

u16 SpeedA = 20; //50%占空比
u16 SpeedB = 20;

u8 flag;                 //标志,1代表前进,0代表后退
u8 cmd;         //串口接收的命令sbuf

void delay(u16 z);        //声明延时函数

//前进
void forward()
{
flag = 1;                 //代表前进状态
in1=1;                    //l298n手册
in2=0;  
in3=1;  
in4=0;
}

//后退
void fallback()
{
flag = 0;                //代表后退状态
in1=0;  
in2=1;  
in3=0;  
in4=1;
}

//加速
void quick()
{
SpeedA += 1;  //每次加1
if(SpeedA >= 40)        //最大40
{
SpeedA = 40;
}
SpeedB += 1;
if(SpeedB >= 40)
{
SpeedB = 40;
}
}

//减速
void slow()
{
SpeedA -= 1;        //每次减1
if(SpeedA <= 5)//最小5
{
SpeedA = 5;
}
SpeedB -= 1;
if(SpeedB <= 5)
{
SpeedB = 5;
}
}

//左转
void move_left()              //只有前进的时候可以左转
{
if(flag == 1)            //前进状态
{
in1=1;  
in2=0;  
in3=0;  
in4=0;
delay(50000);
forward();
}
}

//右转
void move_right()                 //只有前进的时候可以右转
{
if(flag == 1)                //前进状态
{
in1=0;  
in2=0;  
in3=1;  
in4=0;
delay(50000);
forward();
}
}

//停止
void stop()
{
in1=0;  
in2=0;  
in3=0;  
in4=0;
}

void delay(u16 z)
{  
u16 x,y;  
for(x=z;x>0;x--)   
for(y=125;y>0;y--); 
}

void SendOneByte(u8 c)    //串口发送数据
{
SBUF = c;
while(!TI);
TI = 0;
}

void main()
{   
//串口定时器 定时器T0
TMOD = 0x21;  //T0定时器为工作方式一,T1定时器为工作方式二
PCON = 0x00;  //串口初始化相关,波特率
SCON = 0x50;                 //串口初始化相关,串口工作方式一,允许接收
        TH1 = 0xFD;                   //设置初值
        TL1 = 0xFD;                   //设置初值
TR1 = 1;                          //开启定时器T1

TH0 = 0xF4;                    //设置初值
TL0 = 0x48;          //设置初值
TR0 = 1; //开启定时器T0

ES = 1;//开放串口中断
//PS = 1;                         //串口中断优先
PT0 = 1;                 //定时器0中断优先
ET0 = 1;//开放定时器T0中断
EA = 1;//开放总中断

//按键控制小车
while(1)
{
if(key1 == 0)
{
delay(10);
if(key1 == 0)
{
forward();
SendOneByte(1);
}
while(key1 == 0);
}
if(key2 == 0)
{
delay(10);
if(key2 == 0)
{
fallback();
SendOneByte(2);
}
while(key2 == 0);
}
if(key3 == 0)
{
delay(10);
if(key3 == 0)
{
quick();
SendOneByte(3);
}
while(key3 == 0);
}
if(key4 == 0)
{
delay(10);
if(key4 == 0)
{
slow();
SendOneByte(4);
}
while(key4 == 0);
}
}
}

void time0_int() interrupt 1   //T = 3ms * 40 = 120ms
{  
TR0 = 0;      
TH0 = 0xF4; 
TL0 = 0x48; //3000;  3ms
MA++;          
if(MA < SpeedA)  
{    
ena = 1;  
}  
else 
 
ena = 0;  
if(MA == 40)
{    
 
MA = 0;  
}

MB++;          
if(MB < SpeedB)  
{    
enb = 1;  
}  
else 
 
enb = 0;  
if(MB == 40)
{    
 
MB = 0;  
}  
TR0 = 1;
}

void UARTInterrupt(void) interrupt 4
{
if(RI)
{
RI = 0;
//add your code here!
cmd = SBUF;
SendOneByte(cmd);

//串口控制小车
switch (cmd)
{
case 1:
forward();
SendOneByte(1);
break;
case 2:
fallback();
SendOneByte(2);
break;
case 3:
quick();
SendOneByte(3);
break;
case 4:
slow();
SendOneByte(4);
break;
case 5:
move_left();
SendOneByte(5);
break;
case 6:
move_right();
SendOneByte(6);
break;
default:
SendOneByte(7);
break;
}
}
}

结束!

51单片机 小车 L298N pwm调速 串口控制 按键控制的更多相关文章

  1. [问题解决]不使用PWM调速系统,彻底解决一个L298N带动两个电机却转速不同的问题

    问题描述:由单片机的VCC引脚供电,使用L298N控制两个电机,发现左右两个轮子的转速老是不一样,更多的情况是左轮转速高(左轮电机接OUT1和OUT2),右轮转速低(右轮电机接OUT3和OUT4)甚至 ...

  2. #51单片机#蓝牙模块(ATK-SPP-HC06从机串口)的使用方法

    #include <AT89X51.H> #include <intrins.h> // 函数原形定义 #define uchar unsigned char #define ...

  3. 直流电机PWM调速系统中控制电压非线性研究_控制元件_工业自动化控制_文章

    直流电机PWM调速系统中控制电压非线性研究_控制元件_工业自动化控制_文章_e-works数字化企业网 http://articles.e-works.net.cn/Component/Article ...

  4. 51单片机产生1Hz-5kHz可调占空比方波

    学校的课程设计,总结一下. 注意 1.高低电平的改变不适合在主函数的while循环中,因为要有数码管动态显示的延时和其它逻辑处理,时间太长会不能及时改变高低电平值. 2.中断的执行时间一定是不能超过定 ...

  5. 51单片机—使用PWM对直流电机调速

    文章目录 - 什么是PWM - PWM是怎么对直流电机进行调速的 - 通过定时器中断实现PWM调速 - 上代码 - 什么是PWM PWM(脉宽调制),是靠改变脉冲宽度来控制输出电压,通过改变周期来控制 ...

  6. 用STM32玩L298N(正反转、调速)

    目录 用STM32玩L298N(正反转.调速) 控制直流电机正反转 使用PWM调速 用STM32玩L298N(正反转.调速) 开发板:STM32F103ZET6(正点原子F103核心板)/STM32F ...

  7. 玩转X-CTR100 l STM32F4 l TB6612直流电机调速控制

    我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] 本文介绍X-CTR100控制器的直流调速电机控制,X ...

  8. 51单片机GPIO口模拟串口通信

    51单片机GPIO口模拟串口通信 标签: bytetimer终端存储 2011-08-03 11:06 6387人阅读 评论(2) 收藏 举报 本文章已收录于:   分类: 深入C语言(20) 作者同 ...

  9. [51单片机] 以PWM控制直流电机为例建一个简单的51工程框架

    目录 1)功能概述 2)引脚连接 3)框架介绍 4)模块说明 5)复用规则 6)工程链接 1)功能概述 名称:独立按键控制直流电机调速 内容:对应的电机接口需用杜邦线连接到uln2003电机控制端; ...

随机推荐

  1. angular 的 GET 请求 和 POST 请求的 区别 及 实现

    1.GET 请求 .factory('AlarmService', ['$rootScope','ENV','$resource','$http','ionicToast',function($roo ...

  2. linux系统之shell编程-正則表達式

    shell编程正則表達式: 1:元字符   [ ]  .   *  ? + ( )  |  {  }  ^  $ 2 : [a-z0-9]  表示匹配随意数字和字母的一个 3 :  [^a-z]    ...

  3. 【转载】TCP粘包问题分析和解决(全)

    TCP通信粘包问题分析和解决(全) 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送 ...

  4. C#串口通讯教程 简化一切 只保留核心功能 这可能是最易于理解的一篇教程

    C#串口通讯教程 简化一切 只保留核心功能 这可能是最易于理解的一篇教程   串口的定义,请自行了解. C#操作串口通讯在.Net强大类库的支持下,只需要三个步骤: 1 创建 2 打开 3 发送/接受 ...

  5. 理解OpenStack认证:Keystone PKI

    原文链接: https://www.mirantis.com/blog/understanding-openstack-authentication-keystone-pki/ The latest ...

  6. iOS之UI--涂鸦画板实例

     iOS之UI--涂鸦画板实例  首先是搭建框架 其他的略过,直接展示效果: 然后接下来上传搭建好两个控制器框架的源码百度云下载链接: http://pan.baidu.com/s/1skjpDox  ...

  7. 【Android】Android聊天机器人实现

    昨天看到一个Android视频教程讲图灵机器人.那个API接口用起来还是挺方便的,就准备自己动手做一个了. 另外自己还使用了高德地图的API接口用于定位(曾经用过高德的接口,比X度方便) 大体流程: ...

  8. LeetCode(38)题解: Count and Say

    https://leetcode.com/problems/count-and-say/ 题目: The count-and-say sequence is the sequence of integ ...

  9. VC编码规范(转)

    1    项目风格   1.1    项目取名     在VC之中,项目名为最后可执行文件名,所以项目名最好以最终的可执行文件名一致. 1.2    项目目录设置     为保证VC项目的备份方便.快 ...

  10. linux内核模块依赖图

    Module                  Size  Used by btrfs                 880032  0 raid6_pq               97812  ...