利用AVR的硬件SPI驱动74HC595产生256级(即8位)PWM,74HC595还可以联级,我试过一次联级了16个74HC959。程序是用AVR汇编写的,已经写成模块化了的,移植很简单。在这个坛里混了一段时间了,一直都没有贡献出什么,现在将我的重量级资料共享给大家!!如果有不懂的地方大家可以留言,我尽量为大家解答~~~
另:这里也有一个关于“如何控制74hc595驱动led产生灰度等级 ”
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=985613&bbs_page_no=1&bbs_id=9999
#include <avr/io.h>
.global TIMER2_COMP_vect
.comm cPwmCount 1, 1 ;声明变量,第一个数字表示变量的大小,第二个表示一组
TIMER2_COMP_vect:
sbi _SFR_IO_ADDR(PORTB), 2 ;置位PORTB的第二位 这里是连接74HC595的数据锁存口
cbi _SFR_IO_ADDR(PORTB), 2 ;清除PORTB的第二位
; sei 打开总中断,这个可以根据自己的程序需要做决定
push r24 ;堆栈
in r24, _SFR_IO_ADDR(SREG) ;将SREG数据读到r24中
push r24 ;堆栈
push r25 ;堆栈
push r26 ;堆栈
push r30 ;堆栈
push r31 ;堆栈
lds r26, cPwmCount ;将cPwmCount的值送到r24(是直接从SRAM中读取的)
subi r26, 1 ;r24减去1之后将结果保存到r24中,即r24自减1
brcc save_pwmCount ;当c标志等于0时跳转到save_pwmCount
ldi r26, 255 ;加载立即数,将255送到r24 这里的255就是你所要产生的PWM步数,最大为255,根据需要做调整save_pwmCount:
sts cPwmCount, r26 ;将立即数直接储存到SRAM中
ldi r30, lo8(Led) ;将低8位数据送到r30 Led是一个结构体,结构体的头一个变量是数组,数组的空间=N个74HC595 * 8
ldi r31, hi8(Led) ;将高8位数据送到r31
comp_r25_red_0:
ld r25, z+ ;取LED的首地址给r25后地址指针自加1
cp r26, r25 ;r26与r25比较
ror r24 ;通过进位位C向右移动
comp_r25_red_1:
ld r25, z+
cp r26, r25
ror r24
comp_r25_red_2:
ld r25, z+
cp r26, r25
ror r24
comp_r25_red_3:
ld r25, z+
cp r26, r25
ror r24
comp_r25_red_4:
ld r25, z+
cp r26, r25
ror r24
comp_r25_red_5:
ld r25, z+
cp r26, r25
ror r24
comp_r25_red_6:
ld r25, z+
cp r26, r25
ror r24
comp_r25_red_7:
ld r25, z+
cp r26, r25
ror r24
out _SFR_IO_ADDR(SPDR), r24 ;将r24的数据送到SPDR驱动 我这里是联级了4个74HC595
comp_r25_green_0:
ld r25, z+
cp r26, r25
ror r24
comp_r25_green_1:
ld r25, z+
cp r26, r25
ror r24
comp_r25_green_2:
ld r25, z+
cp r26, r25
ror r24
comp_r25_green_3:
ld r25, z+
cp r26, r25
ror r24
comp_r25_green_4:
ld r25, z+
cp r26, r25
ror r24
comp_r25_green_5:
ld r25, z+
cp r26, r25
ror r24
comp_r25_green_6:
ld r25, z+
cp r26, r25
ror r24
comp_r25_green_7:
ld r25, z+
cp r26, r25
ror r24
out _SFR_IO_ADDR(SPDR), r24
comp_r25_blue_0:
ld r25, z+
cp r26, r25
ror r24
comp_r25_blue_1:
ld r25, z+
cp r26, r25
ror r24
comp_r25_blue_2:
ld r25, z+
cp r26, r25
ror r24
comp_r25_blue_3:
ld r25, z+
cp r26, r25
ror r24
comp_r25_blue_4:
ld r25, z+
cp r26, r25
ror r24
comp_r25_blue_5:
ld r25, z+
cp r26, r25
ror r24
comp_r25_blue_6:
ld r25, z+
cp r26, r25
ror r24
comp_r25_blue_7:
ld r25, z+
cp r26, r25
ror r24
out _SFR_IO_ADDR(SPDR), r24
comp_r25_while_0:
ld r25, z+
cp r26, r25
ror r24
comp_r25_while_1:
ld r25, z+
cp r26, r25
ror r24
comp_r25_while_2:
ld r25, z+
cp r26, r25
ror r24
comp_r25_while_3:
ld r25, z+
cp r26, r25
ror r24
comp_r25_while_4:
ld r25, z+
cp r26, r25
ror r24
comp_r25_while_5:
ld r25, z+
cp r26, r25
ror r24
comp_r25_while_6:
ld r25, z+
cp r26, r25
ror r24
comp_r25_while_7:
ld r25, z+
cp r26, r25
ror r24
out _SFR_IO_ADDR(SPDR), r24
pop r31 ;弹出堆栈
pop r30 ;弹出堆栈
pop r26 ;弹出堆栈
pop r25 ;弹出堆栈
pop r24 ;弹出堆栈
out _SFR_IO_ADDR(SREG), r24 ;将状态数据送到SREG端口
pop r24 ;弹出堆栈
reti ;中断返回
|