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

📄 scm2481_iic.txt

📁 单片机24系列实现主发主收
💻 TXT
字号:
/********************************Copyright (c)**********************************
**                           
** 
*******************************************************************************/

/*******************************************************************************
**------------------------------单片机2481 IIC通信------------------------------
** 文件名:			main.c
** 最后修改时间:	
** 最后修改版本:	
** 版本改进:    
**------------------------------------------------------------------------------
** 创建者:		
** 建立时间:		2007-11-26
** 版 本:		1.0
** Descriptions:	单片机2481同单片机2012、TMS320VC5509A(DSP)通信 
*******************************************************************************/

/*******************************************************************************
** 功    能  :使用IIC模块同5509A通信信令,以及从单片机2012获取时间信息。
** 说    明  :通信波特率100kbps,简单累加校验
** 全局变量  :IIC_flag_master_receive;    IIC_flag_master_send;
**             IIC_flag_receive_succeed;   Flag_ReReceive;
**             IIC_slave;                  Rx_Num ;
**             data_Tx[];                  data_Rx[];			 
** 中    断  : USCIAB0TX_ISR();           USCIAB0RX_ISR();
**             IIC_ISR();
** 			
*******************************************************************************/

/*相关包含文件*/
#include "msp430x24x1.h"

/*全局变量*/
int IIC_flag_master_receive = 0; //请求主接受单片机2012时间信息标志位
int IIC_flag_master_send = 0;   //请求主发送数据给DSP标志位
int IIC_slave = 1;              //工作模式(1:从模式 ;0:主模式)
int IIC_flag_receive_succeed = 0; //接收成功标志位(替代Flag_received = 0)
int Flag_ReReceive;
//int Check_Sum,IIC_Tx_Num = 5;
//int i = 1,w(用delay替代);
volatile int Rx_Num = 0;  //接收数据计数
volatile int IIC_Tx_Num = 5; //发送个数

unsigned char data_Tx[9] =              // 发送数组
{
  0x11,
  0x22,
  0x33,
  0x44,
  0xaa
};

unsigned char data_Rx[7] =                        //接收数组
{
  0x00,
  0x00,
  0x00,
  0x00,
  0x00,
  0x00
};


/*
********************************************************************************
** 函数名称 :def_slave()
** 作者:     
** 修改时间 :2008-11-26
** 函数功能 :寄存器设置,使2481工作在从模式
** 调试说明 :无
** 入口参数 :无
** 出口参数 :无
** 版本改进:  无   
**中断情况:  无
********************************************************************************
*/
void def_slave( void )                                                    
{ 
  UCB0CTL1 |= UCSWRST;                                     // I2C设置使能
  UCB0CTL0 = UCMODE_3 + UCSYNC;                            // I2C主模式,工作在同步模式
  UCB0I2COA = 0x55;                                        // 主地址0x55h
  UCB0CTL1 &= ~UCSWRST;                                    // 清I2C设置使能位
  UCB0I2CIE |= UCSTPIE + UCSTTIE;                          // 开开始和结束中断使能
  IE2 |= UCB0RXIE+UCB0TXIE;                                // 接收和发送中断使能
  Rx_Num = 0;
}


/*
********************************************************************************
** 函数名称 :def_master()
** 作者:    
** 修改时间 :2008-11-26
** 函数功能 :寄存器设置,使2481工作在主模式
** 调试说明 :无
** 入口参数 :无
** 出口参数 :无
** 版本改进:  无   
**中断情况:  无
********************************************************************************
*/
void def_master( void )
{
  UCB0CTL1 |= UCSWRST;                      // Enable SW reset
  UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
  UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
  UCB0BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
  UCB0BR1 = 0;
  if( IIC_flag_master_send == 1)
    UCB0I2CSA = 0x20;                         // DSP地址:0x20h
  else
    UCB0I2CSA = 0x048;                         // 单片机2012地址:0x48h 
  UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
  IE2 |= UCB0TXIE+UCB0RXIE;                          // Enable TX and RX interrupt
}


/*
********************************************************************************
** 函数名称 :Master_Tx_IIC_ISR()
** 作者:     
** 修改时间 :2008-11-26
** 函数功能 :主发送数据给DSP并主接收DSP的校验数据,判断通信是否成功。
** 调试说明 :无
** 入口参数 :无
** 出口参数 :无
** 版本改进:  无   
**中断情况:  无
********************************************************************************
*/
void Master_Tx_IIC_ISR(void)                 
{
  
  if( IIC_Tx_Num > 0 ){                               // 还有多于一个数据等待发送?
    UCB0TXBUF = data_Tx[5 - IIC_Tx_Num];                    // 发送数据
    IIC_Tx_Num--;                            
  }
  else{
    if( IIC_Tx_Num == 0){
      UCB0TXBUF = data_Tx[5-IIC_Tx_Num];              // 发最后一个数据
      IIC_Tx_Num = -1;
      UCB0CTL1 &= ~UCTR;                    // 将主机设为接收模式
      UCB0CTL1 |= UCTXSTT;                 // 发送起始位  
      IFG2 &= ~UCB0TXIFG;                  // 清发送标志位
      Rx_Num = 2;                            //接收数据个数
    }
    else{ 
      Rx_Num--;
      if( Rx_Num ){
        data_Tx[5] = UCB0RXBUF;         // 将数据从接收移位寄存器存放到存储数组 
        UCB0CTL1 |= UCTXSTP;
      }
      else{
        data_Tx[5] = UCB0RXBUF; 
        if( data_Tx[5] == data_Tx[4] ){        //数据正确?
          IIC_flag_master_send = 0;
          P1IE &= 0xFE;           //关P1.0中断
        }
      }
    }          
  }      
}


/*
********************************************************************************
** 函数名称 :Slave_Rx_IIC_ISR()
** 作者:     
** 修改时间 :2008-11-26
** 函数功能 :从接收DSP信令和校验数据,判断接收数据正确性,然后从发送数据给DSP
** 调试说明 :无
** 入口参数 :无
** 出口参数 :无
** 版本改进:  无   
**中断情况:  无
********************************************************************************
*/
void Slave_Rx_IIC_ISR( void )       
{
  if( IFG2 & UCB0RXIFG ){
    data_Rx[Rx_Num++] = UCB0RXBUF; 
    if( Rx_Num == 6 ){
      data_Rx[6] = ( data_Rx[4] + data_Rx[1] + data_Rx[2] + data_Rx[3] ) & ( 0xff );  // 计算校验和
      if( data_Rx[5] == data_Rx[6] ){   //数据正确?
         IIC_flag_receive_succeed = 1;
         Flag_ReReceive = 0;
         P1IE &= 0xFE;
      }
    }
    else  
      data_Rx[5] = 0xFF;
  }
  else if( IFG2 & UCB0TXIFG )    
    UCB0TXBUF = data_Rx[5];
    else;
}


/*
********************************************************************************
** 函数名称 :main()
** 作者:     
** 修改时间 :2008-11-26
** 函数功能 :实现单片机2481与单片机2012以及DSP之间的相互通信
** 调试说明 :在config.h中包含stdio.h
** 入口参数 :无
** 出口参数 :无
** 版本改进:  无   
**中断情况:  单片机2481需要从单片机2012接收时间信息或者发送数据给DSP,
              并且p1.0口接收到上升沿时,开IIC_ISR()中断。
********************************************************************************
*/
void main(void)
{ 
  static int pro_data = 0; //数据处理标志位(1:有数据待处理;0:无数据需处理)
  int delay = 0; //延时
  
  WDTCTL = WDTPW + WDTHOLD;
  P1IES = 0x01;    //中断触发沿:下降沿
  P3SEL |= 0x06;
  def_slave(); 
  
  pro_data = ( IIC_flag_master_send ) || ( IIC_flag_master_receive );
  if( pro_data )
  P1IE  = 0x01;   //中断使能 
  __bis_SR_register(GIE);        // 开全局中断
  
  /*接收2012数据校验*/
  for( delay = 0; delay++; delay <100 )  //延时
    {;}   
  if( Rx_Num == 4 ){
    data_Rx[5] = ( data_Rx[0] + data_Rx[1] + data_Rx[2] + data_Rx[3] ) & ( 0xff );  // 计算校验和
    if( data_Rx[5] == data_Rx[4] ){   //数据正确? 
      IIC_flag_receive_succeed = 1;
      Flag_ReReceive = 0;
      P1IE &= 0xFE;
    }
  }
  else  
    data_Rx[5] = 0x88;
 
  while(1);
}


/*
********************************************************************************
** 中断函数名称 : USCIAB0TX_ISR()
** 作者:	  
** 修改时间 :2008-11-26
** 函数功能 :主接收单片机2012数据或者主发送数据至DSP
** 入口参数 :无
** 出口参数 :无	
** 版本改进:  无  
** 中断情况: 单片机2481需要从单片机2012接收时间信息或者发送数据给DSP
**				
********************************************************************************
*/
#pragma vector = USCIAB0TX_VECTOR           //IIC中断
__interrupt void USCIAB0TX_ISR(void)
{
  if( IIC_slave == 1 ){
    int i = 1;
    if( i ){                        //置数一次
      i = 0;
      IIC_flag_receive_succeed = 0;
      Flag_ReReceive = 1;
      //P1IE |= 0x01;            //开P1.0中断,这个中断在调试时应该关掉,因为调试时不能保证几个器件之间的运行同步
    }
    Slave_Rx_IIC_ISR();
  }
  else if( IIC_flag_master_send == 1)
    Master_Tx_IIC_ISR();
    else if( IIC_flag_master_receive == 1 )
      data_Rx[Rx_Num++] = UCB0RXBUF;
      else ;
}

/*
********************************************************************************
** 函数名称 : USCIAB0RX_ISR()
** 作者:      
** 修改时间 :2008-11-26
** 函数功能 :清起始和结束标志位中
** 入口参数 :无
** 出口参数 :无	
** 版本改进:  无  
** 中断情况: 无
**				
********************************************************************************
*/
#pragma vector = USCIAB0RX_VECTOR              
__interrupt void USCIAB0RX_ISR(void)
{
  UCB0STAT &= ~( UCSTPIFG + UCSTTIFG );       // 清中断标志位
}                                          

/*
********************************************************************************
** 函数名称 : IIC_ISR()
** 作者:     
** 修改时间 :2008-11-26
** 函数功能 :主接收单片机2012数据或者主发送数据至DSP
** 入口参数 :无
** 出口参数 :无	
** 版本改进:  无   
** 中断情况: 单片机2481需要从单片机2012接收时间信息或者发送数据给DSP,
              并且p1.0口接收到上升沿。
**				
********************************************************************************
*/
#pragma vector = PORT1_VECTOR              
__interrupt void IIC_ISR(void)
{   
  P1IE  &= 0xFE;   //关中断 (调试用,程序中删除)
  P1IFG &= 0xFE;                          //清中断标志位
  if( IIC_flag_master_send == 1 ){  
    def_master();
    data_Tx[4] = ( data_Tx[0] + data_Tx[1] + data_Tx[2] + data_Tx[3] ) & ( 0xFF ); //计算校验和
    while ( UCB0CTL1 & UCTXSTP );             // Ensure stop condition got sent
      UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition 
  }
  else{
    int Cyc_Num = 5;  //循环接收次数
    Rx_Num = 0;
    def_master();
    while( Cyc_Num-- ){
      while( UCB0CTL1 & UCTXSTP );             // Ensure stop condition got sent
        UCB0CTL1 |= UCTXSTT;                    // I2C start condition
      while( UCB0CTL1 & UCTXSTT );             // Start condition sent?
          UCB0CTL1 |= UCTXSTP;                    // I2C stop condition
      __bis_SR_register( GIE );                //开全局中断,这是必须的
    }
  } 
}

⌨️ 快捷键说明

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