 |
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
evolution Član

Pridružen-a: Tor 20 Jun 2006 2:07 Prispevkov: 37 Aktiv.: 0.16 Kraj: Izola, Ljubljana
|
Objavljeno: Pon Avg 18, 2008 11:37 am Naslov sporočila: Konfiguracija USART-a?? |
|
|
Pozdravljeni,
imam en nerazumljiv problem z komunikacijo prek USART-a. Nikakor ne morem pravilno pošiljati podatke na pc. Uporabljam kontroler od Atmela AT91SAM7S32, program pa sem spisal v uVison-u (compiler: Real View). Zgleda, kakor da imam probleme z nastavitvijo hitrosti pošiljanja (čeprav sem za pc in krmilnik nastavil npr. 115200), saj na pc-ju sprejemam kar neke znake. Ostale nastavitve (mode=Normal, Clock=MCK, 8-data bit, No patity, 1 stop bit) mislim, da so pravilno nastavljene. Frekvenca zunanjega oscilatorja je 18.432 MHz, MCK pa sem prebral kar iz PMC-ja (Power Management Controller) znotraj uVisiona, ko sem pognal debugger. Probal sem tudi spreminjati zaporedje pošiljanja (prvi MSB oz. LSB), vendar ni bilo nič boljše.
Ni mi jasno, kje tiči napaka. Realiziral sem tudi wait() funkcijo z enakimi nastavitvami za PMC in mi dioda utripa z točno frekvenco, kakor jo nastavim.
Ima kdo kakšen predlog, kaj naj še preverim??
Hvala, Andrej
|
|
Nazaj na vrh |
|
 |
Glitch Član

Pridružen-a: Pet 07 Apr 2006 11:40 Prispevkov: 1477 Aktiv.: 6.30
|
Objavljeno: Pon Avg 18, 2008 11:48 am Naslov sporočila: |
|
|
Če se ne motim je za omenjeni procesor že example, ki uporablja UART. Če ni za Keila je pa za IAR definitivno.
|
|
Nazaj na vrh |
|
 |
jur Član


Pridružen-a: Pet 02 Dec 2005 14:45 Prispevkov: 5142 Aktiv.: 21.65 Kraj: [color=zelena]Ljubljana[/color]
|
Objavljeno: Pon Avg 18, 2008 2:08 pm Naslov sporočila: |
|
|
Ali imaš tudi rs-232 pretvornike, ali kar pošiljaš iz chipa na PC?
Zmanjšaj hitrost na 9600 b/s.
Jur
|
|
Nazaj na vrh |
|
 |
evolution Član

Pridružen-a: Tor 20 Jun 2006 2:07 Prispevkov: 37 Aktiv.: 0.16 Kraj: Izola, Ljubljana
|
Objavljeno: Pon Avg 18, 2008 2:21 pm Naslov sporočila: |
|
|
Ja, imam MAX3232. Vendar sem že probal tudi z nižjimi hitrostmi, pa vseeno ni delalo. Sicer sem pa program naredil po primeru iz "C:\Keil\ARM\Boards\Atmel\AT91SAM7S-EK\Hello", vendar sem tudi nekaj svojih stvari dal noter. Bom naredil še en nov projekt (čistopis) in probal če dela. Javim ko bo narejeno.
|
|
Nazaj na vrh |
|
 |
evolution Član

Pridružen-a: Tor 20 Jun 2006 2:07 Prispevkov: 37 Aktiv.: 0.16 Kraj: Izola, Ljubljana
|
Objavljeno: Pon Avg 18, 2008 4:44 pm Naslov sporočila: |
|
|
Še vedno mi ni uspelo pognati komunikacije. Sem pa nekaj zanimivega odkril pri debuggiranju: predvideval sem, da se bo znak pri pošiljanju vpisal v "Transmit Holding Register" (US_THR). Presenečeno sem odkril, da se le ta vpiše v US0_RHR.
Koda, ki povzroči to (prvi del zagotovi, da lahko pošljem tudi CR, drugi del pa za "navadne" znake):
int sendchar (int ch) {
if (ch == '\n') {
while (!(pUSART->US_CSR & AT91C_US_TXRDY));
pUSART->US_THR = '\r';
}
while (!(pUSART->US_CSR & AT91C_US_TXRDY));
return (pUSART->US_THR = ch);
}
Ko pa sem "US_THR" iskal v "AT91SAM7S32.h" datoteki sem našel samo en zadetek:
AT91_REG US_RHR; // Receiver Holding Register
Zdi se mi, kakor da mi nekaj manjka (npr. kakšen odmik, da se pravilno vpiše v THR). Poleg tega pa se mi zdi zelo nelogično, saj kljub vsemu sem neke podatke sprejemal (je pa res, da sem jih sprejemal samo pri BR=115200, pri BR=9600 ne dobim ničesar).
Kakšna ideja?
|
|
Nazaj na vrh |
|
 |
Glitch Član

Pridružen-a: Pet 07 Apr 2006 11:40 Prispevkov: 1477 Aktiv.: 6.30
|
Objavljeno: Pon Avg 18, 2008 6:10 pm Naslov sporočila: |
|
|
US_RHR je del strukture, kjer je AT91_REG tip spremenljivke. Poišči definicijo AT91_REG. Verjetno je #define AT91_REG ali pa typedef
Struktura je pUSART oz. kazalec na strukturo, glede na p spredaj. Poišči deklaracijo pUSART. Tako boš našel vse kar rabiš.
Vrnil se bom na začetek. Ali si poskusil originalni primer? Zakaj? Zato, ker si napisal si, da si nekaj spreminjal. Definitivno ti mora original delati brez problemov. Ampak predvidevam, da ti dela. Kaj si pa spreminjal? Predvidevam da "samo baude", vendar mislim, da si pozabil upoštevati popolno inicializacijo.
|
|
Nazaj na vrh |
|
 |
evolution Član

Pridružen-a: Tor 20 Jun 2006 2:07 Prispevkov: 37 Aktiv.: 0.16 Kraj: Izola, Ljubljana
|
Objavljeno: Tor Avg 19, 2008 12:28 am Naslov sporočila: |
|
|
Ja, AT91_REG je definiran v "AT91SAM7S32.h" datoteki:
typedef volatile unsigned int AT91_REG; // Hardware register definition
V isti datoreki je tudi del te strukture:
AT91_REG US_RHR; // Receiver Holding Register
Deklaracijo za pUSART imam v isti datoteki, kot kodo iz prejšnje objave ("Serial.c"):
AT91S_USART * pUSART = AT91C_BASE_US0; /* Global Pointer to USART0 */
Tudi to iz "AT91SAM7S32.h":
#define AT91C_BASE_US0 ((AT91PS_USART) 0xFFFC0000) //(US0) Base Address
Vrnem se na začetek: od originalnega primera sem spremenil to, da sem ga priredil za uporabo procesorja AT91SAM7S32 namesto AT91SAM7S64 (spremenil sem katero *.h datoteko naj uporabi, in spremenil razporeditev pinov za LED diode v Board.h. Ostalo sem spremenil tudi tekst (namesto "Hello World" v "aaa", ipd) in zaporedje, kdaj naj se LED vžiga in vgaša (ki deluje). Kakorkoli sem počistil vse moje spremembe, in imam sledeči source:
// Main program ********************************************
#include <stdio.h>
#include <AT91SAM7S32.H>
#include "Board.h"
AT91S_PIO * pPIO = AT91C_BASE_PIOA; /* Global Pointer to PIO */
extern volatile unsigned long timeval; /* Current Time Tick */
void wait (unsigned long time) { /* Wait Function */
unsigned long tick;
tick = timeval;
while ((timeval - tick) < time); /* Wait for specified Time */
}
extern void init_timer (void); /* Initialize Timer */
extern void init_serial (void); /* Initialize Serial Interface */
int main (void) {
*AT91C_PMC_PCER = (1 << AT91C_ID_PIOA) | /* Enable Clock for PIO */
(1 << AT91C_ID_US0); /* Enable Clock for USART0 */
pPIO->PIO_PER = LED_MASK; /* Enable PIO for LED */
pPIO->PIO_OER = LED_MASK; /* LED .. are Outputs */
pPIO->PIO_SODR = LED_MASK; /* Turn off LED's ("1") */
init_timer (); /* Initialize Timer */
init_serial(); /* Initialize Serial Interface */
while (1) { /* Loop forever */
pPIO->PIO_CODR = LED_MASK ; /* Turn On LED1 */
printf ("Hello World !\n"); /* Print "Hello World !" */
wait(100); /* Wait 100ms */
pPIO->PIO_SODR = LED_MASK; /* Turn Off LED1 */
wait(100); /* Wait 100ms */
}
}
Znotraj Serial.c pa imam inicializacijo ipd:
// Serial.c ****************************************************
#include <AT91SAM7S32.H> /* AT91SAM7S64 definitions */
#include "Board.h"
#define BR 9600 /* Baud Rate */
#define BRD (MCK/16/BR) /* Baud Rate Divisor */
AT91S_USART * pUSART = AT91C_BASE_US0; /* Global Pointer to USART0 */
void init_serial (void) { /* Initialize Serial Interface */
*AT91C_PIOA_PDR = AT91C_PA5_RXD0 | /* Enable RxD0 Pin */
AT91C_PA6_TXD0; /* Enalbe TxD0 Pin */
pUSART->US_CR = AT91C_US_RSTRX | /* Reset Receiver */
AT91C_US_RSTTX | /* Reset Transmitter */
AT91C_US_RXDIS | /* Receiver Disable */
AT91C_US_TXDIS; /* Transmitter Disable */
pUSART->US_MR = AT91C_US_USMODE_NORMAL | /* Normal Mode */
AT91C_US_CLKS_CLOCK | /* Clock = MCK */
AT91C_US_CHRL_8_BITS | /* 8-bit Data */
AT91C_US_PAR_NONE | /* No Parity */
AT91C_US_NBSTOP_1_BIT; /* 1 Stop Bit */
pUSART->US_BRGR = BRD; /* Baud Rate Divisor */
pUSART->US_CR = AT91C_US_RXEN | /* Receiver Enable */
AT91C_US_TXEN; /* Transmitter Enable */
}
int sendchar (int ch) { /* Write character to Serial Port */
if (ch == '\n') { /* Check for CR */
while (!(pUSART->US_CSR & AT91C_US_TXRDY)); /* Wait for Empty Tx Buffer */
pUSART->US_THR = '\r'; /* Output CR */
}
while (!(pUSART->US_CSR & AT91C_US_TXRDY)); /* Wait for Empty Tx Buffer */
return (pUSART->US_THR = ch); /* Transmit Character */
}
int getkey (void) { /* Read character from Serial Port */
while (!(pUSART->US_CSR & AT91C_US_RXRDY)); /* Wait for Full Rx Buffer */
return (pUSART->US_RHR); /* Read Character */
}
Zadnjo najbolj čudno ugotovitev, sem dosegel, ko sem probal program debugirati še v simulatorju. V simulatorju namreč vpiše znak, ki je v pošiljanju v pravi register (US_THR Transmitter Holding Register). Ko pa izvajam debuggiranje z Ulink2, pa kaže, da se znak, ki je v pošiljanju vpiše v US_RHR (Recive Holding Register).
Iz tega razmišljam, da se mi ni slučajno pojavil stik med Tx in Rx na ploščici, in gre poslani znak takoj v Rx, ali pa morda Ulink2 "laže", ali pa kaj tretjega ???
|
|
Nazaj na vrh |
|
 |
Glitch Član

Pridružen-a: Pet 07 Apr 2006 11:40 Prispevkov: 1477 Aktiv.: 6.30
|
Objavljeno: Tor Avg 19, 2008 12:36 am Naslov sporočila: |
|
|
Dobiš odgovor še danes (ampak ne prej kot popoldan). Wooooooo glej koliko je že ura, jaz pa še vedno pišem dokumentacijo. I must be mad
Gremo spat.
[spremenjeno precej kasneje]
Tako na prvi pogled izgleda normalno, prav tako primerjava kode s primerom (ADC example) na Keilovi strani. Eno možnost si že omenil (HW težava), vseeno pa preveri nastavitve projekta in pa ... ta printf. Če se ne motim, moraš imeti retarget.c vključeno? Poskusi tudi pisati na UART neposredno iz kode (torej direktno v register, vendar ne preko JTAG).
|
|
Nazaj na vrh |
|
 |
Glitch Član

Pridružen-a: Pet 07 Apr 2006 11:40 Prispevkov: 1477 Aktiv.: 6.30
|
Objavljeno: Tor Avg 19, 2008 9:37 pm Naslov sporočila: |
|
|
Pa zakaj Keil ne naredi en generalni update na svojih straneh, ker ima prastare datasheete. Če že nekaj imajo, naj imajo poštimatno ali pa sploh ne. Kekci.
|
|
Nazaj na vrh |
|
 |
evolution Član

Pridružen-a: Tor 20 Jun 2006 2:07 Prispevkov: 37 Aktiv.: 0.16 Kraj: Izola, Ljubljana
|
Objavljeno: Tor Avg 19, 2008 10:06 pm Naslov sporočila: |
|
|
Tekom nadaljnega debugiranja sem ugotovil še nekaj čudnega. Za inicializacijo komunicacije uporabim funkcijo"init_serial()", ki je opisana v Serial.c datoteki (ki sem jo prilepil v prejšnjo objavo). V zadnji in predzadnji vrstici te funkcije enable-am reciver in transmitter:
pUSART->US_CR = AT91C_US_RXEN | /* Receiver Enable */
AT91C_US_TXEN; /* Transmitter Enable */
Čudno je to, se bita TXEN in RXEN v US_CR (USART CONTROL REGISTER) ne spremenita (polje ostane brez kljukice, torej 0), čeprav pričakujem da postaneta 1. Preveril sem, kje sta definirana AT91C_US_RXEN in AT91C_US_TXEN. Definirana sta v datoteki AT91SAM7S32.h, kjer sem začudeno ugotovil, da sta definirana v sklopu Debug unit in ne USART-a. V nadaljni raziskavi sem v datasheet-u od krmilnika ugotovil, da gre v bistvu za enak odmik. Torej bi se ta dva bita vseeno mogla postaviti na 1, ampak se ne.
Pogledal sem tudi v Errata za ta datasheet in ni opisano, da bi bili problemi s tem. Skoraj pomislim, da je kaj narobe z čipom??
Opis: |
|
 Download |
Ime datoteke: |
AT91SAM7S32.h |
Velikost datoteke: |
129.49 KB |
Downloadano: |
4 krat |
|
|
Nazaj na vrh |
|
 |
evolution Član

Pridružen-a: Tor 20 Jun 2006 2:07 Prispevkov: 37 Aktiv.: 0.16 Kraj: Izola, Ljubljana
|
Objavljeno: Tor Avg 19, 2008 10:08 pm Naslov sporočila: |
|
|
Aha, bom takoj poskusil.
Ja, imam tudi "Retarget.c":
#include <stdio.h>
#include <rt_misc.h>
#pragma import(__use_no_semihosting_swi)
extern int sendchar(int ch); /* in serial.c */
struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
int fputc(int ch, FILE *f) {
return (sendchar(ch));
}
int ferror(FILE *f) {
/* Your implementation of ferror */
return EOF;
}
void _ttywrch(int ch) {
sendchar(ch);
}
void _sys_exit(int return_code) {
label: goto label; /* endless loop */
}
|
|
Nazaj na vrh |
|
 |
Glitch Član

Pridružen-a: Pet 07 Apr 2006 11:40 Prispevkov: 1477 Aktiv.: 6.30
|
Objavljeno: Tor Avg 19, 2008 10:57 pm Naslov sporočila: |
|
|
Če ti originalni primer (kot sem rekel, ga ima Keil tudi za s32, uporablja pa ADC kanal, vrednosti pa pošilja na UART) ne deluje, je skoraj zagotovo nekaj narobe na HW. Je pa še nekaj Enkrat sem porabil precej časa za odkrivanje napake, katero je zakrivila slabo pripravljena .h datoteka (napačne definicije registrov).
Pa še nekaj. Ali opazuješ pravi UART? Atmel ima tudi DBG periferijo, ki je tudi uart. To si tudi omenil, tako da dobro preveri.
[opa 800. prisevek]
|
|
Nazaj na vrh |
|
 |
evolution Član

Pridružen-a: Tor 20 Jun 2006 2:07 Prispevkov: 37 Aktiv.: 0.16 Kraj: Izola, Ljubljana
|
Objavljeno: Tor Avg 19, 2008 11:48 pm Naslov sporočila: |
|
|
S tem njihovim originalnim primerom sem se že ukvarjal, vendar mi ga sploh ni uspelo niti z-build-at. Dobivam sporočilo:
Build target 'AT91SAM7xxx'
linking...
ADC.axf: error: L6938E: Invalid value for --ro-base.
Target not created
V njihovem "Knowledgebase" sem iskal rešitev, vendar sem obupal preden sem jo našel...
|
|
Nazaj na vrh |
|
 |
Glitch Član

Pridružen-a: Pet 07 Apr 2006 11:40 Prispevkov: 1477 Aktiv.: 6.30
|
Objavljeno: Sre Avg 20, 2008 12:28 am Naslov sporočila: |
|
|
Hja, nekaj je narobe s projektom. Tukaj se pa moja pomoč konča, ker nimam Keila. Malce ugibam ampak vseeno:
- poglej v nastavitve projekta, nekje je napačen naslov ali ga pa sploh ni
- je to CARM ali Realview?
BTW, google vrne nekaj rezultatov tvoje napake.
|
|
Nazaj na vrh |
|
 |
evolution Član

Pridružen-a: Tor 20 Jun 2006 2:07 Prispevkov: 37 Aktiv.: 0.16 Kraj: Izola, Ljubljana
|
Objavljeno: Sre Avg 20, 2008 1:11 am Naslov sporočila: |
|
|
Uporabljam Real View. Mislim, da CARM ni na voljo v zastonjski verziji (vendar nisem siguren). Lahko pa namesto Real View uporabim GCC, vendar je verjetno potrebno še kaj dodatno nastaviti...
Tisto napako sem pa rešil. V Project [Options for target '...'] sem pod jezičkom Linker ročno nastavil vrednosti za R/O Base in R/W Base (sicer ne vem kaj pomenijo, vendar naredim build in ni napak). V teh opcijah sem prav tako izbral moj krmilnik AT91SAM7S32 (saj je v originalu uporabljen AT91SAM7S64). Trenutno pa se ubadam s tem, ker mi noče naložiti flash...
Sporočim ko rešim.
|
|
Nazaj na vrh |
|
 |
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 6 dni
Powered by phpBB © 2001, 2005 phpBB Group
|