-
2021-05-21 12:45:13
/*******************************************************************/
/* 程序名称:STC89C52_PWM直流电机调速及正反转
/* 单片机型号:STC89C52系列 晶振:11.00592 MHz
/* 单片机供电5V, L298N模块可共用电源, 也可以单独外接电源(具体看L298N模块说明)
/* 直流电机的PWM波控制,可以直接调速从0到100共21级(每级+5)
/* 所谓的占空比其实就是利用计数改变0和1的比列
/* 大家可以接LED测试, 当占空比越大, LED灯闪烁越慢, 当占空比越小, LED闪烁越快, 直到眼睛都看不出有闪烁
/* 新增功能:
/* 2020.10.24 新增长按停止, 短按保留正反转
/* 2020.10.25 将调速等级和正反转状态写入EEPROM, 以便关机后再次开机能保留关机前状态
/*****************************************************************/
#include "eeprom.h"
#define TH0_TL0 (65536-1000)//设定中断的间隔时长
//引脚声明
sbit Key_add=P2^0; //电机加速(轻触开关一脚接P2^0, 斜对脚接GND)
sbit Key_minus=P2^1; //电机减速(轻触开关一脚接P2^1, 斜对脚接GND)
sbit Key_fr=P2^2; //电机反向(轻触开关一脚接P2^2, 斜对脚接GND)
//L298N模块+引脚接VCC, -引脚接GND
//MOTOR-A二个引脚接电机的二个引脚, 正反自己按需求调整
sbit PWM1=P2^6; //PWM1 (接L298N模块的L298N模块的INT1)
sbit PWM2=P2^7; //PWM2 (接L298N模块的L298N模块的INT2)
//配合eeprom使用
uchar code set1[21]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15}; //用来判断调速等级
uchar code set2[2]={0x01,0x02}; //用来判断正反转
uint zsdj; //转速等级
uchar count0; //低电平的占空比
uchar count1 = 0;//高电平的占空比
bit Flag;//电机正反转标志位 -- 1正转,0反转
bit zt = 1; //记录状态(1启动, 0停止)
//用于判断Key_fr的长按短按
#define key_S 500 //宏定义短按(约20ms)
#define key_L 16000 //宏定义长按(约2/3s)
#define key_M 8000 //宏定义长按间隔(约1/3s)
/************函数声明**************/
void Write_Eeprom(void); //写eeprom
void Motor_High_speed(void); //马达高速
void Motor_Low_speed(void); //马达低速
void Motor_Forward_and_Reverse(void); //马达正反转
void Timer0_init(void); //定时器0初始化
/*写eeprom*/
void Write_Eeprom(void){
IapEraseSector(0x2000); //擦除0x2000--0x21FF
IapProgramByte(0x2001,set1[zsdj]); //存储count0
IapProgramByte(0x2002,set2[Flag]); //存储Flag
}
/*******按键+处理增加PWM,PWM越大,电机越快**********/
void Motor_High_speed(void)
{
if(Key_add==0)
{
Delay(10);
if(Key_add==0)
{
count0 += 5;
zsdj += 1;
if(count0 >= 100)
{
count0 = 100;
}
if(zsdj >= 20)
{
zsdj = 20;
}
Write_Eeprom(); //eeprom操作
}
while(!Key_add);//等待键松开
}
}
/*******按键-处理减少PWM,PWM越小,电机越慢**********/
void Motor_Low_speed(void)
{
if(Key_minus==0)
{
Delay(10);
if(Key_minus==0)
{
count0 -= 5;
zsdj -= 1;
if(count0 <= 0)
{
count0 = 0;
}
if(zsdj <= 0)
{
zsdj = 0;
}
Write_Eeprom(); //eeprom操作
}
while(!Key_minus);
}
}
/************电机正反向控制**************/
void Motor_Forward_and_Reverse(void)
{
static uint jcs=0; //计数变量
if(!Key_fr)
{
jcs++;
if(jcs>=key_L) //长按
{
jcs=key_M; //设一个值
zt=0; //停止
}
}
else //按键抬起
{
if(jcs>key_S && jcs
{
if(zt==1){
Flag=~Flag; //当状态为1时,才会切换正反转
Write_Eeprom(); //eeprom操作
}
if(zt==0){
PWM1=0; //当状态为0时,启动为正转
PWM2=1;
}
zt=1; //设状态为1
}
jcs=0; //count清0
}
}
/***********定时器0初始化***********/
void Timer0_init(void)
{
TMOD=0x01; //定时器0工作于方式1
TH0=TH0_TL0/256;
TL0=TH0_TL0%256;
TR0=1;
ET0=1;
EA=1;
}
/*********主函数********************/
void main(void)
{
//开机初始化定时器0
Timer0_init();
//开机读取记忆数据(转速等级)
switch(IapReadByte(0x2001))
{ //判断
case 0x01:count0=0;zsdj=0;break;
case 0x02:count0=5;zsdj=1;break;
case 0x03:count0=10;zsdj=2;break;
case 0x04:count0=15;zsdj=3;break;
case 0x05:count0=20;zsdj=4;break;
case 0x06:count0=25;zsdj=5;break;
case 0x07:count0=30;zsdj=6;break;
case 0x08:count0=35;zsdj=7;break;
case 0x09:count0=40;zsdj=8;break;
case 0x0A:count0=45;zsdj=9;break;
case 0x0B:count0=50;zsdj=10;break;
case 0x0C:count0=55;zsdj=11;break;
case 0x0D:count0=60;zsdj=12;break;
case 0x0E:count0=65;zsdj=13;break;
case 0x0F:count0=70;zsdj=14;break;
case 0x10:count0=75;zsdj=15;break;
case 0x11:count0=80;zsdj=16;break;
case 0x12:count0=85;zsdj=17;break;
case 0x13:count0=90;zsdj=18;break;
case 0x14:count0=95;zsdj=19;break;
case 0x15:count0=100;zsdj=20;break;
default:count0=50;zsdj=10;
}
//开机读取记忆数据(正向或反向)
if(IapReadByte(0x2002)==0x01){
Flag = 0;
}
else if(IapReadByte(0x2002)==0x02){
Flag = 1;
}
while(1)
{
Motor_High_speed(); //加速
Motor_Low_speed(); //减速
Motor_Forward_and_Reverse(); //正反转
}
}
更多相关内容 -
51单片机H桥电路控制电机正反转和PWM调速
2020-08-10 16:42:24搭了个H桥电路,控制电机的正反转和PWM调速,程序是网上的,改改引脚就能用,本文详细描绘了电路图和源程序。 -
基于H桥PWM控制的直流电机正反转调速驱动控制电路
2021-02-03 13:52:56基于H桥PWM控制的直流电机正反转调速驱动控制电路、电子技术,开发板制作交流 -
使用单片机实现直流电机正反转及PWM调速控制的C语言实例
2021-07-07 11:29:50本文档的主要内容详细介绍的是使用单片机实现直流电机正反转及PWM调速控制的C语言实例免费下载。 -
单片机产生PWM波控制电机正反转
2014-07-21 21:14:33通过单片机的定时器来产生PWM波,控制直流电机的正反转 -
最新单片机仿真 PWM电机正反转
2022-05-20 19:28:44最新单片机仿真 PWM电机正反转最新单片机仿真 PWM电机正反转最新单片机仿真 PWM电机正反转最新单片机仿真 PWM电机正反转最新单片机仿真 PWM电机正反转最新单片机仿真 PWM电机正反转最新单片机仿真 PWM电机正反转最新... -
AT89C51 驱动PWM电机正反转proteus仿真源文件(含C程序源码)
2020-12-01 19:46:33电机由四个8050三极管驱动,有一个按键控制电机开始运转的时间,电机正转一段时间后进行反转,如此循环 -
基于stm32的电机调速与正反转(含有protues仿真)
2020-08-13 14:30:52基于STM32的PWM调速,有四个电机 两个电机可以正反转,两个电机调速,内附程序与protues仿真 -
C51直流电机正反转及PWM调速控制
2019-03-27 09:29:13适合C51直流电机控制初学者,内容包含直流电机正反转及PWM调速控制 -
PWM电机正反转(内含完整的C语言代码).zip
2020-03-09 21:59:18PWM电机正反转(内含完整的C语言代码).zip -
最简单的电机正反转+PWM控制
2019-08-08 09:01:38 -
Protues仿真实例-51单片机-PWM电机正反转.rar
2021-04-28 10:24:58Protues仿真实例-51单片机-PWM电机正反转.rar -
STM32用PWM实现小电机的正反转
2019-07-23 21:37:07其他的定时器都可以用来产生 PWM 输出)的两个通道输出两道PWM脉冲,控制电机的高低电平以实现电机的正反转。 代码如下: #ifndef __TIMER_H #define __TIMER_H #include “sys.h” /********...2019年7月23日
做小车的第三天。/*********************记得这是自己上一年暑假写的代码(已删除了,现在就是想把最新的代码和思路分享出来),当时自己把小电机的前进后退调出来之后,一直想控制速度,那时候自己急于求成啊,就想快点把它弄懂,可是那时候就知道一个思路然后就猛干了。现在是时候进行一下弥补了
***********************/大概思路就是:用TIM1和TIM4两个时钟共8个通道,用PWM来控制小车的4个轮子。
TIM1中的PA8 A9代表左前轮, A10 A11代表左后轮;
TIM4中的PB6 B7代表右前轮,B8 B9代表右后轮还是老样子把完整的代码贴出来。
timer.h
// An highlighted block #ifndef __TIMER_H #define __TIMER_H #include "sys.h" void TIM4_PWM_Init(); void TIM1_PWM_Init(); void Prun(); //前进 void Nrun(); //后退 void Tleft(); //左转 void Trighet();//右转 #endif
timer.c
// An highlighted block #include "timer.h" #include "led.h" //TIM4 PWM部分初始化 //PWM输出初始化 //arr:自动重装值 //psc:时钟预分频数 void TIM4_PWM_Init() { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能定时器4时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9; // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO //初始化TIM4 TIM_TimeBaseStructure.TIM_Period = 99; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler =719; //设置用来作为TIMx时钟频率除数的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 //初始化TIM4 Channel/2/3/4 PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 TIM_OC1Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4 OC1 TIM_OC2Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4 OC2 TIM_OC3Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4 OC3 TIM_OC4Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4 OC4 TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR1上的预装载寄存器 TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR2上的预装载寄存器 TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR3上的预装载寄存器 TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR4上的预装载寄存器 TIM_ARRPreloadConfig(TIM4,ENABLE); TIM_Cmd(TIM4, ENABLE); //使能TIM4 } void TIM1_PWM_Init() { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //使能定时器1时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIO外设 //设置该引脚为复用输出功能,输出TIM1 PWM脉冲波形 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11; //TIM_CHX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO //初始化TIM1 TIM_TimeBaseStructure.TIM_Period = 99; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler =719; //设置用来作为TIMx时钟频率除数的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 //初始化TIM4 Channel/2/3/4 PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OutputNState=TIM_OutputState_Disable;//高级定时器有一个输出N不使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 TIM_OCInitStructure.TIM_OCNPolarity=TIM_OCPolarity_High;// TIM_OCInitStructure.TIM_OCIdleState=TIM_OCIdleState_Reset;//这三个是高级定时器要配置的 TIM_OCInitStructure.TIM_OCNIdleState=TIM_OCIdleState_Reset;// //TIM_OCInitStructure.TIM_Pulse=10; TIM_OC1Init(TIM1, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 OC1 TIM_OC2Init(TIM1, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 OC2 TIM_OC3Init(TIM1, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 OC3 TIM_OC4Init(TIM1, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 OC4 TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIM1在CCR1上的预装载寄存器 TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIM1在CCR2上的预装载寄存器 TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIM1在CCR3上的预装载寄存器 TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIM1在CCR4上的预装载寄存器 TIM_ARRPreloadConfig(TIM1,ENABLE);//使能自动重装载值 TIM_CtrlPWMOutputs(TIM1,ENABLE);//主输出使能 TIM_Cmd(TIM1, ENABLE); //使能TIM1 } //TIM1中的PA8 A9代表左前轮, A10 A11代表左后轮; TIM4中的PB6 B7代表右前轮,B8 B9代表右后轮 void Prun() { TIM_SetCompare1(TIM1,10); //左前前进 TIM_SetCompare2(TIM1,0); TIM_SetCompare3(TIM1,10); //左后前进 TIM_SetCompare4(TIM1,0); TIM_SetCompare1(TIM4,10); //右前前进 TIM_SetCompare2(TIM4,0); TIM_SetCompare3(TIM4,10); //右后前进 TIM_SetCompare4(TIM4,0); } void Nrun() { TIM_SetCompare1(TIM1,0); //左前后退 TIM_SetCompare2(TIM1,10); TIM_SetCompare3(TIM1,0); //左后后退 TIM_SetCompare4(TIM1,10); TIM_SetCompare1(TIM4,0); //右前后退 TIM_SetCompare2(TIM4,10); TIM_SetCompare3(TIM4,0); //右后后退 TIM_SetCompare4(TIM4,10); } void Tleft() // 原地左转 左边的两个轮子往后转,右边的两个轮子往前转 { TIM_SetCompare1(TIM1,0); //左前后退 TIM_SetCompare2(TIM1,10); TIM_SetCompare3(TIM1,0); //左后后退 TIM_SetCompare4(TIM1,10); TIM_SetCompare1(TIM4,10); //右前前进 TIM_SetCompare2(TIM4,0); TIM_SetCompare3(TIM4,10); //右后前进 TIM_SetCompare4(TIM4,0); } void Trighet() { TIM_SetCompare1(TIM1,10); //左前前进 TIM_SetCompare2(TIM1,0); TIM_SetCompare3(TIM1,10); //左后前进 TIM_SetCompare4(TIM1,0); TIM_SetCompare1(TIM4,0); //右前后退 TIM_SetCompare2(TIM4,10); TIM_SetCompare3(TIM4,0); //右后后退 TIM_SetCompare4(TIM4,10); }
// A code block **进行一些简单说明** 上面的重装载值arr=99,预分频系数psc=719; T=arr * psc /72M,结果为1ms,也就是频率为1KHz; PWM模式设置为TIM_OCMode_PWM1,arr=99, 这样一来占空比调整比较方便: arr=10——占空比为10%; arr=20——占空比为20%;
上面的占空比我设置的是10%,电机转的比较慢(还可以),你可以根据你自己的情况进行自己更改。
main.c
// An highlighted block #include "delay.h" //#include "key.h" #include "sys.h" #include "timer.h" int main(void) { delay_init(); //延时函数初始化 TIM4_PWM_Init(); TIM1_PWM_Init(); while(1) { Prun();//前进 } }
下面插一张自己调试的图片:
这次应该没什么问题了,如果你们发现什么问题,希望多多指正。博客经常上ou。
-
基于STM32的直流电机控制pwm控制启动,停止,正反转,转速。
2022-04-15 11:21:26基于STM32的直流电机控制pwm控制启动,停止,正反转,转速。 ID:6980622002864004渣渣丶鹏基于STM32的直流电机控制pwm控制启动,停止,正反转,转速。
ID:6980622002864004渣渣丶鹏
-
stm32f10x pwm控制四个电机正反转.zip
2019-10-20 12:23:53stm32f10x pwm控制四个电机正反转.zip 。 -
PWM电机正反转.zip
2021-03-23 22:34:43PWM电机正反转,比赛练习案例,仿真实例,现成调用封装使用,可运行的仿真电路图和调好的程序,开箱即用。适用于教学案例、毕业设计、电子设计比赛、出书项目实例,实际设计、个人DIY参考。 已调试好,proteus直接... -
基于STM32f103单片机按键控制电机正反转(带PWM调速)
2020-08-09 04:08:41基于STM32f103ZET6单片机按键控制电机正反转(带PWM调速) 学了快半个月的STM32,收获颇多,很明显的感觉是32位的单片机要比8位单片机(51单片机)强的太多了,不管是性能还是功耗上和51是没法比的,而且还有许多的... -
控制5V5线4相步进电机正反转和转动指定角度(ULN2003)
2020-05-27 12:56:43驱动是使用STM32F103 + RT-Thread开发的,移植...压缩包内包含步进电机资料和程序。程序是驱动5线4相步进电机的(ULN2003驱动),使用四相八拍和单四拍方式驱动。调速只需要改延时程序,修改角度只需要修改传入的形参。 -
220V交流电机如何控制正反转
2021-05-07 07:08:54另一种是经特殊设计的单相电动机,如家用洗衣机的洗涤用电机。它最大特点二相绕组不分主付,通过控制电器来改变移相电容串入那个绕组来实现正反转换向的。对于内部定子上加装短路环的单相电机则无法改变转向,在设计... -
pwm 控制直流电机正反转
2010-06-27 18:36:34pwm控制电机正反转 igbt3.1 电流调节器和转速调节器的设计 3.2 PWM生产电路设计 1)SG3524芯片的简介 3.3 IGBT驱动电路设计 1)EXB841芯片的简介 3.4 转速和电流检测电路设计 3.5 总体电路 -
《电子DIY》之使用STM32驱动电机(PWM方式)(控制电机正反转)(用于智能小车轮子的控制)
2020-05-19 19:26:58#if Motor_PWM_Mode TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; #endif RCC_APB2PeriphClockCmd(MOTORPORTClock,ENABLE); GPIO_InitStruct.GPIO_Mode=GPIO_Mode_... -
PWM控制直流电机的正转、反转、加速和减速
2021-01-22 10:00:59使用 PWM 电路来控制直流电机的正转、反转、加速和减速,并将转向和转速显示出来。 设置按键控制直流电机的启动/停止的开关 设置按键控制直流电机的加速、减速 设置按键控制直流电机的正转、反转 设置显示模块可以... -
msp430G2553直流电机控制(PWM调速和正反转)
2015-01-07 10:51:38一、引言: 2 二、系统框图 3 三、硬件部分 3 四、软件部分 4 五、调试结果及总结 6 附录 7 1.原理图 7 2.PCB图 7 3.元器件 7 4.参考文献 8 5.关键代码 8 -
Protues仿真实例(8051)-PWM电机正反转.zip
2022-02-03 02:04:59Protues仿真实例(8051)-PWM电机正反转.zip -
使用PWM的相位控制步进电机正反转和加减速
2020-04-21 19:59:451.步进电机在3D打印上用的比较多,因为步长是固定的,因此能够精准的控制转动产生的位移 (DC 5V 4相8拍5线步进电机 28YBJ-48 / 驱动芯片型号:uln2003芯片) 2.驱动原理: ... -
STM32F103与L298n电机驱动模块按键控制电机正反转及PWM调速(附源码)
2019-10-29 16:43:07硬件 1.普中科技STM32-PZ6806D开发板,核心STM32F103ZET6。...3.若不需要使用PWM调速,只需要控制电机正反转,则逻辑A与B跳线帽插上即可,相当于始终使能。 4.若需要使用PWM调速,需将跳线帽拔起... -
STC单片机简单控制直流电机正反转
2018-09-03 20:46:51最近在研究智能小车,简单研究了一下单片机简单控制直流电机正反转,一开始想着用单片机直接控制,结果失败了。 原因是:虽然I/O口输出的电压也是5V,但输出的电流太小,以致输出功率太小,不足以驱动电机工作。... -
pwm控制电机原理
2021-04-06 11:31:32电动机是由定子和转子组成,一个产生旋转磁场,一个为磁极,电机的转子(轴承)就转起来了。 这便实现了 电能->磁能->机械能的转换 下面两个图可以更直观的理解: 那么关于电机我们不做深究, 我们只需要知道...