0.目标

基于 TMS320F2812 的直流无刷电机(BLDCM)的开环控制系统,通过调节电位器调节给定电压,ADC模块采集电压,改变PWM占空比实现调速,事件管理器的CAP模块来捕获转速大小。

1.硬件背景

在基于 TMS320F2812 的直流无刷电机(BLDCM)的控制系统中加入电位器 R102 的可调分压电路,并将其输出电压接入到 F2812 片上 ADC 模块的模拟输入引脚 ADCINA7,系统框图如下图所示。电位器 R102 顺时钟旋转到头时输出电压为 0V,逆时针旋转到头时输出电压为 3V。系统通过电位器 R102 实现对 BLDCM 的线性 PWM 调速。

2.软件编写

通过 ADC 采集模拟输入引脚 ADCINA7 引脚的电压信号 u,采样率通过 GP Timer1 设置为与 PWM 频率相同;在 ADC 的中断服务子程序中计算 u 的值(单位: V),并令 PWM 占空比δ =u/3( 0~3V 对应 PWM 占空比 0%~100%);在 GP Timer1 的下溢中断服务子程序中,将 PWM1、 PWM3、 PWM5 的占空比刷新为δ ;定义电机转速变量 speed(全局变量),在 CAP1 的中断程序中计算 CAP1 引脚的信号频率 f,并令 speed=f/2*60(单位: rpm),从而计算电机转速;调节 R102,实现开环调速。 (将 R102 输出电压调整为 3V 可得到 BLDCM 的额定转速)。

(0)全局变量的定义

Uint16 rotor_code; //全局变量码值
Uint16 driver_state;//全局变量状态值
Uint16 temp;//公用临时变量
Uint16 temp_new=0,temp_old=0;//计算转速的中间变量
//Uint16 ispcount=0;//进入cap中断的次数
//Uint16 ispadc=0;//进入adc中断的次数
//Uint16 ufist=0;
volatile float v=0.0;//给定电压
volatile const float adclsb =7.326007e-4;
float d=0.0;//占空比
float speed=0.0;//转速

(1)mian函数

int main(void)
{InitSysCtrl();//系统初始化InitPieCtrl();//pie模块初始化InitPieVectTable();//pie中断向量表初始化InitGpio();//gpio初始化InitEv();//初始化时间管理器InitAdc();//adc initializationEALLOW;//解除寄存器写保护PieVectTable.CAPINT1=&Cap123_isr;//CAPINT1中断向量配置PieVectTable.CAPINT2=&Cap123_isr;//CAPINT2中断向量配置PieVectTable.CAPINT3=&Cap123_isr;//CAPINT3中断向量配置PieVectTable.T1UFINT=&Underflow_isr;//ADC中断向量配置PieVectTable.ADCINT=&ADC_isr;//ADC中断向量配置EDIS;//开启写保护PieCtrlRegs.PIEIER3.bit.INTx5 = 1;//使能PIE中的CAPINT1中断PieCtrlRegs.PIEIER3.bit.INTx6 = 1;//使能PIE中的CAPINT2中断PieCtrlRegs.PIEIER3.bit.INTx7 = 1;//使能PIE中的CAPINT3中断PieCtrlRegs.PIEIER1.bit.INTx6 = 1;//使能PIE中的ADC中断PieCtrlRegs.PIEIER2.bit.INTx6 = 1;//Enable Underflow interrupt in PIE//IFR = 0x0000;//clear all CPU interrupt flags:IER=0x0007;//CPU级使能INT1,3中断EnableInterrupts();//使能PIEEINT;//开启全局中断EvaRegs.T1CON.bit.TENABLE=1; //启动GTimer1定时器EvaRegs.T2CON.bit.TENABLE=1; //启动GTimer2定时器//====Motor start output========temp = (GpioDataRegs.GPADAT.all & 0x0700);//保持第8,9,10位的值,其他位清0temp>>=8;//右移8位rotor_code=temp;//读取码值driver_state=Driver_State(rotor_code);//由码值返回状态值Driver_Output(driver_state);//状态输出//=====================================while(1){}return 0;
}

(2)外设时钟的配置

void InitPeripheralClocks(void)
{EALLOW;
// HISPCP/LOSPCP prescale register settings, normally it will be set to default valuesSysCtrlRegs.HISPCP.all = 0x0002;SysCtrlRegs.LOSPCP.all = 0x0002;// Peripheral clock enables set for the selected peripherals.   SysCtrlRegs.PCLKCR.bit.EVAENCLK=1;SysCtrlRegs.PCLKCR.bit.EVBENCLK=1;SysCtrlRegs.PCLKCR.bit.SCIAENCLK=1;SysCtrlRegs.PCLKCR.bit.SCIBENCLK=1;SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=0;SysCtrlRegs.PCLKCR.bit.SPIENCLK=0;SysCtrlRegs.PCLKCR.bit.ECANENCLK=0;SysCtrlRegs.PCLKCR.bit.ADCENCLK=1;EDIS;
}

因为需要使用CAP模块计算转速,所以需要将150MHZ进行4分频到高速外设时钟,打开EVA,EVB的时钟,其他保持默认。

(3)ADC初始化

void InitAdc(void)
{AdcRegs.ADCTRL3.bit.ADCBGRFDN=0x3;//带隙和基准电路上电DELAY_US(10000);//延时10msAdcRegs.ADCTRL3.bit.ADCPWDN=1;//ADC其他模拟电路上电DELAY_US(30);//延时30usAdcRegs.ADCTRL1.bit.ACQ_PS=0;//采样窗配置AdcRegs.ADCTRL1.bit.SEQ_CASC=1;//级联单排序AdcRegs.ADCTRL1.bit.CONT_RUN=0;//启动停止模式AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1=1;//允许EVA事件触发SOC SEQAdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;//级联单排序模式下,始能SEQ中断AdcRegs.ADCTRL3.bit.ADCCLKPS=15;//预分频AdcRegs.ADCMAXCONV.bit.MAX_CONV1=9;//选择10个通道AdcRegs.ADCCHSELSEQ1.all=0x7777;//全部选择模拟通道A7AdcRegs.ADCCHSELSEQ2.all=0x7777;//全部选择模拟通道A7AdcRegs.ADCCHSELSEQ3.all=0x7777;//全部选择模拟通道A7AdcRegs.ADCCHSELSEQ4.all=0x7777;//全部选择模拟通道A7}

(4)ADC中断函数

interrupt void ADC_isr(void)
{//ispadc++;EvaRegs.EVAIFRA.bit.T1UFINT=1;//清除中断标志位AdcRegs.ADCST.bit.INT_SEQ1_CLR=1;//清除SEQ/SEQ1中断标志AdcRegs.ADCTRL2.bit.RST_SEQ1=1;//复位SEQ为CONV00//采样10次取平均值temp=(AdcRegs.ADCRESULT0>>4)+(AdcRegs.ADCRESULT1>>4);temp+=(AdcRegs.ADCRESULT2>>4)+(AdcRegs.ADCRESULT3>>4);temp+=(AdcRegs.ADCRESULT4>>4)+(AdcRegs.ADCRESULT5>>4);temp+=(AdcRegs.ADCRESULT6>>4)+(AdcRegs.ADCRESULT7>>4);temp+=(AdcRegs.ADCRESULT8>>4)+(AdcRegs.ADCRESULT9>>4);v=temp*adclsb*0.1;//计算电压d=v/3;//Calculate duty cycle from analog voltagePieCtrlRegs.PIEACK.bit.ACK1=1;//写1 清零,允许下一次中断}

(5)GPIO初始化函数

void InitGpio(void)//gpio初始化
{EALLOW;//解除寄存器保护GpioMuxRegs.GPADIR.all=0x003F;//配置低6位为输出,其他为输入GpioMuxRegs.GPAMUX.bit.PWM1_GPIOA0=1;//PWM1_GPIOA0配置为pwm功能GpioMuxRegs.GPAMUX.bit.PWM2_GPIOA1=0;//PWM2_GPIOA1 配置为i/o功能GpioMuxRegs.GPAMUX.bit.PWM3_GPIOA2=1;//PWM3_GPIOA2配置为pwm功能GpioMuxRegs.GPAMUX.bit.PWM4_GPIOA3=0;//PWM4_GPIOA3 配置为i/o功能GpioMuxRegs.GPAMUX.bit.PWM5_GPIOA4=1;//PWM5_GPIOA4配置为pwm功能GpioMuxRegs.GPAMUX.bit.PWM6_GPIOA5=0;//PWM6_GPIOA5配置为i/o功能EDIS;//始能保护功能
}

(6)驱动输出函数

void Driver_Output(Uint16 driver_state)//根据状态值driver_state输出
{GpioDataRegs.GPACLEAR.all=0x00FF;//先把低8位清0switch(driver_state){case 1:GpioDataRegs.GPASET.all=0x000B;EvaRegs.ACTRA.all=0x0001;//pwm1为有效低,其他为强制低;break;//根据状态值driver_state将对应的bit置1case 2:GpioDataRegs.GPASET.all=0x0023;EvaRegs.ACTRA.all=0x0001;//pwm1为有效低,其他为强制低;break;case 3:GpioDataRegs.GPASET.all=0x002C;EvaRegs.ACTRA.all=0x0010;//pwm3为有效低,其他为强制低;break;case 4:GpioDataRegs.GPASET.all=0x000E;EvaRegs.ACTRA.all=0x0010;//pwm3为有效低,其他为强制低;break;case 5:GpioDataRegs.GPASET.all=0x0032;EvaRegs.ACTRA.all=0x0100;//pwm5为有效低,其他为强制低;break;case 6:GpioDataRegs.GPASET.all=0x0038;EvaRegs.ACTRA.all=0x0100;//pwm5为有效低,其他为强制低;break;}
}

(7)码值与状态值的映射表

Uint16 Driver_State(Uint16 rotor_code)//根据读取的码值返回对应的状态值
{switch(rotor_code){case 0x0004:return 1;case 0x0005:return 2;case 0x0001:return 3;case 0x0003:return 4;case 0x0002:return 5;case 0x0006:return 6;}
}

(8)时间管理器的初始化

void InitEv(void)
{EvaRegs.T1CON.bit.TMODE=2;//GP TIMER1 连续增计数EvaRegs.T1CON.bit.TECMPR=1;//使能GP Timer1比较功能//=====gtimer2EvaRegs.T2CON.bit.TMODE=2;//GP TIMER2连续增计数EvaRegs.T2CON.bit.TECMPR=1;//使能GP Timer2比较功能EvaRegs.T2CON.bit.TPS=7;EvaRegs.T2PR=65535;//EvaRegs.T2CMPR=65535;EvaRegs.T1PR=14999;EvaRegs.COMCONA.bit.CENABLE=1;//使能EVA的全比较操作EvaRegs.COMCONA.bit.FCOMPOE =1;//使能pwm1-6的比较输出EvaRegs.ACTRA.all=0x0000;//pwm1-6全设置为强制低EvaRegs.CMPR1=0;//有效脉宽设置0EvaRegs.CMPR2=0;//有效脉宽设置0EvaRegs.CMPR3=0;//有效脉宽设置0EvaRegs.COMCONA.bit.ACTRLD=2;//控制寄存器立即重载//EvaRegs.CAPCONA.bit.CAPRES=0;//resetEvaRegs.CAPCONA.bit.CAP12EN = 01;//enable cap1,2EvaRegs.CAPCONA.bit.CAP3EN = 1;//enable cap3;EvaRegs.CAPCONA.bit.CAP3TSEL =0; //cap3选择GTimer2EvaRegs.CAPCONA.bit.CAP12TSEL=0;//cap1,2选择GTimer2EvaRegs.CAPCONA.bit.CAP1EDGE=11;//cap1上升下降沿都捕获EvaRegs.CAPCONA.bit.CAP2EDGE=11;//cap2上升下降沿都捕获EvaRegs.CAPCONA.bit.CAP3EDGE=11;//cap3上升下降沿都捕获EvaRegs.CAPFIFOA.bit.CAP1FIFO=01;//写CAP1的FIFO为01后,发生一个捕获即会触发中断标志位EvaRegs.CAPFIFOA.bit.CAP2FIFO=01;//写CAP2的FIFO为01后,发生一个捕获即会触发中断标志位EvaRegs.CAPFIFOA.bit.CAP3FIFO=01;//写CAP3的FIFO为01后,发生一个捕获即会触发中断标志位EvaRegs.EVAIFRC.bit.CAP1INT=1;//写1,清除CAP1中断标志位EvaRegs.EVAIFRC.bit.CAP2INT=1;//写1,清除CAP2中断标志位EvaRegs.EVAIFRC.bit.CAP3INT=1;//写1,清除CAP3中断标志位EvaRegs.EVAIMRC.bit.CAP1INT=1;//使能CAP1中断EvaRegs.EVAIMRC.bit.CAP2INT=1;//使能CAP2中断EvaRegs.EVAIMRC.bit.CAP3INT=1;//使能CAP3中断EvaRegs.EVAIFRA.bit.T1UFINT=1;//Clear underflow interrupt flag bitEvaRegs.EVAIMRA.bit.T1UFINT=1;//Enable underflow interruptEvaRegs.GPTCONA.bit.T1TOADC=1;//下溢中断标志位被置位时启动ADC
}

(9)捕获中断函数

interrupt void Cap123_isr(void)
{//ispcount++;if(EvaRegs.EVAIFRC.bit.CAP1INT){EvaRegs.EVAIFRC.bit.CAP1INT=1;//写1,清除CAP1中断标志位temp_old=temp_new;temp_new=EvaRegs.CAP1FIFO;temp =temp_new-temp_old;//EvaRegs.CAP1FBOTif(temp<0){speed= (292968.75/(temp+65536))*30;//得到转速单位rmp}else{speed= (292968.75/(temp))*30;//得到转速单位rmp}EvaRegs.CAPFIFOA.bit.CAP1FIFO=01;//写CAP1的FIFO为01后,发生一个捕获即会触发中断标志位}if(EvaRegs.EVAIFRC.bit.CAP2INT){EvaRegs.EVAIFRC.bit.CAP2INT=1;EvaRegs.CAPFIFOA.bit.CAP2FIFO=01;}if(EvaRegs.EVAIFRC.bit.CAP3INT){EvaRegs.EVAIFRC.bit.CAP3INT=1;//写1,清除CAP1中断标志位EvaRegs.CAPFIFOA.bit.CAP3FIFO=01;//写CAP1的FIFO为01后,发生一个捕获即会触发中断标志位}temp = (GpioDataRegs.GPADAT.all & 0x0700);//保持第8,9,10位的值,其他位清0temp>>=8;//右移8位rotor_code=temp;//读取码值driver_state=Driver_State(rotor_code);//由码值返回状态值Driver_Output(driver_state);//状态输出PieCtrlRegs.PIEACK.bit.ACK3=1;//清除PIEACK位,允许下次中断
}

(10)下溢中断函数

interrupt void Underflow_isr(void)
{//ufist++;EvaRegs.CMPR1=15000*d;//占空比dEvaRegs.CMPR2=15000*d;//占空比dEvaRegs.CMPR3=15000*d;//占空比dPieCtrlRegs.PIEACK.bit.ACK2=1;//清除PIEACK位,允许下次中断
}

3.实验效果

调节 电位器R102,可以实现开环调速,并且通过Debug的观察窗口可以实时观测到转测值。

基于 TMS320F2812 的直流无刷电机(BLDCM)的开环控制系统相关推荐

  1. 基于DSPic33 系列的直流无刷电机 无传感控制(Sersorless)控制系统 经过试验 百分百OK

    基于DSPic33 系列的直流无刷电机 无传感控制(Sersorless)控制系统 经过试验 百分百OK 本人长期做嵌入式开发,一直想做一下直流无刷电机的无传感器控制系统,这次有机会帮别人开发了一款直 ...

  2. 直流无刷电机开环调速基于STM32F302R8+X-NUCLEO-IHM07M1(一)

    文章目录 前言 一.直流无刷电机开环调速原理 二.STM32F302R8+X-NUCLEO-IHM07M1直流无刷电机的开环调速 2.1.功能需求 2.2.硬件设计 2.3.软件设计 2.3.1.ST ...

  3. BLDC无刷直流电机和PMSM永磁同步电机 基于stm32F1的有传感器和无传感驱动 直流无刷电机有传感器和无传感驱动程序

    BLDC无刷直流电机和PMSM永磁同步电机 基于stm32F1的有传感器和无传感驱动 直流无刷电机有传感器和无传感驱动程序, 无传感的实现是基于反电动势过零点实现的,有传感是霍尔实现. 永磁同步电机有 ...

  4. 【仿真】基于模糊优化的PID直流无刷电机控制研究

    目录 1. 介绍 2 直流无刷电机数学模型建立 3. 直流无刷电机模糊PID控制器设计 4. 仿真实验 5. 结束语 参考文献: 摘要:针对传统PID控制的直流无刷电机调速系统存在响应速度慢,控制效果 ...

  5. 基于TI DRV10970驱动直流无刷电机

    前言 之前在实验室接手了一个项目,需要使用TI的DRV10970芯片来驱动直流无刷电机带霍尔反馈,最近这几天把电机调通了,所以写个文章记录一下. 关于直流无刷电机的驱动方式,我也不过多赘述,CSDN上 ...

  6. 直流无刷电机驱动基于STM32F302R8+X-NUCLEO-IHM07M1(一)

    文章目录 前言 一.STM32F302R8+X-NUCLEO-IHM07M1驱动直流无刷电机 1.1.功能需求 1.2.硬件设计 1.3.软件设计 1.3.1.STM32CubeMX底层配置 1.3. ...

  7. 基于stm32f405控制三相无刷电机例程_直流有刷电机和无刷电机的区别

    所有电机都是由定子和转子组成,为了让转子转起来,需要不断改变电流方向,否则转子只能转半圈,这点就像自行车脚踏板.所以直流电机需要换向器.广义的直流电机包括有刷电机和无刷电机.有刷电机又称直流电机或碳刷 ...

  8. C语言基于FOC控制算法和STM32主控芯片的双路直流无刷电机控制器源码

    [FOC+STM32]双路直流无刷电机矢量控制器-使用文档

  9. 大疆开发板A型基于HAL库驱动M3508直流无刷电机及PID控制

    1.首先,我们先了解一下大疆开发板A型的资料,官方有提供 官网:RoboMaster 机甲大师赛 芯片型号STM32F427IIH6 2.了解M3508直流无刷电机的资料,官网有提供  3.于是我找到 ...

最新文章

  1. 一看就懂!【英雄联盟锐雯】与 Python 详解设计模式之门面模式
  2. 解决JBoss只能通过localhost访问不能通过IP的问题
  3. SAP CRM呼叫中心end按钮的实现逻辑
  4. npm run dev/build/serve
  5. 从mysql到大数据(二)--数据库的认识
  6. c语言流感,维生素C能防流感?专家:或减轻普通感冒引起不适症状
  7. 做柜员还是程序员_应届生放弃互联网大厂回家乡银行:程序员五万比不上柜员五千...
  8. 芯片设计群 ,欢迎 IC领域朋友请加我微信交流:Jdrobots ,加我备注IC。谢谢! 芯片设计资料
  9. iOS:segment对齐原则
  10. 移动前端开发需要注意的20个要点
  11. 《Java编程那些事儿----这是一本书》
  12. Java类成员变量的默认值
  13. 龙贝格算法的实现以及与复合梯形公式精度的比较
  14. 无法在路径“C:\WINDOWS\TEMP\”中创建临时文件: 拒绝访问。
  15. Servlet API中forward()与redirect()的区别?
  16. c语言自定义关键词,C语言关键字详解
  17. 写在使用 Linux 工作一年后 1
  18. Windows平台下Glade+GTK开发环境的搭建
  19. 金士顿服务器内存条型号解读,金士顿骇内存新版型号编码规则是什么?
  20. 【量化交易笔记】1.数据来源

热门文章

  1. 张邦鑫:组织文化 - 价值观打造方法论初步
  2. python随机密码生成以整数17为随机数种子_简述pythonpytorch 随机种子的实现
  3. 屏蔽iOS11 Xcode9下打印的乱七八糟的日志
  4. 使用各种姿势舒服的部署微前端项目(上:打包与上传)
  5. 小森生活服务器维护还要多久,小森生活暮夕深林材料刷新时间是多久_暮夕深林材料刷新时间位置汇总_3DM手游...
  6. vue3 + uni-app 封装音乐播放插件
  7. 浏览器主页被劫持篡改了怎么办
  8. 数据产品经理之数据准确性及测试必要性
  9. 从头开始学习->JVM(八):运行时数据区(下)
  10. ARM linux解析之压缩内核zImage的启动过程