[3] JAVA i STM32 – ekspresowy kurs programowania z MicroEJ – obsługa ADC i DAC

List. 6. Kod metody main
public static void main(String[] args) {
DAC dac = new DAC();
ADC adc = new ADC();
dac.init();
adc.init();
MWT.RenderingContext.add(new PlainTheme());
Desktop desktop = new Desktop();
Panel panel = new Panel();
GridComposite gc = new GridComposite(MWT.VERTICAL, 4);
TitleLabel title = new TitleLabel("ADC/DAC EXAMPLE");
title.setFontSize(LookExtension.GET_X_BIG_FONT_INDEX);
gc.add(title);
FlowComposite fcDac = new FlowComposite();
TitleLabel labelDacTitle = new TitleLabel("Dac Value [mV]:");
fcDac.add(labelDacTitle);
TextField dacValueField = new TextField("--------");
fcDac.add(dacValueField);
Scale scaleDac = new Scale(0, 300);
scaleDac.setListener(new DACScaleListener(dacValueField, dac));
fcDac.add(scaleDac);
gc.add(fcDac);
FlowComposite fcAdc = new FlowComposite();
TitleLabel labelAdcTitle = new TitleLabel("ADC Value [mV]:");
fcAdc.add(labelAdcTitle);
TextField adcValueField = new TextField("--------");
fcAdc.add(adcValueField);
Button buttonAdc = new Button("Get ADC value");
buttonAdc.setListener(new ADCButtonListener(adcValueField, adc));
fcAdc.add(buttonAdc);
gc.add(fcAdc);
panel.setWidget(gc);
panel.show(desktop, true);
desktop.show();
}
Wystarczy już tylko utworzyć nową konfiguracją z opcją Execute on EmbJPF, aby aplikacja była gotowa do zaprogramowania w pamięci mikrokontrolera.
Obsługa przetworników (C)
Przed uruchomieniem aplikacji trzeba jeszcze dokonać zmian w BSC dodając obsługę przetworników. Po uruchomieniu projektu w środowisku uVision należy utworzyć dwa nowe pliki adc.c i dac.c zawierające implementacje zadeklarowanych w Javie funkcji kontroli przetworników. Funkcje te pokazano na listingach 7 i 8.
List. 7. Implementacja funkcji inicjalizacji i pobrania wartości przetwornika analogowo-cyfrowego
void Java_app_ADC_ADCInit(void) {
printf("ADC init\n");
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC3, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC3, ADC_Channel_13, 1, ADC_SampleTime_3Cycles);
ADC_Cmd(ADC3, ENABLE);
}
int Java_app_ADC_ADCGetValue(void) {
printf("ADC get value\n");
ADC_SoftwareStartConv(ADC3);
while(ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC) == RESET)
__NOP();
ADC_ClearFlag(ADC3, ADC_FLAG_EOC);
uint32_t data = ADC_GetConversionValue(ADC3) >> 4;
data = data * 3000/4096;
return (int)data;
}
List. 8. Implementacja funkcji inicjalizacji i ustawiania wartości przetwornika cyfrowo-analogowego
void Java_app_DAC_DACInit(void) {
printf("DAC init\n");
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
DAC_InitTypeDef DAC_InitStructure;
DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
DAC_Init(DAC_Channel_2, &DAC_InitStructure);
DAC_Cmd(DAC_Channel_2, ENABLE);
DAC_SetChannel2Data(DAC_Align_12b_L, 0x0);
}
void Java_app_DAC_DACSetValue(int value) {
printf("DAC set value %d\n", value);
uint32_t data = value * 4095 / 3000;
DAC_SetChannel2Data(DAC_Align_12b_R, (uint16_t)data);
}
Na pierwszy rzut oka można zauważyć charakterystyczne nazwy wszystkich czterech funkcji. Z uwagi na to, że są one wywoływane z kodu Javy, muszą one mieć w swojej nazwie pełną ścieżkę do swoich deklaracji w aplikacji z uwzględnieniem pakietów i klas w których się one znajdują. Poza nazwani, nie odbiegają niczym od funkcji znanych z przykładów biblioteki STM32 Standard Peripheral Library. Funkcje konfiguracyjne inicjalizują sygnały zegarowe dla swoich peryferii oraz przypisanych im portów GPIO (PC3 dla ADC i PA5 dla DAC) wypełniają struktury inicjalizacyjne. Funkcja odczytująca wartość ADC nie wykorzystuje przerwań, lecz po uruchomieniu konwersji czeka na jej zakończenie sygnalizowane odpowiednią flagą.
Projekt można teraz skompilować i zaprogramować pamięć mikrokontrolera. Po każdym odwołaniu do funkcji C, w konsoli debugowania (Debug (printf) Viewer) można zaobserwować logi wyświetlane przez poszczególne funkcje.

Technologie End of Life i bezpieczeństwo sieci – wyzwania Europy związane z tzw. długiem technologicznym
Najczęstsze błędy firm przy wyborze dostawcy energii i jak ich uniknąć
Fotorezystor, czyli czujnik światła dwojakiego działania. Przykład innowacji w automatyce i elektronice możliwej dzięki technologii fotooporników 



