gpt4 book ai didi

c - tiva c上单步调试和运行程序的不同结果

转载 作者:太空宇宙 更新时间:2023-11-04 01:51:30 27 4
gpt4 key购买 nike

我有一个 TIVA tm4c123G 我一直在尝试使用 I2C 协议(protocol)在它和我的 ADXL345 传感器之间建立通信,我成功地从加速度计写入和读取设备地址的读数以及我刚刚写入的寄存器值这意味着一切都运行良好。但是我已经在 keil 中逐步调试了这个并且它工作正常但是如果我运行程序它会一直给出零而且我不知道为什么?我应该在寄存器的写入和读取之间添加延迟,还是我的代码出了什么问题?

附上我的代码
我正在为系统使用 80 MHZ 的时钟,但我认为这可能是问题所在,因为代码执行下一次发送的速度太快,应该有一些延迟?我不确定我只是在猜测,请帮忙谢谢!

我的 adxl 连接也是

  1. Vcc -> 3.3 伏
  2. GND -> 地面
  3. CS -> 3.3 伏
  4. SDO -> 地面
  5. SDA -> PB3
  6. SCL -> PB2

#include "tm4c123gh6pm.h"
#include "stdint.h"

void EnableI2CModule0(void);
uint8_t ReadRegister(uint8_t RegisterAddress);
void PLL_Init(void);
void WriteRegister(uint8_t RegisterAddress,uint8_t Data);
volatile uint8_t X_Axis1,X_Axis2,Y_Axis1,Y_Axis2,Z_Axis1,Z_Axis2=0;

int main()
{
volatile long temp;
PLL_Init();
EnableI2CModule0();
temp=ReadRegister(0x00);
WriteRegister(0x2D,0x08);
temp=ReadRegister(0x2D);
WriteRegister(0x31,0x0B);
temp=ReadRegister(0x31);
while(1)
{
X_Axis1=ReadRegister(0x32);
X_Axis2=ReadRegister(0x33);
Y_Axis1=ReadRegister(0x34);
Y_Axis2=ReadRegister(0x35);
Z_Axis1=ReadRegister(0x36);
Z_Axis2=ReadRegister(0x37);
}
}

void PLL_Init(void){
// 0) Use RCC2
SYSCTL_RCC2_R |= 0x80000000; // USERCC2
// 1) bypass PLL while initializing
SYSCTL_RCC2_R |= 0x00000800; // BYPASS2, PLL bypass
// 2) select the crystal value and oscillator source
SYSCTL_RCC_R = (SYSCTL_RCC_R &~0x000007C0) // clear XTAL field, bits 10-6
+ 0x00000540; // 10101, configure for 16 MHz crystal
SYSCTL_RCC2_R &= ~0x00000070; // configure for main oscillator source
// 3) activate PLL by clearing PWRDN
SYSCTL_RCC2_R &= ~0x00002000;
// 4) set the desired system divider
SYSCTL_RCC2_R |= 0x40000000; // use 400 MHz PLL
SYSCTL_RCC2_R = (SYSCTL_RCC2_R&~ 0x1FC00000) // clear system clock divider
+ (4<<22); // configure for 80 MHz clock
// 5) wait for the PLL to lock by polling PLLLRIS
while((SYSCTL_RIS_R&0x00000040)==0){}; // wait for PLLRIS bit
// 6) enable use of PLL by clearing BYPASS
SYSCTL_RCC2_R &= ~0x00000800;
}

void EnableI2CModule0(void)
{
volatile int Delay=0;
SYSCTL_RCGCI2C_R|=0x00000001; //set i2c module 0 clock active
Delay=SYSCTL_RCGCI2C_R; //delay allow clock to stabilize
SYSCTL_RCGCGPIO_R |=0x00000002; //i2c module 0 is portB so activate clock for port B
Delay = SYSCTL_RCGCGPIO_R; //delay allow clock to stabilize
GPIO_PORTB_AFSEL_R|= 0x0000000C; //enable alternate functions for PB2 and PB3
GPIO_PORTB_ODR_R |= 0x00000008; //set PB3 (I2C SDA) for open drain
GPIO_PORTB_DEN_R |= 0xFF; //Enable digital on Port B
GPIO_PORTB_PCTL_R |=0x03;
I2C0_PP_R |= 0x01;
I2C0_MTPR_R |= 0x00000027; //set SCL clock
I2C0_MCR_R |= 0x00000010; //intialize mcr rigester with that value given in datasheet
}

uint8_t ReadRegister(uint8_t RegisterAddress)
{
volatile uint8_t result=0;
I2C0_MSA_R = 0x000000A6; //write operation
I2C0_MDR_R = RegisterAddress; //place data to send mdr register
I2C0_MCS_R = 0x00000007; //stop start run
while((I2C0_MCS_R &= 0x00000040)==1); //poll busy bit
I2C0_MSA_R = 0x000000A7; // read operation
I2C0_MCS_R = 0x00000007; // stop start run
while((I2C0_MCS_R &= 0x00000040)==1); //poll busy bit
result = I2C0_MDR_R;
return result;
}

void WriteRegister(uint8_t RegisterAddress,uint8_t Data)
{
I2C0_MSA_R = 0x000000A6; //write operation
I2C0_MDR_R = RegisterAddress; //place register address to set in mdr register
I2C0_MCS_R = 0x00000003; //burst send ( multiple bytes send )
while((I2C0_MCS_R &= 0x00000040)==1); //poll busy bit
I2C0_MDR_R = Data; //place data to be sent in mdr register
I2C0_MCS_R = 0x00000005; // transmit followed by stop state
while((I2C0_MCS_R &= 0x00000040)==1); //poll busy bit
}

最佳答案

您的 WriteRegisterReadRegister 函数不遵循 TM4C123G 数据表中定义的流程图。除了不检查或处理 MCS 错误标志外,图 16-10 多数据字节的主传输 显示,在写入 MCS 寄存器时,您应该在写入时断言特定位 所有位,你应该改为执行读-修改-写:

I2C0_MCS_R = 0x00000003; //burst send ( multiple bytes send ) 

应该是:

// I2CMCS = ---0-011
uint32_t mcs = I2C0_MCS_R ;
msc &= ~0x00000014; // ---0-0--
mcs |= 0x00000003; // ------11
I2C0_MCS_R = mcs ;

类似地:

I2C0_MCS_R = 0x00000005; // transmit followed by stop state 

应该是

// I2CMCS = ---0-101
mcs = I2C0_MCS_R ;
mcs &= ~0x00000012; // ---0--0-
mcs |= 0x00000005; // -----1-1
I2C0_MCS_R = mcs ;

enter image description here

ReadRegister() 有类似的问题(尽管在这种情况下不太可能成为问题):

I2C0_MCS_R = 0x00000007; //stop start run

应该严格是:

// I2CMCS = ---00111
uint32_t mcs = I2C0_MCS_R ;
mcs &= ~0x00000018; // ---00---
mcs |= 0x00000007; // -----111
I2C0_MCS_R = mcs ;

数据表建议位 31:5:

Software should not rely on the value of a reserved bit. To provide compatibility with future products, the value of a reserved bit should be preserved across a read-modify-write operation.

上面的代码就是这样做的,但实际上对于这个特定的产品来说不是必需的,但在任何情况下都是很好的做法。

enter image description here

在任何情况下,您都应该添加推荐的错误处理代码。可能是没有设置错误标志,但我们不知道,除非您检查它,这样做至少有助于调试 - 而不是步进代码,您可以简单地在错误上设置一个断点处理,然后全速运行。这将缩小可能性的数量。

关于c - tiva c上单步调试和运行程序的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42183843/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com