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.