本帖最后由 JLennon 于 2018-3-1 14:18 编辑
跑马灯实例
1.功能说明
利用Curiosity开发板上的D4~D7这四个LED,实现跑马灯效果。
2.硬件电路
查阅microchip官方文档DS40001804B可知,D4~D7阴极接地,阳极分别接至RA5、RA1、RA2、RC5。
当对应的引脚输出高电平时,则该LED点亮。因为开发板没有外置晶振,所以系统时钟源选用内部时
钟源,这里我们就用8MHZ。
3.软件设计
(1)程序关键点分析
本例的RA和RC端口需要被配置为输出方向,初始化端口输出全为低电平,即D4~D7处于全灭状态。当
RA5输出高电平,其他引脚输出低电平,则D4亮;延时250ms后,RA1输出高电平,其他引脚输出低电
平,则D5亮;如此循环,则实现了跑马灯效果。在进行程序设计时,主要涉及的内容如下:
1)选择配置字,设置系统时钟为内部时钟源。
2)初始化与内部时钟源相关的寄存器和I/O端口,见PIC16F1619的datasheet的5.6章节。
2)在主程序中实现循环输出跑马灯效果。
(2)程序流程图
(3)汇编源程序
1)延时程序如何计算:
PIC单片机1个指令周期占用4个时钟周期,对于8MHZ的时钟频率,时钟周期为0.125μs,指令周期为
0.5μs。要实现250ms延时,约等于5.0*10^6个指令周期。
内循环指令周期(1+1+2)*250-1=999
中循环指令周期(1+1+inner+1+2)*249-1=249,995
外循环指令周期(1+1+middle+1+2)*2-1=499,999
DELAY指令周期 1+1=2
RETURN指令周期 =2
总指令周期=外循环+DELAY+RETURN=500,003,约等于5.0*10^6个指令周期
#include "p16f1619.inc"
; CONFIG1
; __config 0x3FFC
__CONFIG _CONFIG1, _FOSC_INTOSC & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
; CONFIG2
; __config 0x3EFF
__CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_ON & _ZCD_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_ON
; CONFIG3
; __config 0x3F9F
__CONFIG _CONFIG3, _WDTCPS_WDTCPS1F & _WDTE_OFF & _WDTCWS_WDTCWSSW & _WDTCCS_SWC
;*******************************************************************************
CBLOCK 0x20
SHIFTDAT ;作为跑马灯状态标识
DELAY_A
DELAY_B
DELAY_C
ENDC
;*******************************************************************************
RES_VECT CODE 0x0000 ; processor reset vector
GOTO START ; go to beginning of program
; MAIN PROGRAM
;*******************************************************************************
MAIN_PROG CODE ; let linker place main program
START
;***************************************************************************
;初始化时钟
BANKSEL OSCCON
MOVLW 0x70
MOVWF OSCCON ;8MHZ内部时钟
CLRF OSCTUNE
;***************************************************************************
;初始化PORTA
BANKSEL PORTA
CLRF PORTA
BANKSEL ANSELA
CLRF ANSELA
BANKSEL TRISA
MOVLW 0x00
MOVWF TRISA
;***************************************************************************
;初始化PORTC
BANKSEL PORTC
CLRF PORTC
BANKSEL ANSELC
CLRF ANSELC
BANKSEL TRISC
CLRF TRISC
;*******************************************************************************
RELOAD
;重置SHIFTDAT
CLRF BSR ;切换到bank0,否则第一次运行时立即数1会赋给120H地址
MOVLW 0x01
MOVWF SHIFTDAT
MAIN
;*******************************************************************************
;主程序
BTFSC SHIFTDAT, 4 ;若SHIFTDAT第4位是0,则跳过下一条指令
GOTO RELOAD ;若SHIFTDAT第4位是1,则无条件跳转到RELOAD重置
MOVLW 0x01 ;WREG寄存器赋值B'0000,0001'
ANDWF SHIFTDAT, W ;SHIFTDAT与WREG逻辑与后的结果存入WREG寄存器
BTFSC WREG, 0 ;若WREG第0位是0,则跳过下一条指令
CALL D4ON ;若WREG第0位是1,则执行本指令
MOVLW 0x02 ;依次类推,判断D5是否处于点亮状态
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 DELAY
GOTO MAIN
;*******************************************************************************
;点亮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
;******** 延时子程序 ************************************************************
DELAY
MOVLW 0x02
MOVWF DELAY_A ;外循环2
DLY_A
MOVLW 0xF9
MOVWF DELAY_B ;中循环249
DLY_B
MOVLW 0xFA
MOVWF DELAY_C ;内循环250
DLY_C
NOP
DECFSZ DELAY_C
GOTO DLY_C
DECFSZ DELAY_B
GOTO DLY_B
DECFSZ DELAY_A
GOTO DLY_A
RETURN
END
|