在上一教程中,我们已将步进电机与ARM7-LPC2148连接。在本教程中,我们将使用ARM7-LPC2148控制伺服电机。伺服电机比步进电机具有较低的功耗优势。当到达所需位置时,伺服电机停止其功耗,但步进电机连续消耗功率以将轴锁定在所需位置。伺服电机由于其准确性高且易于处理而被广泛用于机器人项目。
在本教程中,我们将学习有关Servo Motor以及 如何将Servo与ARM7-LPC2148接口。还连接了一个电位计以改变伺服电机轴的位置,并连接一个LCD以显示角度值。
伺服马达
伺服电机是直流电机,位置控制系统和齿轮的组合。伺服电机的旋转是通过向其施加PWM信号来控制的,PWM信号的宽度决定了电机的旋转角度和方向。在这里,我们将 在本教程中使用 SG90伺服电机,它是最受欢迎和最便宜的一种。SG90是180度伺服。因此,使用该伺服器,我们可以将轴定位在0-180度之间:
- 工作电压:+ 5V
- 齿轮类型:塑料
- 旋转角度:0至180度
- 重量:9克
- 扭矩:2.5kg / cm
在开始为伺服电机编程之前,我们应该知道要发送哪种类型的信号来控制伺服电机。我们应该对MCU进行编程,以将PWM信号发送到伺服电机的信号线。伺服电机内部有一个控制电路,可读取PWM信号的占空比并将伺服电机轴定位在相应位置,如下图所示
伺服电机每20毫秒检查一次脉冲。因此,请调整信号的脉冲宽度以旋转电动机的轴。
- 1毫秒(1毫秒)脉冲宽度,用于将伺服器旋转至0度
- 1.5ms脉冲宽度可旋转至90度(空档)
- 2 ms脉冲宽度,用于将伺服旋转至180度。
在 将伺服连接到ARM7-LPC2148之前,您可以借助此伺服电机测试仪电路来测试伺服。还要检查伺服电机如何与其他微控制器连接:
- 使用Arduino的伺服电机控制
- 伺服电机与8051单片机的接口
- 使用MATLAB的伺服电机控制
- Raspberry Pi伺服电机控制
- 将伺服电机与MSP430G2连接
- 伺服电机与STM32F103C8的接口
使用LPC2148 PWM和ADC控制伺服电机
可以通过LPC2148使用PWM控制伺服电机。通过以20ms的周期和50Hz的频率向SERVO的PWM引脚提供PWM信号,我们可以将伺服电机的轴定位在180度左右(-90至+90)。
电位计用于改变PWM信号的占空比并旋转伺服电机的轴,该方法通过使用LPC2148中的ADC模块来实现。因此,我们需要在本教程中同时实现PWM和ADC概念。因此,请参考我们以前的教程,以学习ARM7-LPC2148中的PWM和ADC。
- 如何在ARM7-LPC2148中使用PWM
- 如何在ARM-LPLC2148中使用ADC
ARM7-LPC2148中的PWM和ADC引脚
下图显示了LPC2148中的PWM和ADC引脚。黄色框表示(6)PWM引脚,黑色框表示(14)ADC引脚。
所需组件
硬件
- ARM7-LPC2148
- LCD(16x2)显示模块
- 伺服马达(SG-90)
- 3.3V稳压器
- 10k电位器(2个)
- 面包板
- 连接线
软件
- Keil uVision5
- Flash魔术工具
电路图和连接
下表显示了伺服电机与ARM7-LPC2148之间的连接:
伺服针 |
ARM7-LPC2148 |
红色(+ 5V) |
+5伏 |
棕色(GND) |
地线 |
橙色(PWM) |
P0.1 |
引脚P0.1是LPC2148的PWM输出。
下表显示了LCD与ARM7-LPC2148之间的电路连接。
ARM7-LPC2148 |
液晶屏(16x2) |
P0.4 |
RS(寄存器选择) |
P0.6 |
E(启用) |
P0.12 |
D4(数据引脚4) |
P0.13 |
D5(数据引脚5) |
P0.14 |
D6(数据引脚6) |
P0.15 |
D7(数据引脚7) |
地线 |
VSS,R / W,K |
+5伏 |
VDD,A |
下表显示了ARM7 LPC2148与带有3.3V稳压器的电位计之间的连接。
3.3V稳压器IC |
引脚功能 |
ARM-7 LPC2148引脚 |
1.左销 |
-来自GND的Ve |
GND引脚 |
2.中心销 |
稳压+ 3.3V输出 |
至电位计输入和电位计的输出至LPC2148的P0.28 |
3.右销 |
+ Ve从5V 输入 |
+5伏 |
注意事项
1.这里使用3.3V的稳压器为LPC2148的ADC引脚(P0.28)提供模拟输入值。当我们使用5V电源时,我们需要使用3.3V的稳压器来调节电压。
2.电位计用于在(0V至3.3V)之间变化电压,以向LPC2148引脚P0.28提供模拟输入(ADC)
3. LPC2148的引脚P0.1将PWM输出提供给伺服电机,以控制电机的位置。
4.根据模拟输入(ADC)的值,通过LPC2148的P0.1处的PWM输出引脚,伺服电动机的位置从(0到180度)变化。
编程用于伺服电机控制的ARM7-LPC2148
要编程ARM7-LPC2148,我们需要keil uVision和Flash Magic工具。我们正在使用USB电缆通过微型USB端口对ARM7 Stick进行编程。我们使用Keil编写代码并创建一个十六进制文件,然后使用Flash Magic将HEX文件闪存到ARM7 Stick。要了解有关安装keil uVision和Flash Magic以及如何使用它们的更多信息,请单击链接ARM7 LPC2148微控制器入门并使用Keil uVision对其进行编程。
配置用于PWM和ADC的LPC2148以控制伺服电机的步骤
步骤1:-包含必要的头文件以对LPC2148进行编码
#包括
步骤2:-下一步是配置PLL以产生时钟,因为它根据程序员的需要设置LPC2148的系统时钟和外设时钟。LPC2148的最大时钟频率为60Mhz。以下几行用于配置PLL时钟生成。
void initilizePLL (void)//使用PLL生成时钟的功能 { PLL0CON = 0x01; PLL0CFG = 0x24; PLL0FEED = 0xAA; PLL0FEED = 0x55; while(!(PLL0STAT&0x00000400)); PLL0CON = 0x03; PLL0FEED = 0xAA; PLL0FEED = 0x55; VPBDIV = 0x01; }
步骤3:-接下来要做的是使用PINSEL寄存器选择LPC2148的PWM引脚和PWM功能。我们将PINSEL0用作LPC2148的PWM输出的P0.1。
PINSEL0-= 0x00000008; //将LPC2148的引脚P0.1设置为PWM3
步骤4:-接下来,我们需要使用PWMTCR(定时器控制寄存器)将定时器复位。
PWMTCR = 0x02; //重置和禁用PWM计数器
然后接下来设置决定PWM分辨率的预分频值。
PWMPR = 0x1D; //预分频寄存器值
步骤5:-接下来,设置PWMMCR(PWM匹配控制寄存器),因为它设置了诸如复位,PWMMR0和PWMMR3中断之类的操作。
PWMMCR = 0x00000203; //复位并在MR0匹配时中断,在MR3匹配时中断
步骤6:-使用PWMMR0设置PWM通道的最大周期,并将PWM占空比的Ton初始设置为0.65msec
PWMMR0 = 20000; // PWM波的周期,20毫秒 PWMMR3 = 650;// PWM波的音调0.65毫秒
步骤7:-接下来,我们需要使用PWMLER将锁存启用设置为相应的匹配寄存器
PWMLER = 0x09; // PWM3和PWM0的锁存使能
(我们使用PWMMR0和PWMMR3),因此通过在PWMLER中设置1来启用相应的位
步骤8:-要使能PWM输出到引脚,我们需要使用PWMTCR来使能PWM定时器计数器和PWM模式。
PWMPCR = 0x0800; //使能PWM3和PWM 0,单边沿控制PWM PWMTCR = 0x09; //启用PWM和计数器
步骤9:-现在我们需要从ADC引脚P0.28获取用于设置PWM占空比的电位器值。因此,我们在LPC2148中使用ADC模块将电位计的模拟输入(0至3.3V)转换为ADC值(0至1023)。
步骤10:-为了 在LPC2148中选择ADC引脚P0.28, 我们使用
PINSEL1 = 0x01000000; //将P0.28设置为ADC INPUT AD0CR =((((14)<< 8)-(1 << 21)); //设置时钟和PDN以进行A / D转换
以下各行 捕获模拟输入(0至3.3V) 并将其转换为数字值(0至1023)。然后将此数字值除以4,将其转换为 (0至255) ,最后作为PWM输出馈入 LPC2148的P0.1引脚。在这里,我们 将其值从0-1023转换为0-255,方法是将其除以4,因为LPC2148的PWM具有8位分辨率(28)。
AD0CR-=(1 << 1); //在ADC寄存器 delaytime(10)中 选择AD0.1通道 AD0CR-=(1 << 24); //开始A / D转换 while((AD0DR1&(1 << 31))== 0); //检查ADC数据寄存器中的DONE位 adcvalue =(AD0DR1 >> 6)&0x3ff; //从ADC数据寄存器的 dutycycle = adcvalue / 4中 获取结果 //获得(0到255)占空比值的公式:PWMMR1 =占空比;//将占空比值设置为PWM匹配寄存器 PWMLER-=(1 << 1); //启用占空比值的PWM输出
步骤11:-接下来,我们在LCD(16X2)显示模块中显示这些值。所以我们添加以下几行来初始化LCD显示模块
无效LCD_INITILIZE(void)//准备LCD的功能 { IO0DIR = 0x0000FFF0; //设置引脚P0.12,P0.13,P0.14,P0.15,P0.4,P0.6为OUTPUT delaytime(20); LCD_SEND(0x02); //以4位工作模式初始化LCD LCD_SEND(0x28); // 2行(16X2) LCD_SEND(0x0C); //在光标旁边显示 LCD_SEND(0x06); //自动递增光标 LCD_SEND(0x01); //显示清晰的 LCD_SEND(0x80); //第一行第一位置 }
当我们将LPC2148以4位模式连接LCD时,我们需要发送值以逐个半字节显示(上半字节和下半字节)。因此,使用以下几行。
void LCD_DISPLAY(char * msg)//打印一一发送的字符的功能 { uint8_t i = 0; while(msg!= 0) { IO0PIN =((IO0PIN&0xFFFF00FF)-(((msg&0xF0)<< 8));; //发送高位半字节 IO0SET = 0x00000050; // RS HIGH&ENABLE HIGH以打印数据 IO0CLR = 0x00000020; // RW LOW写模式 delaytime(2); IO0CLR = 0x00000040; // EN = 0,RS和RW不变(即RS = 1,RW = 0) delaytime(5); IO0PIN =((IO0PIN和0xFFFF00FF)-((msg&0x0F)<< 12)); //发送低位半字节 IO0SET = 0x00000050; // RS&EN HIGH IO0CLR = 0x00000020; delaytime(2); IO0CLR = 0x00000040; delaytime(5); i ++; } }
为了显示这些ADC和PWM值,我们在 int main() 函数中使用了以下几行 。
LCD_SEND(0x80); sprintf(displayadc,“ adcvalue =%f”,占空比); LCD_DISPLAY(displayadc); //显示ADC值(0至1023) angle =(adcvalue / 5.7); //将ADC值转换为角度(o到180度)的 公式LCD_SEND(0xC0); sprintf(anglevalue,“ ANGLE =%。2f deg”,角度); LCD_DISPLAY(角度值);
该教程的完整代码和视频描述如下