Die Peripheriegeräte der GigaDevice-RISC-V-Mikrocontroller sind an denen des STM32F1 angelehnt. Hier wollen wir abermals auf das kostenlose Nuclei Studio zurückgreifen, um den DAC eines Evaluationsboards in Betrieb zu nehmen.
von Tam HANNA
Worum geht es hier?
Seit der Übernahme von ARM durch NVIDIA gilt, dass ARM eine „amerikanische“ Architektur ist – mit allen Vorteilen (finanzstarker Eigentümer) und allen Nachteilen (Sanktionsanfällig).
RISC-V ist eine quelloffene Prozessor-Architektur, die schon vom Konzept her sanktionssicherer ist, und ob der wegfallenden Lizenzkosten langfristig billiger ausfallen dürfte (Skalierungseffekte bevorzugen derzeit ARM, was zu „Preisparität“ führt).
GigaDevice bietet mit dem GD32VF1 seit einiger Zeit eine vergleichsweise gut verfügbare Serie von Mikrocontrollern an, die vom Aufbau der EA-Geräte am STM32 orientiert sind.
In diesem Artikel wollen wir den DAC eines Evaluationsboards in Betrieb nehmen. Die Einrichtung von der IDE haben wir dabei – im Detail – im unter https://www.mikrocontroller.net/topic/518533 bereitstehenden Artikel beschrieben.
Kein Codegenerator
Wir hatten im letzten Artikel festgestellt, dass es für die GD32VF-Architektur keinen Codegenerator gibt. GigaDevice stellt stattdessen eine Sammlung leicht nutzbarer Codebeispiele zusammen – der verwendet Autor die Version 1.1.1.
Der Unterordner GD32VF103_Firmware_Library_V1.1.1Examples enthält die in Abbildung eins gezeigte Projektstruktur, die die für die diversen Peripheriegeräte vorgesehenen Codestücke zur Verfügung stellt.
Das unter http://www.gd32mcu.com/data/documents/yingyongbiji/GD32VF103_Firmware_Library_User_Guide_V1.0.pdf bereitstehende PDF ist ebenfalls empfehlenswert, da es „alle“ Peripherietreiberfunktionen en Detail erklärt.
Wir wollen an dieser Stelle mit dem im letzten Artikel erzeugten Projektskelett weiterexperimentieren, und die in einem der DAC-Unterordner zur Verfügung stehenden Codeänderungen Tour a Tour einpflegen.
Das für uns relevante Beispiel ist ExamplesDACDACC_output_voltage, der Inhalt des Verzeichnisses präsentiert sich wie in Abbildung zwei gezeigt.
Bei der „Analyse“ des von GigaDevice bereitgestellten Codes ist es immer empfehlenswert, mit der Datei readme.txt zu starten. Unter den Lizenzbedingungen findet sich im Fall des Beispiels folgende Funktionsbeschreibung:
1 |
This example is based on the GD32V103V-EVAL-V1.0 board, it shows how to use DAC concurrent mode |
2 |
output voltage. No trigger source is chosen to trigger DAC. The DAC0 output pin is configured |
3 |
PA4 and DAC1 output pin is configured PA5. There are two different voltage in PA4 and PA5. The |
4 |
voltage of PA4 is VREF/2 and the voltage of PA5 is VREF/8. |
Die Struktur der main-Methode zeigt nun den Aufruf dreier Funktionen:
1 |
int main(void) |
2 |
{
|
3 |
rcu_config(); |
4 |
gpio_config(); |
5 |
dac_config(); |
6 |
while (1){ |
7 |
}
|
8 |
}
|
Analog zum STM32 hat auch der GD32VF Clock Gating – wir müssen dafür sorgen, dass die Einheiten mit Arbeitstakt versorgt werden:
1 |
void rcu_config(void) |
2 |
{
|
3 |
/* enable the clock of peripherals */
|
4 |
rcu_periph_clock_enable(RCU_GPIOA); |
5 |
rcu_periph_clock_enable(RCU_DAC); |
6 |
}
|
Die eigentliche Konfiguration erfolgt in folgenden Funktionen:
1 |
void gpio_config(void) |
2 |
{
|
3 |
/* once enabled the DAC, the corresponding GPIO pin is connected to the DAC converter automatically */
|
4 |
gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_4 | GPIO_PIN_5); |
5 |
}
|
6 |
|
7 |
void dac_config(void) |
8 |
{
|
9 |
dac_deinit(); |
10 |
/* configure the DAC0 */
|
11 |
dac_trigger_disable(DAC0); |
12 |
dac_wave_mode_config(DAC0, DAC_WAVE_DISABLE); |
13 |
dac_output_buffer_enable(DAC0); |
14 |
|
15 |
/* configure the DAC1 */
|
16 |
dac_trigger_disable(DAC1); |
17 |
dac_wave_mode_config(DAC1, DAC_WAVE_DISABLE); |
18 |
dac_output_buffer_enable(DAC1); |
19 |
|
20 |
/* enable DAC concurrent mode and set data */
|
21 |
dac_concurrent_enable(); |
22 |
dac_concurrent_data_set(DAC_ALIGN_12B_L, DAC_OUT_VAL0, DAC_OUT_VAL1); |
23 |
}
|
Wichtig sind noch die beiden Konstanten:
1 |
#define DAC_OUT_VAL0 0x7FF0
|
2 |
#define DAC_OUT_VAL1 0x1FF0
|
Der Hinweis, dass der Wert 0x7FF0 dem Wert VREF/2 entspricht, zeigt dass der DAC eine Nominalauflösung von 12 bit bereitstellt. Mit diesem Wissen können wir die Hauptschleife unseres Programms nach folgendem Schema anpassen:
1 |
int main(void) { |
2 |
rcu_config(); |
3 |
gpio_config(); |
4 |
dac_config(); |
5 |
uint16_t daculator = 0; |
6 |
while(1) { |
7 |
dac_concurrent_data_set(DAC_ALIGN_12B_R, daculator, daculator); |
8 |
daculator+=10; |
9 |
if (daculator>4000)daculator=0; |
10 |
}
|
11 |
|
12 |
return 0; |
13 |
}
|
Ein weiterer Unterschied zum von GigaDevice bereitgestellten Code ist, dass wir hier die Konstante DAC_ALIGN_12B_R verwenden – das deshalb, weil der in daculator befindliche Wert rechtsbündig ist.
Lohn der Mühen ist, dass wir an den Pins PA4 und PA5 des „kleinen“ Evaluationsboard die in der Abbildung gezeigte Wellenform sehen. Die kleinen Unsauberkeiten in diesem Oszillographen stammen von EMI im Labor des Autors.
Fazit
Der Verzicht auf einen automatischen Codegenerator mag auf den ersten Blick erschrecken – in der Praxis lässt sich nach einer Umgewöhnungsphase erfahrungsgemäß genauso gut ohne ihn arbeiten. Der Autor hofft, dass die hier durchgeführten Experimente zur „Vertiefung“ ihres Interesses an RISC-V geführt haben.
Weitere Ressourcen
GD32VF-Evaluationsboards bei TME
=> https://www.tme.eu/hu/en/katalog/?s_field=1000011&s_order=desc&search=GD32VF&visible_params=2%2C367%2C2479%2C35%2C783%2C2408%2C10%2C32%2C788%2C2955%2C9%2C351&mapped_params=351%3A1530178%3B
GD32VF-Evaluationsboards bei LCSC (seriöser chinesischer Distributor)
=> https://lcsc.com/search?q=GD32VF
Hennessy und Pedersen – allgemeine Einführung zu RISC-V bzw seiner ISA
=> https://www.amazon.com/Computer-Organization-Design-RISC-V-Architecture/dp/0128122757
(Bitte keinesfalls nach dem String “Hennessy Pedersen RISC-V architecture” auf Google HU suchen)
Zuerst erschienen bei Mikrocontroller.net News
Quelle: Read More