如何使用ARM7-LPC2148微控制器中的PWM控制LED的亮度

发布者:Ziran520最新更新时间:2023-02-08 来源: elecfans关键字:ARM7  LPC2148  微控制器  PWM控制  LED 手机看文章 扫描二维码
随时随地手机看文章

众所周知,微控制器从模拟传感器获取模拟输入,并使用ADC(模数转换器)来处理这些信号。但是,如果微控制器想要产生模拟信号来控制伺服电机、直流电机等模拟操作设备怎么办?微控制器不会产生像 1V、5V 这样的输出电压,而是使用一种称为 PWM 的技术来操作模拟设备。PWM的一个例子是我们笔记本电脑的冷却风扇(直流电机)需要根据温度进行速度控制,这也是通过在主板中使用脉宽调制(PWM)技术来实现的。


在本教程中,我们将使用 ARM7-LPC2148 微控制器中的 PWM 控制 LED 的亮度。


PWM(脉冲宽度调制)

PWM 是一种使用数字值控制模拟设备的好方法,例如控制电机的速度、LED 的亮度等。虽然 PWM 不提供纯模拟输出,但它会产生不错的模拟脉冲来控制 Analog Devices。PWM 实际上调制矩形脉冲波的宽度,以便得到结果波平均值的变化。


PWM 的占空比

PWM 信号保持高电平(开启时间)的时间百分比称为占空比。如果信号始终打开,则占空比为 100%,如果始终关闭,则占空比为 0%。

占空比=开启时间/(开启时间+关闭时间)

pYYBAGMtXNCAMOj8AAAZHO5ECTU282.gif

ARM7-LPC2148 中的 PWM

ARM7-LPC2148 有 6 个 PWM 引脚和 14 个 ADC 引脚。它具有 8 位 PWM 分辨率(2 8),即计数器和变量可以高达 255,因此:

255 的数字值可提供 LED 的全亮度(100% 占空比)

同样,数字值 127 可提供 50% 的 LED 亮度(占空比为 50%)

数字值 64 提供 25% 的 LED 亮度(25% 占空比)

PWM-in-ARM7-LPC2148.gif

ARM7-LPC2148 中的 PWM 引脚

下图显示了ARM7-LPC2148 的 PWM 输出引脚。PWM共有 6 个引脚。

pYYBAGMtXNWASp14AADIPErUgzY620.jpgpYYBAGMtXIiADus6AAASJM6ZtwQ911.png

ARM7-LPC2148 中的 PWM 寄存器

在进入我们的项目之前,我们需要了解 LPC2148 中的 PWM 寄存器。

这是 LPC2148 中用于 PWM 的寄存器列表

1. PWMPR : PWM 预分频寄存器

用途:它是一个 32 位寄存器。它包含在递增 PWM 定时器计数器之前 PCLK 必须循环的次数(减 1)(它实际上保存了预分频计数器的最大值)。

2. PWMPC: PWM 预分频计数器

用途:它是一个 32 位寄存器。它包含递增的计数器值。当该值等于 PR 值加 1 时,PWM 定时器计数器 (TC) 递增。

3. PWMTCR : PWM 定时器控制寄存器

用途:它包含计数器使能、计数器复位和 PWM 使能控制位。它是一个 8 位寄存器。

pYYBAGMtXIOAfDJXAAAfylyjcBA333.png

4. PWMTC : PWM 定时器计数器

用途:它是一个 32 位寄存器。它包含递增 PWM 定时器的当前值。当预分频器计数器 (PC) 达到预分频器寄存器 (PR) 的值加 1 时,该计数器递增。

5. PWMIR: PWM中断寄存器

用途:它是一个 16 位寄存器。它包含 PWM 匹配通道 0-6 的中断标志。当该通道(MRx 中断)发生中断时,将设置一个中断标志,其中 X 是通道号(0 到 6)。

6. PWMMR0-PWMMR6: PWM匹配寄存器

用途:它是一个 32 位寄存器。 实际上,匹配通道组允许设置 6 个单边沿控制或 3 个双边沿控制 PWM 输出。您可以修改七个匹配通道来配置这些 PWM 输出以满足您在 PWMPCR 中的要求。

7. PWMMCR : PWM 匹配控制寄存器

用途:它是一个 32 位寄存器。它包含控制所选匹配通道的中断、复位和停止位。PWM 匹配寄存器和 PWM 定时器计数器之间发生匹配。

poYBAGMtXH6ACca-AAAwpd_Ve6s532.png

8. PWMPCR : PWM 控制寄存器

用途:它是一个 16 位寄存器。它包含启用 PWM 输出 0-6 并为每个输出选择单边沿或双边沿控制的位。

poYBAGMtXHmAYMtLAAAYc53b3Mw236.png

9. PWMLER: PWM 锁存器使能寄存器

用途:它是一个 8 位寄存器。它包含每个匹配通道的匹配 x 锁存位。

pYYBAGMtXHOAPu_VAAAS01YEfP4295.png

现在让我们开始构建硬件设置来演示 ARM 微控制器中的脉冲宽度调制。

所需组件

poYBAGMtXG-ATghvAAAUybA6ZP8861.png

电路图和连接

pYYBAGMtXU-AFDC5AAGVr6j7zoY793.pngpYYBAGMtXNyAZFQXAAE6423-bjQ878.jpg

LCD和ARM7-LPC2148之间的连接

poYBAGMtXGiAH7rsAAAd2-19aOM953.png

LED与ARM7-LPC2148之间的连接

LED 的 ANODE 连接到 LPC2148 的 PWM 输出 (P0.0),而 LED 的 CATHODE 引脚连接到 LPC2148 的 GND 引脚。

ARM7-LPC2148与带3.3V稳压器的电位器连接

pYYBAGMtXGOAPG0AAAAWzQZJclo520.png

需要注意的点

1. 这里使用 3.3V 的稳压器为 LPC2148 的 ADC 引脚 (P0.28) 提供模拟输入值,因为我们使用的是 5V 电源,我们需要使用 3.3V 的稳压器来调节电压。

2. 电位器用于在(0V 至 3.3V)之间改变电压,以向 LPC2148 引脚 P0.28 提供模拟输入(ADC)

为 PWM 和 ADC 编程 LPC2148 所涉及的步骤
第 1 步:-首先是配置 PLL以生成时钟,因为它根据程序员的需要设置 LPC2148 的系统时钟和外设时钟。LPC2148 的最大时钟频率为 60Mhz。以下行用于配置 PLL 时钟生成。

void initilizePLL (void) //使用 PLL 产生时钟的函数
{
PLL0CON = 0x01;
PLL0CFG = 0x24;
PLL0FEED = 0xAA;
PLL0FEED = 0x55;
而(!(PLL0STAT&0x00000400));
PLL0CON = 0x03;
PLL0FEED = 0xAA;
PLL0FEED = 0x55;
VPBDIV = 0x01;
}
第 2 步:-接下来是使用 PINSEL 寄存器选择 LPC2148 的 PWM 引脚和 PWM 功能。我们使用 PINSEL0,因为我们使用 P0.0 作为 LPC2148 的 PWM 输出。

PINSEL0 = 0x00000002;//设置引脚P0.0为PWM输出
第 3 步:-接下来我们需要使用 PWMTCR(定时器控制寄存器)重置定时器。

PWMTCR = (1<<1); //设置PWM定时器控制寄存器为计数器复位
然后,设置决定 PWM 分辨率的预分频值。我将它设置为零

PWMPR = 0X00;//设置PWM预分频值
第 4 步:-接下来我们需要设置 PWMMCR(PWM 匹配控制寄存器),因为它设置了复位等操作,PWMMR0 的中断。

PWMMCR = (1<<0)|(1<<1); //设置PWM匹配控制寄存器
第 5 步:-使用 PWMMR 设置 PWM 通道的最大周期。

PWMMR0 = PWM值;//给PWM值最大值
在我们的例子中,最大值是 255(对于最大亮度)

第 6 步:-接下来我们需要使用 PWMLER 将 Latch Enable 设置为相应的匹配寄存器

PWMLER = (1<<0); //启用PWM锁存器
(我们使用 PWMMR0)所以通过在 PWMLER 中设置 1 来启用相应的位

第 7 步:-要使 PWM 输出到引脚,我们需要使用 PWMTCR 来启用 PWM 定时器计数器和 PWM 模式。

PWMTCR = (1<<0) | (1<<3); //启用PWM和PWM计数器
第 8 步:-现在我们需要从 ADC 引脚 P0.28 获取用于设置 PWM 占空比的电位器值。因此,我们使用 LPC2148 中的 ADC 模块将电位器模拟输入(0 至 3.3V)转换为 ADC 值(0 至 1023)。

在这里,我们通过将其除以 4 将值从 0-1023 转换为 0-255,因为 LPC2148 的 PWM 具有 8 位分辨率 (2 8 )。

第 9 步:-为了选择 LPC2148 中的 ADC 引脚 P0.28,我们使用

PINSEL1 = 0x01000000;//设置P0.28为ADC INPUT
AD0CR = (((14)<<8) | (1<<21)); //为A/D转换设置时钟和PDN
以下行捕获模拟输入(0 到 3.3V)并将其转换为数字值(0 到 1023)。然后将此数字值除以 4 以将它们转换为(0 到 255),最后作为PWM 输出馈送到连接 LED 的 LPC2148 的 P0.0 引脚。

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 数据寄存器中获取 RESULT
dutycycle = adcvalue/4; //从 (0 到 255) 获取占空比值的公式
PWMMR1 = dutycycle; //设置占空比值到 PWM 匹配寄存器
PWMLER |= (1<<1); //使用占空比值启用 PWM 输出
第 10 步:-接下来我们在 LCD (16X2) 显示模块中显示这些值。所以我们添加以下行来初始化 LCD 显示模块

void 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); // 第一行第一个位置
}
当我们将4 位模式的 LCD 与 LPC2148连接时,我们需要发送值以逐个半字节(上半字节和下半字节)显示。所以使用以下几行。

void LCD_DISPLAY (char* msg) //函数将发送的字符一一打印
{
uint8_t i=0;
while(msg[i]!=0)
{
IO0PIN = ( (IO0PIN & 0xFFFF00FF) | ((msg[i] & 0xF0)<<8) ); //发送高半字节
IO0SET = 0x00000050; //RS HIGH & ENABLE HIGH 打印数据
IO0CLR = 0x00000020; //RW LOW 写模式
延迟时间(2);

IO0CLR = 0x00000040;// EN = 0,RS 和 RW 不变(即 RS = 1,RW = 0)
delaytime(5);

IO0PIN = ( (IO0PIN & 0xFFFF00FF) | ((msg[i] & 0x0F)<<12) ); //发送低半字节
IO0SET = 0x00000050; //RS & EN HIGH
IO0CLR = 0x00000020;
延迟时间(2);

IO0CLR = 0x00000040;
延迟时间(5);

我++;
}
}
为了显示这些 ADC 和 PWM 值,我们在int main()函数中使用以下行。

LCD_SEND(0x80);
sprintf(displayadc, "adcvalue=%f", adcvalue);
LCD_DISPLAY(displayadc); //显示ADC值(0到1023)
LCD_SEND(0xC0);
sprintf(ledoutput,“PWM OP=%.2f”,亮度);
LCD_DISPLAY(LED输出);//显示从(0到255)的占空比值

poYBAGMtXN6ADeUVAAD6lfyzO8I170.jpg

无效初始化PLL(无效);

无效初始化PWM(无符号整数周期PWM);

无效延迟时间(uint16_t j);



void initilizePLL (void) //使用PLL产生时钟的函数

{

PLL0CON = 0x01;

PLL0CFG = 0x24;

PLL0FEED = 0xAA;

PLL0FEED = 0x55;

而(!(PLL0STAT&0x00000400));

PLL0CON = 0x03;

PLL0FEED = 0xAA;

PLL0FEED = 0x55;

VPBDIV = 0x01;

}



void delaytime(uint16_t j) // 产生 1 毫秒延迟的函数

{

uint16_t x,i;

for(i=0;i
{

对于(x=0;x<6000;x++);

}

}



无效初始化PWM(无符号整数PWM值)

{

PINSEL0 = 0x00000002;//设置引脚P0.0为PWM输出

PWMTCR = (1<<1); //设置PWM定时器控制寄存器为计数器复位

PWMPR = 0X00;//设置PWM预分频值

PWMMCR = (1<<0)|(1<<1); //设置PWM匹配控制寄存器

PWMMR0 = PWM值;//给PWM值最大值

PWMLER = (1<<0); //启用PWM锁存器

PWMTCR = (1<<0) | (1<<3); //启用PWM和PWM计数器

}



void LCD_SEND(char command) //发送十六进制命令的函数

{

IO0PIN = ( (IO0PIN & 0xFFFF00FF) | ((命令 & 0xF0)<<8) ); //发送命令的上半字节

IO0SET = 0x00000040;//使启用高

IO0CLR = 0x00000030;//使 RS & RW 低

延迟时间(5);

IO0CLR = 0x00000040;//使启用低

延迟时间(5);

IO0PIN = ( (IO0PIN & 0xFFFF00FF) | ((命令 & 0x0F)<<12) ); //发送命令的低半字节

IO0SET = 0x00000040;//启用高

IO0CLR = 0x00000030;//RS & RW 低

延迟时间(5);

IO0CLR = 0x00000040;//启用低

延迟时间(5);

}



void LCD_INITILIZE(void) //准备LCD的函数

{

IO0DIR = 0x0000FFF0;//设置引脚P0.12,P0.13,P0.14,P0.15,P0.4,P0.6为OUTPUT

延迟时间(20);

LCD_SEND(0x02); // 以 4 位操作模式初始化 lcd

LCD_SEND(0x28); // 2 行 (16X2)

LCD_SEND(0x0C); // 光标关闭时显示

LCD_SEND(0x06); // 自动递增光标

LCD_SEND(0x01); // 显示清晰

LCD_SEND(0x80); // 第一行第一个位置

}



void LCD_DISPLAY (char* msg) //函数将发送的字符一一打印

{

uint8_t i=0;

而(味精[i]!=0)

{

IO0PIN = ( (IO0PIN & 0xFFFF00FF) | ((msg[i] & 0xF0)<<8) ); //发送上半字节

IO0SET = 0x00000050;//RS HIGH & ENABLE HIGH 打印数据

IO0CLR = 0x00000020;//RW LOW 写模式

延迟时间(2);

IO0CLR = 0x00000040;// EN = 0,RS 和 RW 不变(即 RS = 1,RW = 0)

延迟时间(5);

IO0PIN = ( (IO0PIN & 0xFFFF00FF) | ((msg[i] & 0x0F)<<12) ); //发送低半字节

IO0SET = 0x00000050;//RS & EN 高

IO0CLR = 0x00000020;

延迟时间(2);

IO0CLR = 0x00000040;

延迟时间(5);

我++;

}

}



主函数()

{

LCD_INITILIZE(); //调用函数准备LCD显示

字符显示ADC[18];

浮动亮度;

字符 LED 输出[18];

LCD_DISPLAY("电路摘要");

延迟时间(900);

LCD_SEND(0xC0);

LCD_DISPLAY("LPC2148 中的 PWM");

延迟时间(900);



占空比;

浮动 adc 值;

初始化PLL();//调用函数initilizePLL

PINSEL1 = 0x01000000;//设置P0.28为ADC INPUT

AD0CR = (((14)<<8) | (1<<21)); //为A/D转换设置时钟和PDN

初始化PWM(255);//调用函数initilizePWM,值为255

PWMPCR |= (1<<9); //在LPC2148的P0.0引脚启用PWM1输出



而(1)

{

AD0CR |= (1<<1); //选择ADC寄存器中的AD0.1通道

延迟时间(10);

AD0CR |= (1<<24); //开始A/D转换

而( (AD0DR1 & (1<<31)) == 0 ); //检查ADC数据寄存器中的DONE位

adcvalue = (AD0DR1>>6) & 0x3ff; //从ADC数据寄存器中获取RESULT

占空比 = adcvalue/4;//从 (0 到 255) 获取占空比值的公式

PWMMR1 = 占空比;//设置占空比值到PWM匹配寄存器

PWMLER |= (1<<1); //使用占空比值启用 PWM 输出

亮度 = 占空比;

LCD_SEND(0x80);

sprintf(displayadc, "adcvalue=%f", adcvalue);

LCD_DISPLAY(displayadc); //显示ADC值(0到1023)

LCD_SEND(0xC0);

sprintf(ledoutput,“PWM OP=%.2f”,亮度);

LCD_DISPLAY(LED输出);//显示从(0到255)的占空比值

}

}


关键字:ARM7  LPC2148  微控制器  PWM控制  LED 引用地址:如何使用ARM7-LPC2148微控制器中的PWM控制LED的亮度

上一篇:基于LPC11C24微控制器组成的CAN网络,实现对节点MCU的软件更新
下一篇:基于LPC2292微控制器和CAN控制器实现车辆行驶监控系统的设计

推荐阅读最新更新时间:2024-11-12 22:17

光柱LED测试仪电路
该电路是由一个4.5伏电池供电并且与一个在测试的具有内部参考的电池相比较,它由R1,R2和P1来设置。为了达到最佳效果,电池(DUT)应装入一个合适的电阻。该LM3914A的LED光柱用在这里作为一个检测电池的电压表。光柱LED测试仪电路:
[测试测量]
光柱<font color='red'>LED</font>测试仪电路
单片机C语言程序设计:并行数据转换为串行数据
/* 名称:并行数据转换为串行数据 说 明 : 切 换 连 接 到 并 串 转 换 芯 片 74LS165 的拨码开关,该芯片将并行数据以 串行方式发送到 8051 的 RXD 引脚,移位脉 冲由 TXD 提供,显示在 P0 口。 */ #include reg51.h #include intrins.h #include stdio.h #define uchar unsigned char #define uint unsigned int sbit SPL=P2^5; //shift/load //延时 void DelayMS(uint ms) { uchar i;
[单片机]
<font color='red'>单片机</font>C语言程序设计:并行数据转换为串行数据
Intersil推出用于智能手机的集成显示电源和LED驱动器的单芯片方案
ISL98611提供更高效率,帮助延长电池续航时间和提高显示图像质量。 美国加州、MILPITAS--- 2014年8月19日 — 创新电源管理与精密模拟解决方案领先供应商Intersil公司(纳斯达克交易代码:ISIL)今天宣布,推出用于智能手机的显示电源和LED驱动器二合一解决方案---ISL98611。ISL98611是首款单芯片集成显示电源与背光LED驱动器功能的电源管理IC产品,并显著提高了这两部分电源的效率,从而延长电池续航时间达一小时以上。 除了延长电池续航时间,ISL98611还可改善显示屏亮度均匀性和色彩一致性。高度集成的ISL98611不仅包括升压稳压器、LDO和反相电荷泵产生+5V和-5V两路
[手机便携]
51单片机入门之四:静态数码管
LED数码管是单片机外围接口设备中常用的显示设备,有七段管和米字管两种,实验室中常用的是七段管。其工作方式有两种:共阴极和共阳极。所谓共阴极是把LED的com端都接地,而共阳极就是把com端都接高电平。其驱动显示方式也有两种:静态显示和动态显示。 静态显示中每个数码管占用单片机的一个八位口I/O口,工作时点亮的段常亮。于该种方式而言,硬件电路简单,编程简单,但是浪费单片机的I/O口。下面简单演示一下该种驱动方式。 P2口接一个数码管,数码管显示的数字每秒钟自动加一,加到9后清0,一直循环,本实验中数码管采用共阴极接法。 实验原理图如下: 实验程序如下: view plain copy #include reg52.
[单片机]
51<font color='red'>单片机</font>入门之四:静态数码管
自己写单片机操做系统3-任务创建和调度
如果存在两个或以上的任务调度就需要将栈保CPU的寄存器了。这个地方就是各个MCU不同的地方了。 这个要看MCU进入中断的流程才能知道栈需要怎么保护。 OS_STK* InitStkBuff(VOID_FUN_PTR task,OS_STK* pstk) { pstk--; *pstk = (U16)(((U32)task) 8); 存要执行的函数 pstk--; *pstk = 0xFFFF; //IY 存y寄存器 (pstk)--; *pstk = 0x1111; //IX 存x寄存器 pstk--; *pstk = 0xAA;//A;
[单片机]
基于单片机设计的数字摄像机配置系统
0 引 言   本文以BASLER A202k面阵 CCD摄像机的配置为目标设计嵌入式摄像机配置系统。BASLER公司提供了2种摄像机配置方案:一是利用该公司提供的摄像机配置软件CCT+(Camera Configuration Tool Plus),二是利用该公司提供的二进制配置命令,由用户编程实现。本文采用二进制配置命令,通过设计的嵌入式系统配置摄像机。该摄像机的二进制配置命令帧格式如下:   起始字 描述字 数据段 BCC 结束字   BCC是块检查字(Block Check Character),需要由用户计算。主要的配置命令及其二进制帧格式如表1所示。 表中02h是起始字;03h是
[单片机]
基于<font color='red'>单片机</font>设计的数字摄像机配置系统
合理的驱动器设计可优化LED照明
LED 照明如今已成为具有巨大节能潜力的主流技术,仅在中国,如果整个国家1/3的照明市场采用LED,预计每年可节约1亿千瓦时电量和减少2900万二氧化碳排放量。但是,这其中还存在一项障碍,即如何控制电压闪烁问题,这对于家庭或道路照明等应用都是一个通病。让我们来仔细分析这一问题,并了解一些可支持调暗和无闪烁运作的驱动器设计方案。   对于白炽灯而言,利用简单、低成本且先进的三端双向可控硅调光器即可进行调暗;此类调光器随处可见。而固态照明(SSL)或LED改造灯要真正取得成功,它们必须可以在与现有控制器和接线配合使用的情况下调暗。   但人们在调暗LED灯的过程中遇到了很多问题,最典型的问题就是闪烁和另外一些不良表现。要理解这
[电源管理]
合理的驱动器设计可优化<font color='red'>LED</font>照明
单片机应用系统的硬件电路设计
一、单片机电路 单片机采用ATF89S52 1.时钟电路Xl、C2、C3与单片机内部的反相放大器一起构成时钟振荡电路,采用12MHz晶振,AT89S52的机器周期为12个振荡周期,每个机器周期正好lμs. 2.复位电路Cl、R9构成上电复位电路,S5是手动复位按键。 3.其他AT89S52单片机内部有8k字节FlashROM、256字节RAM,不用外扩程序存储器和数据存储器,因此其EA脚固定接高电平,ALE和:IPSEN脚悬空。 二、电源 由于AT89S52的工作电压为4V~5.5V,而输出驱动的继电器采用9V直流电,故直接采用市售的9V直流稳压电源,再加5V稳压电路组成其电源电路。 三、键盘电路 根据系统要求,需要用按键来完成定
[电源管理]
<font color='red'>单片机</font>应用系统的硬件电路设计
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved