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