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

📄 iictimelcd.c

📁 MSP430F147软件配合液晶(IIC接口)显示
💻 C
字号:
//************************************************************************
//文件名:IICtimelcd.c
//
//创建人:章玉刚
//
//时间  :2003.6.21
//
//描述  :本程序是通过IIC口设置时钟芯片PCF8563和从时钟芯片读取时间;
//	  设置只设置一次,读取时不要设置,不要运行void SetPCF8563(uchar timetype,uchar value)
//
//修改  :考虑到设置以后的每次读取都要把etPCF8563函数注释掉,为了避免这种麻烦,
//        所以用while语句来循环读取,但同时请注意,在C-SPY调试的时候就不能每次
//        让程序复位后运行,这样运行读取的时间就依然是第一次设定的时间,比系统时间慢了
//        后面一直用"Go"即可。           
//修改时间:2003.6.21
//
//修改  :把时间的设定和读取做成函数,以便外部程序调用,传递的是全局变量
//	  同时把液晶的显示函数做好了。	
//
//修改时间:2003.6.24
//
//修改  :时间设定和读取做成用指针做形参的函数,以便外部调用;6.25
//修改  :加入一个不清屏的显示函数,主要是给设定时间用的;
//时间  :2003.7.1
//
//修改  :把清除屏幕和显示数据做成一个最底层的函数Cls()和Dispdata(char *data),供各显示函数调用	
//        把flash()改成Dispdata();
//时间  :2003.7.2
//修改  :把显示9033OFF的函数放在底层,供9033.c调用
//时间  :2003.7.5
//************************************************************************//	        
#include "msp430x14x.h"
#define uint unsigned int
#define uchar unsigned char

#define SCL1 P4OUT |= BIT1; 
#define SCL0 P4OUT &= ~BIT1;
#define SDA1 P4OUT |= BIT0; 
#define SDA0 P4OUT &= ~BIT0;
#define I2COut P4DIR |=BIT0;P4DIR |=BIT1; 
//#define I2CIn P4DIR &= ~BIT1; 
#define I2CIn P4DIR &= ~BIT0;//我觉得应该为BIT0;是用SDA作为147输入的,而不是时钟SCL
#define I2CBit 0x01 

unsigned char ack;


//启动总线函数:启动I2C总线,即发送I2C起始条件
void Start_I2c(void);
//结束I2C总线,发送结束条件?
void Stop_I2c(void);
//字节数据传送函数
void SendByte(uchar c);
//字节数据接收函数
uchar RcvByte(void);
//应答函数:主控器进行应答信号,(可以是应答或非应答信号)
void Ack_I2c(uchar a);
//应答信号函数
void SendAck(void);
//向有子地址器件发送多字节数据函数
uchar ISendStr256(uchar sla,uint suba, uchar *s,uchar no);
//向有子地址器件读取多字节数据
uchar IRcvStr256(uchar sla,uint suba, uchar *s,uchar no);
//时间设置函数
void Settime8563(uchar *time);
//时间读取函数
void Read8563(uchar *time);			

uchar GetPCF8563(uchar firsttype);//只接收一个时间的函数
void SetPCF8563(uchar timetype,uchar value);
uchar BCD(uchar time1);			//BCD到十进制转换
uchar countBCD(uchar time2);		//十进制到BCD

//液晶显示函数,先清屏,再显示
void Display(uchar *data);
//液晶显示函数,不清除屏幕
void Dispdata(uchar *data);
//液晶清除屏幕函数
void Cls(void);
//显示E9033OFF函数
void DispOff(uchar);
//void delay(uchar delaytime);		//这里面没有使用延时函数,注释掉
//注释掉的语句调试的时候用
/*unsigned char data_bak[7];  		//时间读取后暂存数组
unsigned char data_time[7]; 
//这些变量应该是专门用来存放读取时间的,最后应该做成全局变量;用来设定时间的变量要另外定义
unsigned char Sec,Min,Hour,Day,Week,Mon,Year;

void main(void)
{
	unsigned char disp_time[20]={0xd8,0x70,0xed,0x00,0xff,0xff,0xff,0x31,0xff,0x32,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
	uchar nowtime[7]={00,50,3,26,4,6,03};//当前时间
	uchar d_time[7]={0,0,0,0,0,0,0};
	WDTCTL = WDTPW + WDTHOLD;            		 // Stop watchdog timer
	Settime8563(nowtime);
	Read8563(d_time);
	Display(disp_time);
	while(1);
}*/
//启动总线函数:启动I2C总线,即发送I2C起始条件
void Start_I2c(void)
{
         SDA1; SCL1; _NOP(); SDA0;_NOP(); SCL0;_NOP();
}
//结束I2C总线,发送结束条件?
void Stop_I2c(void)
{
         SCL0; _NOP(); SDA0; _NOP(); SCL1; _NOP(); SDA1; _NOP();
}
//字节数据传送函数
void SendByte(uchar c)
{
    uchar BitCnt;
    uchar errtime=255;
    for(BitCnt=0;BitCnt<8;BitCnt++)
       {
           SCL0; _NOP();
           if((c<<BitCnt)&0x80)
              {
                  SDA1; 
              }
            else 
             {
                  SDA0; 
              }
            _NOP();
            SCL1;_NOP(); 
        }
     SCL0; _NOP(); 

     I2CIn;
     SCL1; _NOP(); 

     aaa:
     if (P4IN&I2CBit) ack=0;else ack=1;
     if(ack==0) {
             errtime--; 
             if (errtime==0){
             Stop_I2c(); 
             goto bbb;
      }
  
     goto aaa; 
    }
   bbb:
   SCL0;
   _NOP();
   I2COut; 
}
//字节数据接收函数
uchar RcvByte(void)
{
    uchar retc;
    uchar BitCnt;
    retc=0;
    I2COut; 
    SDA1; 
    for(BitCnt=0;BitCnt<8;BitCnt++)
      {
          SCL0;SCL1;
          retc=retc<<1;
          I2CIn; 
          if (P4IN&I2CBit) retc=retc+1;
      }
    SCL0;;
    return(retc);
}
//应答函数:主控器进行应答信号,(可以是应答或非应答信号)
void Ack_I2c(uchar a)
{
    I2COut;
    if(a==0) {
       SDA0;
      _NOP();
    } 
    else
     {
        SDA1;
        _NOP();
     } 
    SCL1; 
    _NOP();
    SCL0;
    _NOP();
}

//向有子地址器件发送多字节数据函数
uchar ISendStr256(uchar sla,uint suba, uchar *s,uchar no)
{
      uchar i,temp;
      Start_I2c(); //启动总线
      SendByte(sla);//发送器件地址
      if (ack==0){ return(0);}   
      temp=(suba&0xff00)>>8;
      SendByte(temp);//发送器件子地址高地址
      if (ack==0) return(0);
      temp=suba&0xff;
      SendByte(temp); //发送器件子地址低地址
      if (ack==0) return(0);
      for(i=0;i<no;i++)
       {
          SendByte(*s); //发送数据
          if (ack==0) return(0);
          s++;
       }
      Stop_I2c();//结束总线
      return(1);
} 
//向有子地址器件读取多字节数据函数
uchar IRcvStr256(uchar sla,uint suba, uchar *s,uchar no)
{
   uchar i,temp;
   Start_I2c(); //启动总线
   SendByte(sla);//发送器件地址
   if (ack==0){ return(0);   }

   temp=(suba&0xff00)>>8;
   SendByte(temp);//发送器件子地址高地址
   if (ack==0) return(0);
   temp=suba&0xff;
   SendByte(temp); //发送器件子地址低地址
   if (ack==0) return(0);
   Start_I2c();
   SendByte(sla+1);
   if (ack==0) return(0);
   for(i=0;i<no-1;i++)
    {
       *s=RcvByte(); //接收数据
       Ack_I2c(0); //发送就答位
       s++;
    }
   *s=RcvByte();
   Ack_I2c(1); //发送非应位
   Stop_I2c();//结束总线
   return(1);
} 
//**************************************************************************
//调用方式:void GetPCF8563(uchar firsttype)
//函数说明:读取时间。设置要读的时间类型firsttype,firsttype为地址
//0x02:秒/0x03:分/0x04:小时/0x05:日/0x06:星期/0x07:月(世纪)/0x08:年
//**************************************************************************//
uchar GetPCF8563(uchar firsttype)
{
    uchar time;
    Start_I2c();
    SendByte(0xA2);
    SendByte(firsttype);

    Start_I2c();
    SendByte(0xA3);

    time=RcvByte();
    SendAck();   //除最后一个字节外,其他都要从MASTER发应答。
  
    Stop_I2c();
    return(time);
}  
   

/**--------------------------------------------------------------------------------
调用方式:void SetPCF8563(uchar timetype,uchar value)
函数说明:调整时钟。timetype是要改的时间类型,value是新设置的时间值(BCD格式)。
0x02:秒/0x03:分/0x04:小时/0x05:日/0x06:星期/0x07:月(世纪)/0x08:年
---------------------------------------------------------------------------------*/
void SetPCF8563(uchar timetype,uchar value)
{
   Start_I2c();
   SendByte(0xA2);
   SendByte(timetype);
   SendByte(value);
   Stop_I2c();
}
/**--------------------------------------------------------------------------------
调用方式:void Settime(uchar *time)
函数说明:时间的一次性设置,年月日星期时分秒全设
---------------------------------------------------------------------------------*/
void Settime8563(uchar *time)
{
	//配置的时间可为当前计算机系统的时间,也可使用全局变量配置,必须用BCD码进行设置
	SetPCF8563(0x00,0x00);             //启动PCF8563 
	SetPCF8563(0x01,0x00);
	SetPCF8563(0x02,countBCD(*time));          //秒                           
	SetPCF8563(0x03,countBCD(*(time+1)));      //分                            
	SetPCF8563(0x04,countBCD(*(time+2)));     //时                           
	SetPCF8563(0x05,countBCD(*(time+3)));     //日			      
	SetPCF8563(0x06,countBCD(*(time+4)));               //星期,必须设置,可以不读取,否则年月不对
	SetPCF8563(0x07,countBCD(*(time+5)));      //月 
	SetPCF8563(0x08,countBCD(*(time+6)));      //年
}

/**--------------------------------------------------------------------------------
调用方式:void SendAck(void) 
函数说明:私有函数,I2C专用,主器件为接收方,从器件为发送方时,应答信号。
---------------------------------------------------------------------------------*/
void SendAck(void)
{
    SDA0; _NOP();
    SCL1; _NOP();
    SCL0;
}
//*********************************************************************************
//调用方式:uchar BCD(unsigned char time1)
//函数说明:是把BCD码变成十进制码
//********************************************************************************//
uchar BCD(uchar time1)
{
        uchar D0,D1;
        D0=time1&0x0f;
        D1=(time1>>4)&0x0f;
        return(D1*10+D0);
} 
//*********************************************************************************
//调用方式:uchar countBCD(unsigned char time2)
//函数说明:是把十进制码变成BCD码,十进制不能超过100*/
//********************************************************************************//
uchar countBCD(unsigned char time2)
{
   	unsigned char D0,D1,D;
	D1=time2/10;		//十位
	D0=time2%10;		//个位
	D=D1<<4;		//注:不能用D=D1<<4+D0;为什么不清楚
	D=D+D0;
	return(D);
}
//-------------------------------------------------------------------------------------
//调用方式:void Read8563(uchar *time)
//函数说明:把从8563读取的时间放到time数组里面,返回给实参
//时间    :2003.6.25
//-------------------------------------------------------------------------------------
void Read8563(uchar *time)
{
	uchar data_bak1[7];
	SetPCF8563(0x00,0x00);
	data_bak1[0]=GetPCF8563(0x02);           //秒  
	data_bak1[0]=data_bak1[0]&0x7f;		
        *time=BCD(data_bak1[0]); 
               
	data_bak1[1]=GetPCF8563(0x03);		//分
	data_bak1[1]=data_bak1[1]&0x7f;
        *(time+1)=BCD(data_bak1[1]);	
        
	data_bak1[2]=GetPCF8563(0x04);		//时
	data_bak1[2]=data_bak1[2]&0x3f;
        *(time+2)=BCD(data_bak1[2]);
        
	data_bak1[3]=GetPCF8563(0x05);		//日
	data_bak1[3]=data_bak1[3]&0x3f;
        *(time+3)=BCD(data_bak1[3]);
        
	data_bak1[4]=GetPCF8563(0x06);		//星期,可以先不读取
	data_bak1[4]=data_bak1[4]&0x07;		
        //if(data_bak1[4]==0) data_bak1[4]=7;		//可以不变
        *(time+4)=data_bak1[4];
        
	data_bak1[5]=GetPCF8563(0x07);		//月
	data_bak1[5] =data_bak1[5]&0x1f;
        *(time+5)=BCD(data_bak1[5]);
        
	data_bak1[6]=GetPCF8563(0x08);		//年	
        data_bak1[6]=*(data_bak1+6);
        *(time+6)=BCD(data_bak1[6]);
}
//-------------------------------------------------------------------------------------
//调用方式:void Display(uchar *data)
//函数说明:把data数组中的数据发到8576进行显示
//时间    :2003.6.25
//-------------------------------------------------------------------------------------
void Display(uchar *data)
{
	uint SubAdd=0xe080;
	uchar i;
	//液晶清屏命令
        unsigned char cls[2]={0xd0,0x70};
        //清除液晶屏幕
	ISendStr256(0x70,SubAdd,cls,2);
	for(i=0;i<0x5f;i++)
	{
	ISendStr256(0x70,SubAdd,cls,2);
	_NOP();
	}
	//液晶显示
	ISendStr256(0x70,SubAdd,data,20);
	for(i=0;i<0x5f;i++)
	{
	ISendStr256(0x70,SubAdd,data,20);
	_NOP();
	}
}
//-------------------------------------------------------------------------------------
//调用方式:void Dispdata(uchar *data)
//函数说明:把data数组中的数据发到8576进行显示,不清除屏幕
//时间    :2003.7.2
//-------------------------------------------------------------------------------------
void Dispdata(uchar *data)
{
	uint SubAdd=0xe080;
	uchar i;
	//液晶显示
	ISendStr256(0x70,SubAdd,data,20);
	for(i=0;i<0x10;i++)
	{
	ISendStr256(0x70,SubAdd,data,20);
	_NOP();
	}
}
//-------------------------------------------------------------------------------------
//调用方式:void Cls(void)
//函数说明:清除屏幕
//时间    :2003.7.2
//-------------------------------------------------------------------------------------
void Cls(void)
{
	uint SubAdd=0xe080;
	uchar i;
	//液晶清屏命令
        unsigned char cls[2]={0xd0,0x70};
        //清除液晶屏幕
	ISendStr256(0x70,SubAdd,cls,2);
	for(i=0;i<0x5f;i++)
	{
	ISendStr256(0x70,SubAdd,cls,2);
	_NOP();
	}
}
//-------------------------------------------------------------------------------------
//调用方式:void DispOff(ucahr flag)
//函数说明:显示E9033OFF函数清除屏幕
//时间    :2003.7.5
//-------------------------------------------------------------------------------------
	
void DispOff(uchar flag)
{
	uchar i;
	uchar dispdata[20]={0xd8,0x70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//显示的数据
	uchar lcd[19]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	
	switch(flag)
	{
		case 1:
			/*lcd[13]=0xf8;			//E
			lcd[14]=0xbe;			//9	
			lcd[15]=0xde;			//0
			lcd[16]=0x3e;			//3
			lcd[4]=0xe3;			//3
			
			lcd[13]=0xf8;	*/		//E
			lcd[13]=0xbe;			//9	101111110
			lcd[14]=0xde;			//0
			lcd[15]=0x3e;			//3
			lcd[16]=0x3e;			//3
			lcd[4]=0x00;

		break;	
		case 2:
		       lcd[13]=0xbc;                    //10111100 S	
		       lcd[14]=0xd0;                    //11010000 L 
		       lcd[15]=0xea;                    //11101010 P
		       lcd[16]=0xed;                    //11101101 O
			//这里是用来显示电台关闭的lcd[]
		break;
	}
	lcd[3]=0xed;			//O
	lcd[1]=0x8e;			//F
	lcd[18]=0xe8;			//F
	for(i=1;i<=18;i++)
	    dispdata[i+1]=lcd[i];
	
	Dispdata(dispdata);			
	for(i=0;i<0xff;i++);	for(i=0;i<0xff;i++);	for(i=0;i<0xff;i++);
}

⌨️ 快捷键说明

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