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

📄 m430iicbus.c

📁 基于MAX1968的TEC控制程序
💻 C
字号:
//模拟IIC,采用P22,23口
//描述:MSP430模拟IIC驱动程序

//编译环境:IAR EW430 V3.42A
//  ACLK = LFXT1 = 32768Hz, MCLK = SMCLK = default DCO = 32 x ACLK = 1048576Hz
//  //* An external watch crystal between XIN & XOUT is required for ACLK *//	
#include<msp430x44x.h>
#include "cry1602.h"                      //包含液晶操作函数
//******************************************************************************
//-----------------------MAX5812专用变量定义------------------------------------
#define	MAX5812_WRITE	0xa8          //1010100 0           写地址
#define	MAX5812_READ 	0xa9          //1010100 1(R/W/)     读地址
#define MAX5812_Wakeup  0x40          //01000000           唤醒命令字

//#define  NUM  4 	                  //	接收和发送缓存区的深度
//unsigned char idata receivebuf[NUM];    // 数据接收缓冲区
//bit   bdata SystemError;                // 从机错误标志位
//------------------------------------------------------------------------------
//SDA 数据线定义------------->P2.3
#define SDAOUT P2DIR |= BIT3
#define SDAIN  P2DIR &= ~BIT3
#define SDA1   P2OUT |= BIT3
#define SDA0   P2OUT &= ~BIT3
//SCL 时钟线定义------------->P2.2
#define SCLOUT P2DIR |= BIT2
#define SCL1   P2OUT |= BIT2
#define SCL0   P2OUT &= ~BIT2

#define SDA_STATE P2IN & BIT3   //读入SDA状态

//******************************************************************************
#define SDA_MOV_BIT 1           //SDA 数据调整移位

//从器件接收方的应答返回标志
#define OK 0x01                 //表示从器件有应答
#define NO 0x00                 //表示从器件无应答  

//IIC总线操作成失标志
#define error 0x01              //错误
#define right 0x00              //正确

//******************************************************************************
//小延时
nop_()
{_NOP();_NOP();}

SomeNOP()
 {nop_();nop_();nop_();nop_();}
//******************************************************************************
// 函数名称: I2CStart()
// 函数功能: 启动I2C总线子程序
//起始信号
void I2CStart(void)     //时钟保持高,数据线从高到低一次跳变,I2C通信开始
 {
 _DINT();               //关总中断;
 SCLOUT;                //SCL口设为输出-------后加
 SDAOUT;                //SDA口设为输出 
 SDA1;                   
 //SCLOUT;                //SCL口设为输出 
 SCL1;
 SomeNOP(); SomeNOP();            //INI
 SDA0;                   
 SomeNOP(); SomeNOP();           //START
 SCL0;         
 }
//******************************************************************************
// 函数名称: I2CStop()
// 函数功能: 停止I2C总线数据传送子程序
//结束信号
void I2CStop(void)        //时钟保持高,数据线从低到高一次跳变,I2C通信停止
 {
  SCL0;   
  SDA0;                   
  SomeNOP();              //INI
  SCL1;                                  
  SomeNOP(); 
  SDA1;                  //STOP
  _EINT();               //EA=1;
 }
//******************************************************************************
// 函数名称: WaitAck()
// 函数功能: 从机发送应答位子程序,等待从器件接收方的应答
unsigned char WaitAck(void)
 {
 unsigned char errtime=255;      //因故障接收方无ACK,超时值为255。
 SDA1;                  
 SomeNOP();
 SCL1;
 SomeNOP();
 SDAIN;                 //SDA口设为输入
 while(SDA_STATE)       //SDA出现为0时,则为有应答
  { errtime--; 
   if (!errtime)        //errtime是否为0
    {I2CStop();        
     return NO;}        //返回为0(失败)
  }
 SDAOUT;                //SDA口设为输出 
 SCL0; 
 return OK;             //返回为1(成功)
 }
//******************************************************************************
//主器件为接收方,从器件为发送方时,单片机发出应答信号
//MCU Send to IC
void SendAck(void)
 {
 SDA0;                 
 SomeNOP();
 SCL1;                 
 SomeNOP();
 SCL0;         
 }
//******************************************************************************
//主器件为接收方,从器件为发送方时,非应答信号
void SendNotAck(void)
 {
 SDA1;  
 SomeNOP();
 SCL1;                   
 SomeNOP();
 SCL0; 
 }
//******************************************************************************
// 函数名称: I2CSendByte
// 入口参数: ch
// 函数功能: 发送一个字节
 void I2CSendByte(unsigned char ch)
 {
  unsigned char i=8;
  while (i--)
  {
   SCL0;                //SCL=0;
   nop_();
   if(ch&0x80)
    SDA1;               //使SDA为1位
   else
    SDA0;               //使SDA为0位
   //-----------------------------------------SDA线上的数据变化应在SCL为低时进行
   ch<<=1;              //先发送一个字节的高位,然后发送低位
   SomeNOP();
   SCL1;                //SCL为高时,数据有效
   SomeNOP();
   }
  SCL0;         
 }
//******************************************************************************
// 函数名称: I2CreceiveByte
// 返回接收的数据
// 函数功能: 接收一字节子程序
unsigned char I2CReceiveByte(void)
 {
 unsigned char i=8;   //接收8位
 unsigned char ddata,timp;
 ddata=0;
 SDA1;                  
 SDAIN;               //SDA口设为输入
 while (i--)
 {
  ddata<<=1;           //将ddata位向高位移,于让位0
  SCL0;
  SomeNOP();
  SCL1;
  SomeNOP();
  
  timp = SDA_STATE;     //读入SDA,后加
  timp>>=SDA_MOV_BIT;   //将timp的SDA位数据移到位0
  ddata|=timp;          //将timp的SDA位数据移到ddata位0 
 }
 SCL0;                  //SCL=0;
 SDAOUT;                //(附加)SDA口设回为输出
 return  ddata;
 }
//******************************************************************************
//正常操作时返回位值为0,有故障时返回位值为1.
//unsigned char *DataBuff数据缓冲区指针,char ByteQuantity字节数量,
//unsigned int Address IC片内地址,
//unsigned char ControlByte芯片控制字节--------------->IC地址/读写位,


/*unsigned char IIC(unsigned char *DataBuff,char ByteQuantity,unsigned int Address,
	    unsigned char ControlByte)
{
 unsigned char errorflag=error;	//错误标志位,1为错误,0为正确
 unsigned char i;	        //i为允许本次操作的最大次数
  i=1;
 SCLOUT;                        //时钟口长设为输出
 while(i--)
 { 
   I2CStart();                                             //i2c start>>>>>>>>>>
   I2CSendByte(ControlByte&0xfe);//指定芯片,此次必定为写
   if(!WaitAck())	        //涵数返回一个1为成功
     continue;	                //结束写操作,并i-1后,再来一次
   I2CSendByte((unsigned char)Address);	//发送片内地址
   if(!WaitAck())		//数返回一个1为成功    				
     continue;		        //结束写操作,并i-1后,再来一次	
   
                                                         //------------------------------已经选定好IC
   if(!(ControlByte&0x01))      //本次操作是读还是写
      {                         //写操作
	errorflag=right;	//清错误标志位为0
	while(ByteQuantity--)   //操作j个数字节
          {
            I2CSendByte(*DataBuff++);//发送        
	    if(WaitAck())           //涵数返回一个1为成功,涵数返回一个0为失败
              continue;	            //成功,下一个数据循环(跳while)
	    errorflag=error;	    //不应答,失败了. errorflag=1
	    break;	            //退出写操作
	  }
	if(errorflag==error) //经过写完后,如果最后errorflag标志为1,则表示有错误
           continue;	            //结束写操作,并i-1后,再来一次
	break;	                    //写操作完成
      }  
   else 				//则为读操作
     {  I2CStart();			//开始       
        I2CSendByte(ControlByte);
        if(!WaitAck())	                //涵数返回一个1为成功
        {continue;}	                //结束此操作,并i-1后,再来一次
	while(--ByteQuantity)           //读入ByteQuantity个数字节
	      {*DataBuff++=I2CReceiveByte();//连续读入ByteQuantity个数据
              SendAck();}	        //主机向从机发出应答,表示主机已接收	 	
        *DataBuff=I2CReceiveByte();     //读入最后个数据
	SendNotAck();                   //最后发出不应答信号(位),表示主机不再读了.
	errorflag=right;                //向错误标志位写0(right),表示读数据正确.
	break;}                         //读操作完成
     }
 I2CStop();                             //停止,结束IIC总线
 return(errorflag);                     //返回操作成败标志
}
*/
//******************************************************************************
//------------------------------------------------------------------------------
// 函数名称: check_ACK
// 函数功能: 主机应答位检查子程序,迫使数据传输过程结束
//------------------------------------------------------------------------------
/*void check_ACK(void)
{ 
	SDA1;      // 将p1.0设置成输入,必须先向端口写1
	SCL1;
	F0 = 0;
	if(SDA == 1)    // 若SDA=1表明非应答,置位非应答标志F0
		F0 = 1;
	SCL0;
}
*/
//--------------------------------MAX5812唤醒程序-------------------------------
void DAC_MAX5812_Wakeup(void)
{    
	unsigned int i;
        for(i=0;i<3;i++)                   //这里最多可以尝试唤醒3次
        {
          I2CStart();                       // 启动I2C
	  I2CSendByte(MAX5812_WRITE);       // 发送max5812写地址位
          if(WaitAck())                     //涵数返回一个1为成功,涵数返回一个0为失败,成功则发送唤醒命令字,否则什么也不做
         {
          I2CSendByte(MAX5812_Wakeup);      //唤醒MAX5812
          if(WaitAck())
          {
            I2CStop();                      //唤醒成功,则推出总线操作
            i=4;                            //如果成功,则i幅值大于3,则直接退出循环
            //errorflag=right;	            //清错误标志位为0
            DispNChar(0,1,15,"MAX5812 Success");       //显示提示文字
            SomeNOP();
            SomeNOP();
            SomeNOP();
            SomeNOP();
          }
       
         }
         else
           DispNChar(0,1,15,"DAC 5812 Faile.");       //显示提示文字
        }
        Delay400ms();                                 //延迟一小段时间,以便于看清楚初始化的情况
}
//------------------------------MAX5812输出电压---------------------------------
//函数名称: DAC_MAX5812
// 入口参数: slave_add从机地址,n要发送的数据个数
// 函数功能: 发送n位数据子程序
//Slave Address Byte Definition S|A6|A5|A4|A3|A2|A1|A0|R/W!
//Command Byte Definiton        C3|C2|C1|C0|D11|D10|D9|D8
//操作顺序:开始-》设备地址-》ACK-》命令字-》ACK-》数据-》停止

void DAC_MAX5812(unsigned char controlbyte,unsigned char wdata_high,unsigned char wdata_low)
{    
        //unsigned char errorflag;         	//错误标志位,1为错误,0为正确
        //unsigned char i;	                //i为允许本次操作的最大次数
        //i=1;
        SCLOUT;                                 //时钟口长设为输出
	unsigned char i;
        i=1;
        //while(i--)
        while(i)
        {
          I2CStart();                            // 启动I2C
          I2CSendByte(MAX5812_WRITE);            // 发送max5812写地址位
          if(WaitAck())                          //涵数返回一个1为成功,涵数返回一个0为失败
          {
            I2CSendByte(controlbyte|wdata_high); //发送命令字+高字节数据,controlbyte=1100 0000=0xc0,数据同步更新模式
            if(WaitAck())                        //涵数返回一个1为成功,涵数返回一个0为失败
            {
              I2CSendByte(wdata_low);            //发送低字节数据
              if(WaitAck())                      //涵数返回一个1为成功,涵数返回一个0为失败
              {
                 I2CStop();
                 //i=0;                          //退出循环操作
                 //errorflag=right;	         //如果成功了,清错误标志位为0
                 SomeNOP();
                 SomeNOP();
                 SomeNOP();
                 SomeNOP();
                 i=0;                            // 全部操作完成,停止I2C总线的操作,退出循环!!!              
              }
              else
              {
                //;
                //errorflag=error;	         //不应答,失败了. errorflag=1;
              }
              
            }
            
          }
       }
}

⌨️ 快捷键说明

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