unit uADC;
{$mode objfpc}
interface
Procedure ADCInit(AChannelKanal1,AChannelKanal2: byte);
Procedure ADCSingleConversion;
var ADCOnConversionsComplete: Procedure;
const AnalogKanal1Pin = GPIO_Pin_0;
const AnalogKanal2Pin = GPIO_Pin_1;
var AnalogKanal1Port: TPortRegisters absolute PortB;
var AnalogKanal2Port: TPortRegisters absolute PortB;
var
ADC1Result: uInt16;
ADC2Result: uInt16;
IMPLEMENTATION
uses
stm32f103fw,STM32F10x_BitDefs,cortexm3;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Procedure ADCInit(AChannelKanal1,AChannelKanal2: byte);
var
ADC_InitStructure: TADC_InitTypeDef;
NVIC_InitStructure: TNVIC_InitTypeDef;
GPIO_InitStructure: TGPIO_InitTypeDef;
begin
// Analog Eingaenge Kanal 1 und 2
GPIO_InitStructure.GPIO_Pin := AnalogKanal1Pin;
GPIO_InitStructure.GPIO_Mode := GPIO_Mode_AIN; //Analog In
GPIO_InitStructure.GPIO_Speed := GPIO_Speed_50MHz;
GPIO_Init(AnalogKanal1Port, GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin := AnalogKanal2Pin;
GPIO_InitStructure.GPIO_Mode := GPIO_Mode_AIN; //Analog In
GPIO_InitStructure.GPIO_Speed := GPIO_Speed_50MHz;
GPIO_Init(AnalogKanal1Port, GPIO_InitStructure);
// ADCCLK = PCLK2/2
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
////ADC1
ADC_InitStructure.ADC_Mode:= ADC_Mode_Independent; //ADC1 unabhängig von ADC2, nicht dual-mode
ADC_InitStructure.ADC_ScanConvMode:= DISABLED; //nicht Nur ein Kanal
ADC_InitStructure.ADC_ContinuousConvMode:= DISABLED;//Nur einzelne Wandlung
ADC_InitStructure.ADC_ExternalTrigConv:= ADC_ExternalTrigConv_T1_CC1;//Timer1 Kanal1 triggert
ADC_InitStructure.ADC_DataAlign:= ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel:= 1;
ADC_Init(ADC1, ADC_InitStructure);
// ADC1 regular channel14 configuration
ADC_RegularChannelConfig(ADC1, AChannelKanal1, 1, ADC_SampleTime_28Cycles5);
// Enable ADC1 external trigger
ADC_ExternalTrigConvCmd(ADC1, ENABLED);
// Enable EOC interrupt
ADC_ITConfig(ADC1, ADC_IT_EOC, DISABLED);
// Enable ADC1
ADC_Cmd(ADC1, ENABLED);
{////Injected Kanäle
ADC_InjectedSequencerLengthConfig(ADC1,2);
ADC_InjectedChannelConfig(ADC1, AChannelKanal2,1,ADC_SampleTime_13Cycles5);
ADC_InjectedChannelConfig(ADC1, AChannelKanal2,2,ADC_SampleTime_13Cycles5);
// Interrupt für Injected-Gruppe
ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T2_CC1);
ADC_ExternalTrigInjectedConvCmd(ADC1,ENABLED);
ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLED); }
////ADC2
ADC_InitStructure.ADC_Mode:= ADC_Mode_Independent; //ADC1 unabhängig von ADC2, nicht dual-mode
ADC_InitStructure.ADC_ScanConvMode:= DISABLED; //nicht Nur ein Kanal
ADC_InitStructure.ADC_ContinuousConvMode:= DISABLED;//Nur einzelne Wandlung
ADC_InitStructure.ADC_ExternalTrigConv:= ADC_ExternalTrigConv_T1_CC1;//Timer1 Kanal1 triggert
ADC_InitStructure.ADC_DataAlign:= ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel:= 1;
ADC_Init(ADC2, ADC_InitStructure);
// ADC1 regular channel14 configuration
ADC_RegularChannelConfig(ADC2, AChannelKanal2, 1, ADC_SampleTime_28Cycles5);
// Enable ADC external trigger
ADC_ExternalTrigConvCmd(ADC2, ENABLED);
// Enable EOC interrupt
ADC_ITConfig(ADC2, ADC_IT_EOC, ENABLED);
// Enable ADC1
ADC_Cmd(ADC2, ENABLED);
////ADC1+2
// ADC-NVIC-Konfiguration
NVIC.IP[ADC1_2_IRQn]:= $10; //IRQ-Priority, right 4bits always to be zero,low value=high prio
NVIC.ISER[ADC1_2_IRQn shr 5] := 1 shl (ADC1_2_IRQn and $1F); //Enable Interrupt
//ADC_SoftwareStartConvCmd(ADC1, ENABLED);
// Enable ADC1 reset calibration register
//ADC_ResetCalibration(ADC1);
// Check the end of ADC1 reset calibration register
//while(ADC_GetResetCalibrationStatus(ADC1));
// Start ADC1 calibration
//ADC_StartCalibration(ADC1);
// Check the end of ADC1 calibration
//while(ADC_GetCalibrationStatus(ADC1));
end;
//---------------------------------------------------------
procedure ADCSingleConversion;
begin
ADC_SoftwareStartConvCmd(ADC1, ENABLED);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++ INTERRUPT SERVICE ROUTINE
procedure ADC_ISR; Alias: 'ADC1_and_ADC2_global_interrupt'; Interrupt; Public;
var Timeout: Integer;
begin
//comvisu.cmdLn('ADC1ISR');
Timeout:= 20;
while (ADC1.SR and ADC1.SR and ADC_SR_EOC) = 0
do begin Timeout:= Timeout-1; if Timeout = 0 then BREAK; end;
if (ADC1.SR and ADC_SR_EOC) > 0
then ADC1Result:= ADC1.DR else ADC1Result:= $FFFF;
if (ADC2.SR and ADC_SR_EOC) > 0
then ADC2Result:= ADC2.DR else ADC2Result:= $FFFF;
if assigned(ADCOnConversionsComplete) then ADCOnConversionsComplete;
ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);
ADC_ClearITPendingBit(ADC2,ADC_IT_EOC);
end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
end.