请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
部件号:MSP430F5419A 主题中讨论的其他部件: BQ7.62万
您好,
我尝试使用应用报告中提供的代码- SLAA115,以便与EEPROM 24LC32AT通信。
问题是,当我尝试从EEPROM读取一些值时,它为所有寄存器提供255 (下图)。
EEPROM通过以下方式连接到UC:
我使用的代码如下:
主要c
#include <msp430f5419a.h>
#include <I2Croutings.h>
unsigned char read_val[10];
unsigned char write_val[10];
unsigned int address;
int main(void){
无符号int I;
WDTCTL = WDTPW + WDTHOLD;//停止看门狗计时器
InitI2C (0x50);//初始化I2C模块
而(1){
//用计数器值填充write_val数组
对于(i =0 ; i <= sizeof(write_val); I++){
write_val[i]= i;
}
地址= 0x0000;//将起始地址设置为0
//写入一个数据数组序列
eeprom_PageWrite (地址,write_val,sizeof(write_val));
//从EEPROM读取一系列数据
eeprom_SequentialRead (地址,读取val,大小of (读取val));
__DELAY周期(1万);
}
}
I2Croutings.c
#include "msp430f5419a.h"
#include "I2Croutings.h"
#define MAXPAGEWRITE 32
int PtrTransmit;
unsigned char I2CBufferArray[66];
unsigned char I2CBuffer;/*------------------
*///
说明:
// I2C模块的初始化
/*---------------------------------- */
void InitI2C (unsigned char eeprom_i2c_address)
{
I2C_PORT_DIR |= SDA_PIN + SCL_PIN;
I2C_PORT_SEL || SDA_PIN + SCL_PIN; //将I2C引脚分配给USI_B0
//建议的I2C模块初始化步骤,如用户指南中所示:
UCB2CTL1 |= UCSWRST; //启用软件重置
UCB2CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C主控,同步模式
UCB2CTL1 = UCSSEL_2 + UCTR + UCSSWRST; //使用SMCLK,TX模式,保持软件重置
UCB2BR0 = SCL_CLock_DIV; // fSCL = SMCLK/12 =~100kHz
UCB2BR1 = 0;
UCB2I2CSA = eeprom_i2c_address; //定义从属地址
//在本例中为从属地址
//定义的控制字节是
//发送到EEPROM。
//UCB2I2COA = 0x01A5; //自己的地址。
UCB2IE |= UCTXIE+UCRXIE;
UCB2CTL1 &=~UCSWRST; //清除软件重置,
如果(UCB2STAT和UCBBUSY)恢复操作 //测试总线是否为空闲
{ //否则手动时钟打开
//已生成
I2C_PORT_SEL &=~SCL_PIN; //为SCL选择端口功能
I2C_PORT_OUT &=~SCL_PIN; //
I2C_PORT_DIR || SCL_PIN; //驱动SCL过低
I2C_PORT_SEL || SDA_PIN + SCL_PIN; //为选择模块功能
//使用的I2C引脚
};
__enable_interrupit();
}/*------------------
*///
说明:
//初始化I2C模块以进行写入操作。
/*------------------ */
void I2CWriteInit (void)
{
UCB2CTL1 |= UCTR; // UCTR = 1 =>传输模式(R/W位= 0)
UCB2IFG &=~UCTXIFG;
UCB2IE &=~UCRXIE; //禁用接收就绪中断
UCB2IE|= UCTXIE; //启用传输就绪中断
}//*------------------
*///
说明:
//初始化I2C模块以进行读取操作。
/*------------------ */
void I2CReadInit(void)
{
UCB2CTL1 &=~UCTR; // UCTR = 0 =>接收模式(R/W位= 1)
UCB2IFG &=~UCRXIFG;
UCB2IE &=~UCTXIE; //禁用传输就绪中断
UCB2IE |= UCRXIE; //启用接收就绪中断
}/*----------------------------------
*///
说明:
//字节写入操作。
通过I2C总线与EEPROM //(2465)实现通信。 数据字节写入用户定义的地址。
/*------------------ */
void eeprom_ByteWrite (无符号int地址,无符号char数据)
{
无符号char ADR_HI;
无符号char ADR_lo;
while (UCB2STAT & UCBUSY); //等待I2C模块
//已完成所有操作。
ADR_HI =地址>> 8; //计算高字节
ADR_LO =地址和0xFF; //和地址
I2CBufferArray[2]的低字节= ADR_HI; //低字节地址。
I2CBufferArray[1]= ADR_LO; //高字节地址。
I2CBufferArray[0]=数据;
PtrTransmit = 2; //设置I2CBufferArray Pointer
I2CWriteInit();
UCB2CTL1 || UCTXSTT; //开始条件生成
//=> I2C通信已启动
//__bis_sr_register (LPM0_bits + GIE); //输入LPM0 w/中断
while (UCB2CTL1 & UCTXSTP); //确保已发送停止条件
}/*----------------------------------
*///
说明:
//页面写入操作。
通过I2C总线与EEPROM //(24xx65)实现通信。 数据字节写入用户定义的地址。
/*------------------ */
void eeprom_PageWrite (unsigned int StartAddress,unsigned char * Data,unsigned char size)
{
volatile unsigned int i =0;
volatile unsigned char counterI2cBuffer;
unsigned char ADR_hi;
unsigned char char_lo;adr
int currentAddress = StartAddress;
unsigned char currentSize = size;unsigned
bufferPtr =0;
unsigned moreDataRead =1;
期间(UCB2STAT和UCBUSY); //等待I2C模块
//已完成所有操作。
//执行,直到数据缓冲区中没有更多数据
,同时(moreDataToRead)
{
ADR_HI =当前地址>> 8; //计算高字节
ADR_LO =当前地址和0xFF; //和地址的低字节
//将数据降级为每次传输的64字节数据包
//保留当前startaddress的指针
IF (当前大小> MAXPAGEWRITE)
{
bufferPtr = bufferPtr + MAXPAGEWRITE;
CounterI2cBuffer = MAXPAGEWRITE -1;
PtrTransmit = MAXPAGEWRITE + 1; //设置I2CBufferArray指针
currentSize =当前大小- MAXPAGEWRITE;
currentAddress = currentAddress + MAXPAGEWRITE;
//获取起始地址
I2CBufferArray[MAXPAGEWRITE + 1]= ADR_HI;//高字节地址。
I2CBufferArray[MAXPAGEWRITE]= ADR_lo;//低字节地址
。}
否则
{
bufferPtr = bufferPtr +当前大小;
counterI2cBuffer =当前大小-1;
PtrTransmit =当前大小+1; //设置I2CBufferArray指针。
moreDataToRead = 0;
currentAddress = currentAddress + currentSize;
//获取起始地址
I2CBufferArray[currentSize + 1]= ADR_HI;//高字节地址。
I2CBufferArray[当前大小]= ADR_lo;//低字节地址
。}
//将数据复制到I2CBufferArray
无符号字符temp;
对于(i;i < bufferPtr;I++)
{
Temp =数据[I]; //必需或否则IAR抛出
//警告[Pa082]
I2CBufferArray[counterI2cBuffer]= temp;
CounterI2cBuffer--;
}
I2CWriteInit();
UCB2CTL1 || UCTXSTT; //开始条件生成
//=> I2C通信已启动
//__bis_sr_register (LPM0_bits + GIE); //输入带中断的LPM0
(UCB2CTL1和UCTXSTP); //确保停止条件已发送
eeprom_AckPolling(); //确保在EEPROM中写入数据
}}/*----------------------------------
*///
说明:
//当前地址读取操作。 从EEPROM读取数据。
使用来自EEPROM的当前//地址。
/*------------------ */
unsigned char eeprom_CurrentAddressRead (void)
{
while (UCB2STAT & UCBUSY); //等待I2C模块
//已完成所有操作
I2CReadInit();
UCB2CTL1 || UCTXSTT; // I2C启动条件
while (UCB2CTL1和UCTXSTT); //开始条件已发送?
UCB2CTL1 || UCTXSTP; // I2C停止条件
//__bis_sr_register (LPM0_bits + GIE); //输入LPM0 w/中断
while (UCB2CTL1 & UCTXSTP); //确保停止条件已发送
返回I2CBuffer;
}/*------------------
*///
说明:
//随机读取操作。 从EEPROM读取数据。 EEPROM
//地址是使用参数Address定义的。
/*------------------ */
unsigned char eeprom_RandomRead (unsigned int Address)
{
unsigned char ADR_hi;
unsigned char ADR_lo;
while (UCB2STAT & UCBUSY); //等待I2C模块
//已完成所有操作
ADR_HI =地址>> 8; //计算高字节
ADR_LO =地址和0xFF; //和地址
I2CBufferArray[1]= ADR_HI的低字节; //存储必须存储到
I2CBufferArray[0]= ADR_LO的单个字节; //在I2CBuffer中发送。
PtrTransmit = 1; //设置I2CBufferArray指针
//写入地址第一
I2CWriteInit();
UCB2CTL1 || UCTXSTT; //开始条件生成
//=> I2C通信已启动
//__bis_sr_register (LPM0_bits + GIE); //输入LPM0 w/中断
while (UCB2CTL1 & UCTXSTP); //确保停止条件已发送
//读取数据字节
I2CReadInit();
UCB2CTL1 |= UCTXSTT; // I2C启动条件
while (UCB2CTL1和UCTXSTT); //开始条件已发送?
UCB2CTL1 || UCTXSTP; // I2C停止条件
//__bis_sr_register (LPM0_bits + GIE); //输入LPM0 w/中断
while (UCB2CTL1 & UCTXSTP); //确保停止条件已发送
返回I2CBuffer;
}/*------------------
*///
说明:
//连续读取操作。 从作为
起点的参数地址以连续//形式从EEPROM读取数据。 指定
要//读取的大小并填充到数据缓冲区。
/*------------------ */
void eeprom_SequentialRead (无符号int地址,无符号char *数据,无符号int大小)
{
无符号char ADR_HI;
无符号charADR_lo;
无符号int counterSize;
while (UCB2STAT & UCBUSY); //等待I2C模块
//已完成所有操作
ADR_HI =地址>> 8; //计算高字节
ADR_LO =地址和0xFF; //和地址
I2CBufferArray[1]= ADR_HI的低字节; //存储必须存储到
I2CBufferArray[0]= ADR_LO的单个字节; //在I2CBuffer中发送。
PtrTransmit = 1; //设置I2CBufferArray指针
//写入地址第一
I2CWriteInit();
UCB2CTL1 || UCTXSTT; //开始条件生成
//=> I2C通信已启动
//__bis_sr_register (LPM0_bits + GIE); //输入LPM0 w/中断
while (UCB2CTL1 & UCTXSTP); //确保停止条件已发送
//读取数据字节
I2CReadInit();
UCB2CTL1 |= UCTXSTT; // I2C启动条件
while (UCB2CTL1和UCTXSTT); //开始条件已发送?
对于(尺寸= 0;尺寸<尺寸;尺寸+)
{
//__bis_sr_register (LPM0_bits + GIE); //输入带中断的LPM0
Data[CounterSize]= I2CBuffer;
}
UCB2CTL1 || UCTXSTP; // I2C停止条件
//__bis_sr_register (LPM0_bits + GIE); //输入LPM0 w/中断
while (UCB2CTL1 & UCTXSTP); //确保已发送停止条件
}/*----------------------------------
*///
说明:
//确认轮询。 如果正在
执行写入循环//,EEPROM将不会确认。 它可用于确定何时完成写入周期。
/*------------------ */
void eeprom_AckPolling(void){
while (UCB2STAT & UCBUSY); //等待I2C模块
//已完成所有操作
,请执行
{
UCB2STAT = 0x00; //清除I2C中断标志
UCB2CTL1 |= UCTR; // I2CTRX=1 =>传输模式(R/W位=0)
UCB2CTL1 &=~UCTXSTT;
UCB2CTL1 || UCTXSTT; //生成启动条件
While (UCB2CTL1和UCTXSTT) //等待I2CSTT位被清除
{
IF (!(UCNACKIFG和UCB2STAT)) //如果收到ACK,则中断
中断;
}
UCB2CTL1 || UCTXSTP; //停止条件在之后生成
//已发送从属地址=>开始I2C通信
同时(UCB2CTL1和UCTXSTP); //等待停止位重置
__DELAY周期(500); //软件延迟
时间} While (UCNACKIFG & UCB2STAT);
}//
ISR
#pragma vector = USCI_B2_Vector
__interrupt void USI_B2_B2(void)
{
IF (UCTXIFG & UCB2IFG)
{
UCB2TXBUF = I2CBufferArray[PtrTransmit];//加载TX缓冲区
PtrTransmit --; // Decrement TX字节计数器
IF (PtrTransmit <= 0)
{
while (!(UCB2IFG和UCTXIFG));
UCB2CTL1 || UCTXSTP; // I2C停止条件
UCB2IE &=~UCTXIE; //禁用中断。
UCB2IFG &=~UCTXIFG; //清除USI_B0 TX int标志
//__BIC_SR_REGISTER_ON_EXIT (LPM0_bits);//退出LPM0
}
}
否则IF (UCRXIFG和UCB2IFG)
{
I2CBuffer = UCB2RXBUF; //将收到的数据存储在缓冲区中
//__BIC_SR_REGISTER_ON_EXIT (LPM0_bits);//退出LPM0
}
I2Croutines.h
#define I2C_PORT_SEL P9SEL #define I2C_PORT_OUT P9OUT #define I2C_PORT_DIR P9DIR #define I2C_PIN BIX1 // UCB0SDA引脚 #define SCL_PIN BIIT2 // UCB.S引脚 #define SCL_CLock_DIV 0x14 // 无 符号EEPROM byitchar,I2c_unsigned地址 void eeprom_PageWrite (unsigned int StartAddress,unsigned char * Data,unsigned char size); unsigned char eeprom_CurrentAddressRead (void); void_SequentialRead (unsigned int Address,unsigned char * Data,unsigned int size); void eeprom_AckPolling(void);
我错过了什么吗? 有任何提示?
谢谢!

