:
原以为用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;
}
此帖出自
小平头技术问答
#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;
}
#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);
}
一周热门 更多>