本帖最后由 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
|