基于LPC2124的直流电机调速系统

更新时间:2023-12-27 06:26:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

ARM课程设计实验报告

基于LPC2124

的直流电机调速系统

ARM课程设计实验报告

电控学院

目 录

ARM的简介……?…………………………………………………………………(2) LPC2124简介………………………………………………………………………(3)

电机驱动芯片L298介绍…………………………………………………………(3)

直流电机调速系统软件设计流程图…………………………………………… (6)

PWM模块……………………………………………………………………………(6)

测速模块………………………………………………………………………… (7)

直流电机制动……………………………………………………………………(10)

D触发器作用………………………………………………………………………(8)

硬件电路原理图…………………………………………………………………(10)

ARM课程设计体会…………………………………………………………… (15)

参考文献…………………………………………………………………………(14)

基于LPC2124的直流电机调速系统源代码……………………………………(10)

1.1 ARM的简介

编/解码器,定位于智能PDA市场;Atmel公司的AT91系列片内集成了大容量 Flash和RAM、高精度A/D转换器以及大量可编程I/O端口,特别适合于工业控制领域;Philips公司的LPC2000系列片内集成了128位宽的零等待FlaARM公司的IP核已经由ARM7,ARM9发展到今天的ARM11版本。ARM11囊括了Thumb-2,CoreSight,TrusZone 等众多业界领先技术,同时由单一的处理器内核向多核发展,为高端的嵌入式应用提供了强大的处理平台。高集成度SOC芯片的采用可以带来一系列好处,诸如减少了外围器件和PCB面积,提高系统抗干扰能力,缩小产品体积,降低功耗等。

ARM 公司是一家IP供应商,其核心业务是IP核以及相关工具的开发和设计。半导体厂商通过购买ARM公司的IP授权来生产自己的微处理器芯片。由此以来,处理器内核来自ARM公司、各芯片厂商结合自身已有的技术优势以及芯片的市场定位等因数使芯片设计最优化,从而产生了一大批高度集成、各据特色的SOC芯片。例如Intel公司的XScale系列集成了LCD控制器、音频sh存储器以及I2C, SPI,PWM,UART等传统接口,极高的性价比使它对传统的8/16位MCU提出了严峻的挑战。本次设计仍使用的ARM7系列。

1.2 ARM的广泛应用

ARM 微处理器及技术的应用几乎已经深入到各个领域:

1 、工业控制领域:作为 32 的 RISC 架构,基于 ARM 核的微控制器芯片不但占据了高端微控制器市场的大部分市场份额,同时也逐渐向低端微控制器应用领域扩ARM微控制器的低功耗、高性价比,向传统的 8 位 /16 位微控制器提出了挑战。

2 、无线通讯领域:目前已有超过 85% 的无线通讯设备采用了 ARM 技术, ARM 以其高性能和低成本,在该领域的地位日益巩固。

3 、网络应用:随着宽带技术的推广,采用 ARM 技术的 ADSL 芯片正逐步获得竞争优势。此外,ARM 在语音及视频处理上行了优化,并获得广泛支持,也对 DSP 的应用领域提出了挑战。

4 、消费类电子产品: ARM 技术在目前流行的数字音频播放器、数字机顶盒和游戏机中得到广泛采用。

5 、成像和安全产品:现在流行的数码相机和打印机中绝大部分采用 ARM 技术。手机中的 32位 SIM 智能卡也采用了 ARM 技术。 除此以外, ARM 微处理器及技术还应用到许多不同的领域,并会在将来取得更加广泛的应用。

1.3本课题的意义

目前,基于ARM技术的嵌入式系统几乎已经深入应用到各个领域,是当今32位嵌入式系统应用的主流。ARM在工业控制领域的应用也受到越来越多的关注。 本课题设计了一个基于ARM的嵌入式直流电机转速监控系统。该系统使用PHILIPS公司的以ARM7TDMI-S为内核的LPC2124芯片作为控制核心,配置相应的外设及接口电路,运用性能价格比较好的集成电机控制芯片L298作为直流电动机的PWM驱动器件;采用光电编码器实现对转速信号的采集;采用LPC2124内部集成定时器的捕获功能对编码器生成的脉冲序列信号进行测量;采用74LS74作为鉴相器而识别电动机实时转向;采用单闭环PI控制调节转速;采用LCD1602系列显示屏即时显示电动机的转动信息;采用4×4矩阵键盘对转速及转向进行设置和控制。系统软件主要使用C语言编写,遵循模块化设计的原则,编写了转速的测量、转速的PWM驱动、转速的PI调节、转速的显示、键盘输入等程序模块,程序代码具有良好的易维护性和可移植性。最后使用Proteus ISIS仿真工具对系统仿真,并在仿真平台上对系统性能进行测试与分析。 本系统的设计精度可以满足一般工业控制的要求,能够应用到实际的生产生活中,满足现代化生产的需要。而且能够防止用户的误操作,增强了系统运行的安全性和稳定性,具有一定的实用性和较高的社会推广价值。 关键词:ARM;嵌入式系统;直流电机转速控制;LPC2124

2.1 LPC2124简介

LPC2124是基于一个支持实时仿真和跟踪的16/32位ARM7TDMI-S CPU的微控制器,并带有256KB嵌入的高速Flash存储器。128位宽度的存储器接口和独特的加速结构使32位代码能够在最大时钟速率下运行,且可使用16位Thumb模式。

LPC2124支持多种通信接口,包括UART, 和SPI等串行接口以及PWM输出接口,外围接口部分设计极为方便、灵活。

2.2 电机驱动芯片L298介绍

L298N是ST公司生产的一种高电压、大电流电机驱动芯片。该芯片采用15脚封装。主要特点是:工作电压高,最高工作电压可达46V;输出电流大,瞬间峰值电流可达3A,持续工作电流为2A;额定功率25W。内含两个H桥的高电压大电流全桥式驱动器,可以用来驱动直流电动机和步进电动机、继电器线圈等感性负载;采用标准逻辑电平信号控制;具有两个使能控制端,在不受输入信号影响的情况下允许或禁止器件工作有一个逻辑电源输入端,使内部逻辑电路部分在低电压下工作;可以外接检测电阻,将变化量反馈给控制电路。使用L298N芯片驱动电机,该芯片可以驱动一台两相步进电机或四相步进电机,也可以驱动两台直流电机。芯片内部结构图如图2所示。

图2 L298芯片的内部结构图

L298驱动直流电机参考表1

表1 L298驱动直流电机参考表

输入PWM信号改变电机 旋转方式 控制端IN1 控制端IN2 控制端IN3 控制端IN4 调速端A 调速端B 正转 M1 反转 高 低 低 高 / / / / 高 高 / / 脉宽可调速

停止 正转 M2 反转 停止 低 / / 低 低 / / 低 / 高 低 / / 低 高 / 高 / / / / 高 高 高 2.3系统原理结构

根据本系统的设计目标,本系统的原理结构框图如图所示。

系统的原理结构框图

如图所示,本系统的主要功能模块有:转速检测模块、光电转换、单片机、PWM电机驱动模块、显示模块、键盘模块。转速传感器和光电转换将电机转速转化为可以测量的电信号。PWM电动机驱动用来将计算机信号转换为电动机驱动信号,键盘和显示器是本系统的人机接口。

2.4系统硬件体系结构

本设计的统硬件体系可以分为三部分,第一部分为微控制器组成的控制核心电路,第二部分为转速检测模块和电动机驱动模块组成的电动机接口电路,第三部分为键盘输入模块和液晶显示模块组成用户接口电路,设计方案的硬件详细框图如图。

详细的硬件体系结构框图

2.5系统软件体系结构设计

结合本系统的性能要求,本设计采用前后台系统,其体系结构如图所示。

软件体系结构框图

3.1 直流电机调速系统软件设计流程图

直流电机调速系统软件设计流程图如图3所示,中断程序如图4、图5所示。

图3 调速系统软件 图4 按键中断 图5 测速中断

设流程图 程序流程图 程序流程图

3.2 PWM模块

系统采用PWM方法调整电动机的速度,首先应确定合理的脉冲频率。脉冲宽度一定时,频率对电机运行的平稳性有较大影响,脉冲频率高电动机运行的连续性好,但带负载能力差;脉冲频率低则反之。

调脉宽的方式有三种:定频调宽、定宽调频和调宽调频。

我们采用了定频调宽方式,因为采用这种方式,电动机在运转时比较稳定;并且在采用LPC2124产生PWM脉冲的软件实现上比较方便。

PWM输出频率采用系统时钟频率,通过转速调节器调节PWM占空比,实现直流电机的调速驱动。PWM初始化子程序流程如图6所示。

图6 PWM初始化流程图

PWM驱动电路图

下图为采用内部集成有两个桥式电路的专用芯片L298所组成的电机驱动电路。本设计中只使用L298其中一组引脚控制电机,另一组没有使用。如图所示,P0.25控制电机的方向,P0.21输入的PWM控制电机的速度。P0.25为“0”,P0.21输入PWM波时,电机正转,通过改变PWM的占空比可以调节电机的速度。而当P0.25为“1”,P0.25输入PWM波时,电机反转,同样通过改变PWM的占空比来调节电机的速度。

PWM驱动电路图

3.3测速模块(软件实现)

本系统采用T法测速,旋转编码器输出的脉冲由LPC2124的P0.28捕获,电机每转一圈旋转编码器输出60个脉冲,每捕获一个编码器输出脉冲,则进入中断读取定时器的值,计算测速时间,通过公式(1-2)计算转速 (1-1) T法测速原理如图7所示。

图7 T法测速原理图

定时器0初始化流程图如图8所示。

图8 定时器0初始化流程图

3.4直流电机制动

直流电机要达到快速制动,必须采用反压制动方式,所以制动过程采用另外独立的程序设计。因为原先采用统一的调速程序发现,制动过程反转超调后就向反方向加速,导致系统不稳定。采用独立的程序设计实现电机逐级制动,随转速降低减小PI参数,最后置高P0.6、P0.7,保证超调也不会反转加速。 3.5 LCD显示电路

本系统的显示部分采用RT1602字符显示模块,与采用数码管相比,硬件连接和软件调试上都由优势。只要把要显示的内容放进液晶模块的显示存储器里面就可以直观的显示出指定的内容,操作方便。本设计将LCD连接到LPC2124的P0.0-P0.10口上,其电路如图3-14所示。

图3-14 显示电路原理图

1602采用标准的14脚接口,其各引脚定义如下:

第1脚:VSS为地电源。

第2脚:VDD接5V正电源。

第3脚:V0为液晶显示器对比度调整端。

第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。 第5脚:RW为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和RW共同为低电平时可以写入指令或者显示地址,当RS为低电平RW为高电平时可以读忙信号,当RS为高电平RW为低电平时可以写入数据。

第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。

第7~14脚:D0~D7为8位双向数据线。 第15~16脚:空脚。

3.6键盘电路

本系统采用的是4×4矩阵键盘,接到LPC2124的P1.16-P1.23口而实现,键盘的电路图如图3-15所示。

图3-15 键盘电路

3.7 D触发器测量电机转速

如图所示,测量电机的转速时使用两个传感器进行测量,一旦电机开始转,传感器会输出脉冲信号,分别接入D触发器的输入端和CLK

端,D触发器为脉冲触发,输出端Q会随着输入端的变化而出现高低电平的转换,从而测量电机的转向。

表5-1 Motor-Encoder参数表

参数名 额定电压 线圈电阻 线圈电感 空载转速 负载率 每转脉冲数 12 V 120 ? 100 mH 720 rpm 50 % 300 参数值

由此参数表可知:

① 电机的最大转速=空载转速×负载率

所以本系统中电机的最大转速为350转/分钟。 ② 电机的转速值(rpm)=(编码器的脉冲频率×60)/每转脉冲数 所以本系统中电机的转速值rpm=编码器的脉冲频率/5。

本设计的转速转向检测电路仿真图如图5-2所示,其中将MOTOR-ENCODER的编码器两侧的其中一个引脚作为转速检测,然后再辅以另一侧的引脚接入鉴相器,本设计使用Proteus库中的74LS74仿真芯片实现脉冲相位检测,从而实现转向识别 L298驱动直流电机参考表

用两个传感器检测电机的转速将输出脉冲接入D触发器的CLK及D端,D触发器当

输入PWM信号改变脉宽可调速 电机 旋转方式 控制端IN1 控制端IN2 控制端IN3 控制端IN4 调速端A 调速端B 正转 反转 停止 正转 反转 停止 高 低 低 / / 低 低 高 低 / / 低 / / / 高 低 / / / / 低 高 / 高 高 高 / / / / / / 高 高 高 M1 M2

硬件电路原理图:

LCD2LM032LVSSVDDVEERSRWE456P0.8P0.9P0.101237891011121314D0D1D2D3D4D5D6D7C1X130pFP0.0P0.1P0.2P0.3P0.4P0.5P0.6P0.7VCC+12VU4:AR11M93571012611115IN1IN2IN3IN4ENAENBVCC4VSOUT1OUT2OUT3OUT4GND8U3231314U16261XTAL1XTAL2P0.0/TxD0/PWM1P0.1/RxD0/PWM3P0.2/SCL/CAP0.0P0.3/SDA/MAT0..0/EINT1P0.4/SCK0/CAP0.1P0.5/MISO0/MAT0.1P0.6/MOSI0/CAP0.2P0.7/SSEL0/PWM2/EINT2P0.8/TxD1/PWM4P0.9/RxD1/PWM6/EINT3P0.10/RTS1/CAP1.0P0.11/CTS1/CAP1.1P0.12/DSR1/MAT1.0P0.13/DTR1/MAT1.1P0.14/DCD1/EINT1P0.15/RI1/EINT2P0.16/EINT0/MAT0.2/CAP0.2P0.17/CAP1.2/SCK1/MAT1.2P0.18/CAP1.3/MISO1P0.19/MAT1.2/MOSI1P0.20/MAT1.3/SSEL1/EINT3P0.21/PWM5/CAP1.3P0.22/CAP0.0/MAT0.0P0.23P0.24P0.25+3.3VP0.27/AIN0/CAP0.1/MAT0.1P0.28/AIN1/CAP0.2/MAT0.2P0.29/AIN2/CAP0.3/MAT0.3P0.30/AIN3/EINT3/CAP0.075143236317495859504225186V3AV3V3V3V18AV18V18VSSA_PLLVSSAVSSVSSVSSVSSVSSLPC2124P1.16/TRACEPKT0P1.17/TRACEPKT1P1.18/TRACEPKT2P1.19/TRACEPKT3P1.20/TRACESYNCP1.21/PIPESTAT0P1.22/PIPESTAT1P1.23/PIPESTAT2P1.24/TRACECLKP1.25/EXTIN0P1.26/RTCKP1.27/TDOP1.28/TDIP1.29/TCKP1.30/TMSP1.31/TRST19212226272930313334353738394145P0.0P0.1P0.2P0.3P0.4P0.5P0.6P0.7P0.8P0.9P0.101274HC08VCC57RSTU4:B46574HC08VCCC630pFCRYSTALSENSASENSBC7C222uf22ufL298R32M2R110R222GND46475354551PWM驱动2转向检测359方向开关11131415161284484440363228246460565220U5:A74041U2:ADCLK23+88.8Q转速检测+1.8VR610k174LS74R6QS54R710kR810kR910k741RST8520963设置+/-UPDOWN确定 用designer设计的原理图如下

ARM课程设计体会

此次课程设计,总体来说结果并不十分理想但却受益匪浅,虽然最后我们仿

真成功了,但由于与实验箱上的电路所用芯片不同,而无法运行,然而在这个过程中我收获到了很多很多东西。

从选题到定稿,从理论到实践,在这个过程中我们遇到了各种各样的问题, 发现我们的知识有很大的欠缺,对一些元器件的认识不过深刻,对ARM C语言也掌握得不好,通过这次课程设计之后,也把以前所学过的知识重新温故。同时在实践的过程中,使我们明白理论和实际相结合是多么的重要,只有将理论运用于实践才是知识真正活了起来。

我在图书馆和网上查阅了大量的ARM的相关资料,2124电机驱动芯片,12864液晶显示器和光电传感器的资料,由于资料比较分散,所以整理有用的资料就显得很重要,有些东西实在是不懂我就把资料带回来大家一商量,让我们受益匪浅。

这次课程设计终于完成了,设计中遇到了很多问题,在老师和同学们的指导与帮助下,终于游逆而解,让我学得到很多实用的知识,同时也为以后的课程设计打下了一定的基础。在此,对给过我帮助的各位指导老师和所有同学再次表示忠心的感谢!

XXX

一周的课程设计很快就过去了,可结果却并不很理想,虽然我们每个人都

很努力。当选题确定以后,我们就开始画硬件原理图,可就软件在电脑上装了一天还没装上,费了九牛二虎之力才弄好,可ARM芯片又和实验室所用的不一样,在万般无奈之下只好换了芯片,这样就没法在实验室的试验箱上实现,我们做这个课程设计,可以说是困难重重,弄得每个人都很纠结,可我们仍在坚持,尽最大努力的把它做好,虽然最后还是没能成功。

通过这次课程设计使得我懂得了理论与实践结合是很重要的,只有理论知识

是远远不够的,只有把学到的知识与实际结合起来,从实践中得出结论,才能更好的理解理论知识,才能提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,在这次设计中发现了自己的不足之处,对ARM知识理解得不够深刻,掌握的不够牢固,可能因为我要考研所以这次课程设计受到一点影响,课程设计虽然结束了,但我们的学习还没有结束,我们需要继续努力学习。

这几天让我把以前所学的ARM知识重新温故,尤其是定时器和中断的知识, 这次课程设计我最大的体会就是我还要不断的学习,这样才能提高自己。 XXX

从四个题目中选择直流电机的测速时,心里觉得还是挺简单的,但是当真正设计起来的时候才觉得细节是很重要的问题,从上网查资料再到图书馆看书,许多的资料看得眼花缭乱,其实硬件的问题还是很容易解决的,我们虽然学过一点C语言,但却很不纯熟,我们做单片机课程设计时,我们组用的汇编程序,学ARM时大部分的程序都是C语言,所以程序就成为我们的弱项。此次的软件部有我设计,因为时间有限,程序变起来很费劲,所以参考了书上的部分程序。其实确实如老师说的很简单,但是由于我们接触有限所以对ARM单片机的程序设计有一定的局限性,再加上我们用的ARM芯片与实验室上的ARM芯片有所出入就导致我们的实践部分不能实现,这是我们的一大损失,也让我觉得有些挫败。 通过这次课程设计让我了解,要完成一件事情大家的合作是分不开的,探讨询问都是家常便饭,自己做的部分并不是你自己懂得就可以,你要让你的搭档知道你所做部分的原理,而且三个人的相互配合也是很重要的。懂得体谅懂得理解同时对只是追求的渴望和对原理的探讨都是很必要的。

通过这次课程设计我充分认识到自己所学到只是皮毛,很多地方当要用的时候才发现知道的太少,真是应了那句,书到用时方知少,以后的时间我恐怕要对自己在这方面有更深的要求。 XXX

参考文献

[1] 周立功主编,ARM嵌入式系统基础教程(第2版)[M].北京:北京航天航空

大学出版社,2008.9.

[2] 杨旭强、吴红星、金钊编著,基于ARM的电动机控制技术[M].北京:中国电力出版社,2008.

[3]沈建华.译.ARM嵌入式系统开发、软件设计与优化[M].北京:北京航空航天大学出版社.2005

[4] 周润景、袁伟亭、景晓松编著,Proteus在MCS-51&ARM7系统中的应用百例[M].北京:电子工业出版社,2006..10.

[5] 陈伯时主编,电力拖动自动控制系统——运动控制系统[M].北京:机械工业

出版社,2003.7.

基于LPC2124的直流电机调速系统源代码

#include \#define rs (1<<8) #define rw (1<<9) #define en (1<<10) #define busy (1<<7)

#define MIN_PULSES 6 #define MAX_PULSES 1785 #define MAX_PWM 16000

#define MIN_PWM 1

#define CKTIME 100 /*100ms*/

#define P_ref 1 #define I_ref 2

int32 P_val=0; int32 I_val=0; int32 D_val=0; int32 T_val=0;

int32 changeref=1; uint8 dir[4]={'+','\\0','-','\\0'};

uint8 rpm[]={\

uint8 current[]={%uint8 seted[]={\ Seted:%uint8 curse[4]={'>','\\0',' ','\\0'};

uint8 enternum[]={%uint8 strcrt[5]; uint8 strset[5]; uint8 flag=1;

uint8 shutdown=0; uint8 key=16; uint8 keyhit=16; uint8 dirhit=0; uint8 keydown=0; uint8 downindex=0; uint8 dircrt=0; int32 varcrt=0; int32 varset=(int32)0; int32 keysum=(int32)0;

uint32 rtcounts=0;

int32 setcounts=0; int32 deltacounts=0; int32 pwmdata=0;

/**************************************************************************** * 功能:延时

****************************************************************************/ void delay(int ms) { int i; while(ms--) {

for(i = 0;i<250;i++){} } }

/**************************************************************************** * 名称:WrOp() * 功能:写函数

****************************************************************************/ void WrOp(uint8 dat)

{ }

IO0CLR=rs; IO0CLR=rw; IO0CLR=0xff; IO0SET=dat; IO0SET=en; IO0CLR=en;

//全部清零 //先清零 //再送数

/**************************************************************************** * 名称:WrDat() * 功能:写数据函数

****************************************************************************/ void WrDat(uint8 dat) {

IO0SET=rs; IO0CLR=rw; IO0CLR=0xff; IO0SET=dat; IO0SET=en;

//先清零 //再送数

IO0CLR=en; }

/**************************************************************************** * 名称:lcd_init() * 功能:lcd初始化函数

****************************************************************************/ void lcd_init(void) { }

/**************************************************************************** * 名称:DisText() * 功能:显示文本函数

****************************************************************************/ void DisText(uint8 addr,uint8 *p) { WrOp(addr);

WrOp(0x38); WrOp(0x06);

WrOp(0x0c); IO0CLR=0x7ff;

//16*2显示,5*7点阵,8位数据 //光标加1

//开显示,关光标

//设置为输出

IO0DIR |=0x000007ff;

while(*p !='\\0')WrDat(*(p++));

}

/**************************************************************************** * 功能:闪动的提示符,必须放入执行循环中

****************************************************************************/ void DisCurse(uint8 addr) { }

/**************************************************************************** 功能:浮点数值转换为字符串函数,5.2格式

****************************************************************************/

void Int2Str(unsigned char str[],int32 var) {

for(i=5;i>=3;i--) {

int32 t=(int32)(var*100); int32 i,k;

DisText(addr,curse); DisText((addr+1),(curse+2)); DisText((addr+2),(curse+2)); delay(300);

DisText(addr,curse); DisText((addr+1),curse); DisText((addr+2),(curse+2)); delay(300);

DisText(addr,curse); DisText((addr+1),curse); DisText((addr+2),curse); delay(300);

DisText(addr,(curse+2)); DisText((addr+1),(curse+2)); DisText((addr+2),(curse+2)); delay(200);

k=(int32)pow(10,i);

str[5-i]=(unsigned char)((int32)((t/k))+48); t=(t%k); }

str[3]=(unsigned char)((((int32)(var)))+48);

str[4]='\\0';

}

/**************************************************************************** * 名称:Key_Process()

****************************************************************************/ void Key_Process(uint8 num) {

switch(num) { case 0:keyhit=7;break;

case 1:keyhit=8;break;

case 2:keyhit=9;break;

case 3:keyhit=10;dirhit=!dirhit;break;//转向设置

case 4:keyhit=4;break; case 5:keyhit=5;break; case 6:keyhit=6;break;

case 7:keyhit=11;if(!flag)varset=(int32)(varset+1);//在监视状态置直接微调整转数 else keysum=(int32)(keysum+1);break;//在设置状态调整keysum case 8:keyhit=1;break; case 9:keyhit=2;break; case 10:keyhit=3;break;

case 11:keyhit=12;if(!flag)varset=(int32)(varset-1);//在监视状态直接微调整转数 else keysum=(int32)(keysum-1);break;//在设置状态调整keysum case 12:keyhit=13;shutdown=!shutdown; if(shutdown) {flag=0;varset=0;}

else {flag=1;keysum=(int32)0;downindex=0;WrOp(0x01);} break;// 强制将电机重启为初始值

case 13:keyhit=0;break; case 14:keyhit=14;flag=1;keysum=(int32)0;downindex=0;WrOp(0x01);break;// 进入设置模式 式

case 15:keyhit=15;flag=0; varset=keysum;WrOp(0x01);break;//确定输入,返回监视模

default:break; }

if((keysum<0))keysum=0;

if((varset<0))varset=0;

if(varset>350)varset=350;// 最大转数限制

}

void __irq catch_pulses(void) {

rtcounts++;

T0IR=0x20; //清除中断标志,复位CR1中断 VICVectAddr=0x00; //通知VIC中断处理结束

}

void __irq PI_porcess(void)// 每 CKTIME ms计算一次占空比 {

deltacounts=(rtcounts*1000)/CKTIME;//对脉冲速率采样 setcounts=varset*5;//把设定的转速转换为脉冲速率 }

T1IR=0x01; //清除中断标志,复位MR0中断 VICVectAddr=0x00; //通知VIC中断处理结束 if(T_valMAX_PWM)T_val=MAX_PWM;

pwmdata=(int32)T_val;

varcrt=deltacounts/5;//把采样的脉冲速率转换为转速 pwmdata=(int32)(P_val/10); rtcounts=0;

P_val=setcounts*P_ref*changeref;

if((setcounts-deltacounts)>0)

if(I_val

if(I_val>(-MAX_PULSES))I_val--;

T_val=(I_val*I_ref*changeref*1000)/CKTIME;//平均误差的累积和

T_val=(int32)(T_val/10);//还原changeref的放大倍率

void capinit(void)

{

T0PR=5; //2个主频后TC加1 T0CCR=(1<<3)|(1<<5); //设置CAP0.1上升沿捕获,捕获后将TC的值放入T0CR1,并产生中断

T0TC=0;

T0TCR=0x01; //启动定时器 }

void time1init(void)

{

T1PR=99; //设置定时器分频为25分频,得147450Hz T1MCR=0x03; //匹配通道0匹配中断并复位T1TC

T1MR0=702; //比较值,分母为Fosc,分子/2为0.5秒以此类推,此处为0.01秒,27648/10

T1TCR=0x03; //启动并复位T1TC T1TCR=0x01; }

void pwminit(void) {

PWMPR=0x00; //不分频,计数频率为Fpclk PWMMCR=0x02; //设置PWMMR0匹配时复位PWMTC

PWMMR0=MAX_PWM; //设置PWM周期 PWMMR5=1; //设置PWM占空比

PWMLER=0x21; //PWMMR0,PWMMR5锁存 PWMPCR=1<<13; //允许PWM5输出,单边PWM PWMTCR=0x09; //启动定时器,PWM使能

}

/**************************************************************************** * 名称:main() * 功能:显示文本

****************************************************************************/

int main(void)

{

PINSEL1=0x00800400;//引脚功能选择

IO0DIR =0x020007ff;//对GPIO的方向设置,0入1出。

changeref=(10*MAX_PWM )/ MAX_PULSES;//changeref被放大; lcd_init();//LCD的初始化

Keyboard_Initialize(); pwminit(); //PWM初始化

capinit(); time1init();

VICIntSelect=0x00;

VICVectCntl0=0x24;

VICVectAddr0=(uint32)catch_pulses;

VICVectCntl1=0x25; VICVectAddr1=(uint32)PI_porcess;

VICIntEnable=0x00000030; IO0CLR =(1<<25); //设置初始方向电位 pwmdata=MIN_PWM; while(1) {

key=Keyboard_Scan();

if((key!=255))keydown=1;//捕获按键按下的响应

else keydown=0;

Key_Process(key);//键值对应的操作,修改flag,keysum,varset,dirhit,keyhit.

PWMMR0=MAX_PWM; PWMMR5=pwmdata; PWMLER=0x21;

if(!flag) {

if(IO0PIN&(1<<23))dircrt=0;//转向检测 else dircrt=1;

if(dirhit)IO0SET =(1<<25);//转向开关 else IO0CLR =(1<<25);

DisText(0x80,current); DisText(0x91,rpm); DisText(0xc0,seted);

DisText(0xd1,rpm);

if(dircrt)DisText(0x88,dir);//监视的转向显示 else DisText(0x88,(dir+2));

}

if(dirhit)DisText(0xc8,dir);//设置的转向显示 else DisText(0xc8,(dir+2));

Int2Str(strcrt,varcrt);//监视的转速显示 Int2Str(strset,varset);//设置的转速显示 DisText(0x89,strcrt); DisText(0xc9,strset); delay(100); } else {

if((keydown)&&(keyhit<=9)&&(downindex<4)) {

keysum=(int32)(keysum*10+keyhit);//按键和值 downindex++;

}

DisText(0x80,enternum);

DisCurse(0xc0);

Int2Str(strset,keysum);//用户输入的键值显示 DisText(0xc6,strset);

if(dirhit)DisText(0xc4,dir);//设置的的转向显示 else DisText(0xc4,(dir+2)); delay(100); } }

本文来源:https://www.bwwdw.com/article/7g0x.html

Top