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

📄 51

📁 51单片机应用系统典型模块开发大全
💻
字号:
#include <reg51.h>					
#include <absacc.h>
#include <intrins.h>
#define uchar 	unsigned char
#define uint 	unsigned int
sbit CS7221  = P1^5;				// 7221的片选
sbit DIN7221 = P1^4;				// 7221的数据端
sbit CLK7221 = P1^6;				// 7221的时钟端
sbit SDA=P3^4;						// 2464的数据端
sbit SCL=P3^5;						// 2464的时钟端
sbit RD_key=P1^0;					// 抄电表按键
sbit  PinSD = P3^3;					//zHX1010的使能端
uchar DISPBUF[8]={0,1,2,3,4,5,6,7};	//显示缓冲区
uchar BUF[5]=0;  					//数据处理缓冲区
uchar key[2]={0xaa,0xbb};  			//通信密码2位
uchar key_FLAG=0;  					//密码标志位


void InitSerial(uint temp);			//初始化串口
void ZHX1010_Send(uchar dat);		//ZHX1010发送一字节数据
void Send(void);					//发送电度数据
uchar ZHX1010_Recieve(void);		//ZHX1010接收一字节数据函数
void Recieve();						//接收电度数据
void delay(uint n);					//延时子程序
void Initial7221(void);				//MAX7221初始化
void WR7221(uchar addr,uchar Data);	//MAX7221写程序
void Max7221Display(uchar *buffer);	//MAX7221显示程序
void Display(void);					//循环显示电度数
void start_bit(void);				//IIC开始条件
void stop_bit(void);				//IIC停止条件
void mast_ack(void);				//IIC应答
bit write_8bit(uchar ch);			//IIC写8位数据
uchar page_wr(uint firstw_ad,uint counter,uchar *firstr_ad);//IIC页写
uchar page_rd(uint firstrd_ad,uint count,uchar *firstwr_ad);//IIC页读

main()
{	
	Initial7221();              			//初始化7221
    Max7221Display(&DISPBUF[0]); 			//开机默认显示0~7
    delay(40);								//延时
	InitSerial(0xfdfd);  					//初始化串口 9600 Bds
    while (1)
    {
		if(RD_key==1)						//抄表按键按下
		{
			delay(20);						//延时
			if(RD_key==1)					//抄表按键按下
			{
				Send();						//发送抄电表密码
				if(ZHX1010_Recieve()==0xcc)
				{
					Recieve();				//接收电度数据直到正确					
				}				
			}			
		}
		Display();							//显示电度数
    }
}



//串行通信初始化函数:InitSerial()
void InitSerial(uint temp)
{
    SCON = 0x50;					  	 		//串行通信工作在模式1,8 位, REN=1
    TMOD = TMOD | 0x20 ;       					//定时器1工作在模式2
    TH1  = (temp & 0xff00) >> 8;				//定时时间常数高位
    TL1  = temp & 0xff; 						//定时时间常数低位
	RI = 0;										//清接收标志位
	TI = 0;        								//清发送标志位
    TR1  = 1; 						        	//定时器1运行
    PinSD= 0; 						        	//串行通信使能
}


//ZHX1010发送一字节数据函数:ZHX1010_Send()
//函数功能:ZHX1010发送一字节数据
//说明:参数dat为要发送的数据
void ZHX1010_Send(uchar dat)
{
    while (RI==1);        						//如果正在接收则等待
    TI = 0;        								//清发送标志位
    SBUF = dat; 								//把要发送的数据打入发送寄存器 启动发送
    while (!TI);								//等待发送完成
}

void Send(void)									//发送密码程序
{
	ZHX1010_Send(key[0]);			 			//发送第1位密码
	ZHX1010_Send(key[1]);			 			//发送第2位密码
	
}

//ZHX1010接收一字节数据函数:ZHX1010_Recieve()
uchar ZHX1010_Recieve(void)
{
	uchar temp;
	while(RI!=1);
	RI = 0;
	temp = SBUF;
	return(temp);
}

void Recieve(void)								//接收电度数据
{
	uchar k,j,sum=0;
	reply:
	sum=0;
	for(k=0;k<8;k++)		 					//8户
	{
		for(j=0;j<5;j++)   						//5位电度数
		{
			BUF[j]=ZHX1010_Recieve();			//发送电度数
			sum=sum+BUF[j];						//和校验
		}
		while (page_wr(k*5,5,&BUF[0])==0);   	//读电度数		
	}
	if(ZHX1010_Recieve()==sum)
	{
		ZHX1010_Send(0xdd); 					//发 0xdd
	}
	else
	{
		ZHX1010_Send(0xee); 					//发 0xee
		goto reply;
	}
}

void Display(void)								//循环显示电度数
{
	uchar k;
	for (k=0;k<=7;k++)							//8路电能循环显示
	{
		while (page_rd(k*5,5,&BUF[0])==0);   	//读电度数
		DISPBUF[0]=k+1;                         //显示户号
		DISPBUF[1]=0xf;                         //显示2个F
		DISPBUF[2]=0xf;
		DISPBUF[3]=BUF[0];                      //显示电度数
		DISPBUF[4]=BUF[1];
		DISPBUF[5]=BUF[2];
		DISPBUF[6]=BUF[3];                              
		DISPBUF[7]=BUF[4];
		Max7221Display(&DISPBUF[0]);			//送显示	
		delay(60);								//延时
	}		
}

void WR7221(uchar addr,uchar Data)			//MAX7221的写子程序
{
    uchar i;
    CS7221  = 0;		     				//片选有效
    for (i=0;i<8;i++)     					//写8位地址
    {
        CLK7221 = 0;						//时钟低
        DIN7221 = (addr&(0x80>>i)) ? 1:0;	//先发高位 依次到低位
        _nop_();
        _nop_();
        CLK7221 = 1;						//时钟高  上升沿锁数据
        _nop_();
        _nop_();
    }
    for (i=0;i<8;i++)     					//写8位数据
    {
        CLK7221 = 0;						//时钟低
        DIN7221 = (Data&(0x80>>i)) ? 1:0;	//先发高位 依次到低位
        _nop_();
        _nop_();
        CLK7221 = 1;						//时钟高  上升沿锁数据
        _nop_();
        _nop_();
    }
    CS7221  = 1;		     				//片选无效
}

void Initial7221(void)	//MAX7221初始化
{
    WR7221(0x0A,0x0A);	//亮度地址0AH,0x00~0x0F,0x0F最亮
    WR7221(0x0B,0x07);	//扫描LED个数地址0BH,0x00~0x07,最多扫描8个数码管
    WR7221(0x0C,0x01);	//工作模式地址0x0C. 0x00:关断;0x01:正常
    WR7221(0x09,0xFF);	//编码模式地址0x09. 0x00~0xFF:哪一位为1,哪一位就支持编码
}

void Max7221Display(uchar *buffer)	//MAX7221显示子程序
{
    uchar i;
    for (i=0;i<8;i++)				//MAX7221的8个数码管显示
    {
        WR7221(i+1,*(buffer+i));	//调MAX7221的写子程序
    }
}


void delay(uint n)		     		//延时程序
{
    uint i,j;
    for (i=0;i<n;i++)
        for (j=0;j<1140;j++);
}

/*-----------------------------------------------
调用方式:void start_bit(void)
函数说明:开始位
-----------------------------------------------*/
void start_bit(void)
{
    SCL=1;_nop_();
    SDA=1;_nop_();
    SDA=0;_nop_();
    SCL=0;_nop_();
}
/*-----------------------------------------------
调用方式:void stop_bit(void)
函数说明:停止位
-----------------------------------------------*/
void stop_bit(void)
{
    SDA=0;_nop_();
    SCL=1;_nop_();
    SDA=1;_nop_();
}
/*-----------------------------------------------
调用方式:void mast_ack(void)
函数说明:主答函数
-----------------------------------------------*/
void mast_ack(void)
{
    SCL=0;_nop_();
    SDA=0;_nop_();
    SCL=1;_nop_();
    SCL=0;_nop_();
    SDA=1;_nop_();
}

/*-----------------------------------------------
调用方式:write_8bit(uchar ch)
函数说明:写一个字节(8位)数据
-----------------------------------------------*/
bit write_8bit(uchar ch)
{
    uchar i=8;
    bit fan_w;
    SCL=0;_nop_();
    while (i--)
    {
        SDA=(bit)(ch&0x80);_nop_();
        ch<<=1;
        SCL=1;_nop_();
        SCL=0;_nop_();
    }
    SDA=1;_nop_();
    SCL=1;_nop_();
    fan_w=SDA;
    SCL=0;_nop_();
    return(fan_w);
}

uchar page_wr(uint firstw_ad,uint counter,uchar *firstr_ad)
{
    uchar data *ufirstr_ad;
    ufirstr_ad=firstr_ad;
    start_bit();
    if (write_8bit(0xA0)!=0){
        stop_bit();return(0);
    }
    if (write_8bit(firstw_ad)!=0){
        stop_bit();return(0);
    }
    while (counter--)
    {
        if (write_8bit(*ufirstr_ad)!=0){
            stop_bit();return(0);
        }
        ufirstr_ad++;
    }
    stop_bit();
    return(1);
}
/*-----------------------------------------------
调用方式:void page_rd(uint firstrd_ad,uint count,uint firstwr_ad)
函数说明:页面读函数,firstrd-ad为所读字节首地址,count为读字节数
           *ufirstwr-ad为读出数据存储首地址指针
-----------------------------------------------*/
uchar page_rd(uint firstrd_ad,uint count,uchar *firstwr_ad)
{
    uchar j=8;
    uchar data *ufirstwr_ad;
    ufirstwr_ad=firstwr_ad;
    start_bit();
    if (write_8bit(0xA0)!=0){
        stop_bit();return(0);
    }
    if (write_8bit(firstrd_ad)!=0){
        stop_bit();return(0);
    }
    start_bit();
    if (write_8bit(0xA1)!=0){
        stop_bit();return(0);
    }
    while (count--)
    {
        uchar i=8;
        while (i--)
        {
            (*ufirstwr_ad)<<=1;
            SCL=1;_nop_();
            if (SDA) (*ufirstwr_ad)|=0x01;
            SCL=0; _nop_();
        }
        ufirstwr_ad++;
        mast_ack();
    }
    while (j--)
    {
        (*ufirstwr_ad)<<=1;
        SCL=0;_nop_();_nop_();SCL=1;
        if (SDA) (*ufirstwr_ad)|=0x01;
    }
    stop_bit();
    return(1);
}

⌨️ 快捷键说明

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