⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smgsy.c

📁 郑州远博公司生产的单片机A型实验板原理图及配套试验源程序
💻 C
字号:
/*======YB-51-A单片机通用实验板演示程序===========================*/
/*======程序来源:远博科技  0371-6949037  13949105551  13603453895=======================*/
/*======日期:2004.9.8=====================*/
/*===================================================================

[注]:AT89C51的晶振频率为11.0592MHz
====================================================================*/

/*            ACM1602A (16x2)接线图
=====================================================================
连接线图:   ACM-------51     ACM-------51     ACM--------51
            DB0-----P0.0     DB4-----P0.4     RS-------P1_0
            DB1-----P0.1     DB5-----P0.5     RW-------P1_1
            DB2-----P0.2     DB6-----P0.6     E--------P1_2
            DB3-----P0.3     DB7-----P0.7     BLA------P1_3
            
            VLCD接1K电阻到GND

====================================================================*/

#include <AT89X51.H>
#include <stdio.h>
#include <Intrins.h>
//变量类型标识的宏定义
#define Uchar unsigned char
#define Uint unsigned int

// 控制引脚定义,不同的连接必须修改的部分
//74LS164定义
#define SDA    P2_7    //74LS164 SAD
#define SCK    P2_6    //74LS164 SCK
#define BIT1   P2_5    //数码管位1
#define BIT2   P2_4    //数码管位2
#define BIT3   P2_3    //数码管位3
#define BIT4   P2_2    //数码管位4
#define BIT5   P2_1    //数码管位5
#define BIT6   P2_0    //数码管位6

//继电器、蜂鸣器、LED电源控制端定义
#define LED    P0
#define LEDSW  P3_3    //LED电源控制端
#define BUZZ   P3_6    //蜂鸣器控制
#define JDQ    P3_7    //继电器控制

//24C02定义
#define SCL24    P3_4    //24C02 SCL端
#define SDA24    P3_5    //24C02 SDA端
#define WriteDeviceAddress 0xa0 // 24c02写命令字
#define ReadDviceAddress 0xa1   // 24c02读命令字

// 1602连线
#define RS    P1_0       //数据/命令选择
#define RW    P1_1       //读/写选择
#define Elcm  P1_2       //使能信号
#define BLA   P1_3       //液晶显示屏背光

#define DataPort P0      // 数据端口
#define Busy    0x80

//按键定义
#define  K1 P1_4
#define  K2 P1_5
#define  K3 P1_6 
#define  K4 P1_7
#define  K5 P3_2        //INT0


code char examp[]="   LCD-1602     WELCOME TO YBKJ";
code char examp1[]="K1 be pressed!";
code char examp2[]="K2 be pressed!";
code char examp3[]="K3 be pressed!";
code char examp4[]="K4 be pressed!";
code char examp5[]="INT0 TEST";
void WaitForEnable( void );
void LcdWriteData( char dataW ) reentrant;
void LcdWriteCommand( Uchar CMD,Uchar AttribC )reentrant ;
void LcdReset( void ) reentrant;
void DispOneChar(Uchar x,Uchar y,Uchar Wdata) reentrant  ;
void ePutstr(Uchar x,Uchar y, Uchar code *ptr) reentrant;
code Uchar szdm[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};  //0-9共阴数字数码管代码
void senddata(Uchar dd);
void DelayMs(Uint number);
void Read24c02(Uchar *RamAddress,Uchar RomAddress,Uchar bytes);  //23c02读程序
void Write24c02(Uchar *Wdata,Uchar RomAddress,Uchar number);    //24c02写程序
Uchar ledls(Uchar j);         //LED流水程序
//void comminit(void);          //串口初始化程序
void scomm(void) ;            //串口中断服务程序
void int0test(void);          //int0服务程序
void enint0(void);            //int0初始化
Uchar  sedata,bzw=0;
//测试主程序
void main(void)
{
    Uchar data1[6]={0x01,0x02,0x03,0x04,0x05,0x06};
	Uchar data2[6]={0x05,0x05,0x05,0x05,0x05,0x05};
	Uchar *Pdata1=data1,Romadd=0x00,counter=6,*Pdata2=data2;
    Uchar j,k,m;
	bit bz;
    DelayMs(800);
    BLA=0;                               //打开液晶显示屏背光
    LcdReset();
    ePutstr(0,0,examp);                 // 液晶屏显示一个预定字符串
    DelayMs(800);
	SCK=0;
	//comminit();        //本条语句用来打开串口中断
	enint0();
    Write24c02(Pdata1,Romadd,counter);
    Read24c02(Pdata2,Romadd,counter);
    k=m=0;
    bz=1;
	Elcm=0;                                //关闭液晶显示屏,不加此句会影响LED显示
	LEDSW=0;                               //打开LED电源
    j=0;
	DelayMs(400);
    while(1)
    {
	 if (bzw==1) {                         //bzw为串口中断标志
	               senddata(szdm[sedata]); BIT6=0; 
				                      DelayMs(3000);
				   bzw=0;                          } 
	 while ((K1&K2&K3&K4)==0)  {                            //按键测试
                                LEDSW=1;
								BLA=0;
	                            BUZZ=0;
                                LcdReset();
    							while (K1==0)  ePutstr(1,0,examp1);
								while (K2==0)  ePutstr(1,0,examp2);
                                while (K3==0)  ePutstr(1,0,examp3);
								while (K4==0)  ePutstr(1,0,examp4); 
								BUZZ=1;
								BLA=1;
								LcdReset();
								ePutstr(0,0,examp);
								}
     LEDSW=0;                             
	 LED=ledls(k); 
     // if(bz==1)    {BUZZ=0 ;JDQ=0;}     //继电器和蜂鸣器测试
	 // if(bz==0)    {BUZZ=1;JDQ=1;}
	 if (j==4)                           //LED延时
	 { j=0; k=k+1; bz=~bz;}
     if (k==8)   { k=0; }              //使LED重新从第一个开始轮流点亮
     if (m==50)                         //使液晶屏交替亮灭
	 {m=0;BLA=~BLA;}
     senddata(szdm[data2[0]]);
	 BIT1=0;
     DelayMs(10);
     BIT1=1;
     senddata(szdm[data2[1]]);
	 BIT2=0;
     DelayMs(10);
     BIT2=1;
     senddata(szdm[data2[2]]);
	 BIT3=0;
     DelayMs(10);
     BIT3=1;
     senddata(szdm[data2[3]]);
	 BIT4=0;
     DelayMs(10);
     BIT4=1;
     senddata(szdm[data2[4]]);
	 BIT5=0;
     DelayMs(10);
     BIT5=1;
     senddata(szdm[data2[5]]);
	 BIT6=0;
     DelayMs(10);
     BIT6=1;
	 j=j+1;
     m++;
    }
}
   
/*串口中断服务程序*/
void scomm(void) interrupt 4 {     
                          while(!RI);
                          EA=0;
                          RI=0;
                          sedata=SBUF;     //保存数据
                          SBUF=sedata;     //转发数据
                          while (!TI);
                          TI=0;
                          EA=1;
                          bzw=1;
                              }
 /*串口初始化程序*/                         
/*void comminit(void)     {            
                          TMOD=0x20;   //定时器1方式2定时
                          TH1=0xfd;
                          TL1=0xfd;   //置定时器初值,选定9600bps
                          SCON=0x50;  //选择通讯方式1 (1位起始,8位数据,1位停止)
                          TR1=1;      //启动定时器
						  ET1=0;
                          ES=1;       //开串口中断
                          EA=1;       //开中断 
                         }                              */
/*中断0实验*/
void int0test(void) interrupt 0   {
EA=0;    //关中断
LEDSW=1;  //关闭LED电源
BLA=0;    //使液晶屏背景灯亮
JDQ=0;     //继电器吸合
BUZZ=0;     //蜂鸣器发声
LcdReset();
DelayMs(300);
ePutstr(3,0,examp5);
DelayMs(3000);
LcdReset();
ePutstr(0,0,examp);
LEDSW=0;
EA=1;
BUZZ=1;
JDQ=1;
BLA=1;
                               }
void enint0(void)          {
EX0=1; //允许中断0
IT0=1; //脉冲触发
EA=1;  //开中断
                        }
/*串行发送8位数据 */
void senddata(Uchar dd) {
Uchar j;
for (j=0;j<8;j++) {
                   SDA=(bit)(dd&0x01);
				   SCK=1;  SCK=0;
				   dd=dd>>1;
				   }
				         }


/*使8个LED轮流发光*/
Uchar ledls(Uchar j)     
{  Uchar temp;
switch (j)      {                     
case 0:
       temp=0xfe;
	   break;
case 1:
       temp=0xfd;
	   break;
case 2:
       temp=0xfb;
	   break;
case 3: 
       temp=0xf7;
	   break;
case 4:
       temp=0xef;
	   break;
case 5: 
       temp=0xdf;
	   break;
case 6:
      { temp=0xbf;
	   break;}
case 7: 
       temp=0x7f;
	   break;
default:
       temp=0x55;
	             }
return(temp);
	   }
/***************************************************************************
延时程序
/***************************************************************************/
void DelayMs(Uint number) {
Uchar temp;
 for(;number!=0;number--) {
  for(temp=112;temp!=0;temp--) {
  }
 }
}
/************************************************************
24c02演示程序
/*************************************************************/
void Start() {
 SDA24=1;
 SCL24=1;
 SDA24=0;
 SCL24=0;
}

/***************************************************************************/
void Stop() {
 SCL24=0;
 SDA24=0;
 SCL24=1;
 SDA24=1;
}

/***************************************************************************/
void Ack() {
 SDA24=0;
 SCL24=1;
 SCL24=0;
 SDA24=1;
}

/***************************************************************************/
void NoAck() {
 SDA24=1;
 SCL24=1;
 SCL24=0;
}

/***************************************************************************/
bit TestAck() {
 bit ErrorBit;
 SDA24=1;
 SCL24=1;
 ErrorBit=SDA24;
 SCL24=0;
 return(ErrorBit);
}

/***************************************************************************/
void Write8Bit(Uchar input) {
 Uchar temp;
 for(temp=8;temp!=0;temp--) {
  SDA24=(bit)(input&0x80);
  SCL24=1;
  SCL24=0;
  input=input<<1;
 }
}
/***************************************************************************/
void Write24c02(Uchar *Wdata,Uchar RomAddress,Uchar number) {
 Start();
 Write8Bit(WriteDeviceAddress);
 TestAck();
 Write8Bit(RomAddress);
 TestAck();
 for(;number!=0;number--) {
  Write8Bit(*Wdata);
  TestAck();
  Wdata++;
 }
 Stop();
 DelayMs(10);
}

/***************************************************************************/
Uchar Read8Bit() {
Uchar temp,rbyte=0;
 for(temp=8;temp!=0;temp--) {
  SCL24=1;
  rbyte=rbyte<<1;
  rbyte=rbyte|((Uchar)(SDA24));
  SCL24=0;
 }
 return(rbyte);
}

/***************************************************************************/
void Read24c02(Uchar *RamAddress,Uchar RomAddress,Uchar bytes) {
//unsigned char temp, rbyte;
 Start();
 Write8Bit(WriteDeviceAddress);
 TestAck();
 Write8Bit(RomAddress);
 TestAck();
 Start();
 Write8Bit(ReadDviceAddress);
 TestAck();
 while(bytes!=1) {
 *RamAddress=Read8Bit();
 Ack();
 RamAddress++;
 bytes--;        }
 *RamAddress=Read8Bit();
 NoAck();
 Stop();
}
/*=======================================================
液晶屏上显示字符串
=======================================================*/
void ePutstr(Uchar x,Uchar y, Uchar code *ptr) reentrant{
Uchar i,l=0;
    while (*ptr++ >0){l++;}; //统计字符的个数
	ptr=ptr-(l+1);            //使指针重新指向首个字符
    for (i=0;i<l;i++)     { DispOneChar(x++,y,*ptr++);
                            if ( x == 31 )  { x = 0; y ^= 0; }
                           }
                                                }


/*=======================================================
显示光标定位
=======================================================*/
void Disp_XY( char posx,char posy) {

Uchar temp;

    temp = posx & 0x0f;
    posy &= 0x1;   
    if ( posx>15 )   temp |= 0x40;
	if (posy==1)   temp |=0x40;
    temp |= 0x80;
    LcdWriteCommand(temp,0);
}

/*=======================================================
按指定位置显示数出一个字符
=======================================================*/
void DispOneChar(Uchar x,Uchar y,Uchar Wdata) reentrant {

    Disp_XY( x, y );                // 定位显示地址
    LcdWriteData( Wdata );            // 写字符
}

/*=======================================================
初始化程序, 必须按照产品资料介绍的初始化过程进行
=======================================================*/
void LcdReset( void ) reentrant {

       LcdWriteCommand( 0x38, 0);            // 显示模式设置(不检测忙信号)
        DelayMs(10);
    LcdWriteCommand( 0x38, 0);            // 共三次
        DelayMs(10);
    LcdWriteCommand( 0x38, 0);
        DelayMs(10);

    LcdWriteCommand( 0x38, 1);            // 显示模式设置(以后均检测忙信号)
    LcdWriteCommand( 0x08, 1);            // 显示关闭
    LcdWriteCommand( 0x01, 1);            // 显示清屏
    LcdWriteCommand( 0x06, 1);            // 显示光标移动设置
    LcdWriteCommand( 0x0c, 1);            // 显示开及光标设置
}

/*=======================================================
写控制字符子程序: E=1 RS=0 RW=0
=======================================================*/
void LcdWriteCommand( Uchar CMD,Uchar AttribC )  reentrant{

    if (AttribC) WaitForEnable();                // 检测忙信号?
    RS=0; RW=0; _nop_();
    DataPort=CMD; _nop_();
    // 送控制字子程序
    Elcm=1;_nop_();_nop_();Elcm=0;            // 操作允许脉冲信号
}

/*=======================================================
当前位置写字符子程序: E =1 RS=1 RW=0
=======================================================*/
void LcdWriteData( char dataW ) reentrant {

    WaitForEnable();
        // 检测忙信号

    RS=1; RW=0; _nop_();

    DataPort=dataW; _nop_();

    Elcm=1; _nop_(); _nop_(); Elcm=0;        // 操作允许脉冲信号

}

/*=======================================================
正常读写操作之前必须检测LCD控制器状态:    CS=1 RS=0 RW=1
DB7:    0  LCD控制器空闲; 1  LCD控制器忙
========================================================*/
void WaitForEnable( void ) {

    DataPort = 0xff;

    RS=0; RW=1; _nop_();    Elcm=1; _nop_(); _nop_();

    while( DataPort & Busy );
    Elcm=0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -