正式放弃调试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条回答
默默沉默中
2019-03-24 13:47
表示这个也很难调啊,感觉找写好的程序对比一下会好一点

一周热门 更多>

相关问题

    相关文章