正式放弃调试msp430f169硬件I2C,如有大神,请赐个范例。

2019-03-24 10:06发布



        原以为用169的硬件I2C会把问题简单化,没想到调了两天没弄出来,始终不知道问题在哪里,鉴于本人能力有限,先暂时放弃调试硬件I2C电路,如果有那位大神,能给我个范例,必当感激不尽,TI官方的我自己有。
       我之前是用I2C来驱动ZLG7290键盘管理芯片,现在只能用模拟的了。。希望谁能给我历程。最后我也把我的程序贴上来,希望大家给我上上课,快到崩溃了。

程序如下:
/////////////////////////////////////////////MAIN/////////////////////////////////////////////////////////////////
#include<msp430x16x.h>
#include"C:Documents and SettingsAdministrator桌面I2C_TESThead_hI2C.h"
#include"C:Documents and SettingsAdministrator桌面系统配置头文件sys_msp430.h"
#include"C:Documents and SettingsAdministrator桌面I2C_TESThead_hzlg7290.h"
#include"C:Documents and SettingsAdministrator桌面msp430_12864驱动程序LCD_12864lcd_hlcd12864.h"


unsigned char testdata;
void main(void)
{
  clock_set();
  wdt_set();
  LCD_port_set();
  Ini_Lcd();
  Display_String(0,2,"testing 坑啊");

  Set_Cursor(1,0);

   I2C_Init(ZLG7290_I2C_ADDR) ;
  zlg7290_init();
  _EINT();



//////////////////////////////////////////////I2C.H/////////////////////////////////////////////////////////////////

#include<msp430x16x.h>
#include"C:Documents and SettingsAdministrator桌面I2C_TESThead_hI2C.h"

//PtrTransmit用于发送计数,I2CBufferArray为发送缓存,I2CBuffer为输入缓存
int PtrTransmit;
volatile unsigned char I2CBufferArray[10];
volatile unsigned char I2CBuffer;

/*I2C初始化,slaveAddress:从机地址,I2C_SCL频率:100KHz*/
void I2C_Init(unsigned char slaveAddress)
{
  I2C_PORT_SEL |= SDA_PIN + SCL_PIN;        //设置引脚,用作USART接口
  I2C_PORT_DIR &= ~(SDA_PIN + SCL_PIN);

  U0CTL |= I2C+SYNC;                                                                                                      //USART0配置为I2C模式
  U0CTL &= ~I2CEN;                          //配置I2C前先关闭I2C控制器
                                            //这里采用默认配置,7位地址,无DMA,无反馈
  I2CTCTL = I2CTRX+I2CSSEL_2;               //byte模式,repeat模式,I2C时钟源为SMCLK
  I2CSA = slaveAddress;                     //设置从设备地址

  I2COA = 0xAA;                             //本机地址,这个目前用不到

  I2CPSC = 0x01;                            //I2C时钟 = SMCLK/2 = 2MHz
  I2CSCLH = 0x18;                           //SCL高电平周期 = 20*I2C clock
  I2CSCLL = 0x18;                           //SCL低电平周期  = 20*I2C clock
                                             //I2C_SCL频率 = 2MHz/20 =100KHz
  U0CTL |= I2CEN;                           //开启I2C控制器
  if (I2CDCTL&I2CBUSY)                      //检查I2C模块是否空闲,这里应该是检测时钟正确性吧?
  {                                         
    I2C_PORT_SEL &= ~SCL_PIN;               //将SCL设置为IO输出模式并手动置0
    I2C_PORT_OUT &= ~SCL_PIN;               
    I2C_PORT_DIR |= SCL_PIN;               
    I2C_PORT_SEL |= SDA_PIN + SCL_PIN;      //重新设置引脚为I2C模式
  };
}


/*I2C发送模式,准备向从设备写入数据*/
void I2C_WriteMod(void)
{
  U0CTL |= MST;                             //主机方式,每次发送和接受数据时需配置
  I2CTCTL |= I2CTRX;                        //发送模式
  I2CIFG &= ~TXRDYIFG;                      //先清标志位,不知道是不是和UART模式一样防跑飞
  I2CIE = TXRDYIE;                          //开启I2C发送中断
}

/*I2C接收模式,准备从从设备读取数据*/
void I2C_ReadMod(void)
{

  I2CTCTL &= ~I2CTRX;                       //接收模式
   U0CTL |= MST;                             
  I2CIFG &= ~RXRDYIFG;                      //先清标志位
  I2CIE &= ~TXRDYIE;                        //关闭I2C发送中断,开启接收中断
  I2CIE |= RXRDYIE;                        
}

/*检测I2C Acknowledge*/
void I2C_AckPolling(void)
{
  while (I2CDCTL&I2CBUSY);                  // wait until I2C module has
                                            //   finished all operations
  U0CTL &= ~I2CEN;                          // clear I2CEN bit => necessary to
                                            //   re-configure I2C module
  I2CTCTL |= I2CRM;                         // transmission is software
                                            //   controlled
  U0CTL |= I2CEN;                           // enable I2C module
  I2CIFG = NACKIFG;                         // set NACKIFG
  while (NACKIFG & I2CIFG)
  {
    I2CIFG=0x00;                            // clear I2C interrupt flags
    U0CTL |= MST;                           // define Master Mode
    I2CTCTL |= I2CTRX;                      // I2CTRX=1 => Transmit Mode
                                            //   (R/W bit = 0)
    I2CTCTL |= I2CSTT;                      // start condition is generated
    while (I2CTCTL&I2CSTT);                 // wait till I2CSTT bit was cleared
    I2CTCTL |= I2CSTP;                      // stop condition is generated after
                                            //   slave address was sent => I2C
                                            //   communication is started
    while (I2CDCTL&I2CBUSY);                // wait till stop bit is reset
    __delay_cycles(500);                    // Software delay
  }
  U0CTL &= ~I2CEN;                          // clear I2CEN bit => necessary to
                                            //   re-configure I2C module
  I2CTCTL &= ~I2CRM;                        // transmission is by the I2C module
  U0CTL |= I2CEN;                           // enable I2C module
}



/*I2C中断函数,可以针对相应状态添加代码*/
#pragma vector=USART0TX_VECTOR
__interrupt void ISR_I2C(void)
{

  switch (__even_in_range(I2CIV, I2CIV_STT))
  {
    case I2CIV_AL:      //仲裁丢失 (ALIFG)
      break;
    case I2CIV_NACK:    //无应答,No acknowledge (NACKIFG)
      break;
    case I2CIV_OA:      //I2C地址为本机地址 (OAIFG)
      break;
    case I2CIV_ARDY:    //访问就绪 (ARDYIFG)
      break;
    case I2CIV_RXRDY:   //接收就绪 (RXRDYIFG)
      I2CBuffer = I2CDRB;                   //读取数据,跳出休眠
    _BIS_SR_IRQ(LPM0_bits);
      break;
    case I2CIV_TXRDY:   //发送就绪 (TXRDYIFG)

      //while(!(I2CDCTL & I2CTXUDF));         //等待上一个数据发送完毕
       I2CDRB = I2CBufferArray[PtrTransmit];
       //发送Buff中的数据
      PtrTransmit--;
      if (PtrTransmit < 0)                  //PtrTransmit为发送数据个数的自减计数器,减完表示发送结束
      {
        I2CIE &= ~TXRDYIE;                  //最后清标志位
        I2CIFG &= ~TXRDYIFG;
       _BIS_SR_IRQ(LPM0_bits);
      }

      break;
    case I2CIV_GC:      //通用调用 (GCIFG)
      break;
    case I2CIV_STT:     //Start检测,用于从机 (STTIFG)
      break;
  }
}

//////////////////////////////////////////////7290.H/////////////////////////////////////////////////////////////////


#ifndef _ZLG7290_H
#define _ZLG7290_H
/*************************************I/O口定义********************************/

//ZLG7290中断请求信号的引脚定义
#define ZLG7290INT_DIR            P2DIR
#define ZLG7290_INT               BIT0
#define ZLG7290INT_IES            P2IES = ZLG7290_INT
#define ZLG7290INT_IE             P2IE = ZLG7290_INT



/*************************************寄存器地址声明***************************/

//定义ZLG7290在I2C总线协议中的从机地址
#define ZLG7290_I2C_ADDR                0X70
//定义ZLG7290内部寄存器地址(子地址)
#define ZLG7290_SystemReg                0x00                //系统寄存器
#define ZLG7290_Key                        0x01                //键值寄存器
#define ZLG7290_RepeatCnt                0x02                //连击次数寄存器
#define ZLG7290_FunctionKey                0x03                //功能键寄存器
#define ZLG7290_CmdBuf                        0x07                //命令缓冲区起始地址
#define ZLG7290_CmdBuf0                        0x07                //命令缓冲区0
#define ZLG7290_CmdBuf1                        0x08                //命令缓冲区1
#define ZLG7290_FlashOnOff                0x0C                //闪烁控制寄存器
#define ZLG7290_ScanNum                        0x0D                //扫描位数寄存器
#define ZLG7290_DpRam                        0x10                //显示缓存起始地址
#define ZLG7290_DpRam0                        0x10                //显示缓存0
#define ZLG7290_DpRam1                        0x11                //显示缓存1
#define ZLG7290_DpRam2                        0x12                //显示缓存2
#define ZLG7290_DpRam3                        0x13                //显示缓存3
#define ZLG7290_DpRam4                        0x14                //显示缓存4
#define ZLG7290_DpRam5                        0x15                //显示缓存5
#define ZLG7290_DpRam6                        0x16                //显示缓存6
#define ZLG7290_DpRam7                        0x17                //显示缓存7

/******************************键盘定义****************************************/
#define key1  0x01
#define key2  0x02
#define key3  0x03
#define key4  0x04
#define key5  0x09
#define key6  0x0a
#define key7  0x0b
#define key8  0x0c
#define key9  0x11
#define key10 0x12
#define key11 0x13
#define key12 0x14
#define key13 0x19
#define key14 0x1a
#define key15 0x1b
#define key16 0x1c


extern int PtrTransmit;
extern volatile unsigned char I2CBufferArray[10];
extern volatile unsigned char I2CBuffer;


/*************************************函数声明*********************************/
void zlg7290_init(void);
unsigned char  zlg7290_Rstr(unsigned char DeviceAddr, unsigned char DataAddr);
unsigned char get_key(void);


#endif


#include<msp430x16x.h>
#include"C:Documents and SettingsAdministrator桌面I2C_TESThead_hI2C.h"
#include"C:Documents and SettingsAdministrator桌面I2C_TESThead_hzlg7290.h"
#include"C:Documents and SettingsAdministrator桌面msp430_12864驱动程序LCD_12864lcd_hlcd12864.h"

void zlg7290_init(void)
{
  ZLG7290INT_DIR;
  ZLG7290INT_IES;
  ZLG7290INT_IE ;
}


/*******************************************************************************
* 名称 :
* 功能
* 输入 :
* 输出 :
*******************************************************************************/
unsigned char  zlg7290_Rstr(unsigned char DeviceAddr, unsigned char DataAddr)
{
  unsigned char byte;
  while (I2CDCTL&I2CBUSY);         

  //I2CBufferArray[2] = DeviceAddr;
  I2CBufferArray[1] = DataAddr;
  I2CBufferArray[0] = DeviceAddr|1;
  PtrTransmit = 1;                        

  I2C_WriteMod();
  I2CNDAT = 3;                             

  I2CTCTL |= I2CSTT;                       

  _BIS_SR(LPM0_bits + GIE);   

  I2C_ReadMod();
  I2CNDAT = 1;                              // 1 byte should be received
  I2CTCTL |= I2CSTT;                        // start receiving
                                            // re-start condition
  _BIS_SR(LPM0_bits + GIE);
  byte= I2CBuffer;  
  I2CTCTL |= I2CSTP;                        //发送Stop结束接收
  while(I2CTCTL & I2CSTP);                  //等待Stop发送完毕
  return byte;            
}
/*******************************************************************************
* 名称 :
* 功能
* 输入 :
* 输出 :
*******************************************************************************/
unsigned char get_key(void)
{
  unsigned char temp;
  temp=zlg7290_Rstr(ZLG7290_I2C_ADDR, ZLG7290_Key);
  return temp;
} 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
默默沉默中
1楼-- · 2019-03-24 13:47
表示这个也很难调啊,感觉找写好的程序对比一下会好一点
18780176718
2楼-- · 2019-03-24 19:06
 精彩回答 2  元偷偷看……
Triton.zhang
3楼-- · 2019-03-24 22:40
#include "msp430g2553.h"
#include "i2c_master.h"
//=============================================================================
//=============================================================================
// I2C模块发送数据缓存
unsigned char g_I2cTxBuf[I2C_TXBUF_MAX_SIZE] = {0x36, 0x01,0x10,0x47,0x64,0x9b,0x06,0x07};

// I2C模块接收数据缓存
static unsigned char g_I2cRxBuf[I2C_RXBUF_MAX_SIZE] = {0,0,0,0,0,0,0,0,};


/*******************************************************************************
** Function : InitMstI2c                                                      **
** Parameter:                                                                 **
** Output   :                                                                 **
** Retutn   :                                                                 **
================================================================================
** Author   :                                                                 **
** Date     :                                                                 **
*******************************************************************************/
void InitMstI2c(unsigned char DevAddr)
{
    /*g_stI2cMachine.TxCnt = 0;
    g_stI2cMachine.RxCnt = 0;
    g_stI2cMachine.pTxBuf = g_I2cTxBuf;
    g_stI2cMachine.pRxBuf = g_I2cRxBuf;
  */
    P1SEL |= BIT6 + BIT7;                     // 分配P1.6 P1.7工作在USCI_B0的SDA和SCL模式
    P1SEL2|= BIT6 + BIT7;                     //
   
    UCB0CTL1 |= UCSWRST;                      // 配置I2C模块之前需要复位UCB0模块
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // 配置成7位主I2C模式,同步模式
    UCB0CTL1 = UCSSEL_2 + UCSWRST;            // 选择SMCLK时钟源
    UCB0BR0 = 10;                             // 设置I2C波特率fSCL = SMCLK/10 = 100kHz
    UCB0BR1 = 0;
   
    UCB0I2CSA = DevAddr;                      // 设置默认的I2C从地址
    UCB0CTL1 &= ~UCSWRST;                     // 清除复位标志位,恢复到运行模式
}

/*******************************************************************************
** Function : I2cMSendOneByte                                                 **
** Parameter:                                                                 **
** Output   :                                                                 **
** Retutn   :                                                                 **
================================================================================
** Author   :                                                                 **
** Date     :                                                                 **
*******************************************************************************/
signed short int I2cMSendOneByte(unsigned char Addr, unsigned char Val)
{
      unsigned short int TimeOut = 0;
      if (UCB0STAT & UCBBUSY)
      {
          return I2C_ERRO_BUSY;
      }
     
      TimeOut = I2C_TIME_OUT;
      while ((UCB0CTL1 & UCTXSTP) && (TimeOut--)); // 确保STOP
      if (!TimeOut)
      {
          return I2C_ERRO_TIMEOUT1;
      }
      P1OUT |= BIT4;
      P1OUT &= ~BIT4;
      
      // 设置I2C从设备地址,
      UCB0I2CSA = Addr;                 
      UCB0CTL1 |= UCTR + UCTXSTT;         // I2C模块为发送模式,启动START信号
      TimeOut = I2C_TIME_OUT;
      while ((!(IFG2 & UCB0TXIFG)) && (TimeOut--));
      if (!TimeOut)
      {
          return I2C_ERRO_TIMEOUT2;
      }
      P1OUT |= BIT4;
      P1OUT &= ~BIT4;
      UCB0TXBUF = Val;                 
            
      TimeOut = I2C_TIME_OUT;
      while ((!(IFG2 & UCB0TXIFG)) && (TimeOut--));
      if (!TimeOut)
      {
          return I2C_ERRO_TIMEOUT4;
      }
      P1OUT |= BIT4;
      P1OUT &= ~BIT4;
      
      // 清除I2C发送缓冲空的中断标志,发送 I2C STOP 信号
      IFG2 &= ~UCB0TXIFG;
      UCB0CTL1 |= UCTXSTP;             // 发送I2C STOP 信号
      TimeOut = I2C_TIME_OUT;
      while ((UCB0CTL1 & UCTXSTP) && (TimeOut--)); // 确保STOP
      if (!TimeOut)
      {
          return I2C_ERRO_TIMEOUT5;
      }
      P1OUT |= BIT4;
      P1OUT &= ~BIT4;
      
      return I2C_SUCCESSFUL;
}


/*******************************************************************************
** Function : I2cMSendBytes                                                   **
** Parameter:                                                                 **
** Output   :                                                                 **
** Retutn   :                                                                 **
================================================================================
** Author   :                                                                 **
** Date     :                                                                 **
*******************************************************************************/
signed short int I2cMSendBytes(unsigned char DevAddr, unsigned char *Data, unsigned char Numb)
{
      unsigned short int TimeOut = 0;
      unsigned char i = 0;
      
      if (UCB0STAT & UCBBUSY)
      {
          return I2C_ERRO_BUSY;
      }
     
      TimeOut = I2C_TIME_OUT;
      while ((UCB0CTL1 & UCTXSTP) && (TimeOut--)); // 确保STOP
      if (!TimeOut)
      {
          return I2C_ERRO_TIMEOUT1;
      }
      P1OUT |= BIT4;
      P1OUT &= ~BIT4;
      
      // 设置I2C从设备地址,
      UCB0I2CSA = DevAddr;                 
      UCB0CTL1 |= UCTR + UCTXSTT;         // I2C模块为发送模式,启动START信号
      TimeOut = I2C_TIME_OUT;
      while ((!(IFG2 & UCB0TXIFG)) && (TimeOut--));
      if (!TimeOut)
      {
          return I2C_ERRO_TIMEOUT2;
      }
      P1OUT |= BIT4;
      P1OUT &= ~BIT4;
      
      for (i=0;i<Numb;i++)
      {
          UCB0TXBUF = Data;                 
          TimeOut = I2C_TIME_OUT;
          while ((!(IFG2 & UCB0TXIFG)) && (TimeOut--));
          if (!TimeOut)
          {
              return I2C_ERRO_TIMEOUT4;
          }
          P1OUT |= BIT4;
          P1OUT &= ~BIT4;
      }
      
      // 清除I2C发送缓冲空的中断标志,发送 I2C STOP 信号
      IFG2 &= ~UCB0TXIFG;
      UCB0CTL1 |= UCTXSTP;             // 发送I2C STOP 信号
      TimeOut = I2C_TIME_OUT;
      while ((UCB0CTL1 & UCTXSTP) && (TimeOut--)); // 确保STOP
      if (!TimeOut)
      {
          return I2C_ERRO_TIMEOUT5;
      }
      P1OUT |= BIT4;
      P1OUT &= ~BIT4;
      
      return I2C_SUCCESSFUL;
}
Triton.zhang
4楼-- · 2019-03-25 01:51
#include "msp430g2553.h"
#include "i2c_master.h"

/*******************************************************************************
** Function : SetUCS                                                          **
** Parameter:                                                                 **
** Output   :                                                                 **
** Retutn   :                                                                 **
================================================================================
** Author   :                                                                 **
** Date     :                                                                 **
*******************************************************************************/
void SetUCS(void)
{
    BCSCTL1 = CALBC1_1MHZ;                          // 设置DCO为8Mhz
    DCOCTL = CALDCO_1MHZ;
    if ((CALBC1_1MHZ ==0xFF) && (CALDCO_1MHZ == 0xFF))
    {
        BCSCTL1 = 0x86;                          // 设置DCO为1Mhz
        DCOCTL = 0xDC;                                             
    }   
}

unsigned char SendFlag = 0;
/*******************************************************************************
** Function : main                                                            **
** Parameter:                                                                 **
** Output   :                                                                 **
** Retutn   :                                                                 **
================================================================================
** Author   :                                                                 **
** Date     :                                                                 **
************************************I2cMSendOneByte****************************/
void main(void)
{
    signed short int res;
   
   
    WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
    SetUCS();
    P1DIR |= BIT4;
    P1OUT &= ~BIT4;
   
      
    InitMstI2c(0x62);
   
    /*res =I2cMSendBytes(0x62,g_I2cTxBuf,3);
        if (res)
        {   
            InitMstI2c(0x62);
        }
      */  
        
    P1DIR &= ~BIT3;
    P1IFG &= ~BIT3;         // 开启同步信号的中断处理  
    P1IES &= ~BIT3;          // 设置下降沿触发中断
    P1IE |= BIT3;            // 使能同步管脚的中断
   
    _BIS_SR(GIE);            

   
    SendFlag = 0;

    while(1)
    {
      // WDTCTL = WDT_MRST_32;
      if(SendFlag)
      {
        _BIC_SR(GIE);            

        res =I2cMSendBytes(0x62,g_I2cTxBuf,6);
        if (res)
        {   
            InitMstI2c(0x62);
        }
        SendFlag = 0;
        _BIS_SR(GIE);            

      }
   
    }
}


/***************************************************************************************************
** Function Name : P2_IRQ                                                                         **
** Description   :                                                                                **
** Arguments     :                                                                                **
** Out Put       :                                                                                **
====================================================================================================
** Author        : Triton.Zhang@ti.com                                                            **
** Date          :                                                                                **
***************************************************************************************************/
#pragma vector = PORT1_VECTOR
__interrupt void P1_IRQ(void)
{
    if (P1IFG & BIT3)
    {
      SendFlag =1;
    }

    P1IFG &= ~(BIT3);
}
jiushiggg
5楼-- · 2019-03-25 06:36
 精彩回答 2  元偷偷看……

一周热门 更多>

相关问题

    相关文章