作者 张小波
? PB口: 7F02H ? PC口: 7F03H
? 定时器低8位寄存器: 7F04H ? 定时器高8位寄存器: 7F05H ②程序设计。
图3-13接口电路中,将单片机片内RAM50H~5FH单元的内容送8155片内的50H~5FH单元,设定8155的工作方式为: A口基本输入方式,B口基本输出方式,C口输入方式,定时器作方波发生器,对输入脉冲50分频。 程序清单如下:
D8155: MOV R0,50H ;将源数据单元首地址送寄存器R0中
MOV DPTR,#7E50H ;数据指针指向8155内部RAM单元
LP: MOV A,@R0 ;数据送累加器A
MOVX @DPTR,A ;数据从累加器A送8155内部RAM单元 INC DPTR ;指向下一个8155内部RAM单元 INC R0 ;指向下一个CPU内部RAM单元 CJNE R0,#60H,LP ;数据未传送完继续 MOV DPTR,#7F04H ;指向定时器低8位 MOV A,#32H ;分频系数32H(即50) MOVX @DPTR,A ;低8位初值装入 INC DPTR ;指向定时器高8位
MOV A,#40H ;设定时器方式为连续方波(40H=01000000B) MOVX @DPTR,A ;定时器/计数器方式及高6位初值装入 MOV DPTR,#7F00H ;数据指针指向控制字寄存器
MOV A,#0C2H ;设定A,B口方式,并启动定时器(0C2H=11000010B) MOVX @DPTR,A
RET ;程序返回
程序中,定时器2个字节的内容二进制形是: 0100000000110010B,最高2位01的作用是设定定时器输出方式: 连续方波;其余14位是计数初值0032H=50(十进制)。向控制寄存器写入的命令字的内容是11000010B,对应的十六进制形式是0C2H,其意义是: 最高2位11的作用是启动计数器,最低位D0=0设PA为输入,D1=1设PB为输出。D3D2=00设PA、PB为基本I/O,PC为输入。 ☆ 完整程序代码
1、LCD1602.c源程序
//---------------------LCD1602.c-------------------------- //液晶控制与显示驱动程序
//-------------------------------------------------------- #include
#define uchar unsigned char #define uint unsigned int
sbit RS=P2^0; // LCD寄存器选择 sbit RW=P2^1; // LCD读写控制 sbit EN=P2^2; // LCD启动 //*--------延时子程序--------*//
作者 张小波
void DelayMS(uint K) {
uchar i; while(K--) {
for(i=0;i<120;i++); } }
//----------读取LCD的状态-------*/ uchar Read_LCD_State() {
uchar state; RS=0; RW=1; EN=1;
DelayMS(2); state=P0; EN=0;
DelayMS(2); return state; }
//-------------忙检查--------------*/ void LCD_Busy_Wait() {
while((Read_LCD_State()&0x80)==0x80); DelayMS(5); }
//-----------写LCD命令-----------------*/ void Write_LCD_Command(uchar cmd) {
LCD_Busy_Wait(); RS=0; RW=0; EN=0; P0=cmd; EN=1;
DelayMS(2); EN=0; }
//-----------向LCD写入数据-----------------*/ void Write_LCD_Data(uchar dat) {
LCD_Busy_Wait(); RS=1;
作者 张小波
RW=0; EN=0; P0=dat; EN=1;
DelayMS(2); EN=0; }
//-----------LCD初始化-----------------*/ void Initialize_LCD1602() //液晶初始化函数 {
Write_LCD_Command(0x38);DelayMS(2); //功能设臵,数据长度为8位,双行显示,5×7点阵字体 Write_LCD_Command(0x01);DelayMS(2); //清屏
Write_LCD_Command(0x06);DelayMS(2); //字符进入模式:屏幕不动,字符后移 Write_LCD_Command(0x0c);DelayMS(2); // 显示开,关光标 }
//-----------设臵液晶显示位臵-----------------*/ void Set_LCD_Position(uchar pos) {
Write_LCD_Command(pos|0x80); //设臵7位的DDRAM地址值 }
//-----------在LCD上显示字符串-----------------*/ void LCD_Display(uchar p,uchar *str) {
uchar i;
Set_LCD_Position(p); for(i=0;i<16;i++) {
Write_LCD_Data(str[i]); DelayMS(2); } }
2、main.c源程序
//------------------------------------------------------------------------ // 名称: 用DS1302和1602液晶显示的实时时钟
//-------------------------------------------------------------------------
//说明:本程序运行时会以PC时间为默认时间开始运行,运行过程中可以通过K1按键选择调节对象,用K2、K3
// 按键进行加减,用K4按键保存。
//--------------------------------------------------------------------------------------- #include
#define uchar unsigned char #define uint unsigned int
作者 张小波
void Initialize_LCD1602(); //液晶初始化函数 void LCD_Display(uchar p,uchar *str); sbit SDA=P1^0; //DS1302数据线 sbit CLK=P1^1; //DS1302时钟线 sbit RST=P1^2; // DS1302 复位线 sbit k1=P3^3; // 选择按键 sbit k2=P3^4; // 加 sbit k3=P3^5; // 减 sbit k4=P3^6; // 确定 uchar tcount=0;
uchar MonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31}; // 一年中每个月的天数,二月的天数由年份决定
uchar *Week[]={\周日,周一到周六 // LCD显示缓冲
uchar LCD_DSY_BUFFER1[]={%uchar LCD_DSY_BUFFER2[]={%uchar DateTime[7];//所读取的日期时间
char Adjust_Index=-1; //当前调节的时间对象:秒,分,时,日,月,年(0,1,2,3,4,6) uchar Change_Flag[]=\分,时,日,月,年)不调节秒和周 //函数声明
void Write_Byte_TO_DS1302(uchar X); // 向DS1302写入一个字节 uchar Read_Byte_FROM_DS1302(); //从DS1302中读取一个字节
uchar Read_Data_FROM_DS1302(uchar addr); //从DS1302指定位臵读取数据 , 读数据
void Write_Data_TO_DS1302(uchar addr,uchar dat); // 向DS1302指定位臵写入数据, 写数据 void SET_DS1302(); // 设臵时间 void GetTime(); // 读取当前时间 void Initialization(); //初始化函数
//------------------------------------------ // 主程序
//---------------------------------------- void main() {
Initialization(); while(1) {
if(Adjust_Index==-1) GetTime(); } }
//*-----------------初始化函数--------------*// void Initialization() {
Initialize_LCD1602(); //调用液晶初始化函数
作者 张小波
IE=0x83; //允许中断 外部0中断和T0中断 IP=0x01; // 设臵中断优先级
IT0=0x01; // 设臵外部中断的脉冲触发方式
TMOD=0x01; // 设臵定时器的工作方式,为方式1 TH0=-50000/256; // 写入初值 TL0=-50000%6; // 写入初值 TR0=1; // 启动定时器 }
//*--------写字节函数,向DS1302写入一个字节--------*//
void Write_Byte_TO_DS1302(uchar X) // 向DS1302写入一个字节 {
uchar i;
for(i=0;i<8;i++) {
SDA=X&1; CLK=1; CLK=0; X>>=1; } }
//*--------读字节函数,从DS1302读取一个字节--------*//
uchar Read_Byte_FROM_DS1302() //从DS1302中读取一个字节 {
uchar i,byte,t; for(i=0;i<8;i++) {
byte>>=1; t=SDA;
byte|=t<<7; CLK=1; CLK=0; }
//BCD码转换
return byte/16*10+byte; }
//------------------------------------------------------------- //从DS1302指定位臵读取数据 , 读数据
//---------------------------------------------------------------
uchar Read_Data_FROM_DS1302(uchar addr) //从DS1302指定位臵读取数据 {
uchar dat; RST=0; CLK=0; RST=1;
, 读数据