这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 遥控器的ADC读取

共17条 1/2 1 2 跳转至

遥控器的ADC读取

助工
2014-08-27 13:04:41     打赏

最近在做遥控器的adc转换,总是没有调通,没有读数,请大家帮忙看看程序。


#include "stm32f10x_conf.h"

#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "adc.h"
#include "nvicconf.h"

#include "uart.h"
//#include "acc.h"

// PORT A
#define GPIO_VRF         GPIO_Pin_0
#define GPIO_RSET2       GPIO_Pin_1
#define GPIO_RSET1       GPIO_Pin_2
#define GPIO_VBAT        GPIO_Pin_3
#define GPIO_ADC0        GPIO_Pin_4
#define GPIO_ADC1        GPIO_Pin_5
#define GPIO_ADC2        GPIO_Pin_6
#define GPIO_ADC3        GPIO_Pin_7

// CHANNELS
#define NBR_OF_ADC_CHANNELS   9

#define CH_VRF								ADC_Channel_0
#define CH_RSET2							ADC_Channel_1
#define CH_RSET1							ADC_Channel_2
#define CH_VBAT               ADC_Channel_3
#define CH_ADC0               ADC_Channel_4
#define CH_ADC1               ADC_Channel_5
#define CH_ADC2               ADC_Channel_6
#define CH_ADC3               ADC_Channel_7

#define CH_VREF               ADC_Channel_17

#define CH_TEMP               ADC_Channel_16


static bool isInit;
volatile uint16_t adcValues[NBR_OF_ADC_CHANNELS * ADC_MEAN_SIZE];
void GPIO_Configuration(void);

xQueueHandle      adcQueue;

static void adcDmaInit(void)
{
  DMA_InitTypeDef DMA_InitStructure;

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  // DMA channel1 configuration
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&adcValues;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = NBR_OF_ADC_CHANNELS * ADC_MEAN_SIZE;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  // Enable DMA channel1
  DMA_Cmd(DMA1_Channel1, ENABLE);
}

/**
 * Decimates the adc samples after oversampling
 */
static void adcDecimate(uint16_t * oversampled, uint16_t * decimated)
{
  uint32_t i, j;
  uint32_t sum;

  // Compute sums and decimate each channel
  for (i = 0; i < NBR_OF_ADC_CHANNELS; i++)
  {
    sum = 0;
    for (j = 0; j < ADC_MEAN_SIZE; j++){
      sum += oversampled[i + NBR_OF_ADC_CHANNELS * j];
    }
    // Decimate
		decimated[i] = sum / ADC_MEAN_SIZE;
  }
}


void GPIO_Configuration(void){

	GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	
  GPIO_InitStructure.GPIO_Pin = GPIO_VRF | GPIO_RSET2 | GPIO_RSET1 | GPIO_VBAT
	                         | GPIO_ADC0 | GPIO_ADC1 | GPIO_ADC2 | GPIO_ADC3;
  GPIO_Init(GPIOA, &GPIO_InitStructure);				
}


void adcInit(void)
{

  ADC_InitTypeDef ADC_InitStructure;
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef TIM_OCInitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  if(isInit)
    return;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  // Enable GPIOA and ADC1 clock
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);

	
  //Timer configuration
  TIM_TimeBaseStructure.TIM_Period = ADC_TRIG_PERIOD;
  TIM_TimeBaseStructure.TIM_Prescaler = ADC_TRIG_PRESCALE;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  // TIM2 channel2 configuration in PWM mode
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 1;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
  TIM_OC2Init(TIM2, &TIM_OCInitStructure);
  TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
  // Halt timer 2 during debug halt.
  DBGMCU_Config(DBGMCU_TIM2_STOP, ENABLE);
	
  GPIO_Configuration();

  adcDmaInit();

  // ADC1 configuration
  ADC_DeInit(ADC1);
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = NBR_OF_ADC_CHANNELS;
  ADC_Init(ADC1, &ADC_InitStructure);

  // ADC1 channel sequence
  ADC_RegularChannelConfig(ADC1, CH_VRF  , 1, ADC_SampleTime_28Cycles5);
  ADC_RegularChannelConfig(ADC1, CH_RSET2, 2, ADC_SampleTime_28Cycles5);
  ADC_RegularChannelConfig(ADC1, CH_RSET1, 3, ADC_SampleTime_28Cycles5);
  ADC_RegularChannelConfig(ADC1, CH_VBAT , 4, ADC_SampleTime_28Cycles5);
  ADC_RegularChannelConfig(ADC1, CH_ADC0 , 5, ADC_SampleTime_28Cycles5);
  ADC_RegularChannelConfig(ADC1, CH_ADC1 , 6, ADC_SampleTime_28Cycles5);
  ADC_RegularChannelConfig(ADC1, CH_ADC2 , 7, ADC_SampleTime_28Cycles5);
  ADC_RegularChannelConfig(ADC1, CH_ADC3 , 8, ADC_SampleTime_28Cycles5);
  ADC_RegularChannelConfig(ADC1, CH_VREF , 9, ADC_SampleTime_28Cycles5);


  // Enable ADC1
  DMA_ITConfig(DMA1_Channel1, DMA_IT_TC | DMA_IT_HT, ENABLE);
  ADC_DMACmd(ADC1, ENABLE);
  ADC_Cmd(ADC1, ENABLE);
  // Calibrate ADC1
  ADC_ResetCalibration(ADC1);
  while(ADC_GetResetCalibrationStatus(ADC1));
  ADC_StartCalibration(ADC1);
  while(ADC_GetCalibrationStatus(ADC1));

  // Enable ADC1 external trigger
  ADC_ExternalTrigConvCmd(ADC1, ENABLE);
  ADC_TempSensorVrefintCmd(ENABLE);

  // Enable the DMA1 channel1 Interrupt
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_ADC_PRI;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  adcQueue = xQueueCreate(1, NBR_OF_ADC_CHANNELS);

	printf("this is in adcInit\r\n");

  isInit = true;
}

bool adcTest(void)
{
  return isInit;
}

float adcConvertToVoltageFloat(uint16_t v, uint16_t vref)
{
  return ((v<<1) / (vref / ADC_INTERNAL_VREF));
}


void adcInterruptHandler(void)
{
  portBASE_TYPE xHigherPriorityTaskWoken;
  uint16_t *adcBuffer;

	printf("\r\n");
  if(DMA_GetITStatus(DMA1_IT_HT1))
  {
    DMA_ClearITPendingBit(DMA1_IT_HT1);
    adcBuffer = adcValues;
    xQueueSendFromISR(adcQueue, &adcBuffer, &xHigherPriorityTaskWoken);
  }
  if(DMA_GetITStatus(DMA1_IT_TC1))
  {
    DMA_ClearITPendingBit(DMA1_IT_TC1);
    adcBuffer = adcValues;
    xQueueSendFromISR(adcQueue, &adcBuffer, &xHigherPriorityTaskWoken);
  }
}

void adcTask(void *param)
{
  uint16_t adcRawValues[NBR_OF_ADC_CHANNELS];
  uint16_t adcValues[NBR_OF_ADC_CHANNELS];

	printf("This is in adcTask\r\n");

  while(1)
  {
		printf("This is in adc while loop1\r\n");
    xQueueReceive(adcQueue, adcRawValues, portMAX_DELAY);
		printf("This is in adc while loop2\r\n");
    adcDecimate(adcRawValues, adcValues);  // 10% CPU
//    pmBatteryUpdate(&adcValues);

    vTaskDelay(1000/portTICK_RATE_MS);
		printf("%04x, %04x, %04x, %04x\r\n",adcValues[0],adcValues[1],adcValues[2],adcValues[3] );
  }
}

 

另外串口设置的频率是实际频率的2倍,求reason。







关键词: adc     串口    

助工
2014-08-27 13:06:07     打赏
2楼
这是头文件
#define ADC_DECIMATE_TO_BITS  12
#define ADC_MEAN_SIZE         8

#define ADC_RESOLUTION        12
#define ADC_DECIMATE_DIVEDEND (ADC_MEAN_SIZE / (1 << (ADC_DECIMATE_TO_BITS - ADC_RESOLUTION)))

#if ADC_DECIMATE_TO_BITS < ADC_RESOLUTION
#  error "ADC_DECIMATE_TO_BITS must be bigger or equal to ADC_RESOLUTION"
#endif

#define ADC_SAMPLING_FREQ      100
#define ADC_OVERSAMPLING_FREQ  (ADC_SAMPLING_FREQ * ADC_MEAN_SIZE)

#define ADC_TRIG_PRESCALE       1
#define ADC_TRIG_PRESCALE_FREQ  (72000000 / (ADC_TRIG_PRESCALE + 1))
#define ADC_TRIG_PERIOD         (ADC_TRIG_PRESCALE_FREQ / (ADC_OVERSAMPLING_FREQ))

#define ADC_INTERNAL_VREF   1.20

/******** Types ********/

 


专家
2014-08-27 13:49:40     打赏
3楼
串口设置的频率是什么意思?你指的是波特率吗?你这代码里面也没有用到串口啊?

高工
2014-08-27 14:13:26     打赏
4楼

什么遥控器是用AD做的?




高工
2014-08-27 15:08:38     打赏
5楼

粗看一眼都在配置和处理ADC

遥控器用来干嘛?

感觉撸主是不是想说串口助手波特率调整成代码配置的2倍才能正常显示吧

建议看看频率的配置


助工
2014-08-27 19:33:54     打赏
6楼
我说的是四轴的遥控器,采集摇杆和微调的数据,怎么处理?

助工
2014-08-27 19:34:34     打赏
7楼

四轴飞行器的遥控器



助工
2014-08-27 19:35:48     打赏
8楼
就是波特率,这是模数转换的代码,不是uart的代码

专家
2014-08-28 09:01:58     打赏
9楼
哦,波特率不对,看看系统主时钟的设置是否正确。

高工
2014-08-28 10:55:31     打赏
10楼

波特率问题,四轴上是16M晶振,你得修改相关定义


共17条 1/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]