This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430FR2673:创建 I2C EEPROM 库、不涉及输入

Guru**** 1803110 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1401126/msp430fr2673-i2c-eeprom-library-creation-without-interrput

器件型号:MSP430FR2673

工具与软件:

您好!

我想使用 I2C 协议 而不使用输入来创建 EEPROM 库、 请给出一个示例库。  

 

/*
* I2C.c
*
*创建时间: 2024年4月15日
*作者: Lanware
*/

#include
#include "I2C.h"

#define MAXPAGEWRITE 32.

Int PtrTransmit =0;
unsigned char I2CBufferArray[66];
无符号字符 I2CBuffer;
unsigned int RXByteCtr = 0;
unsigned char ReceiveBuffer[20]={0};
Int ReceiveIndex = 0;

/*------------------ */
//说明:
//初始化 I2C 模块
/*------------------ */
void InitI2C (unsigned char EEPROM_i2c_address)

P3SEL0 |= BIT2 | BIT6;// I2C 引脚
P3SEL1 &=~Ω(BIT2 | BIT6);
//禁用 GPIO 上电默认高阻抗模式以激活
//先前配置的端口设置
PM5CTL0 &=~μ H LOCKLPM5;

UCB1CTLW0 = UCSWRST;//启用软件复位
UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC;// I2C 主模式、SMCLK
UCB1BRW = 160;// fSCL = SMCLK/160 =~100kHz
UCB1I2CSA = EEPROM_i2c_address;//从器件地址
UCB1CTLW0 &=~μ s UCSWRST;//清除软件复位、恢复操作
UCB1IE |= UCNACKIE;
}

空 I2CWriteInit (空)

UCB1I2CSA = 0x50;
UCB1IFG &=~(UCTXIFG + UCRXIFG);
UCB1IE &&~μ P UCRXIE;//禁用接收就绪中断
UCB1IE |= UCTXIE;//启用发送就绪中断
}

/*------------------ */
//说明:
//初始化 I2C 模块以进行读操作。
/*------------------ */
void I2CReadInit (void)

UCB1CTLW0 &=~μ V UCTR;// UCTR=0 =>接收模式(R/W 位= 0)
UCB1I2CSA = 0x50;
UCB1IFG &=~(UCRXIFG + UCRXIFG);
UCB1IE &&~μ P UCTXIE;//禁用接收就绪中断
UCB1IE |= UCRXIE;//启用发送就绪中断

}
void EEPROM_ByteWrite (unsigned int Address、unsigned char * Data)

unsigned char adr_hi;
unsigned char adr_lo;

while (UCB1STAT & UCBUSY);//等待 I2C 模块具有
//完成所有操作。

Adr_hi =地址>> 8;//计算高字节
ADR_lo = Address & 0xFF;//和 address 的低字节


I2CBufferArray[2]= ADR_hi;//低字节地址。
I2CBufferArray[1]= ADR_lo;//高字节地址。
I2CBufferArray[0]=数据;
PtrTransmit = 2;//设置 I2CBufferArray 指针

I2CWriteInit();

UCB1CTLW0 |= UCTR + UCTXSTT;// I2C TX、启动条件
__bis_SR_register (LPM0_bits + GIE);//随着中断进入 LPM0

while ((UCB1CTLW0和 UCTXSTP);

}

空 EEPROM_AckPolling (空)

while (UCB1STAT & UCBUSY);//等待 I2C 模块具有
//完成所有操作
应执行的操作

UCB1STAT = 0x00;//清除 I2C 中断标志
UCB1CTLW0 |= UCTR;// I2CTRX=1 =>发送模式(R/W 位= 0)
UCB1CTLW0 &=~μ s UCTXSTT;
UCB1CTLW0 |= UCTXSTT;//生成起始条件
while (UCB1CTLW0 & UCTXSTT)//等待 I2CSTT 位被清零

if (! (UCNACKIFG & UCB1STAT)//如果收到 ACK、则进行分解

休息;
}
}
UCB1CTLW0 |= UCTXSTP;//在之后生成停止条件
//已发送从器件地址=> I2C 通信已开始
while (UCB1CTLW0 & UCTXSTP);//等待 STOP 位被复位
__delay_cycles (500);//软件延迟
} while (UCNACKIFG & UCB1STAT);
}

unsigned char EEPROM_RandomRead (unsigned int 地址)

unsigned char adr_hi;
unsigned char adr_lo;


while (UCB1STAT & UCBUSY);//等待 I2C 模块具有
//完成所有操作

Adr_hi =地址>> 8;//计算高字节
ADR_lo = Address & 0xFF;//和 address 的低字节

I2CBufferArray[1]= ADR_hi;//存储必须保存的单个字节
I2CBufferArray[0]= ADR_lo;//要在 I2CBuffer 中发送。
PtrTransmit = 1;//设置 I2CBufferArray 指针

//首先写入地址
I2CWriteInit();
UCB1CTLW0 |= UCTR + UCTXSTT;// I2C TX、启动条件
//=> I2C 通信已开始
__bis_SR_register (LPM0_bits + GIE);//随着中断进入 LPM0

while (UCB1CTLW0 & UCTXSTP);//确保已发送停止条件

I2CReadInit();

UCB1CTLW0 |= UCTXSTT;// I2C TX、启动条件

while (UCB1CTLW0 & UCTXSTT);//是否发送启动条件?

UCB1CTLW0 |= UCTXSTP;// I2C 停止条件

__bis_SR_register (LPM0_bits + GIE);//随着中断进入 LPM0

while (UCB1CTLW0 & UCTXSTP);//确保已发送停止条件

返回 I2CBuffer;
}
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 adr_lo;
unsigned int currentAddress = StartAddress;
unsigned char currentSize = size;
unsigned char bufferPtr = 0;
unsigned char moreDataToRead = 1;

while (UCB1STAT & UCBUSY);//等待 I2C 模块具有
//完成所有操作。

//执行、直到数据缓冲区中没有更多数据
while (moreDataToRead)

adr_hi = currentAddress >> 8;//计算高字节
Adr_lo = currentAddress 和0xFF;//以及地址的低字节

//将数据切换到每次要传输的64字节数据包
//保留当前起始地址的指针
if (currentSize > MAXPAGEWRITE)

bufferPtr = bufferPtr + MAXPAGEWRITE;
counterI2cBuffer = MAXPAGEWRITE - 1;
PtrTransmit = MAXPAGEWRITE + 1;//设置 I2CBufferArray 指针
currentSize = currentSize - MAXPAGEWRITE;
currentAddress = currentAddress + MAXPAGEWRITE;

//获取起始地址
I2CBufferArray[MAXPAGEWRITE + 1]= ADR_hi;//高字节地址。
I2CBufferArray[MAXPAGEWRITE]= ADR_lo;//低字节地址。
}
设计

bufferPtr = bufferPtr + currentSize;
counterI2cBuffer = currentSize - 1;
PtrTransmit = currentSize + 1;//设置 I2CBufferArray 指针。
moreDataToRead = 0;
currentAddress = currentAddress + currentSize;

//获取起始地址
I2CBufferArray[currentSize + 1]= adr_hi;//高字节地址。
I2CBufferArray[currentSize]= ADR_lo;//低字节地址。
}

//将数据复制到 I2CBBufferArray
unsigned char temp;
for (i;i < bufferPtr;i++)

Temp = Data[i];//必填或 IAR 抛出
//警告[Pa082]
I2CBufferArray[counterI2cBuffer]= temp;
counterI2cBuffer--;
}

I2CWriteInit();

UCB1CTLW0 |= UCTR + UCTXSTT;// I2C TX、启动条件

__bis_SR_register (LPM0_bits + GIE);//进入 LPM0并产生中断

while ((UCB1CTLW0和 UCTXSTT));
UCB1CTLW0 |= UCTXSTP;//发送停止条件
__delay_cycles (100000);
EEPROM_AckPolling ();//确保数据写入 EEPROM
}
}
void EEPROM_SequentialRead (unsigned int Address、unsigned char * Data、unsigned int Size)

unsigned char adr_hi;
unsigned char adr_lo;
unsigned int counterSize;

Adr_hi =地址>> 8;//计算高字节
ADR_lo = Address & 0xFF;//和 address 的低字节

I2CBufferArray[1]= ADR_hi;//存储必须保存的单个字节
I2CBufferArray[0]= ADR_lo;//要在 I2CBuffer 中发送。
PtrTransmit = 1;//设置 I2CBufferArray 指针

//首先写入地址
I2CWriteInit();

UCB1CTLW0 |= UCTR + UCTXSTT;// I2C TX、启动条件

__bis_SR_register (LPM0_bits + GIE);//随着中断进入 LPM0

while (UCB1CTLW0 & UCTXSTP);//确保已发送停止条件

//读取数据字节
I2CReadInit();

UCB1CTLW0 |= UCTXSTT;// I2C TX、启动条件
while (UCB1CTLW0 & UCTXSTT);//是否发送启动条件?

for (counterSize = 0;counterSize < size;counterSize++)

__bis_SR_register (LPM0_bits + GIE);//随着中断进入 LPM0
Data[counterSize]= I2CBuffer;
}
UCB1CTLW0 |= UCTXSTP;// I2C 停止条件
__bis_SR_register (LPM0_bits + GIE);//随着中断进入 LPM0
while (UCB1CTLW0 & UCTXSTP);//确保已发送停止条件
}

/*------------------ */
/*中断服务例程*/
/*请注意、在以下代码中检查编译器版本、并且*/
/*根据编译器的版本、正确的中断服务*/
/*使用例程定义。 */
#if defined (__TI_Compiler_version__)|| defined (__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B1_VECTOR
_interrupt void USCI_B1_ISR (void)
#elif defined (_GNUC__)
void __attribute__(((interrupt (USCI_B1_vector))) USCI_B1_ISR (void)
#else
错误编译器不受支持!
#endif

IF (UCTXIFG & UCB1IFG)

UCB1TXBUF = I2CBufferArray[PtrTransmit];//加载 TX 缓冲区
PtrTransmit--;//递减 TX 字节计数器
if (PtrTransmit < 0)

while (! (UCB1IFG 和 UCTXIFG));
UCB1CTLW0 |= UCTXSTP;// I2C 停止条件
UCB1IE &&~μ P UCTXIE;//禁用中断。
UCB1IFG 并且=~UCTXIFG;//清除 USCI_B0 TX int 标志
_BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//退出 LPM0
}
}
否则为(UCRXIFG & UCB1IFG)

I2CBuffer = UCB1RXBUF;//将接收到的数据存储在缓冲区中
_BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//退出 LPM0
}
}

谢谢你

Athulya Shaji.