ADC

请大神帮忙看下风格 还是哪里有问题 照着串口驱动写的ADC驱动

发布于 2014-11-27 11:51:03
注释凑合看下刚写好 还没改
可以用 但是风格是自己稍微理解一下 然后全抄的 不知道有没有问题
osc.c

/**
******************************************************************************
* @file adc.c
* @author UEL Engineering
* @version V0.0.1
* @date 2014/11/20
* @brief adc控制程序
******************************************************************************
*
*/

/** @addtogroup Driver
* @{
*/

/** @defgroup adc ADC驱动程序
* @{
*/

#include
#include "board.h"
#include "osc.h"

#include
#include

#define OSC_DEFAULT_TIMES 255

static rt_err_t rt_osc_init(struct rt_device *dev)
{
rt_err_t result = RT_EOK;
struct rt_osc_device *osc;

RT_ASSERT(dev != RT_NULL);
osc = (struct rt_osc_device *)dev;

if (osc->ops->configure)
{
result = osc->ops->configure(osc, &osc->config);
}
return result;
}

static rt_err_t rt_osc_open(struct rt_device *dev, rt_uint16_t oflag)
{
struct rt_osc_device *osc;

RT_ASSERT(dev != RT_NULL);
osc = (struct rt_osc_device *)dev;

if ((oflag & RT_DEVICE_FLAG_DMA_RX) && !(dev->flag & RT_DEVICE_FLAG_DMA_RX))
return -RT_EIO;
if ((oflag & RT_DEVICE_FLAG_DMA_TX) && !(dev->flag & RT_DEVICE_FLAG_DMA_TX))
return -RT_EIO;
if ((oflag & RT_DEVICE_FLAG_INT_RX) && !(dev->flag & RT_DEVICE_FLAG_INT_RX))
return -RT_EIO;
if ((oflag & RT_DEVICE_FLAG_INT_TX) && !(dev->flag & RT_DEVICE_FLAG_INT_TX))
return -RT_EIO;

if (oflag & RT_DEVICE_OFLAG_WRONLY)
return -RT_EIO;

dev->open_flag = oflag & 0xff;

if(dev->flag & RT_DEVICE_OFLAG_RDONLY)//只读权限 开启为内部读取osc结果
{
if(osc->buffer == RT_NULL)osc->ops->set_buffer(osc,OSC_DEFAULT_TIMES * 2);
else osc->ops->set_buffer(osc,osc->times * 2);
}
else//不开为直接usb输出到上位机
{

}
return RT_EOK;
}

static rt_err_t rt_osc_close(struct rt_device *dev)
{
struct rt_osc_device *osc;

RT_ASSERT(dev != RT_NULL);
osc = (struct rt_osc_device *)dev;

if(dev->flag & RT_DEVICE_OFLAG_RDONLY)//只读权限 开启为内部读取osc结果
{
osc->ops->stop(osc);
osc->ops->reset_bufffer(osc);
}
else//不开为直接usb输出到上位机
{

}
return RT_EOK;
}

static rt_size_t rt_osc_read(struct rt_device *dev,
rt_off_t pos,
void *buffer,
rt_size_t size)
{
struct rt_osc_device *osc;

RT_ASSERT(dev != RT_NULL);
if (size == 0) return 0;

osc = (struct rt_osc_device *)dev;

if (dev->open_flag & RT_DEVICE_OFLAG_RDONLY)
{
osc->ops->calculate(osc,(struct osc_global_para*)buffer);
return sizeof(struct osc_global_para);
}
return 0;
}

static rt_err_t rt_osc_control(struct rt_device *dev,
rt_uint8_t cmd,
void *args)
{
struct rt_osc_device *osc;

RT_ASSERT(dev != RT_NULL);
osc = (struct rt_osc_device *)dev;

switch (cmd)
{
case RT_DEVICE_OSC_CTRL_CONFIG:
/* configure device */
osc->ops->configure(osc, (struct osc_configure *)args);
break;
case RT_DEVICE_OSC_SET_TIMES:
/* configure device */
if(dev->open_flag & RT_DEVICE_OFLAG_OPEN)
{
if(osc->buffer != RT_NULL)rt_free(osc->buffer);
osc->ops->set_buffer(osc, *(rt_uint16_t*)args);
}
else return RT_EIO;
break;
case RT_DEVICE_OSC_TRIP:
osc->continue_flag = RT_FALSE;
osc->ops->start(osc);
break;
case RT_DEVICE_OSC_AUTO:
osc->continue_flag = RT_TRUE;
osc->ops->start(osc);
break;
default :
/* control device */
break;
}

return RT_EOK;
}

rt_err_t rt_hw_osc_register(struct rt_osc_device *osc,
const char *name,
rt_uint32_t flag,
void *data)
{
struct rt_device *device;
RT_ASSERT(osc != RT_NULL);

device = &(osc->parent);

device->type = RT_Device_Class_Miscellaneous;
device->rx_indicate = RT_NULL;
device->tx_complete = RT_NULL;

device->init = rt_osc_init;
device->open = rt_osc_open;
device->close = rt_osc_close;
device->read = rt_osc_read;
device->write = RT_NULL;
device->control = rt_osc_control;
device->user_data = data;

/* register a character device */
return rt_device_register(device, name, flag);
}

void rt_hw_osc_isr(struct rt_osc_device *osc, int event)
{
switch (event & 0xff)
{
case RT_OSC_EVENT_RX_HALF:
//usb传输用
break;
case RT_OSC_EVENT_RX_FINISH:
if(osc->parent.open_flag || RT_DEVICE_FLAG_RDONLY)
{
if(osc->continue_flag == RT_FALSE)osc->ops->stop(osc);
osc->parent.rx_indicate(&osc->parent, RT_NULL);
}
else
{
//usb传输用
}
break;
}
}

adc.c
/**
******************************************************************************
* @file adc.c
* @author UEL Engineering
* @version V0.0.1
* @date 2014/8/22
* @brief adc控制程序
******************************************************************************
*
*/

/** @addtogroup Driver
* @{
*/

/** @defgroup adc ADC驱动程序
* @{
*/

#include "board.h"
#include "adc.h"
#include "osc.h"
#include
#include

#define ADC_C1_PIN GPIO_Pin_0
#define ADC_C1_GPIO GPIOC
#define ADC_C2_PIN GPIO_Pin_1
#define ADC_C2_GPIO GPIOC

struct osc_use_peripheral
{
ADC_TypeDef* adc_device;
rt_uint32_t adc_externaltrigconv;
TIM_TypeDef* tim_device;
rt_uint16_t tim_trgosource;
DMA_Channel_TypeDef* dma_device;
IRQn_Type irq;
};

static rt_err_t osc_start(struct rt_osc_device *osc)
{
struct osc_use_peripheral* peripheral;
RT_ASSERT(osc != RT_NULL);

peripheral = (struct osc_use_peripheral *)osc->parent.user_data;

TIM_Cmd(peripheral->tim_device, ENABLE);
DMA_Cmd(peripheral->dma_device, ENABLE);
return RT_EOK;
}

static rt_err_t osc_stop(struct rt_osc_device *osc)
{
struct osc_use_peripheral* peripheral;
RT_ASSERT(osc != RT_NULL);

peripheral = (struct osc_use_peripheral *)osc->parent.user_data;

TIM_Cmd(peripheral->tim_device, DISABLE);
DMA_Cmd(peripheral->dma_device, DISABLE);
return RT_EOK;
}


static rt_err_t osc_configure(struct rt_osc_device *osc, struct osc_configure *cfg)
{
struct osc_use_peripheral* peripheral;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;

rt_uint16_t adc_chan, channel;

RT_ASSERT(osc != RT_NULL);
RT_ASSERT(cfg != RT_NULL);

peripheral = (struct osc_use_peripheral *)osc->parent.user_data;

TIM_DeInit(peripheral->tim_device);
TIM_TimeBaseStructure.TIM_Period = 72000000 / cfg->sample_rate - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(peripheral->tim_device, &TIM_TimeBaseStructure);

TIM_SelectOutputTrigger(peripheral->tim_device, peripheral->tim_trgosource);

DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (rt_uint32_t)&(peripheral->adc_device->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = RT_NULL;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_BufferSize = 0;
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);

DMA_ITConfig(peripheral->dma_device,DMA_IT_TC,ENABLE);

ADC_DeInit(peripheral->adc_device);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE ;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = peripheral->adc_externaltrigconv;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(peripheral->adc_device, &ADC_InitStructure);


channel = cfg->channel;
for(;channel>1;channel = channel >> 1)adc_chan++;

ADC_RegularChannelConfig(peripheral->adc_device, adc_chan, 1, ADC_SampleTime_28Cycles5);

ADC_ExternalTrigConvCmd(peripheral->adc_device, ENABLE);

ADC_DMACmd(peripheral->adc_device, ENABLE);

ADC_Cmd(peripheral->adc_device, DISABLE);
__ASM("NOP");
__ASM("NOP");
__ASM("NOP");
__ASM("NOP");
__ASM("NOP");
ADC_Cmd(peripheral->adc_device, ENABLE);
ADC_ResetCalibration(peripheral->adc_device);
while(ADC_GetResetCalibrationStatus(peripheral->adc_device));

ADC_StartCalibration(peripheral->adc_device);
while(ADC_GetCalibrationStatus(peripheral->adc_device));

return RT_EOK;
}

static rt_err_t osc_set_buffer(struct rt_osc_device *osc, rt_uint16_t times)
{
struct osc_use_peripheral* peripheral;

RT_ASSERT(osc != RT_NULL);

peripheral = (struct osc_use_peripheral *)osc->parent.user_data;

if(osc->buffer != RT_NULL)rt_free(osc->buffer);
osc->times = times;
osc->buffer = (rt_uint16_t*)rt_malloc(osc->times * 2);
if(osc->buffer != RT_NULL)
{
DMA_SetCurrDataCounter(peripheral->dma_device, times);
peripheral->dma_device->CMAR = (rt_uint32_t)osc->buffer;
return RT_EOK;
}
return RT_ENOMEM;
}

static rt_err_t osc_reset_buffer(struct rt_osc_device *osc)
{
RT_ASSERT(osc != RT_NULL);

if(osc->buffer != RT_NULL)rt_free(osc->buffer);
osc->times = 0;
return RT_EOK;
}

static rt_err_t osc_calculate(struct rt_osc_device *osc, struct osc_global_para* para)
{
float acvrms_sum = 0, dcvrms_sum = 0;
float vavr_sum = 0, vmin = 0, vmax = 0;
float cur_data, amp;

uint16_t freq = 0;
uint16_t i,len;
uint16_t *buffer;
int16_t flag = 0;

buffer = osc->buffer;
amp = 4096 / 3.3 / osc->config.extern_amp;
vmin = (*buffer - 2047.0) / amp;
vmax = vmin;
len = osc->times;

for(i = len; i > 0; i--)
{
cur_data = (*buffer - 2047.0) / amp;
vavr_sum = vavr_sum + cur_data;
if(cur_data > vmax) vmax = cur_data;
else if(cur_data < vmin) vmin = cur_data;
dcvrms_sum = cur_data * cur_data + dcvrms_sum;
buffer++;
}
dcvrms_sum = sqrt(dcvrms_sum / len);
vavr_sum = vavr_sum / len;
para->Vdcrms = dcvrms_sum;
para->Vavr = vavr_sum;
para->Vmax = vmax;
para->Vmin = vmin;
para->Vpp = vmax - vmin;


buffer = osc->buffer;
for(i = len; i > 0; i--)
{
cur_data = (*buffer - 2047.0) / amp;
if(cur_data > vavr_sum + 0.01)flag = 1;
else if(cur_data < vavr_sum - 0.01 && flag == 1)
{
freq++;
flag = 0;
}
acvrms_sum = (cur_data - vavr_sum) * (cur_data - vavr_sum) + acvrms_sum;
buffer++;
}
acvrms_sum = sqrt(acvrms_sum / len);
para->Vacrms = acvrms_sum;
if(freq < 10)para->Freq = 0;
else para->Freq = osc->config.sample_rate * 1.0 * freq / len;

return RT_EOK;
}

static const struct rt_osc_ops osc_ops =
{
osc_start,
osc_stop,
osc_configure,
osc_set_buffer,
osc_reset_buffer,
osc_calculate,
};

struct osc_use_peripheral peripheral1 =
{
ADC1,
ADC_ExternalTrigConv_T3_TRGO,
TIM3,
TIM_TRGOSource_Update,
DMA1_Channel1,
DMA1_Channel1_IRQn,
};

struct rt_osc_device osc1;

void DMA1_Channel1_IRQHandler(void)
{/****待写完整***/
rt_interrupt_enter();
if(DMA_GetITStatus(DMA1_IT_TC1))
{
rt_hw_osc_isr(&osc1, RT_OSC_EVENT_RX_FINISH);
DMA_ClearITPendingBit(DMA1_IT_TC1);
}
rt_interrupt_leave();
}

static void NVIC_Configuration(struct osc_use_peripheral* peripheral)
{
NVIC_InitTypeDef NVIC_InitStructure;

/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = peripheral->irq;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

static void RCC_Configuration(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
}

static void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

/* Configure USART Rx/tx PIN */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin = ADC_C1_PIN;
GPIO_Init(ADC_C1_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = ADC_C2_PIN;
GPIO_Init(ADC_C2_GPIO, &GPIO_InitStructure);
}



void rt_hw_adc_init(void)
{
struct osc_use_peripheral *peripheral;
struct osc_configure config = RT_OSC1_CONFIG_DEFAULT;

RCC_Configuration();
GPIO_Configuration();

peripheral = &peripheral1;

osc1.ops = &osc_ops;
osc1.config = config;

NVIC_Configuration(peripheral);

rt_hw_osc_register(&osc1, "osc1",
RT_DEVICE_FLAG_RDONLY | RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_STANDALONE,
peripheral);
}

/**
* @}
*/

/**
* @}
*/

/**
* @}
*/

查看更多

关注者
0
被浏览
2.3k
2 个回答
bernard
bernard 2014-12-01
光是看到OSC就一头雾水了,拎不清啊

这个是以前lgnq写的,可以稍微参考下,当然这样也不能上完全合理:
https://github.com/RT-Thread/rt-thread/ ... 500r/adc.h
https://github.com/RT-Thread/rt-thread/ ... 500r/adc.c

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览