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.

[参考译文] TM4C1294NCPDT:读取 Ds1307 i2c RTC 时出现问题

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1111607/tm4c1294ncpdt-problem-reading-ds1307-i2c-rtc

器件型号:TM4C1294NCPDT

大家好,

我将 TM4C129XL Launchpad 与 DS1307相连我的代码在更新小时、秒、日期、年方面运行良好。 当我分别更新 Min、Day 和 Month 时、它会得到正确更新、并且工作正常。 但是、当我尝试一次全部更新这些参数时、即使电源已接通、它们也会被复位。

我正在验证 docklight 上的输出。 附件是代码和日志文件。

有人能告诉我哪里出错了吗

代码:

/*
*@物理接口:
* 1) LED (PNO/PN1)
* 2)开关(PN4)
* 3) UART
* a.UART0 (TX:PA1 RX:PA0)
* b.UART1 (TX:PB1 RX:PB0/PQ4)
* C.UART6 (TX:PP1 RX:PP0)
4) RTC (I2C:PB2、PB3)
*
*
*
*
***/

//#include
//#include
//#include "inc/hw_memmap.h"
//#include "inc/hw_types.h"
//#include "driverlib/gpio.h"
//#include "driverlib/pin_map.h"
//#include "driverlib/sysctl.h"
//#include "driverlib/uart.h"
//要处理中断,我们将使用:
//#include "inc/hw_ints.h"
//#include "driverlib/interrupt.h"
//#include "driverlib/i2c.h"
//
//#include "utils/uartstdio.h"


//include 文件
#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"
#include "driverlib/uart.h"
//#include "uartstdio.h"
#include "utils/uartstdio.h"

DS1307的//定义
#define SLAVE_ADDRESS 0x68
#define SEC 0x00
#define min 0x01
#define HRS 0x02
#define Day 0x03
#define date 0x04
#define 月0x05
#define 年份0x06
#define CNTRL 0x07

uint32_t g_ui32SysClock;
unsigned char sec、min、hour、day、date、month、year、control;


//初始化 I2C 模块0
// TI 示例代码的轻微修改版本
空 InitI2C0 (空)

SysCtlPeripheralReset (SYSCTL_Periph_I2C0);
//启用 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、g_ui32SysClock、false);


//向指定的从设备发送 I2C 命令
void I2CSend (uint8_t slave_addr、uint32_t num_for_args、...)

//告诉主模块何时将在总线上放置什么地址
//与从设备通信。
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 完成传输。
SysCtlDelay (800);
while (I2CMasterBusy (I2C0_BASE));
//"close"变量参数列表
va_end (vargs);

//否则,我们开始在上传输多个字节
//I2C 总线
其他

//从 MCU 发起数据发送
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);
//等待 MCU 完成传输。
SysCtlDelay (800);
while (I2CMasterBusy (I2C0_BASE));
//send num_of _args-2数据片段、使用
///burse_send_contt 命令的 I2C 模块
unsigned char i;
for (i = 1;i <(num_of _args);i++)

//将下一段数据放入 I2C FIFO 中
I2CMasterDataPut (I2C0_BASE、va_arg (vargs、uint32_t));
//发送刚刚放置到 FIFO 中的下一个数据
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_CONT);
//等待 MCU 完成传输。
SysCtlDelay (800);
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 完成传输。
SysCtlDelay (800);
while (I2CMasterBusy (I2C0_BASE));
//"Close"变量 args 列表
va_end (vargs);

//读取从器件上的指定寄存器
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 完成事务
SysCtlDelay (800);
while (I2CMasterBusy (I2C0_BASE));
//指定我们将从从从器件读取
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、TRUE);

I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_Receive_start);
//指定我们将从从从器件读取

//等待 MCU 完成事务
SysCtlDelay (800);
while (I2CMasterBusy (I2C0_BASE));
//发送刚刚放置到 FIFO 中的下一个数据
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_Receive_CONT);
//指定我们将从从从器件读取
//等待 MCU 完成传输。
SysCtlDelay (800);
while (I2CMasterBusy (I2C0_BASE));
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_Receive_finish);
//指定我们将从从从器件读取
//等待 MCU 完成事务
SysCtlDelay (800);
while (I2CMasterBusy (I2C0_BASE));
//返回从指定寄存器提取的数据
返回 I2CMasterDataGet (I2C0_BASE);

//将解码转换为 bcd
unsigned char dec2bcd (unsigned char val)

返回(((val / 10)<< 4)|(val % 10));

//将 BCD 转换为二进制
unsigned char bcd2dec (unsigned char val)

返回(((val & 0xF0)>> 4)* 10)+(val & 0x0F);

//设置时间
/*void SetTimeDate (unsigned char sec、unsigned char min、unsigned char hour、unsigned char day、unsigned char date、 unsigned char 月、unsigned char 年)

i2CSend (slave_address、8、sec、dec2bcd (sec)、dec2bcd (min)、dec2bcd (hour)、dec2bcd (day)、dec2bcd (date)、dec2bcd (month)、dec2bcd (year));
}*/
void SetHour (无符号字符 hh)

unsigned char h=0;
h=dec2bcd (hh);
I2CSend (slave_address、2、hrs、h);


void SetMinute (无符号字符 mm)

unsigned char m =0;
m=dec2bcd (mm);
I2CSend (slave_address、2、min、m);

void SetSec (无符号字符 ss)

unsigned char s =0;
s=dec2bcd (ss);
I2CSend (slave_address、2、SEC、s);


void SetDay (无符号字符日)

unsigned char d;
d=dec2bcd (天);
I2CSend (slave_address、2、day、d);


void setdate (无符号字符日期)

unsigned char d;
d=dec2bcd (date);
I2CSend (slave_address、2、date、d);


空 SetMonth (无符号字符月份)

unsigned char m;
m=dec2bcd (月);
I2CSend (slave_address、2、Month、m);


空 SetYear (无符号字符年份)

unsigned char y;
y=dec2bcd (年);
I2CSend (slave_address、2、年、y);


void SetControl (无符号字符控制)

I2CSend (slave_address、2、CNTRL、dec2bcd (control));


//获取时间和日期
unsigned char GetClock (unsigned char reg)

unsigned char clockData = I2CReceive (slave_address、reg);
返回 bcd2dec (clockData);
//返回时钟数据;

空配置 UART (空)

//启用 UART 使用的 GPIO 外设。
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
//启用 UART0。
SysCtlPeripheralEnable (SYSCTL_Periph_UART0);

//为 UART 模式配置 GPIO 引脚。
GPIOPinConfigure (GPIO_PA0_U0RX);
GPIOPinConfigure (GPIO_PA1_U0TX);
GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);

//初始化控制台 I/O 的 UART
UARTStdioConfig (0、115200、g_ui32SysClock);
//UARTConfigSetExpClk (UART0_BASE、g_ui32SysClock、115200、(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));

void main (void)

//将时钟设置为直接从外部晶振/振荡器运行。
G_ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |SYSCTL_MAIN|SYSCTL_USE_PLL|SYSCTL_CFG_VCO_480)、120000000);

//初始化 I2C 模块0
InitI2C0();
ConfigureUART();
//SetTimeDate (36、55、10、4、27、10、16);
SetSec (00);
SetMinute (41);
SetHour (11);
SetDay (2);
setdate(21);
SetMonth (6);
SetYear(22);
SetControl (0x13);


while (1)

SEC = GetClock (SEC);
min = GetClock (min);
小时= GetClock (小时);
Day = GetClock (Day);
日期= GetClock (date);
月= GetClock (月);
年= GetClock (年);
控制= GetClock (CNTRL);

UARTprintf ("%02d:%02d:%02d\r\n %02d %02d/%0d/%02d\r\n \n%02d\r\n "、小时、分钟、秒、日、日期、月、年、控制);
//UARTprintf ("hh:mm:ss:%02d:%02d:%02d \r\n"、小时、分钟、秒);
//UARTprintf ("%02d \r\n"、control);
SysCtlDelay (g_ui32SysClock);

日志文件:


//******** 日志文件

11:21:09
22 21/22.
00


11:21:12
22 21/22.
00

11:21:15
22 21/22.
00

11:21:18
22 21/22.
00

11:21:21
22 21/22.
00

此致、

Sagar Kanjariya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="289369" URL"~μ C/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1111607/tm4c1294ncpdt-problem-read-ds1307-i2c-rtc"]但当我尝试一次全部更新这些参数时,即使是在重新启动报价/重新启动时,也会更新这些参数。]

    您好!

     谁被重置? 是 Ds1307吗?

     您能否使用逻辑分析仪查看 I2C 总线并调试发生的情况? 检查是否正确写入 ds1307、然后检查读取是否正确。

     查看您的代码、我多次看到以下两行代码。

    SysCtlDelay (800);
    while (I2CMasterBusy (I2C0_BASE));

    您是否可以将  while (I2CMasterBusy (I2C0_BASE))替换为以下两行? 更改后、它会产生影响吗?

    发自:

    //SysCtlDelay (800);//注释掉此固定延迟
    while (I2CMasterBusy (I2C0_BASE));//在任何地方,用下面两行红色代码替换该行。  

    至:

    //
    //等待主机模块完成传输。
    //
    while (!map_I2CMasterBusy (I2C0_BASE))


    while (MAP_I2CMasterBusy (I2C0_BASE))

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

    谢谢 Charles、

    Ds1307被复位。 您要求我实施的 while 语句不会在 docklight 上显示任何数据

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

    您好!

     我不熟悉第三方器件 DS1307、因此无法评论在什么情况下将其复位。 您需要了解哪些命令或任何可能导致其复位的方法。 您需要查看示波器或逻辑分析仪上的总线信号、以查看发送到 DS1307的命令/数据是否正确。