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

📄 8563写读.c

📁 mega16做处理芯片
💻 C
字号:

#include<iom16v.h>
#include<macros.h>
#include<stdio.h>

#define uint unsigned int
#define uchar unsigned char



//1602
#define SetRS PORTD|=(1<<PD7)
#define ClrRS PORTD&=~(1<<PD7)

#define SetRW PORTD|=(1<<PD6)
#define ClrRW PORTD&=~(1<<PD6)

#define SetE PORTD|=(1<<PD5)
#define ClrE PORTD&=~(1<<PD5)

 



//8563
#define 	rd_device_add 	0xa3			//定义器件读地址
#define 	wr_device_add 	0xa2			//定义器件写地址

#define 	START 			0x08
#define 	RE_START 		0x10

#define 	MT_SLA_ACK 		0x18            //主机发送模式标志
#define 	MT_SLA_NOACK 	0x20	
#define 	MT_DATA_ACK 	0x28
#define     MT_DATA_NOACK   0x30

#define 	MR_SLA_ACK 		0x40             //主机接受模式标志
#define 	MR_SLA_NOACK    0x48
#define 	MR_DATA_ACK 	0x50
#define 	MR_DATA_NOACK 	0x58

//                    {秒  ,分 ,时 ,日,星期,月 ,年}
uchar read_shijian[7]={0x02,0x21,0x16,0x24,0x00,0x12,0x27};
uchar write_shijian[7]={0x50,0x59,0x23,0x31,0x07,0x12,0x99};

uchar s[4]; //把数字转换成字符串



uchar ReadStatusLCM(void);//读状态 
void WriteDataLCM(uchar WDLCM);//写数据
void WriteCommandLCM(uchar WCLCM,uchar c);//写指令
//uchar ReadDataLCM(void);//读数据
void LCMInit(void);//初始化
void DisplayOneChar(uchar X,uchar Y,uchar DData);//在指定位置显示单个字符 
void DisplayListChar(uchar X,uchar Y,uchar *DData);//在指定位置显示字符串
void Delay5ms(void);//延时5ms
void Delay400ms(void);  //延时




//读状态,忙则循环,不忙则返回Data
uchar ReadStatusLCM(void)
{
  uchar Data;
  
  DDRA=0xff;           //设置指令
  PORTA=0xff;
  DDRD=0xff;//1,输出,置数        0,输入,读数
  ClrRS;
  SetRW;
  
  SetE;                  //执行指令
  SetE;
  
  DDRA=0x00;           //读忙标志,忙则循环 
  Data=PINA;  
  while(Data&0x80)
   Data=PINA;
  return(Data);
  
}




   
   
//写指令
void WriteCommandLCM(uchar WCLCM,uchar c)
{
 if(c==1)             //标志为0不忙检测,标志为1检测
   ReadStatusLCM();
 
 DDRA=0xff;           //设置指令
 PORTA=WCLCM;
 DDRD=0xff;//1,输出,置数        0,输入,读数
 ClrRS;
 ClrRW;
 
 SetE;
 SetE;
 ClrE;
 
} 
     


//读数据
/*uchar ReadDataLCM(void)
{
 ReadStatusLCM();      //忙检测
 
 ClrRS;                //指令设置   
 ClrRW;
 
 ClrE;                //执行指令
 ClrE;
 SetE;
 
 return(Data);
}*/



//初始化
void LCMInit(void)
{
 DDRA=0xff;
 PORTA=0x00;
 
 WriteCommandLCM(0x38,0);//三次显示设置 ,不需忙检
 Delay5ms();             //四位总线,双行显示,5*7点阵
 WriteCommandLCM(0x38,0);
 Delay5ms();
 WriteCommandLCM(0x38,0);
 Delay5ms();
 
 WriteCommandLCM(0x38,1);//显示模式设置,以后都须忙检
 WriteCommandLCM(0x08,1);//关闭显示
 WriteCommandLCM(0x01,1);//清屏
 WriteCommandLCM(0x06,1);//光标右移,字符不移
 WriteCommandLCM(0x0c,1);//显示开,有光标,有闪烁
}


//写数据
void WriteDataLCM(uchar WDLCM)
{
 ReadStatusLCM();      //忙检测
 
 DDRA=0xff;           //设置指令
 PORTA=WDLCM;
 DDRD=0xff;//1,输出,置数        0,输入,读数
 SetRS;
 ClrRW;
 
 SetE;
 SetE;
 
 ClrE;
}


//按指定位置显示一个字符
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
 Y&=0x01;//Y不能>1
 X&=0x0f;//X不能>15
 
 if(Y)
   X+=0x40;//显示第二行时地址码+0x40
 
 X+=0x80;//计算指令码
 
 WriteCommandLCM(X,0);//发送地址码不需忙检   
 WriteDataLCM(DData);
 
}


//在指定位置显示字符串
void DisplayListChar(uchar X,uchar Y,uchar *DData)
{
 uchar pose=0;
 
 Y&=0x01;//Y不能>1
 X&=0x0f;//X不能>15
 
 while(DData[pose]>0x20)
 {
  DisplayOneChar(X,Y,DData[pose]);//显示单个字符
  pose++;
  X++; 
  if(X>=0xF)
   {X=0x00;
    Y=0x01;
   }	
  
 }
}

void Delay1ms(void)
{
 uint time,i;
 time=5552;
  while(time--);
 
}


//延时5ms,已验证
void Delay5ms(void)
{
 uint time,i;
 for(i=0;i<5;i++)
 {time=5552;
  while(time--);
 }
}



//延时400ms
void Delay400ms(void)
{
 uchar j;
 for(j=0;j<8;j++)//延时400ms
 {
  Delay5ms();
 } 
}


//////////TWI总线操作函数 ////////////
void Start(void)                  //TWSTA置位,产生START状态
{TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);}

void Wait(void)                   //应用程序等待硬件操作完成
{while((TWCR&0x80)!=0x80);}       //一直循环,直至硬件已置位TWINT
    
unsigned char TestAck(void)       //读并返回状态寄存器TWSR的状态位,屏蔽低三位
{unsigned char twsr;
 twsr=TWSR&0xf8;
 return twsr;
}

void Write8Bit(unsigned char data)//应用程序写数据到数据寄存器TWDR,清TWINT启动发送
{TWDR=data;
 TWCR=(1<<TWINT)|(1<<TWEN);
}

void Stop(void)                   //TWSTO置位,产生STOP状态
{TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);}

void Ack(void)                    //使能EA,如果接受到数据发送ACK脉冲  
{TWCR=(1<<TWINT)|(1<<TWEA)|(1<<TWEN);}
 
void Twi(void)                    //使能TWI操作激活TWI接口
{TWCR=(1<<TWINT)|(1<<TWEN);}



// 向I2C总线写数据 ,正确写入数据返回0,否则分别返回2,3,4
unsigned char i2c_Write(unsigned char command,unsigned char RomAddress)
{
	Start();  					 	  		//发总线起始命令
	Wait();									//等待应答
	if(TestAck()!=START)       return 1;	//测试应答
	
	Write8Bit(wr_device_add);  				//装入写器件地址
	Wait();									//等待应答
	if(TestAck()!=MT_SLA_ACK)  return 2;	//测试应答
	
	Write8Bit(RomAddress);					//装入写器件内的寄存器地址
	Wait();									//等待应答
	if(TestAck()!=MT_DATA_ACK) return 3;	//测试应答
	
	Write8Bit(command);				 		//写命令
	Wait();									//等待应答
	if(TestAck()!=MT_DATA_ACK) return 4;	//测试应答
	
	Stop();							 		//停止总线
    Delay5ms();						//延时
	Delay5ms();
	return 0;								
}



//向I2C总线连续写入7个数据 
unsigned char i2c_WriteData(unsigned char RomAddress)
{
 	unsigned char i;
	
	Start(); 	  					 	  	//发总线起始命令
	Wait();									//等待应答
	if(TestAck()!=START)      return 1;		//测试应答
	
	Write8Bit(wr_device_add);  				//写器件地址
	Wait();					   				//等待应答
	if(TestAck()!=MT_SLA_ACK) return 2;		//测试应答
	
	Write8Bit(RomAddress);					//写器件内的寄存器首地址
	Wait();									//等待应答
	if(TestAck()!=MT_DATA_ACK)return 3;		//测试应答

	for(i=0;i<7;i++)				 		//循环7次
	{										
	 Write8Bit(write_shijian[i]);		    //写数据
	
	 Wait();								//等待应答
	 if(TestAck()!=MT_DATA_ACK)return 4;    //测试应答
		                    
	}									 	
	
	Stop();									//停止总线
	Delay5ms();						//延时
	Delay5ms();							//延时
	return 0;								
}



//连续读取I2C总线
unsigned char i2c_Read(unsigned char RomAddress)
{
 	unsigned char i;
	
	Start(); 	  					 		//发总线起始命令
	Wait();									//等待应答
	if(TestAck()!=START)          return 1;	//测试应答
	
	Write8Bit(rd_device_add);	  			//装入读器件地址	
	Wait();									//等待应答
	if(TestAck()!=MR_SLA_ACK)     return 5;	//测试应答
	
	for(i=0;i<7;i++)						
	{										
	 	Ack();								//使能EA,如果接受到数据发送ACK脉冲
		Wait();								//等待应答
		if(TestAck()!=MR_DATA_ACK)return 6;	//测试应答
		read_shijian[i]=TWDR;			 	//将读取的数据放入数组中
	}										
	
	Stop();									//停止总线
	return 0;								
}



//INT0中断函数,刷新显示时间 
#pragma interrupt_handler Int0_isr:3            //中断向量2是INT0,3是INT1
void Int0_isr(void)
{
    uchar result,result1,result2,result3,result4,result5;
	
 	i2c_Write(0x19,0x01); 						//向8563的01H控制状态寄存器2写入0x19
	i2c_Read(0x02);								//读取8563的02H-08H装入read_shijian[]
	
	      
	result1=read_shijian[0]&0x7f;
	sprintf(s,"%x",result1);//转换成字符串    秒
	if(result1<0x10)
	 {DisplayOneChar(6,1,'0');
	  DisplayListChar(7,1,s);
	 } 
	else DisplayListChar(6,1,s);              //刷新时间
				
					
	result2=read_shijian[1]&0x7f;
	sprintf(s,"%x",result2);//转换成字符串    分
	if(result2<0x10)
	 {
	  DisplayOneChar(3,1,'0');
	  DisplayListChar(4,1,s);
	 }
	else DisplayListChar(3,1,s);              //刷新时间
	
					
	result3=read_shijian[2]&0x3f;
	sprintf(s,"%x",result3);//转换成字符串    小时
	if(result3<0x10)
	 {
	  DisplayOneChar(0,1,'0');
	  DisplayListChar(1,1,s);	
	 }
	else DisplayListChar(0,1,s);              //刷新时间
				
					
    result4=read_shijian[3]&0x3f;
	sprintf(s,"%x",result4);//转换成字符串    日
	if(result4<0x10)
	 {
	  DisplayOneChar(8,0,'0');
	  DisplayListChar(9,0,s);	
	 }
	else DisplayListChar(8,0,s);              //刷新时间
			
					
	Delay1ms();
	sprintf(s,"%x",read_shijian[4]&0x07);//转换成字符串    星期
	DisplayListChar(11,0,s);             //刷新时间
	
	
	result5=read_shijian[5]&0x1f;
	sprintf(s,"%x",result5);//转换成字符串    月 
	if(result5<0x10)
	{
	  DisplayOneChar(5,0,'0');
	  DisplayListChar(6,0,s);	
	 }
	else DisplayListChar(5,0,s);              //刷新时间
			
						
    result=read_shijian[6];
	sprintf(s,"%x",read_shijian[6]);    //转换成字符串    年
	if(result<0x10)
	{
	  DisplayOneChar(2,0,'0');
	  DisplayListChar(3,0,s);	
	 }
	else DisplayListChar(2,0,s);             //刷新时间
	if((result5==0x01)&&(result4==0x01)&&(result3==0x00)&&(result2==0x00)&&(result1==0x00))
	 {sprintf(s,"%d",20);
      DisplayListChar(0,0,s);
	 }			
	
}



//初始化TWI总线 
void Twi_Init(void)
{
 	TWBR=32;	   							//设置波特率
	TWSR=0;									//复位TWI总线
	
	i2c_Write(0,0);							//设置时钟状态
	i2c_Write(0x81,0x0d);
	i2c_Write(0x82,0x0e);
	i2c_Write(1,0x0f);
	i2c_Write(0x81,0x01);
	i2c_WriteData(0x02);
	
	i2c_Write(0x19,0x01); 					//向8563的01H控制状态寄存器2写入0x19
	i2c_Read(0x02);							//读取8563的02H-08H装入read_shijian[]
	
		
}



void main(void)
{
  uint k=19;//年
  DDRD=0xfb;
  DDRC=0xff;
  
  
  CLI(); 	   								//关中断
  Delay400ms();//延时,启动
  //MCUCR=(1<<ISC01);						//设置INT0下降沿触发中断
  GICR=(1<<INT1);							//使能INT1中断
  DDRB=0xff;   //启动后灯亮
  PORTB&=~(1<<PB0);
  
  Twi_Init();								//初始化TWI总线
  LCMInit();   //初始化
  PORTB|=(1<<PB0);//初始化后灯灭
  
  Delay5ms();	//年
  sprintf(s,"%d",k);
  DisplayListChar(0,0,s);
  
  Delay5ms();	
  DisplayOneChar(4,0,'.');
  Delay5ms();	
  DisplayOneChar(7,0,'.');
  Delay5ms();	
  DisplayOneChar(10,0,'.');
  Delay5ms();	
  DisplayOneChar(2,1,':');
  Delay5ms();	
  DisplayOneChar(5,1,':');
  
  //DisplayOneChar(10,0,'.');
  //sprintf(s,"%d",k);
  //DisplayListChar(0,0,s);
  
   
  // DisplayListChar(5,0,net);
  SEI();					   				//开中断
  while(1);
 
}



  




	 

⌨️ 快捷键说明

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