1. 首先我的 PWM 模块直接连接 了 直流电机 所以 我的 直流电机 利用 PWM 模块控制 。
直流电机 转速=(电枢端电压-两个电刷上的电压降-电枢绕组电阻上的压降)/(电机常数乘以电机定子磁场的磁通量);
如果忽略两个电刷上的电压降和电枢绕组电阻上的压降,再不考虑电机常数,
那么:转速=电枢端电压/磁场的磁通量,也就是说转速电枢端电压成正比,
与磁场的磁通量成反比。
总结: 在我们的程序里面 直流电机的转速 只与 电压有关
2.知识点
PWM 可以控制电压的大小, 所以我们可以 利用 PWM 模块 控制 直流电机的 速度, 转动的方向!
控制速度的函数:
转机的方向 与 下面的命令有关
EPwm1Regs.CMPA.half.CMPA = EPWM1_MIN_CMPA; // Set compare A value
EPwm1Regs.CMPB = EPWM1_MAX_CMPB; // Set Compare B value
当 脉冲 是向上增加模式 或 增减 模式 的时候 那么 EPwm1Regs.CMPA.half.CMPA 控制 0 的数量 , EPwm1Regs.CMPB 控制 1 的数量 , 谁的数量多, 就往 那边转 !
EPwm1Regs.CMPB 正方向
EPwm1Regs.CMPA.half.CMPA 反方向
3.这个部分不知到怎么讲知识点 !
程序功能 : 通过按键 控制 直流电机的转速, 并且在 TFTLCD 显示屏幕上 显示数值 !
(.c .h 文件 用 TFTLCD 那一部分的)
代码:
/*
* main.c
* TFTLCD字符显示实验
* 作者 : she001
* 时间: 2022/10/24
* 程序功能:外部中断 开始方向 , key1 num全局变量 +1 key2 num全局变量 -1 key3 num全局变量 +10 key 全局变量 -10 (别按 中断2 有 bug)
*/
/* 头文件汇总 */
#include
typedef struct
{
volatile struct EPWM_REGS *EPwmRegHandle;
Uint16 EPwm_CMPA_Direction;
Uint16 EPwm_CMPB_Direction;
Uint16 EPwmTimerIntCount;
Uint16 EPwmMaxCMPA;
Uint16 EPwmMinCMPA;
Uint16 EPwmMaxCMPB;
Uint16 EPwmMinCMPB;
}EPWM_INFO;
#define Key_Read *((Uint16 *)0x4700)
#define KeyValue ((Key_Read)&0x0f)
#define keyon1 GpioDataRegs.GPADAT.bit.GPIO29
// Configure the period for each timer
#define EPWM1_TIMER_TBPRD 2000 // Period register
#define EPWM1_MAX_CMPA 1950
#define EPWM1_MIN_CMPA 50
#define EPWM1_MAX_CMPB 1950
#define EPWM1_MIN_CMPB 50
// To keep track of which way the compare value is moving
#define EPWM_CMP_UP 1
#define EPWM_CMP_DOWN 0
// 中断服务子程序在主程序下面时,需要在主程序之前要先申明才能使用.
interrupt void xint1_isr(void);
void delay_loop_2(void);
void delay_loop_1(void);//超短时间的延时
void InitEPwm1Example(void);
void update_compare(EPWM_INFO*);
void Init_Port(void);//电机初始化函数
// Global variables used in this example
EPWM_INFO epwm1_info;
int num=200;//速度的数值
int fangxiang=0;//当fangxiang=0 电机转动的方向为 正向 , fangxiang==1 电机转动的方向为 反向
/********************************************************************************************
* 在做TFTLCD时,找到对用的头文件,改变宏定义即可,
* */
#if (TFTLCD_TEST == 1)
uchar class[]= {"班级 :"};
uchar Name[]= {"名字: "};
uchar student_ID[]={"学号: "};
uchar Str1[] = {"电机转动方向: "};//方向的提示语句
uchar direction1[]={"正向 "};//正向
uchar direction2[]={"反向 "};//反向
uchar Str2[] = {"速度: "};//速度的提示语句
#endif
void interrupt_init()
{
EALLOW; // 修改被保护的寄存器,修改前应添加EALLOW语句
PieVectTable.XINT1 = &xint1_isr;
EDIS; // EDIS的意思是不允许修改被保护的寄存器
// 在外设中断扩展模块中断使能寄存器中允许XINT1和XINT2: (组1中断4 & 5)
// 使能CPU中断1(INT1):
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // 使能外设中断扩展PIE模块
PieCtrlRegs.PIEIER1.bit.INTx4 = 1; // 使能PIE组1的INT4
IER |= M_INT1; // 使能CPU中断1(INT1)
EINT; // 开全局中断
// GPIO29配置为输入引脚通用I/O口,接按键TZ1,TZ2
EALLOW;
GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 0; // 选择为通用I/O口
GpioCtrlRegs.GPADIR.bit.GPIO29 = 0; // 方向定义为输入
GpioCtrlRegs.GPAPUD.bit.GPIO29=0;
GpioCtrlRegs.GPAQSEL2.bit.GPIO29 = 0; // 外部中断1(XINT1)与系统时钟SYSCLKOUT同步
GpioCtrlRegs.GPACTRL.bit.QUALPRD0 = 0x80; // 每个采样窗口的周期
EDIS;
// 通过GPIO外部中断选择寄存器,选择GPIO12为外部中断1,选择GPIO13为外部中断2
EALLOW;
GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 0x1D; // XINT1是GPIO29
EDIS;
// 配置外部中断1和2的中断控制寄存器
XIntruptRegs.XINT1CR.bit.POLARITY = 0; // 下降沿触发中断
// 使能外部中断1和外部中断2
XIntruptRegs.XINT1CR.bit.ENABLE = 1; // 使能XINT1
}
void TFTLCD(uchar str3)
{
//TFTLCD实验
#if (TFTLCD_TEST == 1)
ILI9325_Init(); //TFT初始化
//显示字符
LCD_PutString(37, 20,class, WHITE,RED);//显示班级
LCD_PutString(37, 50,Name, WHITE,RED);//显示名字
LCD_PutString(37, 80,student_ID, RED,WHITE);//显示学号
LCD_PutString(37, 110,Str1, BLUE,WHITE);//直流电机的转动方向
if(fangxiang==0)
{
LCD_PutString(150,110,direction1, RED,WHITE);
}
else if(fangxiang==1)
{
LCD_PutString(150,110,direction2, RED,WHITE);
}
LCD_PutString(37,140,Str2, WHITE,RED);//速度
LCD_PutString(110,140,str3, WHITE,RED);//速度的数值
#endif
}
void update_compare(EPWM_INFO *epwm_info)//电机调速函数
{
if(fangxiang==0)
{
epwm_info->EPwmRegHandle->CMPB=EPWM1_TIMER_TBPRD/2 - num;
epwm_info->EPwmRegHandle->CMPA.half.CMPA=EPWM1_TIMER_TBPRD/2 + num;
}
else
{
epwm_info->EPwmRegHandle->CMPB=EPWM1_TIMER_TBPRD/2 + num;
epwm_info->EPwmRegHandle->CMPA.half.CMPA=EPWM1_TIMER_TBPRD/2 - num;
}
}
void bianhua()//改变显示器的 显示数据
{
int n1;
int n2;
int n3;
int n4;
if(num>(EPWM1_TIMER_TBPRD/2+1))
{
return;
}
update_compare(&epwm1_info);
if(num<10)
{
n1=num;
}
else if(num<100)
{
uchar str3[5];
n1=num/10;
str3[0]=n1+48;
n2=num%10;
str3[1]=n2+48;
TFTLCD(str3);//输出数据
}
else if(num<1000)
{
uchar str3[5];
n1=num/100;
str3[0]=n1+48;
n2=num%100/10;
str3[1]=n2+48;
n3=num%10;
str3[2]=n3+48;
TFTLCD(str3);//输出数据
}
else if(num<10000)
{
uchar str3[5];
n1=num/1000;
str3[0]=n1+48;
n2=num%1000/100;
str3[1]=n2+48;
n3=num%100/10;
str3[2]=n3+48;
n4=num%10;
str3[3]=n4+48;
TFTLCD(str3);//输出数据
}
}
//函数入口
void main(void)
{
//TFTLCD 初始化
InitSysCtrl();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
InitEPwm1Gpio();//PWM 控制电机的引脚初始化
InitEPwm1Example();//PWM 控制电机的初始化 函数
InitXintf();
InitSpiaGpio();
interrupt_init();//中断初始化
bianhua();//开始的显示
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
InitEPwm1Example();
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
IER |= M_INT3;
EINT;
ERTM;
update_compare(&epwm1_info);
while (1)
{
if(KeyValue==0x0e)//1110 e
{
if(numd
{
if(num>=100)
{
num-=100;
}
bianhua();
}
delay_loop_1();//这里加一个延时是为了保证 key 按键按下去的时候能够识别的到
if(KeyValue==0x0b)//1011 11->b
{
if(num=10)
{
num=num-10;
}
bianhua();
}
}
}
interrupt void xint1_isr(void)
{
Uint32 i;
for(i=0;i<1000000;i++); //键盘消抖动
while(keyon1==0);
if(fangxiang==0)
{
fangxiang=1;
}
else if(fangxiang==1)
{
fangxiang=0;
}
bianhua();
// 应答寄存器的位1清0,以响应同组内其他中断;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
void delay_loop_2()
{
Uint32 i;
Uint32 j;
for(i=0;i<40;i++)
{
for (j = 0; j < 100000; j++);
}
}
void delay_loop_1()//超短时间的延时
{
Uint32 i;
Uint32 j;
for(i=0;i<20;i++)
{
for (j = 0; j < 10000; j++);
}
}
void InitEPwm1Example()//PWM 控制电机的 初始化
{
// Setup TBCLK
EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD; // Set timer period 801 TBCLKs
EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
EPwm1Regs.TBCTR = 0x0000; // Clear counter
// Set Compare values
EPwm1Regs.CMPA.half.CMPA = EPWM1_MIN_CMPA; // Set compare A value
EPwm1Regs.CMPB = EPWM1_MAX_CMPB; // Set Compare B value
// Setup counter mode
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
// Setup shadowing
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// Set actions
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on event A, up count
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM1A on event A, down count
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET; // Set PWM1B on event B, up count
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR; // Clear PWM1B on event B, down count
// Interrupt where we will change the Compare Values
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm1Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event
// Information this example uses to keep track
// of the direction the CMPA/CMPB values are
// moving, the min and max allowed values and
// a pointer to the correct ePWM registers
epwm1_info.EPwm_CMPA_Direction = EPWM_CMP_UP; // Start by increasing CMPA &
epwm1_info.EPwm_CMPB_Direction = EPWM_CMP_DOWN; // decreasing CMPB
epwm1_info.EPwmTimerIntCount = 0; // Zero the interrupt counter
epwm1_info.EPwmRegHandle = &EPwm1Regs; // Set the pointer to the ePWM module
epwm1_info.EPwmMaxCMPA = EPWM1_MAX_CMPA; // Setup min/max CMPA/CMPB values
epwm1_info.EPwmMinCMPA = EPWM1_MIN_CMPA;
epwm1_info.EPwmMaxCMPB = EPWM1_MAX_CMPB;
epwm1_info.EPwmMinCMPB = EPWM1_MIN_CMPB;
}
4.直流电机, 与 步进电机 的区别
直流电机
定义:输出或输入为直流电能的旋转电机,称为直流电机,它是能实现直流电能和机械能互相转换的电机。当它作电动机运行时是直流电动机,将电能转换为机械能;作发电机运行时是直流发电机,将机械能转换为电能。直流电机在数控机床、光缆线缆设备、机械加工、印制电路板设备、焊接切割、机车车辆、医疗设备、通讯设备、卫星地面接受系统等行业广泛应用。
分类:按结果主要分为直流电动机和直流发电机;按类型主要分为直流有刷电机和直流无刷电机;直流电机的励磁方式是指对励磁绕组如何供电、产生励磁磁通势而建立主磁场的问题。按励磁方式主要分为他励直流电机、并励直流电机 、串励直流电机和复励直流电机。
步进电机
步进电机是机电控制中一种常用的执行机构,在自动化仪表、自动控制、机器人、自动生产流水线等领域的应用相当广泛。它的用途是将电脉冲转化为角位移,通俗的说:当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(步进角)。通过控制脉冲个数即可控制角位移量,从而达到准确定位的目的;同时通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。
常用的步进电机分三种:永磁式(PM)、反应式(VR)和混合式(HB)。永磁式一般为两相,转矩和体积较小,步进角为15°和7.5°;反应式一般为三相,可以实现大转矩输出,步进角为1.5°,但噪声和震动较大;混合式是指混合了永磁式和反应式的优点,分为两相和五相,步进角分别为1.8°和0.72 °,应用最为广泛。
步进电机的控制方式
根据步进电机的驱动原理,当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(称为步进角),它的旋转是以固定的角度一步一步运行的。
可以通过控制一个周期内脉冲个数来控制角位移量,从而达到准确定位的目的。
可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。