EDN China > 设计实例 > 可编程器件 > PLD > 正文
? 2016博客大赛-不限主题,寻找电子导师,大奖升级??

(多图) 单片机驱动CPLD的PWM正弦信号发生器设计

/?? 2013年11月22日 ?? 收藏1

二、基于CPLD的PWM方案

一个PWM发生器必须包括计数器,数据比较器,另外就是配置PWM参数的时钟分频寄存器和占空比寄存器,结构框图如图2所示,这些电路都可以用CPLD来实现。


图2 PWM控制器结构框图

高频时钟信号经分频器驱动计数器,计数器如图3所示,总是从Bottom到Top的循环计数,计数器的输出和占空比寄存器里的数据经数据比较器比较,输出PWM信号,当计数器输出小于占空比设定值时输出低电平(0),否则输出高电平(1),如图3(b)(c)所示。


图3 PWM信号发生器时序波形图

从图中还可以看出,计数器的周期就是PWM信号的周期,通过修改占空比寄存器从而实现对输出PWM信号高低电平比例控制,图3(b)是占空比为P1的PWM输出,图3(c)是占空比为P2的PWM输出,它们周期相同,高低电平的比例不同。

下面用硬件描述语言来设计CPLD的内部电路,这里给出VerilogHDL版本的参考代码。

module Mini51b_PWM(P0,ALE,P27,WR,PWM);//模块电路命名和端口说明。

input [7:0]P0;//数据输入接MCU数据P0口

input ALE,P27,WR;//几个MCU读写控制引脚

output PWM;//PWM信号输出

wire [7:0]addr;//内部地址线

reg [7:0]daPWMc,daPWMs;//定义计数器和占空比设定寄存器

reg [3:0]divPWM,divPWMc;//分频控制变量

reg PWM;//输出锁存器

assign addr = ALE?P0 : addr; //低八位地址锁存

always @(negedge WR)//在MCU写信号有效时执行寄存器设定

begin

case({P27,addr[4:0]}) //根据地址选择寄存器

6'b10_1000: daPWMs <= P0;//写带地址的寄存器

6'b10_1001: divPWM <= P0[3:0];//写带地址的寄存器

default:begin//其它地址则让寄存器保持不变

daPWMs <= daPWMs;

divPWM <= divPWM;

end

endcase

end

always @(posedge ALE) begin//这里利用MCU的ALE做时钟信号

if(divPWMc == divPWM) begin //与分频系数比较

divPWMc<=0;

if(daPWMc<100) daPWMc <= daPWMc+1; //PWM调整精度1%

else daPWMc <= 0;

if(daPWMs < daPWMc) PWM <= 0;//PWM发生器

else PWM <= 1;

end

else divPWMc <= divPWMc+1;//时钟分频

end

endmodule

关于单片机与CPLD之间的接口请读者参考本刊前几期笔者撰写的文章。

与之对应的MCU测试程序为:

#include

#include

#define PWM XBYTE[0xffe8]

#define DIV XBYTE[0xffe9]

void main()

{

DIV = 15; //PWM信号频率计算晶振22.1184M/6/100/

(DIV+1)=2.30K(实测2.281K)

PWM=50; // 设定占空比50%,前面计数器范围为0~99

while(1);

}

执行单片机程序,选择不同的分频系数和占空比值,从CPLD的引脚输出PWM信号示波器截图如图4所示。


图4 不同占空比的PWM信号示波器截图

分页导航

第1页:PWM原理

第2页:基于CPLD的PWM方案

第3页:SPWM

第4页:三路精确相位差正弦信号发生器



?? ?? ??


打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮

1.扫描左侧二维码
2.点击右上角的分享按钮
3.选择分享给朋友
?? ??

单片机? CPLD? PWM? 信号发生器?

相关文章

我来评论
美国的游客
美国的游客 ??? (您将以游客身份发表,请登录 | 注册)
?
有问题请反馈