Forum: Mikrocontroller und Digitale Elektronik FM4-U120-9B560 mit winIDEA Open ADCs


von NewARM (Gast)


Lesenswert?

Moin,

schon mal sry für den langen Text aber wollte keine Informationen 
unterschlagen.

Habe mir mal ein "FM4-U120-9B560" zugelegt um in die ARM-Welt 
einzusteigen und etwas rum zuspielen.
http://www.cypress.com/documentation/development-kitsboards/sk-fm4-u120-9b560-mem-fm4-mcu-evaluation-board
Dazu den "winIDEA Open" runter geladen da dort dieses Board unterstütz 
wird.
http://www.isystem.com/download/winideaopen

An sich tut das Ding so wie es soll nur verstehe ich viele Sachen noch 
nicht.
Und finde gerade bezüglich der ADCs wenig Dokumentation.
Daher hangele ich mich momentan an den Beispielprojekten entlang.

Habe da z.B. "mb9bf56xr_adc_dvm.zip (V1.2)"
http://www.cypress.com/file/258591/download  (Anmeldung erforderlich)
This project demonstrates a simple Digital-Voltage-Meter, based on the 
ADC...

Da gibt es unter anderem die Init Funktion
1
static void InitAdc0(void)
2
{
3
  FM4_GPIO->ADE_f.AN18 = 1u; // Select analogue pin -> AN18
4
5
  FM4_ADC0->SCIS23 = 0x0004u; // Scan channel select AN31-AN16 -> AN18
6
  FM4_ADC0->SCIS01 = 0x0000u; // Scan channel select AN15-AN00
7
8
  FM4_ADC0->ADST01 = 0x2F2Fu; // Sampling Time 1
9
10
  FM4_ADC0->ADSS23 = 0x0000u; // Sampling Time Select AN31-AN16 -> Use Sampling Time 0 for AN18
11
  FM4_ADC0->ADSS01 = 0x0000u; // Sampling Time Select AN15-AN00 
12
13
  FM4_ADC0->ADCT  = 0x06u; // Comparison Time = 14 x (ADCT + 2) / HCLK
14
15
  FM4_ADC0->ADCEN = 0x2801u; // Enable ADC, set ENBLTIME to 1us @ 160MHz
16
17
  while (0u == bFM4_ADC0_ADCEN_READY); // wait until ADC operation is enabled
18
19
  FM4_ADC0->CMPCR = 0x00u; // No comparison
20
  FM4_ADC0->CMPD  = 0x00u; // No comparison value
21
22
  FM4_ADC0->SFNS  = 0x00u; // Set Fifo Stage Count Interrupt
23
  FM4_ADC0->ADCR  = 0x00u; // Disable ADC interrupts  
24
  FM4_ADC0->ADSR  = 0x40u; // Result on LSB side
25
  
26
  FM4_ADC0->SCCR  = 0x11u; // FIFO clear, start ADC Single Conversion   
27
}

Und die zum Daten holen
1
static uint16_t GetAdc0Value(void)
2
{
3
  uint16_t u16AdcValue;
4
  
5
  while (0u != ((FM4_ADC0->SCFDL) & 0x1000u))  // Is valid data available?
6
  {}
7
  
8
  u16AdcValue = FM4_ADC0->SCFDH; 
9
  
10
  return u16AdcValue;
11
}

Alles wunderbar und funktioniert.
Kann auch an
1
FM4_GPIO->ADE_f.AN18 = 1u; // Select analogue pin -> AN18
&
1
FM4_ADC0->SCIS23 = 0x0004u; // Scan channel select AN31-AN16 -> AN18
2
FM4_ADC0->SCIS01 = 0x0000u; // Scan channel select AN15-AN00
rumspielen und andere Pins wählen

Wollte nun das ganze so umbauen das ich GetAdc0Value einen Channel 
übergebe und der entsprechende Wert zurück gegeben wird.
Leider finde ich dabei nicht den richtigen Ansatz wie das hier 
Funktioniert.
Habe das bisher entsprechend umgestrickt
1
void InitAdc0(void)
2
{
3
  FM4_GPIO->ADE_f.AN0  = 1u;  // Select analogue pin -> AN0
4
  FM4_GPIO->ADE_f.AN1  = 1u;  // Select analogue pin -> AN1
5
  FM4_GPIO->ADE_f.AN2  = 1u;  // Select analogue pin -> AN2  
6
  FM4_GPIO->ADE_f.AN3  = 1u;  // Select analogue pin -> AN3
7
  FM4_GPIO->ADE_f.AN4  = 1u;  // Select analogue pin -> AN4
8
  FM4_GPIO->ADE_f.AN5  = 1u;  // Select analogue pin -> AN5
9
  FM4_GPIO->ADE_f.AN6  = 1u;  // Select analogue pin -> AN6 
10
  FM4_GPIO->ADE_f.AN7  = 1u;  // Select analogue pin -> AN7 
11
12
  //FM4_ADC0->SCIS23 = 0x0004u; // Scan channel select AN31-AN16 -> AN18
13
  //FM4_ADC0->SCIS01 = 0x0000u; // Scan channel select AN15-AN00
14
  ...   
15
}
1
uint16_t GetAdc0Value(uint8_t u8Chann)
2
{
3
  uint16_t u16AdcValue;
4
  
5
  switch(u8Chann) {
6
    case 0:   FM4_ADC0->SCIS0 = 0x01u; break;
7
    case 1:   FM4_ADC0->SCIS0 = 0x02u; break;
8
    case 2:   FM4_ADC0->SCIS0 = 0x04u; break;  
9
    case 3:   FM4_ADC0->SCIS0 = 0x08u; break;
10
    case 4:   FM4_ADC0->SCIS0 = 0x10u; break;
11
    case 5:   FM4_ADC0->SCIS0 = 0x20u; break;
12
    case 6:   FM4_ADC0->SCIS0 = 0x40u; break;  
13
    case 7:   FM4_ADC0->SCIS0 = 0x80u; break;  
14
  default: break;
15
  }
16
  ...
17
}

gibt im Compiler zwar keine Fehler funktioniert aber nicht.

Wenn ich die switch case Anweisung in die InitAdc0 einbaue und jedes mal 
wenn ich Daten holen möchte erst InitAdc0 und dann GetAdc0Value aufrufe 
funktioniert es aber gehe davon aus das ich da einfach etwas noch nicht 
verstanden habe.

Oder muss ich wirklich jedes mal die ganze Initialisierung neu machen?

Vielleicht hat ja schon jemand mit diesen Sachen gearbeitet und kann mir 
nen Tip oder Link zu brauchbarer Doku geben.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.