|
这个是我写的pwm测试程序,当调节时,频率可以改变(但灯的亮度变化不是很理想,是不是要改变灯的亮度,就一定需要改变占空比?),频率<32khz,看看有什么方法可以提高频率的范围啊,
程序如下:
Chip SN8F27E65
//{{SONIX_CODE_OPTION
.Code_Option WDT_CLK Flosc/4
.Code_Option Reset_Pin P04
.Code_Option LVD LVD_Max ; 3.3V Reset
.Code_Option Watch_Dog Always_On
.Code_Option Low_Fcpu Flosc/1
.Code_Option High_Clk IHRC_16M ; Internal 16M RC Oscillator
.Code_Option High_Fcpu Fhosc/16
.Code_Option Security Enable
.Code_Option Noise_Filter Enable
//}}SONIX_CODE_OPTION
.list
INCLUDESTD MACRO1.H
INCLUDESTD MACRO2.H
INCLUDESTD MACRO3.H
.DATA
rPwm_Data ds 1
rAcc_Buf ds 1
rPflag_Buf ds 1
rPwm_Data_Adj ds 1 ;按键调节pwm时,数据加,减
rDelayCT1 ds 1
rDelayCT2 ds 1
rDelayAdj ds 1
rFlag1 ds 1
.CONST
cTC1C_INIT_DATA equ 0xF0 ;256-(500us * 16MHz /16 /32) =256-(0.0005s*16000000Hz/16/32)
cTC1M_INIT_DATA equ 00100100b ;tc1m模式设置Tc1m,(bit2=0,Fcpu ;bit2=1,fhose) 时钟= Fhosc/32。最大512us,最小2us,采用高速时钟
cTC1D_INIT_DATA equ 0xf8 ;TC1D 的值必须大于TC1R 的值,否则PWM 的信号保持低电平状态
;1/2占空比, 此值是通过tc1c寄存器的值计算得到的
;cTC1D_INIT_DATA_MIN equ 0x00 ;最小值
;cTC1D_INIT_DATA_MAX equ 0xff ;最大值
cTC1R_INIT_DATA_MIN equ 0x00 ;最小值
cTC1R_INIT_DATA_MAX equ 0xff ;最大值
cPWM1_INTERRUPT_ADDR equ 0x0d ;PWM1 中断向量地址
bKEY_ADD equ P0.6 ;pwm按键加
bKEY_DEC equ P0.4 ;pwm按键减
bKEY_BIT EQU rFlag1.0 ;按键扫描检测 =0没有按键按下 =1有按键按下
.CODE
org 0
jmp L_main
org 15h
/*------------------------------------------------------------------------------
8 位二进制定时器TC1 具有基本定时器、事件计数器和PWM 功能。基本定时器功能可以支持中断请求标志的显示
(TC1IRQ)和中断操作(中断向量)。由TC1M、TC1C、TC1R 寄存器控制TC1 的中断间隔时间。事件计数器可以将
TC1 时钟源由系统时钟(Fcpu/Fhosc)更改为外部时钟信号(如连续的脉冲、R/C 振荡信号等)。TC1 作为计数器时记
录外部时钟数目以进行测量应用。TC1 还内置周期/占空比可编程控制的PWM 功能,PWM 的周期和分辨率由TC1 时钟
周期、TC1R 和TC1D 寄存器控制,故具有良好性能的PWM 可以处理IR 载波信号,马达控制和光度调节等。
TC1 的主要用途如下:
8 位可编程定时器:根据选择的时钟信号,产生周期性中断;
中断功能:TC0 定时器支持中断,当TC0 溢出时,TC0IRQ 置1,系统执行中断;
外部事件计数器:对外部事件计数;
可编程控制占空比/周期的PWM 输出:由TC1R 和TC1D 寄存器控制占空比/周期;
绿色模式功能:绿色模式下,TC1 正常工作,但无唤醒功能。
TC1D 初始值的计算方法如下:
TC1D 初始值 = TC1R +(PWM 脉冲高电平宽度周期 / TC1 时钟rate)
. 例:计算TC1D 的值。1/3 占空比PWM,TC1 时钟源Fcpu=16MHz/16=1MHz,TC1RATE=000(Fcpu/128)。
TC1R = B2H,TC1 间隔时间=10ms,PWM 周期频率为100Hz,1/3 占空比条件下,PWM 高电平的宽度值约为3.33ms。
TC1D 初始值 = B2H +(PWM 脉冲高电平宽度值/TC0 时钟Rate)
= B2H + (3.33ms * 16MHz / 16 / 128)
= B2H + 1AH
= CCH
8.4.8 脉冲宽度调制(PWM)
可编程控制占空比/周期的PWM 可以提供不同的PWM 信号。使能TC1 定时器且PWM1OUT=1 时,由PWM 输出
引脚(P5.2)输出PWM 信号。PWM 首先输出高电平,然后输出低电平。TC1R 寄存器控制PWM 的周期,TC1D 控制
PWM 的占空比(脉冲高电平的长度)。开启TC1 定时器且定时器溢出后,TC1R 重装载TC1C 的初始值。当TC1C=TC1D
时,PWM 输出低电平;TC1 溢出时(TC1C 的值从0FFH 到00H),整个PWM 周期完成,并进入下一个周期。TC1 溢
出时,TC1R 的值自动装入TC1C,PWM 的一个周期完成,以保持PWM 的连贯性。在PWM 输出的过程由程序更改PWM
的占空比,则在下一个周期开始输出新的占空比的PWM 信号。
------------------------------------------------------------------------------*/
;********************************************************************************
L_Pwm1_Init:
clr TC1M ;清tc1m
mov a,#cTC1M_INIT_DATA ; 设置TC1 时钟源和TC1Rate。
b0mov tc1m,a
; 设置TC1C 和TC1R 寄存器获得PWM 周期。
mov a,#cTC1C_INIT_DATA ; TC1C 必须和TC1R 相等。
b0mov tc1c,a
b0mov tc1r,a
; 设置TC1D 寄存器获得PWM 占空比。
mov a,#cTC1D_INIT_DATA ; TC1D 的值必须大于TC1R 的值。
b0mov tc1d,a
; 使能PWM 和TC1 定时器。
b0bset fpwm1out ; 使能PWM。
b0bset ftc1enb ; 使能TC1 定时器。
RET
;********************************************************************************
L_Sys_Init:
b0mov y,#0 ;clear 00-80h RAM bank0 128byte
b0mov z,#0x80 ;80h
mov a,#0
L_clearRam1:
b0mov @yz,a
decms z
jmp L_clearRam1
b0mov y,#1 ;clear 00-ffh RAM bank1 256byte
b0mov z,#0xff ;ffh
mov a,#0
L_clearRam2:
b0mov @yz,a
decms z
jmp L_clearRam2
b0mov y,#2 ;clear 00-7fh RAM bank2 128byte
b0mov z,#0x7f ;7fh
mov a,#0
L_clearRam3:
b0mov @yz,a
decms z
jmp L_clearRam3
mov a,#cTC1D_INIT_DATA
b0mov rPwm_Data_Adj,a
b0bclr p0m.4 ;set input
b0bclr p0m.6 ;set input
mov a,p0ur
or a,#01010000b
mov p0ur,a
b0bclr bKEY_BIT
ret
;********************************************************************************
L_main:
call L_Sys_Init
CALL L_Pwm1_Init
mian_while: ;主程序循环
;b0bts0 FTC1IRQ
;b0bclr FTC1IRQ
call L_Key_Add
call L_Key_Dec
;----------------------------------------------------------------------------------
;mov a,#0x5a
;b0mov wdtr,a
jmp mian_while ;主程序循环
;********************************************************************************
;********************************************************************************
;********************************************************************************
L_Key_Add:
b0bts0 bKEY_ADD
ret
mov a,#20
mov rDelayAdj,a
call L_Delay_Xms ;delay 20ms
b0bts0 bKEY_ADD
ret
;---------------------------------------------------------------------------------
mov a,rPwm_Data_Adj
cmprs a,#cTC1R_INIT_DATA_MAX
jmp next_add
ret
next_add:
incms rPwm_Data_Adj
mov a,rPwm_Data_Adj
;---------------------------------------------------------------------------------
b0mov tc1r,a ; 写入到pwm控制寄存器
cmprs a,#cTC1R_INIT_DATA_MAX
ret
decms rPwm_Data_Adj ;如果rPwm_Data_Adj==0xff,那么就让他减1一次,等下次加时,始终都保持不会超过0xff(即亮度保持总是最大).
ret
;********************************************************************************
;********************************************************************************
;********************************************************************************
L_Key_Dec:
b0bts0 bKEY_DEC
ret
mov a,#20
mov rDelayAdj,a
call L_Delay_Xms ;delay 20ms
b0bts0 bKEY_DEC
ret
;---------------------------------------------------------------------------------
mov a,rPwm_Data_Adj
cmprs a,#cTC1R_INIT_DATA_MIN ;如果刚开始时的值等于0xc1(即初值的最小值),返回
jmp next_sub
ret
next_sub:
decms rPwm_Data_Adj
mov a,rPwm_Data_Adj
;---------------------------------------------------------------------------------
b0mov tc1r,a ; 写入到pwm控制寄存器
cmprs a,#cTC1R_INIT_DATA_MIN
ret
incms rPwm_Data_Adj ;如果rPwm_Data_Adj==0xc1,那么就让他加1一次,等下次减时,始终都保持不会低于0xc1(即亮度保持总是最小).
ret
;********************************************************************************
;********************************************************************************
;********************************************************************************
/********************************************************
函数名称:Delay_Xms
函数描述:此函数的延时时间取决于这个“rDelayAdj”变量的值
此函数的基本延时是1ms的时间
********************************************************/
L_Delay_Xms:
mov a,rDelayAdj ;延时时间可以调节的,此函数是延时1ms的基本函数
mov rDelayCT2,a
delay_b:
mov a,#165 ;165延时1ms很准,但是延时越大,误差相对会大一点点的,如:延时200ms,误差大概少995us(以一周期为一个us为基准,其他周期请自行修改)
mov rDelayCT1,a
delay_us:
mov A, #0x5A
b0mov WDTR, A
decms rDelayCT1
jmp delay_us
decms rDelayCT2
jmp delay_b
ret
;********************************************************************************
ENDP |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|