这是我们使用MPLAB和XC8学习PIC单片机的第10个教程 。到目前为止,我们已经涵盖了许多基本教程,例如LED与PIC一起闪烁,PIC中的计时器,LCD与LCD的接口,7段接口与使用PIC的ADC等。如果您是绝对的初学者,请在此处访问PIC教程的完整列表,以及开始学习。
在本教程中,我们将学习 如何使用PIC PIC16F877A生成PWM信号。我们的PIC MCU具有一个称为比较捕获模块(CCP)的特殊模块,可用于生成PWM信号。在这里,我们将生成5 kHz的PWM,占空比从0%到100%不等。为了改变占空比,我们使用了电位计,因此建议在开始PWM之前先学习ADC教程。PWM模块还使用计时器来设置其频率,因此请在此处预先学习如何使用计时器。此外,在本教程中,我们将使用RC电路和LED将PWM值转换为模拟电压,并将其用于调光LED灯。
什么是PWM信号?
脉宽调制(PWM)是一种数字信号,最常用于控制电路中。该信号在预定义的时间和速度中设置为高(5v)和低(0v)。信号保持高电平的时间称为“开启时间”,信号保持低电平的时间称为“关闭时间”。如下所述,PWM有两个重要参数:
PWM的占空比:
PWM信号保持高电平(导通时间)的时间百分比称为占空比。如果信号始终为ON,则占空比为100%;如果信号始终为OFF,则占空比为0%。
占空比=打开时间/(打开时间+关闭时间)
PWM频率:
PWM信号的频率决定了PWM完成一个周期的速度。如上图所示,一个周期完成了PWM信号的ON和OFF。在我们的教程中,我们将设置5KHz的频率。
使用PIC16F877A的PWM:
使用CCP (比较捕获PWM)模块可以在我们的PIC单片机中生成PWM信号。我们的PWM信号的分辨率为10位,即值为0时,占空比为0%,值为1024(2 ^ 10)时,占空比为100%。PIC MCU中有两个CCP模块(CCP1和CCP2),这意味着我们可以在两个不同的引脚(引脚17和16)上同时生成两个PWM信号,在本教程中,我们将使用CCP1在引脚17上生成PWM信号。
以下寄存器用于使用我们的PIC MCU生成PWM信号:
- CCP1CON(CCP1控制寄存器)
- T2CON(定时器2控制寄存器)
- PR2(定时器2模块周期寄存器)
- CCPR1L(CCP寄存器1低)
对PIC进行编程以生成PWM信号:
在我们的程序中,我们将从电位计读取0-5v的模拟电压,并使用我们的ADC模块将其映射到0-1024。然后,我们生成一个频率为5000Hz的PWM信号,并根据输入的模拟电压来改变其占空比。即0-1024将转换为0%-100%占空比。本教程假定您已经学习了如何在PIC中使用ADC,请从这里开始阅读,因为我们将在本教程中跳过有关ADC的详细信息。
因此,一旦设置了配置位并编写了程序以读取模拟值,就可以继续使用PWM。
将CCP模块配置为PWM操作时,应采取以下步骤:
- 通过写入PR2寄存器设置PWM周期。
- 通过写CCPR1L寄存器和CCP1CON <5:4>位来设置PWM占空比。
- 通过将TRISC <2>位清零,使CCP1引脚成为输出。
- 设置TMR2预分频值,并通过写T2CON使能Timer2。
- 将CCP1模块配置为PWM操作。
此程序中有两个重要的函数来生成PWM信号。一个是PWM_Initialize()函数,该函数将初始化设置PWM模块所需的寄存器,然后设置PWM的工作频率,另一个函数是PWM_Duty()函数,该函数将设置PWM信号的占空比。所需的寄存器。
PWM_Initialize(){PR2 =(_XTAL_FREQ /(PWM_freq * 4 * TMR2PRESCALE))-1; //使用数据表设置PR2公式//使PWM在5KHZ下工作CCP1M3 = 1; CCP1M2 = 1; //配置CCP1模块T2CKPS0 = 1; T2CKPS1 = 0; TMR2ON = 1; //配置定时器模块TRISC2 = 0; //将C上的端口引脚作为输出}
上面的功能是PWM初始化功能,在此功能中,通过将CCP1M3和CCP1M2位设置为高电平,可以将CCP1模块设置为使用PWM。
通过将T2CKPS0位设置为高电平并将T2CKPS1设置为低电平来设置定时器模块的预分频比,将TMR2ON位置1以启动定时器。
现在,我们必须设置PWM信号的频率。频率值必须写入PR2寄存器。可以使用以下公式设置所需的频率
PWM周期= * 4 * TOSC *(TMR2预分频值)
重新排列这些公式以获得PR2
PR2 =(期间/(4 * Tosc * TMR2预分频))-1
我们知道Period =(1 / PWM_freq)和Tosc =(1 / _XTAL_FREQ)。因此…..
PR2 =(_XTAL_FREQ /(PWM_freq * 4 * TMR2PRESCALE))– 1;
设置频率后,除非再次需要更改频率,否则无需再次调用此函数。在我们的教程中,我分配了 PWM_freq = 5000; 这样我们就可以为PWM信号获得5 KHz的工作频率。
现在,让我们使用以下函数来设置PWM的占空比
PWM_Duty(无符号整数占空比){if(duty <1023){占空比=((float)duty / 1023)*(_ XTAL_FREQ /(PWM_freq * TMR2PRESCALE)); //降低//占空比=(((float)duty / 1023)*(1 / PWM_freq))/(((1 / _XTAL_FREQ)* TMR2PRESCALE); CCP1X =占空比&1; //存储第一个位CCP1Y = duty&2; //存储第0位CCPR1L = duty >> 2; //存储第8位}}
我们的PWM信号具有10位分辨率,因此该值不能存储在单个寄存器中,因为我们的PIC只有8位数据线。因此,我们已使用CCP1CON <5:4>的其他两位(CCP1X和CCP1Y)存储最后两个LSB,然后将其余8位存储在CCPR1L寄存器中。
PWM占空比时间可以使用以下公式计算:
PWM占空比=(CCPRIL:CCP1CON <5:4>)* Tosc *(TMR2预分频值)
重新排列这些公式以获得CCPR1L和CCP1CON的值将得出:
CCPRIL:CCP1Con <5:4> = PWM占空比/(Tosc * TMR2预分频值)
ADC的值为0-1024,因此我们需要将其设置为0%-100%,因此PWM占空比=占空比/ 1023。进一步将此占空比转换为一个时间段,我们必须将其乘以周期(1 / PWM_freq)
因此,我们也知道Tosc =(1 / PWM_freq)。
占空比=(((float)duty / 1023)*(1 / PWM_freq))/((1 / _XTAL_FREQ)* TMR2PRESCALE);
解决上述方程式将给我们:
占空比=((float)占空比/ 1023)*(_XTAL_FREQ /(PWM_freq * TMR2PRESCALE));
您可以在下面的代码部分中查看完整的程序以及详细的视频。
原理图和测试:
和往常一样,让我们使用Proteus仿真来验证输出。的电路图如下所示。
将电位计连接到第7针以输入0-5的电压。CCP1模块带有引脚17(RC2),此处将生成PWM,可使用数字示波器对其进行验证。为了进一步将其转换为可变电压,我们使用了RC滤波器和LED来验证输出而没有示波器。
什么是RC过滤器?
一个RC滤波器或低通滤波器是一个简单的电路具有两个无源元件即电阻器和电容器。这两个分量用于对PWM信号的频率进行滤波并使之成为可变的DC电压。
如果我们检查电路,当向R的输入端施加可变电压时,电容器C将开始充电。现在,基于电容器的值,电容器将需要一些时间才能充满电,一旦充电,它将阻止直流电流(记住电容器会阻止直流电,但允许交流电),因此输入直流电压将出现在输出两端。高频PWM(交流信号)将通过电容器接地。因此,在电容器两端获得了纯直流电。发现该项目适合使用1000Ohm和1uf的值。计算R和C的值涉及使用传递函数进行电路分析,这超出了本教程的范围。
可以使用数字示波器来验证程序的输出,如下所示,改变电位器,PWM的占空比应改变。我们还可以使用电压表注意到RC电路的输出电压。如果一切正常,我们可以继续使用我们的硬件。进一步在最后检查视频以了解完整过程。
在硬件上工作:
该项目的硬件设置非常简单,我们将重复使用下面所示的PIC Perf板。
我们还需要一个电位计来提供模拟电压,我已经将一些母端导线连接到了我的电位器上(如下所示),以便我们可以将它们直接连接到PIC Perf板上。
最后,为了验证输出,我们需要一个RC电路和一个LED来查看PWM信号的工作原理,我只用了一块小的穿孔板,并将RC电路和LED焊接在其上(以控制亮度),如下所示
我们可以使用简单的母对母连接线,并根据上面显示的示意图进行连接。连接完成后,使用我们的pickit3将程序上传到PIC,您应该能够根据电位计的输入获得可变电压。此处,可变输出用于控制LED的亮度。
我用万用表测量了可变输出,我们还可以注意到LED的亮度随着电压水平的变化而变化。
就是这样,我们已经编程了从POT读取模拟电压并转换为PWM信号,然后再使用RC滤波器将其转换为可变电压,并使用我们的硬件验证结果。如果您有任何疑问或卡在某个地方,请使用下面的评论部分,我们将很乐意为您提供帮助。在完整的工作是工作在视频。
另请查看其他微控制器上的其他PWM教程:
- Raspberry Pi PWM教程
- 带Arduino Due的PWM
- 使用PWM的基于Arduino的LED调光器
- 使用ATmega32单片机的功率LED调光器