PIC12F629七彩灯程序

这段程序是用在一款七彩灯红外遥控解码程序里,单片机使用PIC12F629,软件模拟三路PWM输出驱动红绿蓝LED分八组共24个LED,实现单LED渐明渐暗,两LED一明一暗,七彩等九种花样.有断电记忆功能.如下是解码程序.

;--------------------------------------------------------
;filename: 24LED_Remote.asm
; mcu: PIC12f629
; clock: 4 MHz for INTRC
; date: 2006/02/25
; writer: aLin
; IC type: PT2262IR
; Rosc: 470K
;--------------------------------------------------------

    list p=pic12f629
    #i nclude"p12f629.inc"
   
    #define    B_LED    gpio,0   ;绿LED输出端口
    #define    G_LED    gpio,1   ;蓝LED输出端口
    #define    R_LED    gpio,2   ;红LED输出端口
    #define    rem      gpio,3   ;GP3/MCLR,定义遥控输入端

;因为当按住PT2262的按键不放的时候
;PT2262会把编码不断的送出
;设置ENABLE位用来检测按键有没有放开过,
;如果没有放开则不再响应
;用于遥控型

    #define    enable       user_reg,0     ;接收允许位
    #define    on_off       user_reg,1     ;该位为0时,按花样选择键无效
    #define    go_next      user_reg,2     ;该位为1时,跳下一段
    #define    reset        user_reg,3     ;该位为1时,关显示 
    #define    unlock       user_reg,4     ;用于配合on_off位

;---------------------------------------------------------
;定义变量
;
r1 equ 20h ;用于d5ms子程序
r2 equ 21h ;用于d5ms子程序
r3 equ 22h ;用于d320mS子程序
P_reg equ 23h ;正脉宽时间寄存器
N_reg equ 24h ;负脉宽时间寄存器
count1 equ 25h ;计数器1
count2 equ 26h ;计数器2
W_temp equ 27h ;W临时寄存器
user_reg equ 28h ;用户寄存器
ee_data equ 29h ;eeprom读写数据出入口
ee_addr equ 2ah ;eeprom读写地址入口
data_temp equ 2bh ;用于暂存从EEPROM读出的数所数据
index_reg equ 2ch ;用于保存引导值
data_reg equ 2dh ;用于保存从EEPROM读出的值

A0_addr1 equ 30h
A0_addr2 equ 31h
A1_addr1 equ 32h
A1_addr2 equ 33h
r5 equ 34h ;用于解码延时
r6 equ 35h ;用于解码延时
addr_set1 equ 36h ;用于存储比较密码
addr_set2 equ 37h ;用于存储比较密码
output equ 38h
count equ 39h ;接收12位编码
status_temp equ 3ah ;保存status的值,用于现场保护
ww_temp equ 3bh ;W工作寄存器,用于现场保护用
A0_data1 equ 3ch ;用于存储比较数据D8
A0_data2 equ 3dh ;用于存储比较数据D8
A1_data1 equ 3eh ;用于存储比较数据D11
A1_data2 equ 3fh ;用于存储比较数据D11
;-------------------------------------------
;定义常数
;
index equ 00h ;EEData数据引导地址

;--------------------------------------------------
org 0000h

        call init          ;调用初始化程序
        goto main

;--------------------------------------------------
;中断处理入口
;TMR1溢出中断,说明按键松开时间大于等于65.536mS左右

        org 0004h
        movwf ww_temp      ;保护现场
        swapf status,w
        movwf status_temp
       
        bcf intcon,gie     ;关所有中断
        bcf t1con,tmr1on   ;停止TMR1
        bcf pir1,tmr1if    ;清TMR1中断标志位
        bcf enable         ;按键松开,清enable
       
        swapf status_temp,w
        movwf status
        swapf ww_temp,f
        swapf ww_temp,w
       
        return                                

;--------------------------------------------------
;读出引导地址单元(00H)内容

  main  movlw index        ;送引导地址中转
        movwf ee_addr 
       
        call ee_data_rd    ;调用读EEPROM程序           
        movf ee_data,w     ;读出引导地址内容
       
        movwf index_reg    ;保存引导地址内容
        movwf ee_addr      ;送待读出内容地址
       
        call ee_data_rd
        movf ee_data,w
        movwf data_reg     ;保存读出    
       
        movf data_reg,w
        addlw jumper_tab           
        movwf pcl

jumper_tab goto start ;跳到开始0段
goto seg1 ;跳到第1段
goto seg2 ;跳到第2段
goto seg3 ;跳到第3段
goto seg4 ;跳到第4段
goto seg5 ;跳到第5段
goto seg6 ;跳到第6段
goto seg7 ;跳到第7段
goto seg8 ;跳到第8段

;------------------------------------------------

         如下略....

;-----------------------------------------------

;

;解码程序

;

;---------------------------------------------------------
; A0 | A1 | 说明
;-----±----±-----------------
; 30H | 32H | 接收的8位地址编码
;-----±----±-----------------
; 31H | 33H | 接收的4位数据编码
;-----±----±-----------------
; 36H | 37H | 设定的8位地址密码
;------------------------------
;
; A0_addr1 equ 30h
; A0_addr2 equ 31h
; A1_addr1 equ 32h
; A1_addr2 equ 33h
;
;其中以30H,0和32H,0为例
;悬空: 30H,0=1,32H,0=0
;1: 30H,0=0,32H,0=0
;0: 30H,0=1,32H,0=1
;38H: 输出控制
;---------------------------------------------------------
;
;解码子程序

check_sw btfss rem ;rem为1,无接收到信号,返回
goto remote0
bcf go_next ;没按键,清0
bcf reset ;没按键,清0
bcf unlock

remote_end return ;没有按键,反回
;--------------------------------------------------------

remote0 btfss enable ;rem为0,但enable为1,按键没放开,返回
goto incept ;接收12位编码

;重新设定TMR1
bcf t1con,tmr1on ;停止TMR1
clrf tmr1h ;ffff为65.536mS
clrf tmr1l
bsf t1con,tmr1on ;重启动TMR1

        bcf reset          ;按键没松开,解码取消,清0
        bcf go_next        ;按键没松开,解码取消,清0 
        bcf unlock
       
        goto remote_end    ;按键没有放开,返回

;清除上次解码内容
;接收12位编码
;
incept movlw .12
movwf count
;解码
;先找出接收到的开头,即16mS左右的高电平
;设置高电平时间为15~17mS
;
;检测和等待15mS的高电平
;
remote1 movlw .30
movwf r5
remote2 movlw .100
movwf r6
remote3 btfss rem
goto remote1
decfsz r6,f
goto remote3
decfsz r5,f
goto remote2

;等待在2mS内接收到的低电平
movlw .4
movwf r5
remote4 movlw .100
movwf r6

;15mS到17mS内接收到下降沿,则跳去解码,否则返回
remote5 btfss rem
goto remote6
decfsz r6,f
goto remote5
decfsz r5,f
goto remote4

;超出17mS,接收错误,返回
bcf enable
goto remote_end

;等待1200uS后,采集接收信号
remote6 movlw .200
movwf r5
decfsz r5,f
goto $-1
movlw .200
movwf r5
decfsz r5,f
goto $-1

;采集接收信号,并记录

        btfss rem         ;如果rem为1,则c置1,否则清0
        clrc
        btfsc rem           
        setc              ;rem为1,c置1
       
        rlf A0_addr2,f
        rlf A0_addr1,f

;等待第二个下降沿
;加入了限时判断,防止死循环。
;
; btfss rem ;rem为0,一直执行
; goto $-1

        movlw .255
        movwf r5
        btfsc rem         ;rem为0,一直执行
        goto $+4
        decfsz r5,f
        goto $-3
        goto remote8      ;超时,跳到错误处理

; btfsc rem ;rem为1,一直执行
; goto $-1

        movlw .255
        movwf r5
        btfss rem         ;rem为1,一直执行
        goto $+4
        decfsz r5,f
        goto $-3
        goto remote8      ;超时,跳到错误处理

;等待1200uS后采集接收信号
movlw .200
movwf r5
decfsz r5,f
goto $-1
movlw .200
movwf r5
decfsz r5,f
goto $-1

        btfss rem         ;如果rem为1,则c置1,否则清0
        clrc
        btfsc rem
        setc              ;rem为1,c置1
       
        rlf A1_addr2,f
        rlf A1_addr1,f

;等待第二个码值的下降沿
;加入了限时判断,防止死循环。
;
; btfss rem ;rem为0,一直执行
; goto $-1

        movlw .255
        movwf r5
        btfsc rem         ;rem为0,一直执行
        goto $+4
        decfsz r5,f
        goto $-3
        goto remote8      ;超时,跳到错误处理

; btfsc rem ;rem为1,一直执行
; goto $-1

        movlw .255
        movwf r5
        btfss rem         ;rem为1,一直执行
        goto $+4
        decfsz r5,f
        goto $-3
        goto remote8      ;超时,跳到错误处理
       
            
        decfsz count,f
        goto remote6      ;连续接收12位
        goto decode       ;接收完12位编码,跳到解码

;开始解码
;把接收的编码左移4位,将8位密码放在同一字节上
decode movlw .4
movwf count
remote7 clrc
rlf A0_addr2,f
rlf A0_addr1,f
clrc
rlf A1_addr2,f
rlf A1_addr1,f
decfsz count,f
goto remote7

;把4位数据编码由高4位移到低4位上
swapf A0_addr2,f
swapf A1_addr2,f

;比较密码
movf A0_addr1,w
xorwf addr_set1,w
skpz
goto remote8 ;跳到接收错误处理

        movf A1_addr1,w
        xorwf addr_set2,w
        skpz
        goto remote8       ;跳到接收错误处理

;接收正确处理
;每次按键都一次响应
;按键为PT2262IR pin10(D8) 和 pin13(D11)
;以下只识别D8、D11,对数据理D9、D10不作处理
;
;悬空: A0=1 , A1=0
; 1: A0=0 , A1=0
; 0: A0=1 , A1=1
;
;检查键值D8,ON/OFF键

        movf A0_addr2,w
        andlw 0fh
        xorwf A0_data1,w  
        skpz
        goto D11           ;不是只有键值D8按下,检查键值D11,
                           ;即D8没有按下或D8按下同时还有其它按键按下
        movf A1_addr2,w
        andlw 0fh
        xorwf A1_data1,w
        skpz
        goto D11           ;不是只有键值D8按下,检查键值D11
                           ;即D8没有按下或D8按下同时还有其它按键按下

;是键值D8按下,开始处理
;on/off处理,按下on/off键假如on,
;再按下就是off,然后再按下又是off。

        movlw b'00000010'  ;取反user_reg的on_off位
        xorwf user_reg,f
        btfss on_off       ;on_off位为0,reset置1,返回时关显示
        goto clr_rst
        bsf unlock         ;on_off位为1,置unlock为1,返回时开显示
        goto back

;检查键值D11,NEXT键。
D11 btfss on_off ;on_off为0,当前已关显示,按键NEXT无效
goto back ;返回

        movf A0_addr2,w
        andlw 0fh
        xorwf A0_data2,w   
        skpz
        goto back          ;也不是只有键值D11按下,返回
                           ;即D11没有按下或D11按下同时还有其它按键按下
        movf A1_addr2,w
        andlw 0fh
        xorwf A1_data2,w
        skpz
        goto back          ;也不是只有键值D11按下,返回
                           ;即D11没有按下或D11按下同时还有其它按键按下

;是键值D11按下,开始处理
bsf go_next ;跳下一段
bcf reset
goto back

clr_rst bsf reset
bcf go_next
goto back

  back  bcf t1con,tmr1on  ;停止TMR1
        clrf tmr1h
        clrf tmr1l
        bsf t1con,tmr1on  ;启动TMR1
        bsf enable        ;置1,防止开关按住不放,不断响应。

work_end retfie ;返回并开中断

;接收错误处理
remote8 bcf enable

        bcf go_next       ;密码错误,取消解码,清0
        bcf reset         ;密码错误,取消解码,清0
        bcf unlock
       
        bsf enable        ;虽接收错误,但都是有按键按下

;重新设定TMR1
bcf t1con,tmr1on ;停止TMR1
clrf tmr1h ;ffff为65.536mS
clrf tmr1l
bsf t1con,tmr1on ;重启动TMR1
retfie ;返回并开中断

;-------------------------------------------
;初始化程序

  init  bsf status,rp0     ;选择bank1
        call 3ffh
        movwf osccal
        movlw b'00001000'  ;GP0/1/2为输出
        movwf trisio       ;GP3为输入
        clrf ioc           ;关闭所有电平变化中断
        bsf pie1,tmr1ie    ;开TMR1中断
       
        bcf status,rp0     ;选择bank0
        bcf intcon,gie     ;关所有中断
        bsf intcon,peie    ;开外设中断
        bcf t1con,tmr1on   ;停止TMR1
       
        clrf gpio          ;输出清0
        movlw 07h        
        movwf cmcon        ;设置GP0/1/2为IO
       
        bcf enable         ;头次上电,初始化enable、reset、go_next
        bcf reset
        bcf go_next

;编码地址设定为:A0~A7为悬空(A0=1,A1=0)
movlw b’11111111’ ;A0
movwf addr_set1
movlw b’00000000’ ;A1
movwf addr_set2

;D8设置1(A0=0,A1=0),D9、D10悬空(A0=1,A1=0)
;D11设置0(A0=1,A1=1),该状态为只有D8按下。D8为ON/OFF键。
movlw b’00001110’ ;A0
movwf A0_data1
movlw b’00001000’ ;A1
movwf A1_data1

;D11设置1(A0=0,A1=0),D9、D10悬空(A0=1,A1=0)
;D8设置0(A0=1,A1=1),该状态为只有D11按下。D11为NEXT键。
movlw b’00000111’ ;A0
movwf A0_data2
movlw b’00000001’ ;A1
movwf A1_data2

        return      

;------------------------------------------------------
————————————————

原文链接:https://blog.csdn.net/liht_1634/article/details/124154677

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值