我用过一有空就去检查按键是否有输入 效果还可以
'------------------------------------------------------------------------------
'名 称 : ex0031-1.bas
'目 的 : 试验读取pcf8563时间日期,在lcd显示
'按 键 说 明 : 按键sw13为 调整/正常 功能按钮,按键sw14,sw15,sw16,sw11为调整按钮←↓→↑
'
'目 标 芯 片 : mega16
'试 验 环 境 : mega16_32%20kit.pdf(
www.basicavr.com m16试验板)
'编 译 环 境 : bascom-avr 1.11.8.1 demo
'跳 线 设 置 : j42/j43 =12 j46=23,j16按晶体情况连接;没提到跳线均为空
'熔 丝 说 明 : 外部晶振12m, jtag禁止
'------------------------------------------------------------------------------
$regfile = "m16def.dat"
'$lib "mcsbyte.lbx" ' use the byte lib since we do not need longs
$crystal = 12000000
$baud = 19200
'declare used subs
declare sub settime(byval s1 as byte , byval m1 as byte , byval h1 as byte , byval d1 as byte , byval month1 as byte)
declare sub gettime()
declare sub time_start()
declare sub time_stop()
declare sub time_set()
'declare variables
dim tm(7) as byte at &h60 '定义存放时间日期的数组
dim show_str(7) as string * 4 '定义变量 tm()对应内容 调整时间时显示用
dim i as byte , temp as byte
dim j as byte
dim clock_state as bit '时钟的工作状态标志,0:工作;1 调整
'these are pointers to tm() for simple handling. 下面定义的几个变量对应tm(1-7)
dim s as byte at &h60 overlay
dim m as byte at &h61 overlay
dim h as byte at &h62 overlay
dim d as byte at &h63 overlay
dim w as byte at &h64 overlay
dim month as byte at &h65 overlay
dim year as byte at &h66 overlay
dim cent as integer
dim b as byte '键值
dim set_up as byte '调整时增加量 +时为2,-时为0,不操作时为1
dim set_addr as byte '要调整的寄存器地址 时间、日期的地址为02h到08h
dim byte_old_key as byte '记录旧键值
'configure the used port pin for i2c
config i2cdelay = 5 ' default slow mode
config sda = portd.2
config scl = portd.3
config lcdpin = pin , db4 = portc.4 , db5 = portc.5 , db6 = portc.6 , db7 = portc.7 , e = portb.3 , rs = portb.4
config lcd = 16 * 2
config kbd = portc , delay = 50 '键盘端口和消抖延时
clock_state = 0
set_up = 1
set_addr = 2
show_str(1) = "sec"
show_str(2) = "min"
show_str(3) = "hou"
show_str(4) = "day"
show_str(5) = "wek"
show_str(6) = "mon"
show_str(7) = "yer"
' not needed since the pins are in the right state
'i2cinit
'call settime(0 , 0 , 0 , 1 , 1 ) '设置时间 1-1,0

0,
cls
do
call gettime
'since the values are stored in bcd format we can use hex() to display them
h = h and &h3f
m = m and &h7f
s = s and &h7f
cent = month and &h80
if cent = 0 then
cent = 1900
else
cent = 2000
end if
month = month and &h1f
cent = cent + makedec(year)
d = d and &h3f
w = w and &h7
locate 1 , 1 '指定lcd显示位置
lcd hex(h ) ; ":" ; hex(m) ; ":" ; hex(s) 'lcd显示
locate 2 , 1
lcd cent ; "-" ; hex(month) ; "-" ; hex(d) ; " w " ; hex(w)
b = getkbd() '读取键值
if b = 0 then '设置 工作/调整状态
clock_state = not clock_state
locate 1 , 10 '指定lcd显示位置
if clock_state = 1 then
lcd "set " 'lcd显示
else
lcd " "
end if
end if
locate 1 , 10 '指定lcd显示位置
if clock_state = 1 then
lcd "set " ; show_str(set_addr -1) 'lcd显示
select case b
case 4 : set_addr = set_addr - 1
case 8 : set_up = 0
case 9 : set_up = 2
case 12 : set_addr = set_addr + 1
end select
if set_addr > 8 then
set_addr = 8
end if
if set_addr < 2 then
set_addr = 2
end if
if set_up <> 1 then
call time_set()
set_up = 1
end if
end if
waitms 100
loop
end
sub gettime()
'there are 2 ways to get the time. with low level i2c calls or with a high level call
'first the high level call
tm(1) = 2 ' point to second register
i2creceive &ha3 , tm(1) , 1 , 7 ' write the second address and get 7 bytes back
'i2creceive will first write 1 byte from tm(1) which is 2, and then will read 5 bytes and store it onto tm(1)-tm(5)
'and optional with low level calls
' for i = 1 to 7
' temp = i - 1
' i2cstart
' i2cwbyte &ha2 'write addres of pcf8583
' i2cwbyte temp 'select register
' i2cstart 'repeated start
' i2cwbyte &ha3 'write address for reading info
' i2crbyte tm(i) , nack 'read data
' next
'i2cstop
end sub
sub settime(s1 as byte , m1 as byte , h1 as byte , d1 as byte , month1 as byte)
'values are stored as bcd values so convert the values first
tm(1) = makebcd(s1) 'seconds
tm(2) = makebcd(m1) 'minutes
tm(3) = makebcd(h1) 'hours
tm(4) = makebcd(d1) 'days
tm(5) = 5 'week
tm(6) = makebcd(month1) or &h80 'cent=20
tm(7) = makebcd(06) 'year=06 默认06年
call time_stop()
i2cstart 'repeated start
i2cwbyte &ha2 'write mode
i2cwbyte 2 'select seconds register
for i = 1 to 7
i2cwbyte tm(i)
next
i2cstop
call time_start()
end sub
sub time_stop()
i2cstart 'generate start
i2cwbyte &ha2 'write address
i2cwbyte 0 'select control register
i2cwbyte 32 'clock stop
i2cstop
end sub
sub time_start()
i2cstart 'generate start
i2cwbyte &ha2 'write address
i2cwbyte 0 'select control register
i2cwbyte 0 'clock run
i2cstop
end sub
sub time_set()
i2cstart
i2cwbyte &ha2 'write addres of pcf8583
i2cwbyte set_addr 'select register
i2cstart 'repeated start
i2cwbyte &ha3 'write address for reading info
i2crbyte temp , nack 'read data
i2cstop
' print "t"
' print temp
' if set_addr <> 6 then '处理星期部分
temp = makedec(temp)
' end if
' print temp
temp = temp + set_up
temp = temp - 1
' print temp
' if set_addr <> 6 then
temp = makebcd(temp)
' end if
print temp
call time_stop()
i2cstart 'repeated start
i2cwbyte &ha2 'write mode
i2cwbyte set_addr 'select seconds register
i2cwbyte temp
i2cstop
call time_start()
end sub