本帖最后由 JLennon 于 2018-3-7 15:02 编辑
【Curiosity试用】3.PIC16F1619汇编实例二
闪灯实例
1.功能说明
利用timer0触发中断,实现跑马灯。
2.硬件电路
D4~D7阴极接地,阳极分别接至RA5、RA1、RA2、RC5。当对应的引脚输出高电平时,则该LED点亮。
Curiosity开发板无外置晶振,所以系统时钟源选用内部时钟源。
3.软件设计
(1)程序关键点分析
RA和RC端口需要被配置为输出方向,初始化端口输出全为低电平,即D4~D7处于全灭状态。当
RA5输出高电平,其他引脚输出低电平,则D4亮;延时250ms后,RA1输出高电平,其他引脚输出低电
平,则D5亮;如此循环,则实现了跑马灯效果。延时利用timer0定时触发中断。在进行程序设计时,
主要涉及的内容如下:
1)选择配置字,设置系统时钟为内部时钟源。
2)初始化与内部时钟源相关的寄存器和I/O端口,见PIC16F1619的datasheet的5.6章节。
2)主程序只有做一件事,无限循环。
3)中断服务程序判断timer0是否溢出,然后调用子程序。
4)其余子程序进行循环点灯,timer0重置等操作。
(2)程序流程图
(3)汇编源程序
1)Timer0初始值如何设置:
由于timer0是一个8位递增定时计数器,最多256分频,要实现250ms延时,就必须选取MHZ以下
的频率,这里我们选用500KHZ,同时预分频比选择1:256分频。
PIC单片机1个指令周期占用4个时钟周期,对于500KHZ的时钟频率,时钟周期为2μs,指令周期为
8μs。256倍分频后,时钟周期为512μs,指令周期为2048μs。250ms延时,约等于122个指令周期。
TMR0寄存器从FFh上溢到00h时,将产生Timer0中断。那么timer0初始值就等于255(FFh)+1-122=
134(0x86)。
2)源程序
#include "p16f1619.inc"
; CONFIG1
; __config 0xFFFC
__CONFIG _CONFIG1, _FOSC_INTOSC & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
; CONFIG2
; __config 0xFEFF
__CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_ON & _ZCD_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_ON
; CONFIG3
; __config 0xFF9F
__CONFIG _CONFIG3, _WDTCPS_WDTCPS1F & _WDTE_OFF & _WDTCWS_WDTCWSSW & _WDTCCS_SWC
;*******************************************************************************
CBLOCK 0x20
SHIFTDAT
ENDC
RES_VECT CODE 0x0000 ; processor reset vector
GOTO START ; go to beginning of program
;*******************************************************************************
ISR CODE 0x0004 ; interrupt vector location
BRA ISR
;*******************************************************************************
; MAIN PROGRAM
;*******************************************************************************
MAIN_PROG CODE ; let linker place main program
START
;***************************************************************************
;初始化时钟
BANKSEL OSCCON
MOVLW 0x38
MOVWF OSCCON
;***************************************************************************
;初始化I/O
BANKSEL PORTA
CLRF PORTA
CLRF PORTC
BANKSEL ANSELA
CLRF ANSELA
CLRF ANSELC
BANKSEL TRISA
CLRF TRISA
CLRF TRISC
;***************************************************************************
;初始化Timer0
MOVLW 0xD7 ;禁止弱上拉,上升沿触发,timer0时钟FOSC/4
BANKSEL OPTION_REG ;在T0CKI引脚信号从高至低跳变时,递增计数
OPTION ;预分频器分配给Timer0模块,预分频比1:256
CLRF BSR ;转到Bank0
MOVLW 0x86
MOVWF TMR0
BCF INTCON, TMR0IF ;清中断标识
BSF INTCON, TMR0IE ;开中断
;***************************************************************************
;开中断
BSF INTCON, GIE
BSF INTCON, TMR0IE
MAIN
GOTO $
;*******************************************************************************
;中断服务程序
ISR
BTFSC INTCON, TMR0IF ;TMR0中断标志为0,,则跳过下一条指令
CALL BLINK
RETFIE
BLINK
BTFSC SHIFTDAT, 4
CALL RELOAD
MOVLW 0x01
ANDWF SHIFTDAT, W
BTFSC WREG, 0
CALL D4ON
MOVLW 0x02
ANDWF SHIFTDAT, W
BTFSC WREG, 1
CALL D5ON
MOVLW 0x04
ANDWF SHIFTDAT, W
BTFSC WREG, 2
CALL D6ON
MOVLW 0x08
ANDWF SHIFTDAT, W
BTFSC WREG, 3
CALL D7ON
RLF SHIFTDAT, F
CALL RELOADTMR0
RETURN
;*******************************************************************************
;点亮D4
D4ON
CLRF PORTA
CLRF PORTC
BSF PORTA, RA5
BCF PORTC, RC5
RETURN
;*******************************************************************************
;点亮D5
D5ON
CLRF PORTA
BSF PORTA, RA1
BCF PORTC, RC5
RETURN
;*******************************************************************************
;点亮D6
D6ON
CLRF PORTA
BSF PORTA, RA2
BCF PORTC, RC5
RETURN
;*******************************************************************************
;点亮D7
D7ON
CLRF PORTA
BSF PORTC, RC5
RETURN
;*******************************************************************************
;重新赋值SHIFTDAT
RELOAD
;CLRF BSR ;此段可省略,因调用前BSR就是Bank0
MOVLW 0x01
MOVWF SHIFTDAT
RETURN
;*******************************************************************************
RELOADTMR0
MOVLW 0x86
MOVWF TMR0 ;timer0重新加载初始值
BCF INTCON, TMR0IF ;清除中断标识
BSF INTCON, TMR0IE ;重开中断
RETURN
END
|