主题中讨论的其他器件:TM4C123、
您好!
我将提供来自 uC 的 I2C 信号、SCL 和 SDA 被上拉。
但是、当我检查示波器时、我有时会看到 SCL 信号、有时无法看到它。
所有信号短路、连接正常。
请说明这种开关的原因。
此致、
Kiranjit
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.
您好!
我将提供来自 uC 的 I2C 信号、SCL 和 SDA 被上拉。
但是、当我检查示波器时、我有时会看到 SCL 信号、有时无法看到它。
所有信号短路、连接正常。
请说明这种开关的原因。
此致、
Kiranjit
您好!
[引用 userid="532865" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1179088/tm4c1292ncpdt-i2c-clock-waveform-comes-randomly "]我将从 uC 和 SCL 以及 SDA 中发出 I2C 信号。[/quot]- SCL 和 SDA 总线上是否都有外部上拉电阻器? 这两条总线的 PCB 上必须有上拉电阻。
[引用 userid="532865" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1179088/tm4c1292ncpdt-i2c-clock-waveform-comes-randomly "]但当我检查范围时,我有时会看到 SCL 信号,有时无法看到它。-您运行的是任何 I2C 代码吗? 如果您没有运行任何代码、并且无法看到 SCL 上拉至电源轨、则这意味着您存在上拉问题。
您好、Charles、
以下是 SCL 线路的一般范围捕获、在没有通信的情况下、该值始终为高电平。
当我在 I2C 线路上发送一些简单数据时、该 SCL 线路有时会检测到以下时钟信号、但 每次都无法检测到该信号。
另一个问题是、我需要400kHz 的 I2C 时钟、但如上所示、时钟速率为1.77MHz、上拉电阻为4.7K。 我尝试了1k 至10k 范围内的不同电阻、但时钟速率仅在 MHz 范围内。 我的代码是将 I2C 时钟保持在快速模式、即400kbps
您好、Charles、
感谢您的建议、我将尝试使用该功能。
[引用 userid="532865" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1179088/tm4c1292ncpdt-i2c-clock-waveform-comes-randomly/4443562 #4443562"]但信号不一致的原因可能是什么?
此致、
Kiranjit
你(们)好
零 PCB 表示通用电路板、而不是制造的 PCB。
此外、我的另一个代码(SPI)也不会发生这种情况、此时钟已启动并正在运行。 我也尝试在评估板上进行检查、但信号不会随时出现。(也在代码中进行了上述更改、即使用 了 SysCtlClockFreqSet 函数)。
我觉得这里的代码和硬件不是问题。 我认为问题在于我尝试检查信号的方式、即 通过 LM Flash Programmer 重新设置微控制器、即按下"Hardware Reset"按钮、但有时会挂起。 我在复位时发送信号、因此每次复位时都可以看到时钟信号。
是否有其他方法对其进行复位并检查信号?
此致、
Kiran
您好!
我不清楚您的问题。
[引用 userid="532865" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1179088/tm4c1292ncpdt-i2c-clock-waveform-comes-randomly/4446030 #4446030"]此外,我的其他代码(SPI)也没有发生这种情况,[/引用]您的问题是 I2C。 因此、在我看来、SPI 在这里无关紧要。
[引用 userid="532865" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1179088/tm4c1292ncpdt-i2c-clock-waveform-comes-randomly/4446030 #4446030"]我也尝试在评估板上进行检查、但信号并不是随时出现的。(代码中是否进行了上述更改、即使用 了 SysCtlClockFreqSet 函数)。请显示您的整个 I2C 代码。 您的意思是、信号不会每次都出现。 哪个信号? SCL 或 SDA、还是两者都是? 如前所述、必须使用 SysCtlClockFreqSet 来配置 TM4C129的系统时钟、并将此函数调用的返回值用于其他 API。 不得将 SysCtlClockGet () API 用于 TM4C129 MCU。
[引用 userid="532865" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1179088/tm4c1292ncpdt-i2c-clock-waveform-comes-randomly/4446030 #4446030">我觉得代码和硬件在这里不是问题。 [/报价]在您将代码更改为使用 SysCtlClockFreqSet 的返回值后、您在 SCL 和 SDA 总线上看到了什么? 请显示捕获。
[引用 userid="532865" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1179088/tm4c1292ncpdt-i2c-clock-waveform-comes-randomly/4446030 #4446030"]我认为问题在于我尝试检查信号的方式,即 通过 LM 闪存编程器重新设置微控制器,例如按下“硬件复位”按钮,但它有时会挂起。 我在复位时发送信号、因此每次复位时都可以看到时钟信号。我想我在这里迷路了。 LM 闪存编程器用于将代码加载到闪存中。 加载代码后、如果您按下硬件复位、则只会复位器件、器件应从头开始运行。 这意味着在复位时发送信号。 您在复位时发送什么信号? 谁向谁发送什么信号? 我想您是说、复位后、MCU 将 SCL 时钟发送到总线、对吧?
您好、Charles、
以下是我的参考 I2C 代码:
#include
#include
#include
#include "inc/hw_i2c.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "driverlib/i2c.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
//初始化 I2C 模块0
// TI 示例代码的轻微修改版本
空 InitI2C0 (空)
{
//启用 I2C 模块0
SysCtlPeripheralEnable (SYSCTL_Periph_I2C0);
//复位模块
SysCtlPeripheralReset (SYSCTL_Periph_I2C0);
//启用包含 I2C 0的 GPIO 外设
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);
//为端口 B2和 B3上的 I2C0功能配置引脚复用。
GPIOPinConfigure (GPIO_PB2_I2C0SCL);
GPIOPinConfigure (GPIO_PB3_I2C0SDA);
//为这些引脚选择 I2C 功能。
GPIOPinTypeI2CSCL (GPIO_PORTB_BASE、GPIO_PIN_2);
GPIOPinTypeI2C (GPIO_PORTB_BASE、GPIO_PIN_3);
//启用和初始化 I2C0主机模块。 使用的系统时钟
// I2C0模块。 最后一个参数设置 I2C 数据传输速率。
//如果为 false,则数据速率设置为100kbps,如果为 true,则数据速率将设置为
//设置为400kbps。
I2CMasterInitExpClk (I2C0_BASE、SysCtlClockGet ()、false);
//清除 I2C FIFO
HWREG (I2C0_BASE + I2C_O_FIFOCTL)= 80008000;
}
//向指定的从设备发送 I2C 命令
void I2CSend (uint8_t slave_addr、uint8_t num_for_args、...)
{
uint8_t i;
//告诉主模块何时将在总线上放置什么地址
//与从设备通信。
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、false);
//存储变量数量的参数列表
va_list vargs;
//将 va_list 指定为"open"和最后一个固定参数
//so vargs 知道从何处开始查找
va_start (vargs、num_of _args);
//将要发送的数据放入 FIFO 中
I2CMasterDataPut (I2C0_BASE、va_arg (vargs、uint32_t));
//如果只有一个参数,我们只需要使用
//单发送 I2C 函数
if (num_of _args == 1)
{
//从 MCU 发起数据发送
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);
//等待 MCU 完成传输。
while (!I2CMasterBusy (I2C0_BASE));
while (I2CMasterBusy (I2C0_BASE));
//"close"变量参数列表
va_end (vargs);
}
//否则,我们开始在上传输多个字节
//I2C 总线
其他
{
//从 MCU 发起数据发送
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);
//等待 MCU 完成传输。
while (!I2CMasterBusy (I2C0_BASE));
while (I2CMasterBusy (I2C0_BASE));
//send num_of _args-2数据片段、使用
///burse_send_contt 命令的 I2C 模块
for (i = 1;i <(num_of _args - 1);i++)
{
//将下一段数据放入 I2C FIFO 中
I2CMasterDataPut (I2C0_BASE、va_arg (vargs、uint32_t));
//发送刚刚放置到 FIFO 中的下一个数据
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_CONT);
//等待 MCU 完成传输。
while (!I2CMasterBusy (I2C0_BASE));
while (I2CMasterBusy (I2C0_BASE));
}
//将最后一段数据放入 I2C FIFO 中
I2CMasterDataPut (I2C0_BASE、va_arg (vargs、uint32_t));
//发送刚刚放置到 FIFO 中的下一个数据
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_FINISH);
//等待 MCU 完成传输。
while (!I2CMasterBusy (I2C0_BASE));
while (I2CMasterBusy (I2C0_BASE));
//"Close"变量 args 列表
va_end (vargs);
}
}
//通过 I2C 向指定的从设备发送一组数据
空 I2CSendString (uint32_t slave_addr、char array [])
{
//告诉主模块何时将在总线上放置什么地址
//与从设备通信。
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、false);
//将要发送的数据放入 FIFO 中
I2CMasterDataPut (I2C0_BASE、array[0]);
//如果只有一个参数,我们只需要使用
//单发送 I2C 函数
if (array[1]='\0')
{
//从 MCU 发起数据发送
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);
//等待 MCU 完成传输。
while (!I2CMasterBusy (I2C0_BASE));
while (I2CMasterBusy (I2C0_BASE));
}
//否则,我们开始在上传输多个字节
//I2C 总线
其他
{
//从 MCU 发起数据发送
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);
//等待 MCU 完成传输。
while (!I2CMasterBusy (I2C0_BASE));
while (I2CMasterBusy (I2C0_BASE));
//将索引初始化为数组
uint8_t i = 1;
//send num_of _args-2数据片段、使用
///burse_send_contt 命令的 I2C 模块
while (array[i + 1]!='\0')
{
//将下一段数据放入 I2C FIFO 中
I2CMasterDataPut (I2C0_BASE、array[i++]);
//发送刚刚放置到 FIFO 中的下一个数据
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_CONT);
//等待 MCU 完成传输。
while (!I2CMasterBusy (I2C0_BASE));
while (I2CMasterBusy (I2C0_BASE));
}
//将最后一段数据放入 I2C FIFO 中
I2CMasterDataPut (I2C0_BASE、array[i]);
//发送刚刚放置到 FIFO 中的下一个数据
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_FINISH);
//等待 MCU 完成传输。
while (!I2CMasterBusy (I2C0_BASE));
while (I2CMasterBusy (I2C0_BASE));
}
}
//读取从器件上的指定寄存器
uint32_t I2CReceive (uint32_t SLAVE_addr、uint8_t reg)
{
//指定我们要向写入(寄存器地址)
//从器件
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、false);
//指定要读取的寄存器
I2CMasterDataPut (I2C0_BASE、reg);
//将控制字节和寄存器地址字节发送到从器件
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);
//等待 MCU 完成事务
while (!I2CMasterBusy (I2C0_BASE));
while (I2CMasterBusy (I2C0_BASE));
//指定我们将从从从器件读取
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、TRUE);
//发送控制字节并从我们的寄存器中读取
//specified
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_Receive);
//等待 MCU 完成事务
while (!I2CMasterBusy (I2C0_BASE));
while (I2CMasterBusy (I2C0_BASE));
//返回从指定寄存器提取的数据
返回 I2CMasterDataGet (I2C0_BASE);
}
#define LCD_SLAVE_ADDR 0x28
#define LCD_CMD 0xFE //用于向 LCD 发送命令
//清除 LCD
空 ClearScreen()
{
I2CSend (LCD_SLAVE_ADDR、2、LCD_CMD、0x58);
}
//设置 LCD 的亮度
void SetBrightness (uint8_t brightness)
{
I2CSend (LCD_SLAVE_ADDR、3、LCD_CMD、0x99、亮度);
}
//设置 LCD 的对比度
void SetContrast (uint8_t 对比度)
{
I2CSend (LCD_SLAVE_ADDR、3、LCD_CMD、0x50、对比度);
}
//将单个字符写入 LCD
空 WriteChar (uint8_t 字符)
{
I2CSend (LCD_SLAVE_ADDR、1、字符);
}
//将字符串写入 LCD
空 WriteString (字符串[255])
{
I2CSendString (LCD_SLAVE_ADDR、string);
}
//绘制起始点(x1、y1)和端点(x2、y2)的行
空 DrawLine (uint8_t x1、uint8_t Y1、uint8_t x2、uint8_t Y2)
{
I2CSEL (LCD_SLAVE_ADDR、6、LCD_CMD、0x6C、x1、 Y1、x2、Y2);
}
//设置光标的坐标(以精确像素为单位)
void SetCursorCoord (uint8_t x、uint8_t y)
{
I2CSend (LCD_SLAVE_ADDR、4、LCD_CMD、0x79、x、 y);
}
//设置文本光标的位置
void SetCursorPos (uint8_t col、uint8_t row)
{
I2CSend (LCD_SLAVE_ADDR、4、LCD_CMD、0x47、col、 行);
}
void main (void)
{
//将时钟设置为直接从外部晶振/振荡器运行。
SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_INT | SYSCTL_XTAL_16MHz);
//初始化 I2C 模块0
InitI2C0();
//初始化显示
SetBrightness (0);
while (1){};
}
它只是在 I2C 初始化后的复位时发送一个3字节的 I2C 命令。
我只是检查示波器上的数据线 SCL。
每次复位时、它应该显示时钟信号 SCL、但它不显示相同的时钟信号、即使我在评估板上拉了时钟线也是如此。
范围捕获已在上一帖子中共享。
请说明信号不发送的原因。
谢谢、
Kiran
您好!
我已经多次告诉过你、你不能使用 SysCtlClockSet 和 SysCtlClockGet。 您必须先解决此问题。 您需要使用如下示例所示的内容。 如果不修复基本缺陷、我们就无法调试您的代码。 您为什么不看 C :\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl-bootstxl-sushub\humid_sht21_simples\humide_sht21_simple.c 或 TivaWare 库中其他 TM4C129示例、了解如何为 TM4C129 MCU 配置系统时钟。
ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
SYSCTL_OSC_MAIN |
SYSCTL_USE_OSC)、25000000); //为25MHz 配置系统时钟的示例。 您可以根据自己的速度要求进行配置。
I2CMasterInitExpClk (I2C0_BASE、ui32SysClock、false);
您好!
您能展示您的原理图吗? 或许可以拍摄您的设置图片。 我假设您使用 LaunchPad 作为主 I2C、对吧? I2C 主设备是 具有 TM4C1292NCPDT 的定制板。 您的 LCD 安装在所谓的零 PCB 上。 是这样吗? 图表将有助于了解设置。
-如果您使用自定义电路板上的 I2C 主设备、您是否可以更改为使用 LaunchPad? LaunchPad 是否会产生相同的问题?
-如果您使用自定义板作为主板,是否可以在另一个自定义板上重复同样的问题? 换言之、问题是否出现在所有定制板上?
-您能否显示显示完整 I2C 事务的基本捕获? 逻辑分析仪在这里非常有用。 显示 START -> Slave Address -> ACK 和其余数据传输、最后显示 STOP 位。
——您是否成功完成了一笔交易? 从器件是否向主器件回复 ACK?
我看到您将 I2C 设置为100k 波特率,但您说您需要400k 波特率。
您能不能注释 掉 HWREG (I2C0_BASE + I2C_O_FIFOCTL)= 80008000。 您可以在稍后阶段将其放回。 让我们暂时保持简单。
您好、Charles、
以下是我的更新代码(注释为120MHz 系统时钟和 HWREG (I2C0_BASE + I2C_O_FIFOCTL)= 80008000):
#include
#include
#include
#include "inc/hw_i2c.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "driverlib/i2c.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
uint32_t g_ui32SysClock;
uint32_t ui32SysClock;
//初始化 I2C 模块0
// TI 示例代码的轻微修改版本
空 InitI2C0 (空)
{
//启用 I2C 模块0
SysCtlPeripheralEnable (SYSCTL_Periph_I2C0);
//复位模块
SysCtlPeripheralReset (SYSCTL_Periph_I2C0);
//启用包含 I2C 0的 GPIO 外设
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);
//为端口 B2和 B3上的 I2C0功能配置引脚复用。
GPIOPinConfigure (GPIO_PB2_I2C0SCL);
GPIOPinConfigure (GPIO_PB3_I2C0SDA);
//为这些引脚选择 I2C 功能。
GPIOPinTypeI2CSCL (GPIO_PORTB_BASE、GPIO_PIN_2);
GPIOPinTypeI2C (GPIO_PORTB_BASE、GPIO_PIN_3);
//启用和初始化 I2C0主机模块。 使用的系统时钟
// I2C0模块。 最后一个参数设置 I2C 数据传输速率。
//如果为 false,则数据速率设置为100kbps,如果为 true,则数据速率将设置为
//设置为400kbps。
ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000);
I2CMasterInitExpClk (I2C0_BASE、ui32SysClock、true);
//清除 I2C FIFO
// HWREG (I2C0_BASE + I2C_O_FIFOCTL)= 80008000;
}
//I2C 发送功能
//向指定的从设备发送 I2C 命令
void I2CSend (uint8_t slave_addr、uint8_t num_for_args、...)
{
uint8_t i;
//告诉主模块何时将在总线上放置什么地址
//与从设备通信。
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、false);
//存储变量数量的参数列表
va_list vargs;
//将 va_list 指定为"open"和最后一个固定参数
//so vargs 知道从何处开始查找
va_start (vargs、num_of _args);
//将要发送的数据放入 FIFO 中
I2CMasterDataPut (I2C0_BASE、va_arg (vargs、uint32_t));
//如果只有一个参数,我们只需要使用
//单发送 I2C 函数
if (num_of _args == 1)
{
//从 MCU 发起数据发送
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);
//等待 MCU 完成传输。
while (!(I2CMasterBusy (I2C0_BASE)));
while (I2CMasterBusy (I2C0_BASE));
//"close"变量参数列表
va_end (vargs);
}
//否则,我们开始在上传输多个字节
//I2C 总线
其他
{
//从 MCU 发起数据发送
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);
//等待 MCU 完成传输。
while (!(I2CMasterBusy (I2C0_BASE)));
while (I2CMasterBusy (I2C0_BASE));
//send num_of _args-2数据片段、使用
///burse_send_contt 命令的 I2C 模块
for (i = 1;i <(num_of _args - 1);i++)
{
//将下一段数据放入 I2C FIFO 中
I2CMasterDataPut (I2C0_BASE、va_arg (vargs、uint32_t));
//发送刚刚放置到 FIFO 中的下一个数据
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_CONT);
//等待 MCU 完成传输。
while (!(I2CMasterBusy (I2C0_BASE)));
while (I2CMasterBusy (I2C0_BASE));
}
//将最后一段数据放入 I2C FIFO 中
I2CMasterDataPut (I2C0_BASE、va_arg (vargs、uint32_t));
//发送刚刚放置到 FIFO 中的下一个数据
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_FINISH);
//等待 MCU 完成传输。
while (!(I2CMasterBusy (I2C0_BASE)));
while (I2CMasterBusy (I2C0_BASE));
//"Close"变量 args 列表
va_end (vargs);
}
}
//通过 I2C 向指定的从设备发送一组数据
空 I2CSendString (uint32_t slave_addr、char array [])
{
//告诉主模块何时将在总线上放置什么地址
//与从设备通信。
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、false);
//将要发送的数据放入 FIFO 中
I2CMasterDataPut (I2C0_BASE、array[0]);
//如果只有一个参数,我们只需要使用
//单发送 I2C 函数
if (array[1]='\0')
{
//从 MCU 发起数据发送
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_SEND);
//等待 MCU 完成传输。
while (!(I2CMasterBusy (I2C0_BASE)));
while (I2CMasterBusy (I2C0_BASE));
}
//否则,我们开始在上传输多个字节
//I2C 总线
其他
{
//从 MCU 发起数据发送
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);
//等待 MCU 完成传输。
while (!(I2CMasterBusy (I2C0_BASE)));
while (I2CMasterBusy (I2C0_BASE));
//将索引初始化为数组
uint8_t i = 1;
//send num_of _args-2数据片段、使用
///burse_send_contt 命令的 I2C 模块
while (array[i + 1]!='\0')
{
//将下一段数据放入 I2C FIFO 中
I2CMasterDataPut (I2C0_BASE、array[i++]);
//发送刚刚放置到 FIFO 中的下一个数据
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_CONT);
//等待 MCU 完成传输。
while (!(I2CMasterBusy (I2C0_BASE)));
while (I2CMasterBusy (I2C0_BASE));
}
//将最后一段数据放入 I2C FIFO 中
I2CMasterDataPut (I2C0_BASE、array[i]);
//发送刚刚放置到 FIFO 中的下一个数据
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_FINISH);
//等待 MCU 完成传输。
while (!(I2CMasterBusy (I2C0_BASE)));
while (I2CMasterBusy (I2C0_BASE));
}
}
//I2C 接收功能
//读取从器件上的指定寄存器
uint32_t I2CReceive (uint32_t SLAVE_addr、uint8_t reg)
{
//指定我们要向写入(寄存器地址)
//从器件
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、false);
//指定要读取的寄存器
I2CMasterDataPut (I2C0_BASE、reg);
//将控制字节和寄存器地址字节发送到从器件
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);
//等待 MCU 完成事务
while (I2CMasterBusy (I2C0_BASE));
//指定我们将从从从器件读取
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、TRUE);
//发送控制字节并从我们的寄存器中读取
//specified
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_Receive);
//等待 MCU 完成事务
while (!(I2CMasterBusy (I2C0_BASE)));
while (I2CMasterBusy (I2C0_BASE));
//返回从指定寄存器提取的数据
返回 I2CMasterDataGet (I2C0_BASE);
}
//////// LCD ////////////
#define LCD_SLAVE_ADDR 0x28
#define LCD_CMD 0xFE //用于向 LCD 发送命令
//清除 LCD
空 ClearScreen()
{
I2CSend (LCD_SLAVE_ADDR、2、LCD_CMD、0x58);
}
//设置 LCD 的亮度
void SetBrightness (uint8_t brightness)
{
I2CSend (LCD_SLAVE_ADDR、3、LCD_CMD、0x99、亮度);
}
//设置 LCD 的对比度
void SetContrast (uint8_t 对比度)
{
I2CSend (LCD_SLAVE_ADDR、3、LCD_CMD、0x50、对比度);
}
//将单个字符写入 LCD
空 WriteChar (uint8_t 字符)
{
I2CSend (LCD_SLAVE_ADDR、1、字符);
}
//将字符串写入 LCD
空 WriteString (字符串[255])
{
I2CSendString (LCD_SLAVE_ADDR、string);
}
//绘制起始点(x1、y1)和端点(x2、y2)的行
空 DrawLine (uint8_t x1、uint8_t Y1、uint8_t x2、uint8_t Y2)
{
I2CSEL (LCD_SLAVE_ADDR、6、LCD_CMD、0x6C、x1、 Y1、x2、Y2);
}
//设置光标的坐标(以精确像素为单位)
void SetCursorCoord (uint8_t x、uint8_t y)
{
I2CSend (LCD_SLAVE_ADDR、4、LCD_CMD、0x79、x、 y);
}
//设置文本光标的位置
void SetCursorPos (uint8_t col、uint8_t row)
{
I2CSend (LCD_SLAVE_ADDR、4、LCD_CMD、0x47、col、 行);
}
//////////////// LCD///////////////////////////////////
//SCL_PERIOD = 2×(1 + TPR)×(SCL_LP + SCL_HP)×CLK_PRD
//其中:
/* SCL_PRD 是 SCL 线周期(I2C 时钟)。
TPR 是定时器周期寄存器的值(范围从1到127)。
SCL_LP 是 SCL 低电平周期(固定为6)。
SCL_HP 是 SCL 高电平周期(固定为4)。
CLK_PRD 是以 ns 为单位的系统时钟周期
--> TPR =
*
void main (void)
{
//将时钟设置为直接从外部晶振/振荡器运行。
G_ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
SYSCTL_OSC_MAIN |
SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480)、120000000);
//初始化 I2C 模块0
InitI2C0();
SetBrightness (0);
while (1){};
}
我正在检查 PB2引脚(SCL)、它在 TI Launchpad 上被1k 电阻上拉至3.3V、但我看不到任何时钟信号。
以下是 SCL 信号的示波器捕获:
此致、
Kiranjit
您好!
我在 SCL 和 SDA 总线上使用 LaunchPad 和外部3.3k 上拉电阻器。 我没有连接任何从器件。 我能够在 SCL 和 SDA 上看到波形。 请参阅以下逻辑分析仪。 NAK 是预期的、因为我没有从器件。 否则、时钟和数据都是令人难以置信的。 您可以看到、主器件在总线上输出等于0x28的从器件地址、这就是代码中的地址。 捕获的时钟速度接近400k。 我运行的代码与您上传的代码相同。 我没有修改任何内容。 您需要检查连接。 也许、展示一下设置的图片。 确保 LaunchPad 板和从器件之间具有公共接地。 我建议您使用逻辑分析仪来捕获波形。 更容易对协议进行故障排除。
您好、Charles、
下图是我的设置、目前我只检查 PB2处的时钟 SCL (上拉)。
我在硬件复位时获得了正确的时钟、但它有时会出现、但有时并不总是出现
是否可能与 PC 的 USB 连接松动、这可能导致此问题、我也尝试更换 USB 电缆。
我能否从外部电源提供3.3V 电压并检查时钟(而不是通过 USB 通过 PC 供电)? 如果是、那么我应该将外部3.3V 电源连接到哪里、应该是什么电源电流? 此外、我还需要哪些跳线设置来实现相同的功能?
您还可以共享设置的图片。
谢谢、
Kiran
有关详细信息、请参阅 LaunchPad 用户指南。