1 Star 196 Fork 1

Alancheng86 / ClassA20

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
PWM.pas 3.70 KB
一键复制 编辑 原始数据 按行查看 历史
tjCFeng 提交于 2014-12-06 10:45 . Update PWM.pas
(*
说明:全志A20的PWM底层操作封装类。分为两个部分:
1.TPWMGROUP类,可对寄存器直接操作,单例;
2.TPWM类,对具体的PWM通道实现了一些功能的简化。
作者:tjCFeng
邮箱:tjCFeng@163.com
更新日期:2014.12.06
*)
unit PWM;
{$mode objfpc}{$H+}
interface
uses SysUtils, A20, GPIO;
type
TChannel = (PWM_0, PWM_1);
TPrescal =
(P120, P180, P240, P360, P480, P720, P840, P960,
P12K, P24K, P36K, P48K, P72K, P84K, P96K, P108K);
TPWMGROUP = class
private
class var FInstance: TPWMGROUP;
class function GetInstance: TPWMGROUP; static;
public
class procedure Release;
class property Instance: TPWMGROUP read GetInstance;
private
FPWM_BASE: ^LongWord;
FPWM_CTRL: TGROUP1_REG;
FPWM_PERIOD: TGROUP2_REG;
constructor Create;
destructor Destroy; override;
public
property PWM_CTRL: TGROUP1_REG read FPWM_CTRL;
property PWM_PERIOD: TGROUP2_REG read FPWM_PERIOD;
end;
TPWM = class(TGPIO)
private
FChannel: TChannel;
FCycle: Word;
FDuty: Word;
FPWM_PERIOD: ^LongWord;
private
procedure SetPrescale(Value: TPrescal);
procedure SetCycle(Value: Word);
procedure SetDuty(Value: Word);
public
constructor Create(Channel: TChannel);
procedure Start;
procedure Stop;
public
property Channel: TChannel read FChannel;
property Prescale: TPrescal write SetPrescale;
property Cycle: Word write SetCycle;
property Duty: Word write SetDuty;
end;
implementation
const
PWM_BASE = $01C20C00;
(*PWM Group********************************************************************)
class function TPWMGROUP.GetInstance: TPWMGROUP;
begin
if FInstance = nil then FInstance:= TPWMGROUP.Create;
Result:= FInstance;
end;
class procedure TPWMGROUP.Release;
begin
FreeAndNil(FInstance);
end;
constructor TPWMGROUP.Create;
var Base: LongWord;
begin
inherited Create;
FPWM_BASE:= TA20.Instance.GetMMap(PWM_BASE);
Base:= LongWord(FPWM_BASE) + TA20.Instance.BaseOffset(PWM_BASE);
FPWM_CTRL:= Pointer(Base + $200);
FPWM_PERIOD[0]:= Pointer(Base + $204);
FPWM_PERIOD[1]:= Pointer(Base + $208);
//FPWM_CTRL^:= FPWM_CTRL^ or (($1 shl 24) + ($1 shl 9)); //OSC24MHz
end;
destructor TPWMGROUP.Destroy;
begin
FPWM_CTRL^:= 0;
FPWM_PERIOD[0]^:= 0;
FPWM_PERIOD[1]^:= 0;
TA20.Instance.FreeMMap(FPWM_BASE);
inherited Destroy;
end;
(*PWM Channel******************************************************************)
constructor TPWM.Create(Channel: TChannel);
begin
FChannel:= Channel;
case FChannel of
PWM_0: inherited Create(PB, 2);
PWM_1: inherited Create(PI, 3);
end;
SetFun(Fun2);
FPWM_PERIOD:= TPWMGROUP.Instance.PWM_PERIOD[Ord(FChannel)];
FPWM_PERIOD^:= 0;
with TPWMGROUP.Instance do
PWM_CTRL^:= PWM_CTRL^ or ($1 shl (Ord(FChannel) * 15 + 6)); //Special Clock
end;
procedure TPWM.SetPrescale(Value: TPrescal);
begin
with TPWMGROUP.Instance do
begin
PWM_CTRL^:= PWM_CTRL^ and not ($F shl (Ord(FChannel) * 15));
PWM_CTRL^:= PWM_CTRL^ or (Ord(Value) shl (Ord(FChannel) * 15));
end;
end;
procedure TPWM.SetCycle(Value: Word);
begin
FCycle:= Value;
FPWM_PERIOD^:= FPWM_PERIOD^ and $0000FFFF;
FPWM_PERIOD^:= FPWM_PERIOD^ or (Value shl 16);
end;
procedure TPWM.SetDuty(Value: Word);
var D: LongWord;
begin
if (FCycle > 0) and (Value >= FCycle) then FDuty:= FCycle - 1;
FPWM_PERIOD^:= FPWM_PERIOD^ and $FFFF0000;
FPWM_PERIOD^:= FPWM_PERIOD^ or Value;
end;
procedure TPWM.Start;
begin
with TPWMGROUP.Instance do
FPWM_CTRL^:= FPWM_CTRL^ or ($1 shl (Ord(FChannel) * 15 + 4));
end;
procedure TPWM.Stop;
begin
with TPWMGROUP.Instance do
FPWM_CTRL^:= FPWM_CTRL^ and not ($1 shl (Ord(FChannel) * 15 + 4));
end;
finalization
TPWMGROUP.Instance.Release;
end.
Pascal
1
https://gitee.com/Alancheng86/ClassA20.git
git@gitee.com:Alancheng86/ClassA20.git
Alancheng86
ClassA20
ClassA20
master

搜索帮助