2016-06-11 2 views
0

처음으로 이런 식으로 보입니다. 하드웨어 오류라고 의심하기 시작했습니다. 배열 "test"의 내용을 보내려고 할 때마다 그 배열이 4 개보다 큽니다. 또는 선언에있는 모든 요소를 ​​초기화합니다.이 요소에는 초기화하려고하는 값 대신 0xff가 들어 있습니다.AVR gcc, 이상한 배열 동작

이 작동합니다. I는 동안의 어레이로부터 값을 판독 할 때 모두 판독 테스트 값과 일치 (LCD와 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++; 
} 

그것을 반환하지 않는이 대신 시험 [I] 값 0xff로 :

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++; 
} 

이 또한 작동을 반환 : 나는 다른 하나에 대한 MCU를 교환 리눅스

에서 컴파일하고가 예상대로 작동 할 때 잘 작동

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++; 
    } 

. 하드웨어 문제 여야합니다.

+1

이 질문은 특히 명확하지 않습니다. 제발 코드를 붙여 놓지 마시고 우리가 정신적으로 그것을 차용하지 않게하십시오. * 문제가 무엇인지 설명하십시오. 당신은 "0xFF"를 반환한다고 - 어디서부터? 이 코드는 아무 곳에도 표시되지 않습니다. 전송 문제가있는 경우 수신 측 결과에 신경을 쓰는 이유는 무엇입니까? 문제를 격리하십시오. 너 UART를 전송하고있어, 그렇지? 그럼 명백한 디버깅 단계는 실제로 포트에서 나오는 * 것을 보는 것입니다. –

+1

배열 크기가 변경 되더라도 루프 경계가 변경되지 않는다는 것을 알고 있습니까? 그것은 항상 'while (i <5)'입니다. 이것이'ARRAY_LENGTH' 매크로가 유용한 이유입니다. –

+0

제대로 게시하기 위해 내 게시물을 편집했습니다. 문제는 내가 normaly 할 배열을 할 때 배열 [] = {1,2,3} 및 그것은 0xff 포함 된 내 값 대신 4 개의 요소보다 큽니다. 6 개 이상의 요소 배열을 선언하고 마지막 요소를 건너 뛰고 초기화하면 잘 동작합니다. 나는 게으름에서 값을 바꾸지 않았고 (i <5), 문제에 영향을 미치지 않습니다. 배열에 4 개의 요소가 있다면 그것들을 올바르게 출력하고 + 정크 하나를 출력합니다. 5 개의 요소가 있다면 0xff를 5 번 인쇄합니다. 6 개의 요소가 있지만 5 개가 초기화되면 5 개의 적절한 값이됩니다. – Barricadexx

답변

0

당신의 문제는 당신이 USART를 오버로드하고 있다는 것입니다. GLCD_WriteData()이 매우 빠르며 USART_Transmit()은 전송할 문자를 버퍼링 한 다음 신속하게 반환한다고 가정합니다. 나는 당신의 하드웨어를 모른다, 그래서 나는 말할 수 없다. 그러나 USART를위한 네 글자 버퍼는 합리적으로 들린다.

송신하려고하는 실제 문자가 없어져서 5 자 예가 작동하지 않습니다. 대신 0xFF를 넣습니다. USART 버퍼의 상태를 확인하고 그 공간이 사용 가능할 때까지 기다려야합니다 (NOT 비어 있음 - 비효율적입니다!). 8250 개 및 16450 UART 칩을

개의 상태 비트있다 :

  • TSRE는 말한다 T ransmit S hift egister은 E mpty 인 그 R;
  • THRET egister은 E mpty 인 R을 olding H ransmit 을 말한다.

THRETSRE이 아닌 경우에도 설정할 수 있습니다. TSRE을 테스트하고 방이있을 때까지 다음 문자를 전송하지 않거나 버퍼 및 인터럽트 처리기를 설정합니다.

+0

I/O 하드웨어가 문제가 아니므로 MCU는 lcd의 busy 플래그를 확인하고 USART_transmit은 단일 문자 하드웨어 버퍼이며 비어있는 동안 버퍼 비어있는 플래그가 설정 될 때까지 프로그램을 중지합니다 . 128 개 요소의 배열을 만들 수 있으며 while 루프에서 값을 할당하면 잘 인쇄 할 수 있습니다. 배열 [5] = {1,2,3,4,5}를 수행하고 while 루프를 통해 읽는다면 이상한 이유로 0xFF가됩니다. 또 하나, 만약 내가 하나씩 읽어 보면 : USART_Transmit (array [0]) .. 5는 괜찮아요.하지만 그 코드에 읽는 동안 갑자기 모두 0xff가됩니다. – Barricadexx

+0

@Barricadexx 최적화를 변경하려고 시도 했습니까? – zviad

0

I/O 하드웨어가 아닌 경우 컴파일러가 잘못된 코드를 생성한다는 점만 생각하면됩니다. USART_Transmit()의 정확한 선언은 무엇입니까? uint8_t을 기대합니까? 또는 int (웬일인지)과 같은 다른 무엇입니까?즉, 항상 작동하는 경우 다음 컴파일러 문제가 아니라 하드웨어 문제가 생겼어요,

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

: 그것은 int 같은 뭔가가 있다면

는 다음 코드를 시도하십시오.

편집 : 제공 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보다이 더 낫습니다. LCD 디스플레이가 있습니다! UDRE0 다음, 그 코드 3이라고 가정

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'); 

: 나는 얼마나 많은 문자를 모르고 있지만 그것은

당신은 뭔가를 시도 할 수 ...이, 또는 그 문자를 전송하는 데 걸리는 시간 작동중인 경우 x00x00x00x00x00x08x00x00x00x00x08x00x00x00x08과 같은 시퀀스가 ​​발생합니다. x08x08x08이 생성되면 UCSR0A 비트가 붙어 하드웨어가됩니다.

+0

void USART_Transmit (uint8_t data) { // 빈 전송 버퍼를 기다립니다. while (! (UCSR0A & (1 << UDRE0))); // 데이터를 버퍼에 넣고 데이터를 전송합니다. UDR0 = data; } 코드에 동일한 5 개의 0xFF가 리셋됩니다. 나는 확실히 transmiting 작품입니다. 왜냐하면 나는 test [i]를 int로 바꾸더라도 'i'로 바꾸기 때문에 예상되는 시퀀스가 ​​0-4가되기 때문입니다. 나는 JTAG를 가지고 있었으면 좋겠다. 나는 기억을 들여다 볼 수 있었다. 나는 이걸 포기하고있다. 내가 가진 다른 칩을 위해 그것을 컴파일하고 잘 작동합니다. 그것은 지금 할 것입니다. 도움을 주셔서 감사합니다! 나는 단지 문제가 silocon에 있다고 가정 할 것이다. – Barricadexx

1

첫 번째 예에서는 배열 테스트 [4]를 벗어납니다. 배열에 길이가 4 개 밖에없는 경우 5 번 실행됩니다.

+0

그는 첫 번째 예제가 작동하지만 두 번째 예제는 그렇지 않다고 말했다. –