Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
ADC
请大神帮忙看下风格 还是哪里有问题 照着串口驱动写的ADC驱动
发布于 2014-11-27 11:51:03 浏览:3896
订阅该版
注释凑合看下刚写好 还没改 可以用 但是风格是自己稍微理解一下 然后全抄的 不知道有没有问题 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); } /** * @} */ /** * @} */ /** * @} */ ```
查看更多
bernard
2014-12-01
这家伙很懒,什么也没写!
光是看到OSC就一头雾水了,拎不清啊 这个是以前lgnq写的,可以稍微参考下,当然这样也不能上完全合理: [https://github.com/RT-Thread/rt-thread/blob/master/bsp/mb9bf500r/adc.h](https://github.com/RT-Thread/rt-thread/ ... 500r/adc.h) [https://github.com/RT-Thread/rt-thread/blob/master/bsp/mb9bf500r/adc.c](https://github.com/RT-Thread/rt-thread/ ... 500r/adc.c)
2
个回答
默认排序
按发布时间排序
撰写答案
登录
注册新账号
关注者
0
被浏览
3.9k
关于作者
YoHo.
这家伙很懒,什么也没写!
提问
3
回答
5
被采纳
0
关注TA
发私信
相关问题
1
ADC config
2
rt_thread_delay()和ADC采样之间的冲突
3
请教在官方BSP中的STM32F40X程序中加入ADC,串口没输出。
4
给RT-Thread添加ADC驱动框架
5
求助:ADC采样被干扰
6
【内核和外设学习营】十里 ADC光敏电阻电压采集实验
7
<内核学习营>+坦然+探索者stm32f407板子的ADC测试光传感器实验
8
【内核学习营】+青春+ADC读取光敏传感器实验
9
《内核学习营》+水一方+项目中应用的ADC实现电压采集
10
STM32F10X HAL ADC+TIM+DMA+USART程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
张世争
8
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
KunYi
6
个答案
1
次被采纳
本月文章贡献
程序员阿伟
5
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部