avr单片机的应用.docx
《avr单片机的应用.docx》由会员分享,可在线阅读,更多相关《avr单片机的应用.docx(41页珍藏版)》请在冰豆网上搜索。
avr单片机的应用
LCD显示
源程序:
SLAVR744.ASM
LCD显示器1602AT(S)R简介:
LED显示器模块1602AT(S)R为2X16字符。
含有5*10或5*7点LCD共12*16=192种CG显示字形及双组8个自由利用软件设定(CGRAM)的5*8图点字形,因此除内部固定192种字形外,再加上此16个可自由设定图字型等共计208种字图形如字符代码表所示。
因5*8个点输入设定故5个点仅占用D4-D0的5位,而D7-D5则可为任意值,第八行值为游标地址,因此共八行占八个地址组成一个字形及标示游标地址,总共八个设定字图形,因此占有8*8=26个地址,CG地址设定值为D5-D0。
LCD引脚功能说明
1.GND:
电源地,0V;
2.VCC电源+5V;
3.VLC:
LCD驱动电压0V-5V对比度调节电压;
4.RS寄存器选择信号;
RS=0:
指令寄存器IR写入(WRITE);
(1)忙(BUSYFLAG)读取(READ);
(2)地址计数器(ADDRESSCOUNTER)AC读取(READ);
RS=1:
数据寄存器(DATAREGISTER)读取及写人(READ/WRITE);
5.R/W读/写控制信号(READ/WRITE):
R/W=1读取(READ)、R/W=0写入(WRITE);
6.E(ENABLE)片使能信号,作写数据控制,下降沿触发;
7~14脚为DB0~DB7八位数据总线,三态双向,若作为4位传送时应令:
DL=0,以DB4-DB7作传送将8位数据分二次传送;
15.一般不用(空),如有背光LED,则接VCC;
16.一般不用(空),如有背光LED,则接GND;
LCDTC1602CGRAM字形结构设定输入表
字形码(DDRAM数据
CGRAM地址
字形图样(CGRAM)数据
76543210
高位低位
543210
上位下位
76543210
上位(5*7字形)下位
0000*000
000
001
010
011
000100
101
110
111
***11110
10001
10001
11110
10100
10010
10001
***00000
0000*001
000
001
010
011
001100
101
110
111
***10001
01010
11111
00100
11111
00100
00100
***00000
0000*111
000
001
111
101
110
111
***
LCD指令表
指令
指令码
说明
执行周期fosc=
250Khz
RS
R/W
DB7
DB6
DB5
DB4
DB3
DB2
DB1
DB0
清屏
0
0
0
0
0
0
0
0
0
1
请除屏幕,置AC为0,
光标回位
1.64ms
光标返回
0
0
0
0
0
0
0
0
1
*
DDRAM地址为0,显示回原位,DDRAM内容不变
1.64ms
设置输入
方法
0
0
0
0
0
0
0
1
I/D
S
设置光标移动方向并指定显示是否移动
40μs
显示开关
0
0
0
0
0
0
1
D
C
B
设置显示开或关(D),光标开关(C),光标所在字符闪烁(B)
40μs
移位
0
0
0
0
0
1
S/C
R/L
*
*
移动光标及整体显示,同时不改变DDRAM内容
40μs
功能设置
0
0
0
0
1
DL
N
F
*
*
设置接口数据(DL)、显示行数(L)、字符字体(F)
40μs
CGRAM
地址设置
0
0
0
1
ACG
设置CGRAM地址,设置后发送接收数据
40μs
DDRAM
地址设置
0
0
1
ADD
设置DDRAM地址,设置后发送接收数据
40μs
忙标志/读
地址计数器
0
1
BF
AC
读忙标志(BF)标志正在执行内部操作并读地址计数器内容
40μs
CGRAM/DD
RAM数据写
1
0
写数据
从CGRAM或DDRAM写数据
40μs
CGRAM/DD
RAM数据读
1
1
读数据
从CGRAM或DDRAM读数据
40μs
I/D=1:
增量方式;I/D=0:
减量方式
S=1:
移位
S/C=1:
显示移位;S/C=0光标移位
R/L=1:
右移;R/L=0左移
DL=1:
8位;DL=0:
4位
N=1:
2行;N=0:
1行
F=1:
5*10字体;F=0:
5*7字体
BF=1:
执行内部操作;BF=0:
可接收指令
DDRAM:
显示数据RAM
CGRAM:
字符发生器RAM
ACG:
CGRAM地址
ADD:
DDRAM地址及光标地址
AC:
地址计数器用于DDRAM和CGRAM
执行周期随主频改变而改变例如当fcp或fosc=270khz时:
40μsx
250/270=37μs
源程序:
SLAVR744.ASM
.include"8515def.inc"
.deftemp=r16
.deftemp1=r17
.deftemp2=r18
.defcnt=r20
.defcnt1=r21
.org$0000
rjmpreset
.org$0030
reset:
lditemp,low(ramend);设置堆栈指针。
outspl,temp
lditemp,high(ramend)
outsph,temp
lditemp,$ff;设置D口输出,B口作输入。
outddrd,temp
outportd,temp
clrtemp
outddrb,temp
outportb,temp
rcallsyset;调用系统设置。
lp8:
clrcnt1;循环程序。
lp81:
clrcnt
lditemp1,$80;设置第一行显示寄存器起址。
(第二行为$a8)
rcallcontd
lp82:
cpcnt1,cnt
brnelp83
lditemp1,$38;字形8的代码为$38。
lp84:
rcallwritd
inccnt
cpicnt,$10
brnelp82
lditemp,$55;设置延时常数。
rcalldelay
inccnt1
cpicnt1,$10
brnelp81
rjmplp8
lp83:
lditemp1,$20
rjmplp84
CONTD:
LDITEMP,0B00110000;写控制字入LCD中
OUTPORTD,TEMP
RCALLDELT3
CBIPORTD,$05;使E=0,LCD片选有效
RCALLDELT3
SBIPORTD,$05
BUSYY:
WDR
SBICPINB,$07;读取DB7=PINB7是否为0,为0则非忙跳过一行
RJMPBUSYY;DB7=1为忙,跳回BUSYY再等待DB7=0以写入
LDITEMP,0b00100000;写入数据写入控制字
OUTPORTD,TEMP
RCALLDELT3;延时以免AVR速度太快而使LCD无法工作
LDITEMP,$ff;设定B口为输出
OUTDDRB,TEMP
OUTPORTB,TEMP1;要写入LCD的数据TEMP1输出到PORTB
WDR
CBIPORTD,$05
RCALLDELT3
LDITEMP,0B00111000
OUTPORTD,TEMP
CLRTEMP
OUTDDRB,TEMP
OUTPORTB,TEMP
RET
WRITD:
LDITEMP,0B00110000;写数据入LCD中
OUTPORTD,TEMP
RCALLDELT3;延时以免AVR速度太快而使LCD无法工作
CBIPORTD,$05;使E=0,LCD片选有效
RCALLDELT3
SBIPORTD,$05
BUZY1:
WDR
SBICPINB,$07;读取DB7=PINB7是否为0,为0则非忙跳过一行
RJMPBUZY1;DB7=1为忙,跳回BUSY1再等待DB7=0以写入
LDITEMP,0B00101000;写控制字入LCD中
OUTPORTD,TEMP
OUTPORTB,TEMP1;要写入LCD的数据TEMP1输出到PORTB
LDITEMP,$ff;设定B口为输入
OUTDDRB,TEMP
CBIPORTD,$05;使E=0,LCD片选有效
RCALLDELT3;延时以免AVR速度太快而使LCD无法工作
LDITEMP,0B00111000;写控制字入LCD中
OUTPORTD,TEMP
RCALLDELT3
CLRTEMP;PORTB为输入
OUTDDRB,TEMP
OUTPORTB,TEMP;PORTB为三态输入
RET
syset:
lditemp1,$01;清屏设定
rcallcontd
lditemp,$50;设置时间常数
rcalldelay
lditemp1,$38;2行5*7显示设定
rcallcontd
lditemp1,$06;自动增量,显示不移位
rcallcontd
lditemp1,$0c;字形开关ON,光标开关OFF
rcallcontd
ret
DELT3:
lditemp2,$24
DT111:
wdr
dectemp2
brnedt111
ret
delay:
;延时子程序略
7.4.5LED电脑时钟
源程序:
SLAVR745.ASM
硬件连接见:
3.3AVR单片机开发下载实验器;
本程序若直接按shife+exec即从00:
00:
00开始计时。
本程序下载后(或上电后),LED显示00:
00:
00等待设置,请您从键盘上输入时、分、秒,要求输入位由小数点作光标提示,输入正确时间后,按执行键(SHIFT+EXEC)执行,电脑钟开始计时。
1.请你如何修改程序,可当秒表用?
2.又如何修改程序到点发出报时声?
;本程序在SL-AVR编程开发实验器上通过,由六位LED显示
;本程序采用T0,1/1024分频,设定一次中断为25MS,40次中断为1秒。
.include"8515def.inc"
.defTEMP=r16
.defTEMP1=r17
.deftemp2=r18
.deftemp3=r19
.defCNT=r20
.defSCNN=r21
.defKSNI=r22
.defSCNDP=r23
.defKEYN=r24
.defcnt1=r25
.defhour=r24
.defminute=r22
.defsecond=r21
.equlabel=$0f00;字形表首址
.org$0000
rjmpreset
.org$007
intt0:
lditemp,104;因25ms内差40us故补上40/(1/8)即320个CK。
bu:
dectemp;因中断需4CK这样:
4+104*(1+2)+1+1+1+1=320。
brnebu
nop
inccnt1;cnt1计数40次为1秒钟。
lditemp,256-195;计数(256-195)次才产生1次中断。
outtcnt0,temp;CK/1024分频,这样一次中断需25ms。
rjmprecog
.org$030
reset:
lditemp,low(ramend);设置堆栈指针。
outspl,temp
lditemp,high(ramend)
outsph,temp
clrr2;清工作寄存器。
clrr3
clrr4
clrr5
clrr6
clrr7
clrzh
clrxh
clryh
clrkeyn
clrsecond
clrminute
clrhour
clrcnt
clryh
lditemp,$80
movr8,temp;R8=$80
ldiyl,$60;设置显示內存地址指针Y为$0060.
rcalldisram;调用DISRAM。
ldtemp,y
lditemp1,$80
addtemp,temp1
sty,temp
scanad:
lditemp,$07
ldiyl,$60
scann:
rcallscan1;调用键扫显示子程序SCAN1。
brtsscann
scank:
rcallscan1
brtcscank
rcallscan1
scans:
nop
cpikeyn,$10;KEYN=$10转EXEC。
brccexec
rcallwraddram;调用WRADDRAM。
dectemp;TEMP减1。
cpitemp,$01
brnescann;TEMP=1则转SCANN
rjmpscanad
exec:
movtemp1,r7;把r7,r6的两个十进制换成一个十六进制入hour中
movtemp,r6
rcalldechex
movhour,temp
movtemp1,r5;把r5,r4的两个十进制换成一个十六进制入minute中
movtemp,r4
rcalldechex
movminute,temp
movtemp1,r3;把r3,r2的两个十进制换成一个十六进制入second中
movtemp,r2
rcalldechex
movsecond,temp
lditemp,$05;T0设置为CK/1024分频。
outtccr0,temp
lditemp,256-195
outtcnt0,temp;装载T0时间常数。
lditemp,$ff;设置b口,d口为输出
outddrb,temp
outddrd,temp
sei;开中断总开关
lditemp,$02
outtimsk,temp;允许t0中断。
display:
rcalldisram;调用disram
clryh;设置显示内存地址指针Y为$0060
ldiyl,$60
ldiscndp,$df;设置扫描显示码SCNDP起址0B11011111.
agdis:
ldr1,y+
cpiyl,$62
brnenpoint
addr1,r8
npoint:
cpiyl,$64
brnenext
addr1,r8
next:
outportb,r1;把R1送B口显示
outportd,scndp;扫亮某个数码管
sec;C=1
rorscndp;右移SCNDP
rcalldelay;延时
cpiyl,$66
brneagdis;未扫亮最后一位继续
rjmpdisplay
recog:
cpicnt1,40;40次中断为40*25ms=1秒
brneinthome;40次中断未到转inthome
clrcnt1;40次中断到则清cnt1
incsecond;秒寄存器加1
cpisecond,60
brnechange;秒寄存器未满转change
clrsecond;否则清秒寄存器
incminute;分寄存器加1
cpiminute,60
brnechange;分寄存器未满转change
clrminute;否则清分寄存器
inchour;时寄存器加1
cpihour,24
brnechange;时寄存器未满转change
clrhour;否则清时寄存器
reti;中断返回
change:
movtemp,second;把second中的十六进制转换成二个十进制数存入r3,r2中
rcallhexdec
movr3,temp1
movr2,temp
movtemp,minute;把minute中的十六进制转换成二个十进制数存入r5,r4中
rcallhexdec
movr5,temp1
movr4,temp
movtemp,hour;把hour中的十六进制转换成二个十进制数存入r7,r6中
rcallhexdec
movr7,temp1
movr6,temp
inthome:
reti;中断返回
hexdec:
clrtemp1;把temp中的十六进制转成二个十进制入temp1,temp中的子程序
hexdec1:
subitemp,10
brcsnegs
inctemp1
rjmphexdec1
negs:
subitemp,$f6
ret;子程序返回
dechex:
pushtemp;把temp1,temp的两个十进制数转换成一个十六进制入temp中
lditemp2,$0a
clrtemp
dechex1:
cpitemp1,$00
breqdh
dectemp1
addtemp,temp2
rjmpdechex1
dh:
movtemp1,temp
poptemp
addtemp,temp1
ret;子程序返回
disram:
pushyl;压栈保护
pushzl
pushxl
ldizh,high(label*2);Z指针指向字形表首址label*2
ldizl,low(label*2)
clrxh
ldixl,$60
ldiyl,$07
ramag:
ldtemp2,y;y为间址的内容送temp2
decyl
movzl,temp2
lpm
stx+,r0;把r0的内容送到$0060-$0065中
cpixl,$66
brneramag
popxl
popzl
popyl;退栈
ret;子程序返回
wraddram:
pushtemp;读键存入显示内存及寄存器中。
clrzh
movzl,temp
stz,keyn
ldizh,high(label*2)
movzl,keyn
lpm
sty+,r0
cpiyl,$66
brnepointc
ldiyl,$60
pointc:
ldtemp2,y
lditemp3,$80
addtemp2,temp3
sty,temp2
poptemp
ret;子程序返回
delay:
pushtemp;延时子程序
lp1:
lditemp2,$10
lp2:
dectemp
brnelp2
dectemp2
brnelp2
poptemp
ret;子程序返回
SCAN1:
pushxh;键盘扫描显示子程序(注释从略,见7.3.5)。
PUSHXL
PUSHTEMP1
PUSHTEMP
LDIXL,$60
SET
LDISCNN,$00
LDISCNDP,0B11011111
LDICNT,$06
LDIKSNI,0B11110111
COL1:
LDITEMP,$FF
OUTDDRb,TEMP
OUTDDRC,TEMP
OUTPORTC,TEMP
OUTDDRd,TEMP
OUTPORTd,SCNDP
LDR1,X+
OUTPORTb,R1
RCALLDELAY
MOVTEMP,CNT
SUBITEMP,$03
BRCSNOSK
LDITEMP1,$04
LDITEMP,0B00001111
OUTDDRc,TEMP
OUTPORTc,KSNI
RCALLDELYT
INTEMP,PINc
ANDITEMP,0B11110000
SWAPTEMP
KROW:
SEC
RORTEMP
BRCSNOKEY
CLT
MOVKEYN,SCNN
SBISPINd,$07
ADIWKEYN,$10
NOKEY:
INCSCNN
DECTEMP1
BRNEKROW
SEC
RORKSNI
NOSK:
SEC
RORSCNDP
DECCNT
BRNECOL1
LDITEMP,$FF
OUTDDRC,TEMP
OUTPORTC,TEMP
POPTEMP
POPTEMP1
POPXL
popxh
RET
delyt:
lditemp3,$20
dt31:
dectemp3
brnedt31
ret
.cseg
.org$0f00;字形表
.dw0x063f,0x4f5b,0x6d66,0x077d
.dw0x6f7f,0x7c77,0x5e39,0x7179
7.4.6测频率
;测频率,信号从AT90S8515的ICP引脚输入,最大值为为999999