菜鸟学PIC单片机(一)
2017-12-07 来源:eefocus
菜鸟学PIC 单片机 (一):TS1620字符型液晶模块驱动程序编写苦与乐
小弟学习PIC16F87X系列 单片机 已持续半个月了,遇到的困难还是比较多的,幸好单位的图书馆里还有一些相关的书籍,加之购买了第三方的ICD,因此学习起来还是比较充实的。
虽说如此,但在单位里找不到志同道合者一起来琢磨她,不过这里却有许多热心的站友。
今后,小弟打算将自己的一些学习心得和疑问写出来,与论坛里和我一样的初学者一起进步,并殷切希望能得到前辈的指点,
小弟写的第一个程序是控制三位八段数码管的显示,还没来得及总结,今天下午调试和总结了一下LCD的驱动程序,遇到了很多困难,但也有点小小的收获,拿出来晾晾,大家尽管扔砖,小弟开卡车兜着...
TS1620字符型液晶模块驱动程序编写苦乐
该LCM的控制器为HD47780,其引脚功能如下:
PIN 1 2 3 4 5 6 7~17 15 16
功能 GND VDD VO RS RW E DB0~7 BL+ BL-
说明:
RS:数据/命令选择,用来选择DB0~7输入的是显示数据还是控制字信息,(H/L)
RW:读写选择,(H/L),在延迟时间足够的情况下,一般不用读LCM忙信号,常接地。
E: 使能端,控制DB0~7的数据/命令的写入或者读取,上升或下降沿有效。
VO:LCD偏压信号,用来对调整对比度,一般接10K电位器/电阻到地。
DB0~7:数据I/O,可选择8位数据或者4位数据(分两次传输)。
BL+:背光电源正输入 +5V DV。
BL-:背光电源地。
VDD:电源正 +5V DC。
GND:电源地。
编写驱动:
流程:
上电LCM自动复位—清屏—设置显示模式—开显示和光标设置—设置显示的起始位置—显示字符ASCII码输入显示。
注意事项:
1. LCM属于慢显示器件,其上电后复位的时间比较长,因此,可在系统初始化过程中最后初始化LCM;或者在初始化之前调用20~50ms的延迟子程序。并且,如果系统不需要通过延迟来等待LCM完成每一个操作的话,那么应检测(读)LCM忙标志,若不忙(该标志为低电平),那么指令能得到执行,否则指令失效。
2. 由于E输入的使能是上升沿有效还是下降沿有效存在争议,该问题在调试中将遇到,还没来得及分析,愿意与大家一起分析。
3. 有时候LCM所显示的结果并不遵循我们原来的意愿,此时,需先检查程序中,初始化功能是否完成,尤其是在不检测忙标志的初始化程序中更要注意,可适当延长延迟时间或者重复初始化指令,另外,也要检查硬件连线是否有错。
4. 如果与LCM的引脚相连的端口,需注意该端口是否为普通数字端口,比如本例程中,RA口应先设置成普通数字端口。起初我没有如此设置,结果软件仿真模式下始终发现对RA口的操作均不能从SFR观察窗口中发现任何变化...
5. 由于我所用的demo板电路图上,其LCM模块是由RA和RC来控制的,因此,为了能观察运行结果,程序中依然采用RA和RC来控制LCM。
下面给出一个例程,该例程在小弟用的仿真器和demo板上通过,同时给出调试现象:
1)关于E的使能的问题,如果对LCM 的E输入脚进行复位置位(先复位或先置位结果均一样)操作时中间的延时过短或者过长的话,均会出现一些问题:
过短:5ms,运行正常,但在debug中复位后,会有部分字符残留
特短:3个nop指令,运行后无任何输出
较长:200ms,运行正常,但debug复位后,所有字符均残留
一般:50ms,显示正常,复位后无字符残留
前辈们能分析一下么?
2)由于采用的显示模式是16字x2行,发现,如果字符表_table1或者_table2中,伪指令dt定义的字符个数如果小于16的话,那么在该行字符的末尾会出现一些其他的字符,小弟这里出现的是 “||”,后用空格填充至16字符具体原因愿意与大家一起分析。
3) 该程序采用ICD模式调试烧写,运行正常之后,小弟打算脱机运行,即不烧入调试代码,但烧写过程老是停在 programming ID处,取消ID烧入,那么烧写过程就停在programming program,并且,ICD 就出现 连接错误的提示,需重新更改ICD模式至SIM模式下,此时发现ICD的连接指示灯不再闪烁,连接正常了。
(可能问题描述得不够准确,下次再重现故障,详细说明...)
4) 另外一个有趣的问题是,PIC16系列的指令系统中应该没有movfw这一指令,但是,在mplab中,却发现,诸如movfw value ;(value为一自定义的寄存器变量)却能通过编译,而且,功能似乎等同 movf value,W 小弟感到纳闷(小弟用的是mplab 5.7full版,该第三方的ICD能直接使用在该版本下..
请前辈指点,如果能谈谈自己这些年来学习PIC 单片机 所走过的路就更好了:)
;****************************************************
list p=16f877
#include
;定义保护现场用寄存器
w_temp EQU 0x71
status_temp EQU 0x72
pclath_temp EQU 0x73
;定义主程序用寄存器
count EQU 0x74 ; 定义计数寄存器地址
tmp1 EQU 0x75 ; 定义临时寄存器地址
x EQU 0x76 ; 延时子程序外循环计数器
y EQU 0x77 ; 延时子程序内循环计数器
;定义LCM控制位常量
RS EQU 1 ; LCD寄存器选择信号脚定义在RA.1脚
RW EQU 2 ; LCD读/写信号脚定义在RA.2脚
E EQU 3 ; LCD片选信号脚定义在RA.3脚
;***该段e文注释的程序为模板内容
org 0x000 ; processor reset vector
nop ; nop required for icd
goto main ; go to beginning of program
org 0x004 ; interrupt vector LOCation
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
movf PCLATH,w ; move pclath register into w register
movwf pclath_temp ; save off contents of PCLATH register
; isr code CAN go here or be located as a call subroutine elsewhere
movf pclath_temp,w ; retrieve copy of PCLATH register
movwf PCLATH ; restore pre-isr PCLATH register contents
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt
;******************************
main
bsf STATUS,RP0
movlw 07H
movwf ADCON1 ;设置RA口全部为普通数字IO口
clrf TRISA
clrf TRISC ; 定义RA口,RC口全部为输出
bcf STATUS,RP0
call _delay ;调用廷时,刚上电LCD复位不一定有PIC快
movlw 01H
movwf PORTC ; 清屏
call _enable
movlw 38H
movwf PORTC ; 8位数据,16字x2行,5x7点阵
call _enable
movlw 0CH ; 显示器开、光标不闪
movwf PORTC
call _enable
movlw 06H ; 文字不动,光标自动右移
movwf PORTC
call _enable
movlw 80H
movwf PORTC ; 第一行显示位置
call _enable
call _write1 ; 调用送第一行数子程序' www.21ic.com '
movlw 0C0H
movwf PORTC ; 第二行的位置
call _enable
call _write2 ; 调用送第二行数子程序'best wish to you'
goto $
;***********************
_write1
clrf count ;送第一行数字程序
again1
movf count,W
call _table1
movwf tmp1
call _write
incf count
movf tmp1,W
xorlw 00H
btfss STATUS,Z
goto again1
retlw 0
;*************************
_write2 ;送第二行数子程序
clrf count
again2
movf count,W
call _table2
movwf tmp1
call _write
incf count
movf tmp1,W
xorlw 00H
btfss STATUS,Z
goto again2
retlw 0
;**************************
_write ;送数据到LCD子程序
movwf PORTC
bsf PORTA,RS
bcf PORTA,RW
bcf PORTA,E
call _delay
bsf PORTA,E
retlw 0
;写入控制命令的子程序
_enable
bcf PORTA,RS
bcf PORTA,RW
bcf PORTA,E
call _delay
bsf PORTA,E
retlw 0
;******************************************************
_table1 ;取第一行的显示码 www.21ic.com
addwf PCL ;地址偏移量加当前PC值
dt ' www.21ic.com '
retlw 00H
;-------------------- ----------------------------------
_table2 ;取第一行的显示码best wish to you
addwf PCL ;地址偏移量加当前PC值
dt 'best wish to you'
retlw 00H
;********************************************************
;延时子程序
_delay
movlw 0x3c ;晶振为4 MHz,延时50ms
movwf x
loop_x
movlw 0xff
movwf y
loop_y
decfsz y
goto loop_y
decfsz x
goto loop_x
return
end ;源程序结束