У меня есть TIVA tm4c123G Я пытался создать связь между ним и моим ADXL345-сенсором, используя протокол I2C, который мне удалось написать и прочитать с акселерометра показания адрес устройства и значения регистра, которые я только что написал, что означает, что все работает нормально. Однако я пробовал это поэтапно отлаживать в keil, и он отлично работает, но если я запустил программу, он будет давать нули целиком, и я понятия не имею, почему? Должен ли я добавлять задержки между записью и чтением из регистров или что происходит в моем коде?Различные результаты между программой отладки и запуска шага по tiva c
Вот мой код прилагается
Я использую часы 80 МГц для системы, и я думаю, что это может быть проблемой, однако, как код идет слишком быстро к выполнению следующей передачи и должна быть некоторая задержка ? Я не уверен, что я только угадываю, пожалуйста, спасибо спасибо!
также мое подключение к ADXL является
- Vcc -> 3,3 вольта
- GND -> земля
- CS -> 3,3 вольта
- SDO -> земля
- SDA -> PB3
- 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
}
извините за проблемы с отступом, но сайт по какой-то причине меня отстал, я тоже его ненавижу. –
update, попробовал добавить некоторые задержки между операциями чтения и записи, все еще дает нули при чтении, и все же поэтапная отладка дает правильные результаты. –
@MarkYisri извините меня, но я могу проиллюстрировать больше о том, как вне темы, не связанной или какой части не дать четкую информацию? также я не прошу вас решить мою проблему с I2C. Мне просто нужен кто-то, кто он более эксперт, чем я, в микроконтроллерах, чтобы сказать мне, что происходит неправильно, мой I2C работает нормально, так как чтение выполняется в пошаговой отладке в случае вы не читали оригинальное сообщение :), но спасибо за вашу помощь –