2016-06-11 2 views
0

Это первый раз, когда я вижу что-то подобное. Я начинаю подозревать, что это аппаратная ошибка. всякий раз, когда я пытаюсь отправить содержимое массива «test», и этот массив больше 4 элементов или я инициализирую все элементы в объявлении, он содержит 0xff вместо значений, с которыми я пытаюсь инициализировать.AVR gcc, странное поведение массива

это хорошо работает. когда я читаю значения из массива в то время (отправляя их на ЖК-дисплее и UART) оба показания согласуются со значениями тестов:

uint8_t i=0; 
uint8_t test[4] = {1,2,3,4}; 
    while(i<5){ 
    GLCD_WriteData(test[i]); 
    USART_Transmit(test[i]); 
    i++; 
} 

это не так, она возвращает 0xff вместо теста [I] значения:

uint8_t i=0; 
uint8_t test[5] = {1,2,3,4,5}; 
    while(i<5){ 
    GLCD_WriteData(test[i]); 
    USART_Transmit(test[i]); 
    i++; 
} 

но это работает! он возвращает соответствующие значения

uint8_t i=0; 
uint8_t test[6] = {1,2,3,4,5}; 
    while(i<5){ 
    GLCD_WriteData(test[i]); 
    USART_Transmit(test[i]); 
    i++; 
} 

это также работает:

uint8_t i=0; 
uint8_t test[5]; 
test[0]=1; 
test[1]=2; 
test[2]=3; 
test[3]=4; 
test[4]=5; 
    while(i<5){ 
    GLCD_WriteData(test[i]); 
    USART_Transmit(test[i]); 
    i++; 
    } 

он отлично работает при компиляции на Linux

я выгружена микроконтроллер для другой один, и он работает так, как надо. должна быть проблема с оборудованием

+1

Этот вопрос не особенно ясен. Пожалуйста, не просто вставляйте код и заставляйте нас мысленно различать его. * Объясните *, в чем проблема. Вы говорите «возвращает 0xFF» - откуда? Этот код не отображается нигде. Если ваша проблема заключается в передаче, почему мы заботимся о результатах приема? Изолируйте проблему. Вы передаете UART, верно? Ну, тогда очевидный шаг отладки - посмотреть, что на самом деле выходит * из порта. –

+1

Вы понимаете, что, хотя размер вашего массива меняется, границы вашего цикла никогда не меняются, не так ли? Это всегда 'while (i <5)'. Вот почему макрос «ARRAY_LENGTH» полезен. –

+0

Я отредактировал мое сообщение, чтобы сформировать его правильно. проблема заключается в том, что когда я инициализирую массив так, как обычно я делаю массив [] = {1,2,3}, и он больше 4 элементов вместо моих значений, он содержит 0xff. когда я объявляю 6 или более массив элементов и инициализую его пропускание последнего элемента, он отлично работает. Я не изменил (i <5) значения из ленивости, это не влияет на проблему. если массив имеет 4 элемента, он правильно печатает их + один нежелательный, если он имеет 5 элементов, он печатает 0xff пять раз, если он имеет 6 элементов, но 5 инициализированы, есть пять правильных значений – Barricadexx

ответ

0

Я думаю, ваша проблема в том, что вы перегружаете USART. Я предполагаю, что GLCD_WriteData() ОЧЕНЬ быстрый, и что USART_Transmit() буферизует символ для передачи, а затем быстро возвращается. Я не знаю вашего оборудования, поэтому я не могу сказать, но четырехсимвольный буфер для USART звучит разумно.

Ваши пятисимвольные примеры не работают, потому что фактический символ, который вы пытаетесь передать, теряется - поэтому вместо него помещается 0xFF. Вам нужно проверить состояние буфера USART и дождаться, пока он покажет, что пространство доступно (примечание NOT пустое - это было бы неэффективно!).

В UART чипов 8250 и 16450 существуют два бита статуса:

  • TSRE говорит, что T ransmit S hift R egister является Е MPTY;
  • THRE говорит о том, что Т ransmit Н Олдинг R egister является Е MPTY.

THRE может быть установлен, даже если TSRE не является - он занят. Я бы тестировал TSRE и не отправлял следующий символ до тех пор, пока не будет места - или настройте буфер и обработчик прерываний.

+0

не является проблемой, а MCU проверяет флаг занятости на lcd, а USART_transmit - это только один аппаратный буфер и пустой, пока он останавливает программу до тех пор, пока не будет установлен флаг пустого буфера , Я могу создать массив из 128 элементов, присваивать им значения в цикле while, и он будет печатать их в порядке. по какой-то странной причине, если я сделаю массив [5] = {1,2,3,4,5} и прочитал его через цикл while, это все 0xFF. еще одна вещь, если я прочитаю ее один за другим: USART_Transmit (array [0]) .. до 5, это нормально, но если я добавлю, что прочитал, то до этого кода он внезапно станет 0xff в обоих случаях – Barricadexx

+0

@Barricadexx Вы пытались изменить оптимизацию? – zviad

0

Если это не аппаратное обеспечение ввода-вывода, то единственное, что я могу придумать, это компилятор, создающий неправильный код. Каково точное объявление USART_Transmit()? Ожидает ли это uint8_t? Или что-то еще, вроде int (по какой-то причине)?

Если это что-то другое, как int, пожалуйста, попробуйте следующий код:

while(i<5){ 
    int c = test[i];   // Whatever USART_Transmit wants 
    GLCD_WriteData(test[i]); 
    USART_Transmit(c); 
    i++; 
} // while 

Если это всегда работает, то у вас есть проблема компилятора, а не аппаратная проблема.

EDIT: Код для USART_Transmit() при условии:

void USART_Transmit(uint8_t data) {
//Wait for empty transmit buffer
while(!(UCSR0A & (1<<UDRE0)));
//Put data into buffer, sends the data
UDR0 = data;
}

У вас есть что-то лучше чем JTAG - у вас есть ЖК-дисплей! Хотя я не знаю, сколько символов она имеет, или сколько времени требуется, чтобы передать характер ...

Вы могли бы попробовать что-то вроде:

char Hex(uint8_t nibble) { 
    return nibble<10 ? 
      '0'+nibble : 
      'A'+nibble-10; 
} // Hex 
... 
void Send(uint8_t c) { 
    uint8_t s; 
    UDR0 = c; // Send character NOW: don't wait! 
    do { 
     s = UCSR0A; // Get current USART state 
     //s = UCSR0A & (1<<UDRE0); // Or this: isolate ready bit... 
     GLCD_WriteData('x'); 
     GLCD_WriteData(Hex(s >> 4)); // Write state-hi hex 
     GLCD_WriteData(Hex(s & 0xF)); // Write state-lo hex 
    } while (!(s & (1<<UDRE0)));  // Until is actually ready 
} // Send(c) 
... 
Send('A'); 
Send('B'); 
Send('C'); 

Предполагая, что UDRE0 является 3, то этот код приведет к последовательности, такой как x00x00x00x00x00x08x00x00x00x00x08x00x00x00x08, если она работает. Если он производит x08x08x08, то у вас есть застрявший бит UCSR0A, и это аппаратное обеспечение.

+0

void USART_Transmit (данные uint8_t) { // Дождитесь пустого буфера передачи while (! (UCSR0A & (1 << UDRE0))); // Поместить данные в буфер, отправляет данные UDR0 = данные; } ваш код имеет то же самое, что и пять 0xFF. Я уверен, что передача работает, потому что если я заменил test [i] на «i», даже если это int, я получаю ожидаемую последовательность 0-4. Мне жаль, что у меня не было JTAG, поэтому я мог заглянуть в память. Я отказываюсь от этого. Я скомпилировал его для другого чипа, который у меня был, и он отлично работает. это будет делать пока. Спасибо, что пытались помочь! Я просто предполагаю, что проблема заключается в силоке – Barricadexx

1

В первом примере вы выходите за пределы массива test [4]. Вы работаете в 5 раз, когда массив имеет длину всего 4 элемента.

+0

Хотя он сказал, что первый пример работает, но второй пример этого не делает. –

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