对液晶显示器的编程方法Word文档格式.docx
《对液晶显示器的编程方法Word文档格式.docx》由会员分享,可在线阅读,更多相关《对液晶显示器的编程方法Word文档格式.docx(32页珍藏版)》请在冰豆网上搜索。

}
voidinit()
P0=0;
voidstart()
wr=1;
//启动AD转换
用单片机控制ADC0804进行模数转换,当拧动实验板上A/D旁边的电位器Re2时,在数码管的前三位以十进制方式动态显示出A/D转换后的数字量(8位A/D转换后数值在0~255变化)
intrins.h>
sbitdula=P2^6;
//申明U1锁存器的锁存端
sbitwela=P2^7;
//定义A/D的WR端口
//定义A/D的RD端口
ucharcodetable[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
voiddelayms(uintxms)
uinti,j;
for(i=xms;
i>
i--)
for(j=110;
j>
j--);
voiddisplay(ucharbai,ucharshi,ucharge)//显示子函数
dula=1;
P0=table[bai];
//送段选数据
dula=0;
wela=1;
P0=0x7e;
//送位选数据
wela=0;
delayms(5);
P0=table[shi];
P0=0x7d;
P0=table[ge];
P0=0x7b;
uchara,A1,A2,A3,adval;
P0=0x7f;
//置CSAD为0,选通后不必再管
adwr=1;
_nop_();
//该函数包含在头文件intrins.h中
adwr=0;
//启动A/D转换
//相当于一个机械周期的延时
for(a=10;
a>
a--)//因实验板A/D工作频率较低,
{所以启动转换后要多留
display(A1,A2,A3);
点时间用于转换
}该部分是在数码管上显示数字,是为了给A/D留时间
P1=0xff;
//读取P1口之前先给其写全1
adrd=1;
//选通ADCS
adrd=0;
//A/D读使能
adval=P1;
//A/D数据读取赋给P1口
A1=adval/100;
//分出百、十、个位
A2=adval%100/10;
A3=adval%10;
}
用单片机控制DAC0832输出电流,让二极管D12由灭均匀变到最亮,再由最亮均匀熄灭,并在最亮和最暗时使用蜂鸣器分别警报一声,完成整个周期控制在5s左右,循环变化
//定义D/A的WR端口
//定义D/A的CS端口
sbitbeep=P2^3;
ucharval,flag;
dacs=0;
dawr=0;
if(flag==0)
{
val+=5;
P0=val;
//通过P0口给DA数据口赋值
if(val==255)
{
flag=1;
beep=0;
delayms(100);
beep=1;
}
delayms(50);
}
else
val-=5;
//val=val-5
if(val==0)
flag=0;
『explanation:
(1)程序开始便使能DA的片选,接着使能写入端,这时DA就成了直通模式,只需变化数据输入端,DA的模拟输出端便紧跟着变化;
(2)程序中通过一个标志位flag判断单片机执行灯变亮程序还是变暗程序;
(3)关于延时计算,255共有51个5,每次延时50ms,共计50*51=2551ms,忽略蜂鸣器响占用的100ms,约为2.5s,另外,半周期同样约为2.5s,共计5s。
』
串行口方式1编程与实现
【方式1是10位数据的异步通信口,第一位为起始位,接着8位数据位(其中最后一位为校验位),最后一位为停止位;
其传输波特率可变且由定时器1的溢出率决定(对于51单片机)】
a)REN:
允许串行接收位,REN=1则允许串行口接收数据
b)TI:
发送中断标志位,在串行发送到停止位的开始时,由内部硬件置1,发送中断申请
c)RI:
接收中断标志位,在串行接收停止位的中间时,由内部硬件置1,发送中断申请
●串行口的工作方式:
方式1(当SM0=0,SM1=1时为方式1),其功能为10位异步收发(8位数据),波特率可变(由定时器1的溢出率控制)
操作串行口前,需对相关寄存器进行初始化,主要是设置产生波特率的定时器1、串行口控制和中断控制
1.确定T1的工作方式(编程TMOD寄存器)
2.计算T1的初值,装载TH1、TL1
3.启动T1(编程TCON中的TR1位)
4.确定串行口工作方式(编程SCON寄存器)
5.串行口工作方式在中断方式时,要进行中断设置(编程IE、IP寄存器)
查询法:
实现在串口调试发送指令控制发光管的变化(在STC-ISP中把MaxBuad设为9600,下面的程序一样)
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
SM0=0;
SM1=1;
REN=1;
if(RI==1)
{
RI=0;
P1=SBUF;
}
voidser()interrupt4
RI=0;
P1=SBUF;
中断法:
在串口调试助手发送指令,单片机收到后返回给上机位相同指令(当发送数据时如用十六进制发,则用十六进制收;
若发字符串指令,则不要选两个十六进制选项)
unsignedcharflag,a;
//设置定时器1为工作方式2
EA=1;
ES=1;
if(flag==1)//flag==1表明收到数据
ES=0;
flag=0;
SBUF=a;
while(!
TI);
TI=0;
ES=1;
a=SBUF;
flag=1;
利用单片机向上位机发送123
if(flag==1)
ES=0;
SBUF='
1'
;
while(!
TI=0;
2'
3'
ES=1;
在上位机上用串口调试助手发送一个字符X,单片机收到字符后返回给上位机“IgetX”,串口波特率设为9600bps,晶振为11.0592
#defineuintunsignedint
unsignedcharflag,a,i;
ucharcodetable[]="
Iget"
//定义一个字符类型的编码数组
voidinit()┝→含有6个字符,其中两个为空格
//设定T1定时器工作方式2
//T1定时器装初值
//启动T1定时器
//设定串口工作方式1
//允许串口接收
//开总中断
//开串口中断
if(flag==1)//flag为1时表明执行过中断,即收到
{了数据
//发送数据前关闭串口中断,等发送完后再打开,否则会不停地执行中断程序
for(i=0;
i<
6;
i++)
SBUF=table[i];
//TI为发送中断标志位,置0为取
}消中断申请
//表示发送完后便置0,跳出if语句
}//整个if语句为发送阶段
voidser()interrupt4//串口中断服务程序
//当收到或发送了数据时RI会被硬件置1,因此
由中断程序置0
『
(1)SBUF寄存器:
存放收到的数据(单片机收到的数据会放在SBUF口,取数据时就把SBUF赋出去),执行写指令时,访问串行发送寄存器;
执行读指令时,访问串行接收寄存器;
(2)定时器工作方式2的过程:
先在THX、TLX中装入算好的初值,启动定时器,然后TLX寄存器便在时钟的作用下开始加1计数,当TLX计满溢出后,CPU会自动将THX中的数装入TLX中,继续计数;
(3)使用T1的方式2:
当T1计满溢出后,单片机会自动装初值,并无需进入中断服务程序(4)程序中的SBUF:
当接收数据时,写“a=SBUF;
”语句,单片机便会自动将串口接收寄存器中的数据取走给a;
当发送数据时,写“SBUF=a;
”程序执行完该语句便自动开始将串口发送寄存器中的数据一位位从串口发送出去』
关于THX、TLX的赋值(根据波特率反推出定时器的溢出率,进而计算出定时器的初值)
e.g.已知串口通信在串口方式1下,波特率为9600bps,系统晶振频率为11.0592MHz,求TL1和TH1中装入的数值是多少?
解:
设所求的数为X,则定时器每计256-X个数溢出一次,每计一个数的时间为一个机器周期,一个机器周期为12个时钟周期,所以记一个数的时间为12/11.0592MHz(s),那么定时器溢出一次的时间为(256-X)*12/11.0592(s),T1溢出率为其倒数,方式1的波特率=(2^SMOD/32)·
(T1溢出率),这里SMOD=0,将数代入的X=253,转为十六进制为0xfd,即TL1、TH1赋的值为0xfd。
由上位机发送1给单片机时,蜂鸣器以400ms频率发声,发2时以200ms频率发声,发3时以100ms频率发声,发4时关闲蜂鸣器
unsignedcharflag,a,num,benum;
TMOD=0x21;
TH0=(65536-50000)/255;
TL0=(65536-50000)%255;
ET0=1;
if(flag==1)
EA=0;
TR0=1;
if(a==1)
benum=4;
if(a==2)
benum=2;
if(a==3)
benum=1;
if(a==4)
TR0=0;
EA=1;
voidtime0()interrupt1
num++;
if(num>
=benum)
num=0;
beep=~beep;
以2400bps从计算机发送任一字节数据,当单片机收到该数据后,在此数据前加上一序号然后连同此数据一起发送至计算机,当序号超过255时归零
unsignedcharflag,a,num,num1;
TH1=0xf4;
TL1=0xf4;
num1++;
if(num1==255)
num1=0;
SBUF=num1;
用AD以1HZ的频率采集模拟信号,然后转换成数字量,再将其以1200bps发送到计算机,在计算机上显示
#include<
#defineuintunsignedint//宏定义
#defineucharunsignedchar//宏定义
//申明U1锁存器的锁存端
//申明U2锁存器的锁存端
//定义AD的WR端口
//定义AD的RD端口
ucharadval;
voiddelay(uintz)//延时子函数
x>
x--)
//置CSAD为0,选通ADCS以后不必再管ADCS
TH1=0xe8;
//波特率设置为1200
TL1=0xe8;
//启动AD转换
delay(500);
//读取P1口之前先给其写全1
//AD读使能
//AD数据读取赋给P1口
SBUF=adval;
while(!
TI=0;
常用1602液晶操作
(一)接口信号说明
RS数据/命令选择端(H/L);
R/W读写选择端(H/L);
E使能信号;
(二)基本操作时序(H代表高电平,L代表低电平)
输入
输出
读状态
RS=L,R/W=H,E=H
D0~D7=状态字
读指令
RS=H,R/W=H,E=H
无
写指令
RS=LR/W=LD0~D7=指令码,E=高脉冲
D0~D7=数据
写数据
RS=HR/W=L
D0~D7=数据,E=高脉冲
(三)状态字说明
STA7
D7
STA6
D6
STA5
D5
STA4
D4
STA3
D3
STA2
D2
STA1
D1
STA0
D0
STA0~STA6
当前地址指针的数值
读/写操作使能
1—禁止0—允许
在每次对控制器进行读/写操作之前,都必须进行读/写检测,确保STA7=0
(四)数据指针设置
控制器内部设有一个数据地址指针,可通过它们访问内部的全部80B的RAM,如表:
指令码
功能
80H+地址码(0~27H,40~67H)
设置数据地址指针
(五)其他设置
01H
显示清屏:
1.数据指针清0
2.所有显示清0
02H
显示回车:
数据指针清0
(六)初始化设置
1)显示模式设置:
00111000——设置16*2显示,5*7点阵,8位数据接口
2)显示开/关及光标设置
(a)00001DCB(当D、C、B取0时取否)
D=1开显示;
C=1显示光标;
B=1光标闪烁
(b)000001NS
N=1当读或写一个字符后地址指针加1,且光标加1
N=0当读或写一个字符后地址指针减1,且光标减1
S=1当写一个字符时,整屏显示左移(N=1)或右移(N=0),以得到光标不移动而屏幕移动的效果
S=0当写一个字符时,整屏显示不移动
(c)00010000——光标左移
(d)00010100——光标右移
(e)00011000——整屏左移,同时光标跟随移动
(f)00011100——整屏右移,同时光标跟随移动
操作时序:
1.通过RS确定是写数据还是写命令(写命令包括使液晶的光标显示/不显示、光标闪烁/不闪烁、需/不需要移屏、在液晶的什么位置显示……)
2.读/写控制端设置为写模式,即低电平
3.将数据或命令送达数据线上
4.给E一个高脉冲将数据送入液晶控制器,完成写操作
晶振为24,波特率为9600,液晶和数码管不能共用(因此要把数码管的段选、位选关掉)
让1602液晶的光标闪烁
sbitlcden=P3^4;
//液晶使能端
sbitlcdrs=P3^5;
//液晶数据命令选择端
ucharnum;
voidwrite_com(ucharcom)//定义‘写命令’子函数,(该函数用于写指令)┝→com为参数名
{
lcdrs=0;
P0=com;
delay(5);
lcden=1;
lcden=0;
voidwrite_data(uchardate)//该函数用于写数据
lcdrs=1;
P0=date;
voidinit()//初始化函数(init为初始化的英文)