马老师,请指导一下学生的这个用16×2液晶的定时小程序(bascom)
马老师,请指导一下学生的这个用16×2液晶的定时小程序,谢谢!程序如下:
$regfile = "m16def.dat"
$crystal = 4915200
$hwstack = 32
$swstack = 8
$framesize = 24
Config Lcdpin = Pin , Rs = Portb.2 , E = Portb.3 , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7
Config Lcd = 16 * 1
Cursor Off
Config Timer1 = Timer , Prescale = 1024
On Ovf1 Ovf1_int
Enable Interrupts
Enable Ovf1
Timer1 = &HED40
Dim S As Byte
S = 0
Start Timer1
Cls
Do
Locate 1 , 1
Lcd S
Loop
End
Ovf1_int:
Timer1 = &HED40
'Cls
Incr S
If S = 255 Then
S = 0
End If
Return
现在问题是,为了解决LCD末位显示问题,我在进入中断后加入了一句“cls”,本意是想让显示正确,但不知道为什么却造成了显示混乱,变量跑到“7”的时候就出现了乱码,我思考了很久也想不出原因来,还有就是对于数值型的变量如何进行格式化,就象这个程序中如何使LCD始终显示三位数值,
请马老师指教,谢谢! Config Lcdpin = Pin , Rs = Portb.2 , E = Portb.3 , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7
Config Lcd = 16 * 1
Cursor Off
Config Timer1 = Timer , Prescale = 1024
On Ovf1 Ovf1_int
Enable Interrupts
Enable Ovf1
Timer1 = &HED40
Dim S As Byte
Dim Time_ok As Bit
S = 0
Time_ok = 1
Start Timer1
Do
If Time_ok = 1 Then
Incr S
If S = 255 Then S = 0
Cls
If S > 99 Then
Locate 1 , 1
Elseif S > 9 Then
Locate 1 , 2
Else
Locate 1 , 3
End If
Lcd S
Time_ok = 0
End If
Loop
End
Ovf1_int:
Timer1 = &HED40
Time_ok = 1
Return
==================================================
bascom的LCD S语句实际上是调用了一段内部的汇编子程序在LCD上显示S的值,这段汇编子程序由若干条汇编指令组成,只有完整的执行完整段代码,LCD才能正确的显示。但你在中断中又使用了CLS的语句,它也是要调用了一段内部的汇编子程序,将LCD清屏。
原因再于,你的LCD S 对应的汇编子程序还没执行完,就被CLS打断了,而且又开始另外的对LCD屏的设置,造成对LCD发出的控制指令和数据没有按规定的次序发出,所以LCD显示出错。
中断可以打断正在对LCD的操作,但在该中断服务程序中不能对LCD再次做任何操作。 非常感谢马老师的指教,问题原因我也弄明白了。但是马老师您给出的程序没有正面回答我关于数值型变量的格式化问题,还请马老师给予解释,多谢! "数值型变量的格式化"不明白是何意。我的程序已经将0-255固定显示在LCD的前3位,个位显示在第3位,十位在第2显示,百位显示在第1位。 马老师,我的意思是,使LCD上显示的变量的范围是001-255,而不是1-255,就是使变量保持3位(或N位)有效数字,即数值型变量格式化,在bascom里有关于字符串的格式化语句(format),但似乎没有数值的格式化的语句,那么要使数值格式化,在程序该怎样表述呢? $sim
Config Lcdpin = Pin , Rs = Portb.2 , E = Portb.3 , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7
Config Lcd = 16 * 1
Cursor Off
Config Timer1 = Timer , Prescale = 1024
On Ovf1 Ovf1_int
Enable Interrupts
Enable Ovf1
Timer1 = &HED40
Dim S As Byte
Dim Time_ok As Bit
Dim S1 As String * 3
S = 0
Time_ok = 1
Cls
Start Timer1
Do
If Time_ok = 1 Then
Incr S
If S = 255 Then S = 0
S1 = Str(s)
S1 = Format(s1 , "000")
Locate 1 , 1
Lcd S1
Time_ok = 0
End If
Loop
End
Ovf1_int:
Timer1 = &HED40
Time_ok = 1
Return 马老师,您的思路我明白了,但您给出的上述程序不能正常运行,显示乱码,不知何故? Config Lcdpin = Pin , Rs = Portb.2 , E = Portb.3 , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7
Config Lcd = 16 * 1
Cursor Off
Dim S As String * 3
S = Format(s , "000")
S = "8"
Cls
Do
Locate 1 , 1
Lcd S
Loop
End
马老师请看,这个程序居然也不能运行,显示乱码,仿真的时候发现跑到S = Format(s , "000")这里就停止了,似乎哪里有问题 我的程序全部在BASCOM中软件模拟通过的,你可以在BASCOM中直接用它的软件模拟功能进行模拟,LCD是图形化的,非常直观。
如果要下到芯片执行,请将“$sim”一句去掉,重新编译后下载。
建议你认真看看BASCOM环境中的帮助,里面讲的非常详细,而且都有例子的。
你已经有非常好的老师,就是BASCOM的HELP,要认真看。光是问人家要个程序,你永远不会进步的。 马老师,我又在bascom里模拟运行了一些,LCD显示3后就停止了。
请马老师在bacom里模拟一下下面的程序看能不能通过
Config Lcdpin = Pin , Rs = Portb.2 , E = Portb.3 , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7
Config Lcd = 16 * 1
Cursor Off
Dim S As String * 3
S = Format(s , "000")
S = "8"
Cls
Do
Locate 1 , 1
Lcd S
Loop
End
我模拟的结果是显示333
难道我bascom有问题? 马老师,问题找到了,是我的bascom的版本有问题,用1.11.8.3版的怎么都不行,就是它自己的例子(带format语句)也仿真不了,改用1.11.8.1版的就好了,害得我搞了好几天,头都晕了。
还是要感谢马老师,从您给出的程序我学到了一些编程的思想,其实我没有想找您要程序的想法,只是想要一点思想,希望马老师以后还要多多指教。
页:
[1]