2017-02-12 27 views
0

У меня есть TIVA tm4c123G Я пытался создать связь между ним и моим ADXL345-сенсором, используя протокол I2C, который мне удалось написать и прочитать с акселерометра показания адрес устройства и значения регистра, которые я только что написал, что означает, что все работает нормально. Однако я пробовал это поэтапно отлаживать в keil, и он отлично работает, но если я запустил программу, он будет давать нули целиком, и я понятия не имею, почему? Должен ли я добавлять задержки между записью и чтением из регистров или что происходит в моем коде?Различные результаты между программой отладки и запуска шага по tiva c

Вот мой код прилагается
Я использую часы 80 МГц для системы, и я думаю, что это может быть проблемой, однако, как код идет слишком быстро к выполнению следующей передачи и должна быть некоторая задержка ? Я не уверен, что я только угадываю, пожалуйста, спасибо спасибо!

также мое подключение к 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 
} 
+0

извините за проблемы с отступом, но сайт по какой-то причине меня отстал, я тоже его ненавижу. –

+0

update, попробовал добавить некоторые задержки между операциями чтения и записи, все еще дает нули при чтении, и все же поэтапная отладка дает правильные результаты. –

+0

@MarkYisri извините меня, но я могу проиллюстрировать больше о том, как вне темы, не связанной или какой части не дать четкую информацию? также я не прошу вас решить мою проблему с I2C. Мне просто нужен кто-то, кто он более эксперт, чем я, в микроконтроллерах, чтобы сказать мне, что происходит неправильно, мой I2C работает нормально, так как чтение выполняется в пошаговой отладке в случае вы не читали оригинальное сообщение :), но спасибо за вашу помощь –

ответ

2

как @Clifford объяснил, что я должен следить за блок-схемами, и хотя его ответ абсолютно прав, он не дал мне никаких результатов (ранее давал значения в случае вступления в функцию, после чего дал нули), но я заметил что-то в блок-схемах, которые я раньше не замечал, что противоречит с разделом инициализации и конфигурации в техпаспорте

initialization and configuration from the datasheet

теперь, как говорится в пункте 11, что вы должны быть опрашивает шины занят бит регистр MCS, но это неверно и противоречит блок-схемам, блок-схемы являются более правильными, так как вы должны проверить, занята ли шина перед отправкой чего-либо, а затем проверьте, занят ли бит хозяина, прежде чем читать из регистра MDR или перейти к выполнению, и дальнейшие шаги

В основном правильные шаги в инициализации и конфигурации должны быть: перед шагом 10 опросить бит занятости занятой шины в случае, если какой-либо другой мастер отправляет, который может быть опущен в случае одного ведущего

после шага 10 опросить бит занятой до чтения или перейти к дальнейшему шагу, чтобы заключить, завершена ли передача, и мастер находится в режиме ожидания или не

Извините, я чувствую себя полным идиотом теперь, чтобы не читать блок-схемы внимательно, но я следовал anot ее часть, которая является частью инициализации и конфигурации, принимает факт, который не был там, что оба должны означать одно и то же.

Я также обнаружил, что он корректно работает в API tivaware в соответствии с блок-схемами, а не в другом разделе в техническом описании, однако я не хотел использовать API Tivaware, поскольку я с нетерпением жду таких проблем, которые приводят к лучшее понимание того, как все работает

еще раз спасибо за помощь @Clifford cheers!

+0

окончательный код должен заменять бит для проверки вместо 0x00000040 в регистре MCS должен быть 0x00000001, который является занятым битом, а не занятым битом шины –

+0

Проводя подробное описание решения, которое у вас есть, является очень общительным - хорошая работа. – Clifford

+0

У меня было так много проблем, чтобы найти реальное решение, все просто говорят, что используют tivaware, и делайте с ним, но я не хочу идти простым путем, трудный путь всегда помогает вам лучше понять вещи, и кто знает, что это может реально помочь кто-то в будущем: D благодарит вас за вашу помощь, если бы не ваши блок-схемы, я бы никогда не нашел решение на самом деле: D –

2

Вашего WriteRegister и ReadRegister функция не следует определенным блок-схеме в паспорте TM4C123G. Помимо проверки или обработки флага MCS ERROR, на рисунке 16-10 Мастер TRANSMIT из нескольких байтов данных показывает, что при записи регистра 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:

программного обеспечение не должно полагаться на стоимости зарезервированного бита.Чтобы обеспечить совместимость с будущими продуктами, необходимо сохранить значение зарезервированного бита во время операции чтения-изменения-записи.

Вышеприведенный код делает это, но на практике не обязательно использовать этот конкретный продукт, но это хорошая практика в любом случае.

enter image description here

В любом случае вы должны добавить код обработки ошибок рекомендуется. Возможно, что флаг ошибки не установлен, но мы не знаем, что, если вы его не проверите, и это будет по крайней мере способствовать отладке - вместо того, чтобы наступить на код, вы можете просто установить точку останова на ошибке а затем работать на полной скорости. Это сократит количество возможностей.

+0

правильно во всем, что вы сказали, за исключением того, что оно не исправило его при попытке метода, который вы ему предоставили, он не дал никакого чтения, хотя ваш метод как я вижу, что более правильно, даже шаг за шагом, который использовался для работы также поэтапно, я имею в виду «переход на функцию чтения и запись функций». Извините, я не уточнил это ранее. Я нашел исправление из блок-схем, которые вы только что показали, я внимательно их прочитал, и есть ошибка в инициализации и конфигурации в таблице данных. Я понятия не имею, как это возможно, но это вторая ошибка, которую я нахожу в таблице данных. далеко –

 Смежные вопросы

  • Нет связанных вопросов^_^