Слияние кода завершено, страница обновится автоматически
(*
说明:全志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.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарий ( 0 )