; ledpwm.asm --- drive a blue LED with PWM 21/04/2006
; Copyright (c) 2006 John Honniball
.include "m8def.inc"
.org 0x0000
; 端口 B 位 2 上的LED
.equ LED_PORT = PortB
.equ LED_BIT = 2
; 该程序驱动连接到 AVR 的 I/O 端口的单个 LED。 它将 LED 的阴极连接到 AVR 引脚,
;LED 的阳极通过电阻器。 该电阻的值取决于 LED 的颜色,但通常为几百欧姆。
;我们通过脉宽调制 (PWM) 控制 LED 的亮度,
; 就像脉动那样地周期运动或变化 从未完全“熄灭昏暗状态”到全亮度再调至昏暗状态,然后再变回来。
;为此,设置最小亮度、最大亮度值。
.equ MIN_BRIGHT = 15 ;最小亮度
.equ MAX_BRIGHT = 255 ;最大亮度
; 此值控制 LED 从亮到暗的循环速度。 是的我们为亮度的每一步生成的PWM周期数
;坡道,上坡和坡道。 数字越大,脉动越慢。
.equ N_CYCLES = 6 ;周期数
; 重置后开始执行程序
ldi r16,low(RAMEND) ; 初始化堆栈到RAM顶部
out SPL,r16
ldi r16,high(RAMEND)
out SPH,r16
; 初始化硬件
ldi r16,0xff ; 将端口B设置为所有输出
out DDRB,r16
sbi LED_PORT,LED_BIT ;通过将输出引脚设置为高电平关闭蓝色LED
; 从LED处于最低水平开始,然后上升到最大水平
dopwm: ldi r17,MIN_BRIGHT ; R17保持当前亮度水平
adjust_1: ldi r18,N_CYCLES ; R18计算PWM周期,从而计算脉动速度
adjust_2: cbi LED_PORT,LED_BIT ; 输出引脚低,LED亮起
mov r16,r17 ;R16控制延迟长度(=R17)
rcall delayn4us ;调用延迟子程序
sbi LED_PORT,LED_BIT ; 输出引脚高,LED熄灭
ldi r16,255
sub r16,r17 ; R16控制延迟长度(=255-R17)
rcall delayn4us ; 调用延迟子程序
dec r18 ;递减PWM周期计数器
brne adjust_2
inc r17 ; 亮度增加一步
brne adjust_1
; 现在逐渐降低到最小亮度
ldi r17,MAX_BRIGHT ;R17 保持当前亮度水平
adjust_3: ldi r18,N_CYCLES ;R18 计算 PWM 周期,从而计算脉动速度
adjust_4: cbi LED_PORT,LED_BIT ;输出引脚低电平,LED 亮起
MOV R16,R17 ;R16 控制延迟长度 (= R17)
rcall delayn4us ;呼叫延迟子例程
sbi LED_PORT,LED_BIT ;输出引脚高电平,LED 熄灭
ldi R16,255
sub R16,R17 ;R16 控制延迟长度 (= 255 - R17)
rcall delayn4us ;呼叫延迟子例程
dec R18 ;递减PWM周期计数器
brne adjust_4
dec R17 ;亮度降低一级
CPI r17,MIN_BRIGHT ;我们达到最低限度了吗?
brne adjust_3
rjmp dopwm ; 循环回到开始
; delayn 4US
;延迟 (R16 * 4) 微秒
delayn4us: tst r16 ; R16 = 0?(无延迟)
breq dly4
dly2: ldi r24,low(16)
ldi r25,high(16)
dly3: sbiw r24,1 ; 2 个周期
brne dly3 ; 2 个周期
dec r16
brne dly2
dly4: ret ;返回
; Copyright (c) 2006 John Honniball
.include "m8def.inc"
.org 0x0000
; 端口 B 位 2 上的LED
.equ LED_PORT = PortB
.equ LED_BIT = 2
; 该程序驱动连接到 AVR 的 I/O 端口的单个 LED。 它将 LED 的阴极连接到 AVR 引脚,
;LED 的阳极通过电阻器。 该电阻的值取决于 LED 的颜色,但通常为几百欧姆。
;我们通过脉宽调制 (PWM) 控制 LED 的亮度,
; 就像脉动那样地周期运动或变化 从未完全“熄灭昏暗状态”到全亮度再调至昏暗状态,然后再变回来。
;为此,设置最小亮度、最大亮度值。
.equ MIN_BRIGHT = 15 ;最小亮度
.equ MAX_BRIGHT = 255 ;最大亮度
; 此值控制 LED 从亮到暗的循环速度。 是的我们为亮度的每一步生成的PWM周期数
;坡道,上坡和坡道。 数字越大,脉动越慢。
.equ N_CYCLES = 6 ;周期数
; 重置后开始执行程序
ldi r16,low(RAMEND) ; 初始化堆栈到RAM顶部
out SPL,r16
ldi r16,high(RAMEND)
out SPH,r16
; 初始化硬件
ldi r16,0xff ; 将端口B设置为所有输出
out DDRB,r16
sbi LED_PORT,LED_BIT ;通过将输出引脚设置为高电平关闭蓝色LED
; 从LED处于最低水平开始,然后上升到最大水平
dopwm: ldi r17,MIN_BRIGHT ; R17保持当前亮度水平
adjust_1: ldi r18,N_CYCLES ; R18计算PWM周期,从而计算脉动速度
adjust_2: cbi LED_PORT,LED_BIT ; 输出引脚低,LED亮起
mov r16,r17 ;R16控制延迟长度(=R17)
rcall delayn4us ;调用延迟子程序
sbi LED_PORT,LED_BIT ; 输出引脚高,LED熄灭
ldi r16,255
sub r16,r17 ; R16控制延迟长度(=255-R17)
rcall delayn4us ; 调用延迟子程序
dec r18 ;递减PWM周期计数器
brne adjust_2
inc r17 ; 亮度增加一步
brne adjust_1
; 现在逐渐降低到最小亮度
ldi r17,MAX_BRIGHT ;R17 保持当前亮度水平
adjust_3: ldi r18,N_CYCLES ;R18 计算 PWM 周期,从而计算脉动速度
adjust_4: cbi LED_PORT,LED_BIT ;输出引脚低电平,LED 亮起
MOV R16,R17 ;R16 控制延迟长度 (= R17)
rcall delayn4us ;呼叫延迟子例程
sbi LED_PORT,LED_BIT ;输出引脚高电平,LED 熄灭
ldi R16,255
sub R16,R17 ;R16 控制延迟长度 (= 255 - R17)
rcall delayn4us ;呼叫延迟子例程
dec R18 ;递减PWM周期计数器
brne adjust_4
dec R17 ;亮度降低一级
CPI r17,MIN_BRIGHT ;我们达到最低限度了吗?
brne adjust_3
rjmp dopwm ; 循环回到开始
; delayn 4US
;延迟 (R16 * 4) 微秒
delayn4us: tst r16 ; R16 = 0?(无延迟)
breq dly4
dly2: ldi r24,low(16)
ldi r25,high(16)
dly3: sbiw r24,1 ; 2 个周期
brne dly3 ; 2 个周期
dec r16
brne dly2
dly4: ret ;返回