Erro na tx serial do str711

Software e Hardware para linha ARM

Moderadores: 51, guest2003, Renie, gpenga

Erro na tx serial do str711

Mensagempor stauer » 31 Jan 2008 09:09

Olá,

Estou tendo problema com µC str711fr2 muito intrigante. O problema esta no envio de dados pela serial, por exemplo enviado 0x55, no outro µC/PC chega 0x03, a hipótese de interferência foi descartada pois o valores são sempre os mesmos e enviando string não apresenta erro, também foi testada várias velocidade e o problema persiste inclusive com os mesmo valores.
O compilador é o gcc versão 4.1.1 utilizando a ultima versão da STR71xlib encontrada no site da ST.

O código resumido utilizado para representar o problema é este:
-------------
Código: Selecionar todos
#include <stdarg.h>
#include <stdio.h>
#include <71x_lib.h>
#include <71x_map.h>
#include <gpio.h>

#define UART0_Rx_Pin (0x0001<<8)
#define UART0_Tx_Pin (0x0001<<9)

int main (void){

   /* Configuracao do PLL com cristal de 16Mhz para os clocks Core:48Mhz APB1:24Mhz APB2:24Mhz ------------*/
   // clk / 2
   RCCU_Div2Config( ENABLE );
   // APB1
   RCCU_FCLKConfig ( RCCU_RCLK_2 );
   // APB2
   RCCU_PCLKConfig ( RCCU_RCLK_2 );
   // Configurar MCLK, RCCU_DEFAULT = RCLK /1
   RCCU_MCLKConfig ( RCCU_DEFAULT );
   // Configurar PLL1 ( * 12 , / 2 )
   RCCU_PLL1Config ( RCCU_PLL1_Mul_12, RCCU_Div_2 );
   // Aguarda PLL ativar (lock)
   while( RCCU_FlagStatus( RCCU_PLL1_LOCK ) == RESET ) ;
   // Seleciona PLL1 como fonte de clock para RCLK
   RCCU_RCLKSourceConfig (RCCU_PLL1_Output);

   /* Configure the UART0 pins */
   GPIO_Config(GPIO0, UART0_Tx_Pin, GPIO_AF_PP);
   GPIO_Config(GPIO0, UART0_Rx_Pin, GPIO_IN_TRI_CMOS);

   /*  Configure the UART X */
   UART_OnOffConfig( UART0, ENABLE );       /*  Turn UART0 on */
   //UART_FifoConfig ( UART0, ENABLE );      /*  Disable FIFOs */
   UART_FifoReset  ( UART0 , UART_RxFIFO ); /*  Reset the UART_RxFIFO */
   UART_FifoReset  ( UART0 , UART_TxFIFO ); /*  Reset the UART_TxFIFO */
   UART_LoopBackConfig(UART0 , DISABLE );   /*  Disable Loop Back */
   /* Configure the UART0 as following:
   - Baudrate = 9600 Bps
   - No parity
   - 8 data bits
   - 1 stop bit */
   UART_Config( UART0, 9600, UART_NO_PARITY, UART_1_StopBits ,UARTM_8D );
   UART_RxConfig( UART0, ENABLE );          /*  Enable Rx */

   UART_StringSend(UART0, "Teste 123");
     UART_ByteSend( UART0, 0 );
   for (int ind = 0; ind <= 255;ind++){
       UART_ByteSend(UART0,(u8 *)ind);
   }
   UART_ByteSend( UART0, 255 );
}

-------------

A saída do código acima é esta:
---
Código: Selecionar todos
TX = valor em decimal que sai do µC
RX = valor em decimal que chega no outro µC ou PC

Tx   Rx
----------------------------
Teste 123   Teste 123
0   24
0   24
1   240
2   159
3   229
4   24
5   240
6   159
7   229
8   24
9   240
10   159
11   229
12   24
13   240
14   159
15   229
16   24
17   240
18   159
19   229
20   0
21   0
22   160
23   225
24   24
25   240
26   159
27   229
28   24
29   240
30   159
31   229
32   192
33   0
34   0
35   64
36   160
37   2
38   0
39   64
40   128
41   2
42   0
43   64
44   188
45   2
46   0
47   64
48   220
49   2
50   0
51   64
52   0
53   0
54   0
55   0
56   64
57   2
58   0
59   64
60   252
61   2
62   0
63   64
64   28
65   3
66   0
67   64
68   52
69   3
70   0
71   64
72   76
73   3
74   0
75   64
76   100
77   3
78   0
79   64
80   124
81   3
82   0
83   64
84   148
85   3
86   0
87   64
88   172
89   3
90   0
91   64
92   196
93   3
94   0
95   64
96   220
97   3
98   0
99   64
100   244
101   3
102   0
103   64
104   12
105   4
106   0
107   64
108   36
109   4
110   0
111   64
112   60
113   4
114   0
115   64
116   84
117   4
118   0
119   64
120   108
121   4
122   0
123   64
124   132
125   4
126   0
127   64
128   156
129   4
130   0
131   64
132   180
133   4
134   0
135   64
136   204
137   4
138   0
139   64
140   228
141   4
142   0
143   64
144   252
145   4
146   0
147   64
148   20
149   5
150   0
151   64
152   0
153   0
154   0
155   0
156   0
157   0
158   0
159   0
160   0
161   0
162   0
163   0
164   44
165   5
166   0
167   64
168   68
169   5
170   0
171   64
172   0
173   0
174   0
175   0
176   0
177   0
178   0
179   0
180   92
181   5
182   0
183   64
184   116
185   5
186   0
187   64
188   140
189   5
190   0
191   64
192   44
193   241
194   159
195   229
196   0
197   0
198   160
199   225
200   0
201   0
202   160
203   225
204   0
205   0
206   160
207   225
208   0
209   0
210   160
211   225
212   0
213   0
214   160
215   225
216   0
217   0
218   160
219   225
220   0
221   0
222   160
223   225
224   0
225   0
226   160
227   225
228   0
229   0
230   160
231   225
232   215
233   240
234   33
235   227
236   4
237   209
238   159
239   229
240   219
241   240
242   33
243   227
244   0
245   209
246   159
247   229
248   211
249   240
250   33
251   227
252   252
253   208
254   159
255   229
255   229

---
Lembrando que a string é corretamente interpretada no terminal.

Se alguém tiver alguma dica,
desde já agradeço.
stauer
Bit
 
Mensagens: 9
Registrado em: 23 Jul 2007 17:24
Localização: Blumenau

Mensagempor Fábio Pereira » 31 Jan 2008 09:14

Você já testou os exemplos do meu livro?

Pela descrição o problema parece estar relacionado a uma possível diferença de baud-rate.

T+
Fábio Pereira
embeddedsystems.io
Avatar do usuário
Fábio Pereira
Word
 
Mensagens: 674
Registrado em: 16 Out 2006 09:07
Localização: Kitchener, ON

Mensagempor stauer » 31 Jan 2008 09:18

Fábio, não testei o exemplos do teu livro, mas se é relacionada a uma possível diferença de baud-rate, a string não deveria apresentar erro tb?
As string's enviadas não apresentam erro.

tkz.
stauer
Bit
 
Mensagens: 9
Registrado em: 23 Jul 2007 17:24
Localização: Blumenau

Mensagempor Maia » 31 Jan 2008 10:55

Parece que vc está mandando um ponteiro pro dado "(u8 *)ind" e não o dado em si. Tira o asterisco e testa.
Abraços,
Maia
Avatar do usuário
Maia
Byte
 
Mensagens: 348
Registrado em: 15 Out 2006 16:25
Localização: Rio de Janeiro

Mensagempor stauer » 31 Jan 2008 11:09

Já fiz esse teste, na verdade esse código ai foi colocado como último teste.
A função da lib do st já pega o ponteiro:
void UART_ByteSend(UART_TypeDef *UARTx, u8 *Data)

O pior é que UART_StringSend usa o UART_ByteSend por trás.
:cry:
stauer
Bit
 
Mensagens: 9
Registrado em: 23 Jul 2007 17:24
Localização: Blumenau

Mensagempor stauer » 31 Jan 2008 11:27

Descobri o problema, é um bug na função UART_ByteSend, eu acredito que esse if deve estar furado, fazendo que ele se atropele ao jogar os dados na serial.

Código: Selecionar todos
void UART_ByteSend(UART_TypeDef *UARTx, u8 *Data)
{
 /* if FIFO ENABLED */ 
 if (UARTx->CR & 0x0400)

    /* Wait until the TxFIFO contains at least 1 free place */
    while((UARTx->SR & UART_TxFull));

 /* if FIFO DISABLED */ 
 else

    /* Wait until the transmit shift register is empty */
    while (!(UARTx->SR & UART_TxEmpty));

  UARTx->TxBUFR = *Data;
}



fiz a tx direto na interação e funcionou:
Código: Selecionar todos
for (int ind = 0; ind <= 255;ind++){
   //while((UART0->SR & UART_TxFull));
   while (!(UART0->SR & UART_TxEmpty));
   //UART_ByteSend(UART0,ind);
   UART0->TxBUFR = ind;
}


O estranho é que funcionava com string, e o UART_StringSend chama por trás o UART_ByteSend :?
stauer
Bit
 
Mensagens: 9
Registrado em: 23 Jul 2007 17:24
Localização: Blumenau

Mensagempor Fábio Pereira » 31 Jan 2008 14:49

Eu até ia comentar isso ... Não uso e não gosto de funções prontas. Tanto que no meu livro só utilizei acesso direto aos registradores.

T+
Fábio Pereira
embeddedsystems.io
Avatar do usuário
Fábio Pereira
Word
 
Mensagens: 674
Registrado em: 16 Out 2006 09:07
Localização: Kitchener, ON

Mensagempor filipe.renaldi » 31 Jan 2008 15:25

A função espera um ponteiro para o dado:

Código: Selecionar todos
void UART_ByteSend(UART_TypeDef *UARTx, u8 *Data)


Mas está sendo enviado um ponteiro referenciando de 0 à 255.
Para enviar os valores de 0-255, deveria ser enviado o endereço da variável ind:

Código: Selecionar todos
for (int ind = 0; ind <= 255;ind++){
       UART_ByteSend(UART0,(u8 *)&ind);
   }


Mesmo que sejam acessado direto os registradores, é natural por questão de organização criar funções especialiazadas.
--
Att,
Filipe Renaldi.
filipe.renaldi
 
Mensagens: 4
Registrado em: 23 Ago 2007 09:30
Localização: Blumenau

Mensagempor stauer » 06 Fev 2008 10:41

Obrigado Filipe, é exatamente isto que você citou.
Obrigado ao demais pelos palpites.

[]'s
stauer
Bit
 
Mensagens: 9
Registrado em: 23 Jul 2007 17:24
Localização: Blumenau

Mensagempor tcpipchip » 06 Fev 2008 11:07

Fiquei curioso FABIO

Pq voce nao gosta de funçoes prontas ?
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor Fábio Pereira » 06 Fev 2008 12:52

Muito simples TCPIPCHIP:

Funções prontas mascaram o que realmente acontece no hardware.

Escrever suas próprias funções de baixo nível significa maior domínio sobre o hardware e uma maior adequação as necessidades da aplicação.

Veja o típico exemplo do printf e do sprintf: muitas vezes o que você quer fazer é simplesmente converter um valor binário para ASCII de forma a enviá-lo pela serial ou apresentá-lo em um display, mas acaba tendo de utilizar uma função genérica e com muito mais recursos, os quais na sua maioria não são utilizados (mas ocupam preciosos recursos de memória).

Neste caso, pode ser muito mais interessante escrever uma função para a conversão de base, do que utilizar uma função de biblioteca da linguagem C.

Veja, não sou contra a utilização de funções prontas e nem de bibliotecas, mas é necessário lembrar que todo bônus possui também um ônus (que nem sempre é tão claro ou evidente).

No meu livro sobre ARMs, por exemplo, toda a implementação do exemplo do dispositivo HID foi feita do zero, manipulando registradores "a mão". O motivo disso? Didaticamente é muito mais claro você mostrar como se faz e porque se faz, do que simplesmente utilizar uma função que encapsula tudo, mas que não explica como se faz.

Aliás, ao utilizar tais funções, um dos ônus digamos "não tão claros" é o de que você se torna refém da mesma. Se a aplicação não funcionar e o motivo for um bug dentro do código da função, aí a coisa complica.

Para encerrar, só gostaria de fazer um comentário: não gosto de como a ST e outros fabricantes tratam o tema ARM e organizam seus headers de descrição de dispositivo.

Os exemplos fornecidos pela ST (e outros fabricantes) para os compiladores IAR e GCC, utilizam diversas funções e macros que dificultam o entendimento do programador, escondendo o que realmente acontece no chip.

Outra coisa horrível é a insistência em se utilizar valores hexadecimais na atribuição de registradores de periféricos. Essa parece ser uma prática comum nos ambientes ARM, deve ser para aumentar a idéia de complexidade e transmitir o recado: ARM não é para você, simples mortal.

Por quê não utilizar símbolos ao invés de valores hexadecimais criptográficos? O quê é mais fácil de ler e entender:

ADC_CSR = bSINGLE_CHAN | bADC_CH0;

ou:

ADC_CSR = 0x0040;

????

Depurar um código escrito nesta segunda forma é algo realmente apavorante.
Fábio Pereira
embeddedsystems.io
Avatar do usuário
Fábio Pereira
Word
 
Mensagens: 674
Registrado em: 16 Out 2006 09:07
Localização: Kitchener, ON

Mensagempor tcpipchip » 06 Fev 2008 15:30

Concordo

O printf é o exemplo clássico!

TCPIPCHIP
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!


Voltar para ARM

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x