下面的程序是我在做EL驱动器产品中的单片机程序,此程序是驱动3个EL片按顺序渐亮渐灭的程序,稍加改动可驱动8个EL片按顺序渐亮渐灭.单片机采用的是SONIX的,汇编代码.
;OSC:4.000MHz
chip SN8P2501B
//{{SONIX_CODE_OPTION
.Code_Option LVD LVD_M ; 2.0V Reset Enable LVD24 bit of PFLAG for 2.4V Low Voltage Indicator
.Code_Option Reset_Pin P11
.Code_Option Watch_Dog Always_On
.Code_Option High_Clk IHRC_16M ; Internal 16M RC Oscillator
.Code_Option Fcpu #2 ; Fcpu = Fosc/4
.Code_Option Security Enable
.Code_Option Noise_Filter Disable
; .Code_Option OSG Enable
; .Code_Option High_Clk 12M_X'tal
; .Code_Option High_Clk/2 Disable
; .Code_Option Security Enable
; .Code_Option LVD Enable
; .Code_Option Watch_Dog Enable
//}}SONIX_CODE_OPTION
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;此程序是驱动3位EL片顺次渐亮渐灭(可驱动8位)
;-------------------------------------------------------------------------------
; Variables Definition
;-------------------------------------------------------------------------------
.DATA
ORG 00H
ACCBUF DS 1
PFLAGBUF DS 1
cnt_ms1 DS 1
R_COUNT DS 1
R_HIGH DS 1
R_TIME_C DS 1
BIT_DRIVER DS 1
BIT_DRIVER2 DS 1
CAL_TEMP DS 1
pwm_temp DS 1
mark_temp DS 1
enable_bit EQU mark_temp.0
el_ptime_bit EQU mark_temp.1
add_bit EQU mark_temp.2
VAL_HIGH_INI_H EQU #10
VAL_HIGH_INI_L EQU #1
TIME_SET EQU #80
t0c_temp EQU #206; #51; //T0定时计数初始值
tc0c_temp EQU #240; #178; #191; //TC0定时计数初始值
pwm2_count_temp EQU #18; #28; //升压PWM间隔频率设定值
;-------------------------------------------------------------------------------
; Code section
;-------------------------------------------------------------------------------
.CODE
ORG 0
JMP RESET
ORG 0X0008
JMP INT_SER
ORG 0X0010
;-------------------------------------------------------------------------------
; Program reset section
;-------------------------------------------------------------------------------
RESET:
MOV A,#0x07
B0MOV STKP,A ;堆栈指针清零,禁止全局中断
CLR PFLAG
MOV A,#00H
B0MOV OSCM,A ;初始化系统模式
MOV A,#0X5A
B0MOV WDTR,A ;清零看门狗定时器
CALL ClrRAM ;清RAM
CALL SysInit ;系统初始化
B0BSET FGIE ;使能全局中断
;-------------------------------------------------------------------------------
; Main routine
;-------------------------------------------------------------------------------
MAIN:
MOV A,#0X5A
B0MOV WDTR,A ;清零看门狗定时器
CALL MAIN_PP
JMP MAIN
;-------------------------------------------------------------------------------
; Main application
;-------------------------------------------------------------------------------
MAIN_PP:
RET
;-------------------------------------------------------------------------------
; INT_SER ROUTINE
;-------------------------------------------------------------------------------
INT_SER:
B0XCH A,ACCBUF
B0MOV A,PFLAG
B0MOV PFLAGBUF,A
INTT0CHK:
B0BTS1 FT0IEN ;是否允许TO中断
JMP INTTC0CHK
B0BTS0 FT0IRQ ;是否有T0中断请求
JMP INTT0
INTTC0CHK:
B0BTS1 FTC0IEN ;是否允许TC0中断
JMP INT_EXIT
B0BTS0 FTC0IRQ ;是否有TC0中断请求
JMP INTTC0
INT_EXIT: ;
B0MOV A,PFLAGBUF ;
B0MOV PFLAG,A
B0XCH A,ACCBUF
RETI ;中断返回
;-------------------------------------------------------------------------------
; T0 interrupt service routine
;-------------------------------------------------------------------------------
INTT0:
B0BCLR FT0IRQ ;清T0中断请求标志
MOV A,t0c_temp;#206 ;#51;
B0MOV T0C,A ;重装计数值
MOV A,tc0c_temp;#218 ;#102;
B0MOV TC0C,A ;(256-102)/(256-51)=75%
B0BCLR FTC0IRQ ;清TC0中断标志
B0BSET FTC0IEN ;使能TC0中断
B0BSET FTC0ENB ;使能TC0计数
DECMS cnt_ms1
JMP EOR_EL_PWM
MOV A,pwm2_count_temp;#20;#18
B0MOV cnt_ms1,A
MOV A,#01H
XOR pwm_temp,A ;每间隔1/544 s做1/544 s的P1.0的PWM 输出
EOR_EL_PWM:
B0BTS0 enable_bit
JMP EL_DRIVER_PORT //
B0BSET P0.0
B0BTS1 pwm_temp.0
JMP EL_DRIVER_PORT
B0BSET P1.0
EL_DRIVER_PORT:
MOV A,#1
B0ADD R_COUNT,A ;是否到了把EL驱动位设置为0的时间
B0MOV A,R_COUNT
SUB A,R_HIGH
B0BTS1 FC ;如果借为C为1则表示R_COUNT大于R_HIGH,则跳过下一行
JMP SET_EL_BIT ;没到,设置为1
CLR_EL_BIT:
B0MOV A,BIT_DRIVER
XOR A,#0FFH
AND P2,A
JMP CMP_MAX
SET_EL_BIT:
B0MOV A,P2
OR A,BIT_DRIVER;正在输出PWM的口置为高电平
B0MOV P2,A
JMP INT0_END
CMP_MAX:
MOV A,#10
SUB A,R_COUNT
B0BTS0 FC ;如果C为0,表示R_COUNT>10,则跳过下一行
JMP INT0_END ;否则跳出
CLR R_COUNT ;清R_COUNT
MOV A,#1
B0ADD R_TIME_C,A
MOV A,R_TIME_C
SUB A,TIME_SET
B0BTS1 FC ;如果借为C为1则表示R_TIME_C大于TIME_SET,则跳过下一行
JMP INT0_END ;否则跳出
CLR R_TIME_C ;清每一级亮度所亮时间计数器
B0BTS1 add_bit ;是否处在加亮度循环里,若是,则亮度加一级
JMP SUB_LIGHT ;若不是,则亮度减一级
ADD_LIGHT:
MOV A,#1
B0ADD R_HIGH,A
B0MOV A,R_HIGH
SUB A,#10
B0BTS1 FC
JMP INT0_END ;R_HIGH=<10则跳出
MOV A,VAL_HIGH_INI_L
B0MOV R_HIGH,A;R_HIGH置初始值
B0MOV A,P2
OR A,BIT_DRIVER;正在输出PWM的口置为高电平
B0MOV P2,A
B0BCLR FC
RLCM BIT_DRIVER ;左移一位
B0MOV A,BIT_DRIVER
SUB A,#8
B0BTS1 FC
JMP INT0_END
B0BCLR add_bit ;位数到,则清亮度逐层增加标志
MOV A,VAL_HIGH_INI_H
B0MOV R_HIGH,A ;R_HIGH置为最高亮度
MOV A,#01 ;动作位数从最低位开始
B0MOV BIT_DRIVER,A
JMP INT0_END
SUB_LIGHT:
MOV A,#1
B0MOV CAL_TEMP,A
B0MOV A,R_HIGH
SUB A,CAL_TEMP
B0MOV R_HIGH,A
SUB A,VAL_HIGH_INI_L
B0BTS0 FC
JMP INT0_END ;C为1,即R_HIGH大于初始值则跳出
MOV A,VAL_HIGH_INI_H
B0MOV R_HIGH,A ;重置R_HIGH值
B0MOV A,BIT_DRIVER
XOR A,#0FFH
AND P2,A ;清零正在输出PWM的端口
B0BCLR FC
RLCM BIT_DRIVER
B0MOV A,BIT_DRIVER
SUB A,#8
B0BTS1 FC
JMP INT0_END
B0BSET add_bit
MOV A,VAL_HIGH_INI_L
B0MOV R_HIGH,A
MOV A,#01 ;动作位数从最低位开始
B0MOV BIT_DRIVER,A
INT0_END:
JMP INT_EXIT
;-------------------------------------------------------------------------------
; TC0 interrupt service routine
;-------------------------------------------------------------------------------
INTTC0:
B0BCLR FTC0IRQ ;清TC0中断请求标志
B0BCLR FTC0IEN ;禁止TC0中断
B0BCLR FTC0ENB ;禁止TC0计数
B0BTS0 enable_bit
JMP END_INTTC0 //
B0BCLR P0.0
B0BCLR P1.0
END_INTTC0:
JMP INT_EXIT
;-------------------------------------------------------------------------------
; SysInit
; System initial to define Register, RAM, I/O, Timer......
;-------------------------------------------------------------------------------
SysInit:
;--------------------------------
;init_port0:
;--------------------------------
B0BCLR P0.0
B0BSET P0M.0 ;P0.0 AS OUTPUT
;--------------------------------
;init_port1:
;--------------------------------
B0BCLR P1.0 ;
MOV A,#00000001B ;P1.0作为开关频率输出口
B0MOV P1M,A
MOV A,#11111110B
B0MOV P1UR,A ;使能P1口上拉功能
;--------------------------------
;init_port2:
;--------------------------------
MOV A,#00000000B
B0MOV P2,A ;P2.0-P2.4作为EL驱动口,初始化为输出0
MOV A,#00011111B
B0MOV P2M,A ;P2.0-P2.4作为EL驱动口
MOV A,#00100000B ;使能P2.5上拉功能
B0MOV P2UR,A
;--------------------------------
;init_port5:
;--------------------------------
; B0BSET P5.4
B0BCLR P5M.4
MOV A,#00010000B
B0MOV P5UR,A
;--------------------------------
; init ram
;--------------------------------
MOV A,pwm2_count_temp;#25;#18
B0MOV cnt_ms1,A ;初始化ms计数器1计数值==255
MOV A,#01H
B0MOV pwm_temp,A
CLR mark_temp
CLR R_HIGH
CLR R_COUNT
MOV A,#01 ;动作位数从最低位开始
B0MOV BIT_DRIVER,A
B0BSET add_bit
;--------------------------------
; init T0
;--------------------------------
B0BCLR FT0IEN ;禁止T0中断
B0BCLR FT0ENB ;禁止T0计数
MOV A,#01110000B
B0MOV T0M,A ;设置定时模式为Fcpu/2
MOV A,t0c_temp;#206;#51; ;4M时:256-206=50 16M时:256-51=205
B0MOV T0C,A ;定时中断为10K频率
B0BCLR FT0IRQ ;清T0中断标志
B0BSET FT0IEN ;使能T0中断
B0BSET FT0ENB ;使能T0计数
;--------------------------------
; init TC0
;--------------------------------
B0BCLR FTC0IEN ;禁止TC0中断
B0BCLR FTC0ENB ;禁止TC0计数
MOV A,#01110000B
B0MOV TC0M,A ;设置定时模式为Fcpu/2
MOV A,tc0c_temp;#218;#102; ;4M时:256-218=38 16M时:256-102=154
B0MOV TC0C,A ;4M (265-218)/(256-206)=75% 16M (256-102)/(256-51)=75%
B0BCLR FTC0IRQ ;清TC0中断标志
B0BSET FTC0IEN ;使能TC0中断
B0BSET FTC0ENB ;使能TC0计数
RET
;-------------------------------------------------------------------------------
; ClrRAM
; Use index @YZ to clear RAM (00h~2Fh)
;-------------------------------------------------------------------------------
ClrRAM:
CLR Y
MOV A, #0x2F
B0MOV Z, A ;Set @YZ address from 2fh
ClrRAM10:
CLR @YZ ;Clear @YZ content
DECMS Z ;z = z - 1 , skip next if z="0"
JMP ClrRAM10
CLR @YZ ;Clear address $00
RET
;-------------------------------------------------------------------------------
ENDP