Nrf52832 SAADC

2024-01-13 10:48
文章标签 nrf52832 saadc

本文主要是介绍Nrf52832 SAADC,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一. 测试平台

       环境:win10,64位,MDK集成开发环境.
       SDK:nRF5_SDK_15.2
       协议栈:s132_nrf52_6.1_softdevice.hex.
       硬件平台:pca10040开发板

       参考例程:nRF5_SDK_15.2.0_9412b96\examples\peripheral\saadc

       ADC的最快采样时间为5us采样一个点,如果为两通道扫描采样的话,最快为10us采样一次

二. Application移植

       1. 添加相关头文件

#include "nrf_drv_saadc.h"
#include "nrf_drv_ppi.h"

       2. SAADC的工作模式

      (1). 单次采样模式

                SAADC初始化

void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
//   
}void saadc_init(void)
{ret_code_t err_code;nrf_saadc_channel_config_t channel_config =NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN1);err_code = nrf_drv_saadc_init(NULL, saadc_callback);APP_ERROR_CHECK(err_code);err_code = nrf_drv_saadc_channel_init(0, &channel_config);APP_ERROR_CHECK(err_code);}

         启动一次ADC采样,获取ADC值

nrf_drv_saadc_sample_convert(0,&saadc_val);

      (2).单缓冲中断模式

                SAADC初始化,相关中断函数

#define SAMPLES_IN_BUFFER 6
static nrf_saadc_value_t       m_buffer_pool[SAMPLES_IN_BUFFER];void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{   float  val; if (p_event->type == NRF_DRV_SAADC_EVT_DONE){ret_code_t err_code;//设置好缓存,为下次转换预备缓冲err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);APP_ERROR_CHECK(err_code);int i;for (i = 0; i < p_event->data.done.size; i++){val = p_event->data.done.p_buffer[i] * 3.6 /1024;	printf("Voltage = %.3fV\r\n", val);}}
}void saadc_init(void)
{ret_code_t err_code;nrf_saadc_channel_config_t channel_0_config =NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN2);err_code = nrf_drv_saadc_init(NULL, saadc_callback);APP_ERROR_CHECK(err_code);err_code = nrf_drv_saadc_channel_init(0, &channel_0_config);APP_ERROR_CHECK(err_code);err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool,SAMPLES_IN_BUFFER);APP_ERROR_CHECK(err_code);
}

         启动一次ADC采样,要采样次数等于SAMPLES_IN_BUFFER时,才会进入中断

nrf_drv_saadc_sample();

     (3).双缓冲PPI采样

              用PPI的方式去触发SAADC,工作方式如下所示:

            

        所以相对之前的初始化会复杂一点,需要初始化定时器,设置采样时间(这个采样时间是采样一个点的时间,如果采样时间设置为400ms,采集5个点,则全部的采样时间为400*5=2s。如果为两个通道,则400ms取两个点,取五次),设置PPI通道,初始化SAADC

#define SAMPLES_IN_BUFFER 5static const nrf_drv_timer_t m_timer = NRF_DRV_TIMER_INSTANCE(0);
static nrf_saadc_value_t     m_buffer_pool[2][SAMPLES_IN_BUFFER];
static nrf_ppi_channel_t     m_ppi_channel;void timer_handler(nrf_timer_event_t event_type, void * p_context)
{}void saadc_sampling_event_init(void)
{ret_code_t err_code;err_code = nrf_drv_ppi_init();APP_ERROR_CHECK(err_code);nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;err_code = nrf_drv_timer_init(&m_timer, &timer_cfg, timer_handler);APP_ERROR_CHECK(err_code);/* setup m_timer for compare event every 400ms */uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, 400);nrf_drv_timer_extended_compare(&m_timer,NRF_TIMER_CC_CHANNEL0,ticks,NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,false);nrf_drv_timer_enable(&m_timer);uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer,NRF_TIMER_CC_CHANNEL0);uint32_t saadc_sample_task_addr   = nrf_drv_saadc_sample_task_get();/* setup ppi channel so that timer compare event is triggering sample task in SAADC */err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);APP_ERROR_CHECK(err_code);err_code = nrf_drv_ppi_channel_assign(m_ppi_channel,timer_compare_event_addr,saadc_sample_task_addr);APP_ERROR_CHECK(err_code);
}void saadc_sampling_event_enable(void)
{ret_code_t err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);APP_ERROR_CHECK(err_code);
}void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{if (p_event->type == NRF_DRV_SAADC_EVT_DONE){ret_code_t err_code;err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);APP_ERROR_CHECK(err_code);int i;for (i = 0; i < SAMPLES_IN_BUFFER; i++){NRF_LOG_INFO("%d", p_event->data.done.p_buffer[i]);}}
}void saadc_init(void)
{ret_code_t err_code;nrf_saadc_channel_config_t channel_config =NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);err_code = nrf_drv_saadc_init(NULL, saadc_callback);APP_ERROR_CHECK(err_code);err_code = nrf_drv_saadc_channel_init(0, &channel_config);APP_ERROR_CHECK(err_code);err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], SAMPLES_IN_BUFFER);APP_ERROR_CHECK(err_code);err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], SAMPLES_IN_BUFFER);APP_ERROR_CHECK(err_code);}

     启动ADC,值需要初始化ADC即可,数据会不停的缓冲在easydma中,每次数据需要及时读取,不然会被覆盖掉。

saadc_init();
saadc_sampling_event_init();
saadc_sampling_event_enable();

       防止数据覆盖的方式:

      ①采样完之后,在ADC中断函数中关掉定时器,等数据处理完再开启定时器,可以用下面两条语句

nrf_drv_timer_disable(&m_timer);
nrf_drv_timer_enable(&m_timer);

      ② 同时将ADC,PPI,TIMER都关掉,可以有效降低功耗

           启动ADC

void ADC_PWM_START(void)
{nrf_saadc_enable();nrf_saadc_task_trigger(NRF_SAADC_TASK_START);nrf_drv_timer_enable(&m_timer);
}

            关闭ADC,需要将相关标志位清楚,不然会导致错误

void ADC_PWM_STOP(void)
{nrf_drv_timer_disable(&m_timer);nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP);nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);nrf_saadc_event_clear(NRF_SAADC_EVENT_END);nrf_saadc_disable();
}

(4)采样数据的存放方式

         在模式2和3中,如果是多通道的话,数据将会交替存放,如下所示:

                假设采集数据为3,通道为2

                   

这篇关于Nrf52832 SAADC的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/601186

相关文章

nrf52832 esb 2.4G通信 一对多 改频道

若想支持更多客户端,可通过修改通道号及频率的方式, 同频道下,最多支持8个通道,若想支持更多的设备,接收端需要修改频道,与发送端保持一致; 常用函数: bool nrf_esb_set_enabled_prx_pipes(uint32_t pipes) 用于使能接收通道,第0位对应通道1,依次类推,可同时使能多个通道 bool nrf_esb_set_crc_length (nrf

关于NRF52832 一对多NUS数据传输问题的补充

上几篇文章中实现了一主多从及MTU大数据传输后,由于上篇一主多从的传输还有很大问题,主机再分时的接收数据的时候,总是会对当前连接的设备,接收的数据多,其它的设备接收的少,甚至丢包非常的严重,现对次问题再做补充说明,改善接收数据问题。 1、要注意主机接收数据的时候是分时的,所以几个从机设备以同一个连接间隔连接发送数据,肯定是不行的,这样就会出现当前连接的设备数据才能被接收到,其它的设备有可能都接收

nrf52832 MTU 提高BLE空中发送速率

参考https://www.cnblogs.com/iini/p/9095622.html 蓝牙4.2的理论吞吐率大概为100kB/s,而我们实际达到了80kB/s,已经非常接近理论值 我自己实际测试达到了72KB/s,虽然还有些差距,但也是比较接近了。 首先测试的时候,工具要选择正确,如果用手机测试的话,很可能达不到你的要求,同样的程序,我用手机(华为荣耀5),本身 蓝牙是4.1的,测试

NRF52832时钟控制系统

NRF52832时钟控制系统可以从内部或外部高频、低频振荡器获得系统时钟,并根据模块的各自需要给他们分配时钟,时钟 分配是自动化的,并通过模块独立分组,以限制未使用的电流消耗。 HFCLK clock controller 下面是时钟的主要特点: • 64 MHz 内部振荡器  •64 MHz 晶体振荡器,使用外部32 MHz的晶振 • 32.768KZ +- 250

nRF52832——唯一 ID 与加密解密

nRF52832——唯一 ID 与加密解密 唯一 ID 概念唯一 ID 作用读取唯一 ID 唯一 ID 用于加密TEA 加密算法唯一 ID 的加密和解密 唯一 ID 概念 唯一 ID 作用 nRF52xx 微控制器提供一组 64 位的唯一 ID 号,这个唯一身份标识所提供的 ID 值对任意一个 nRF52xx 微控制器,在任何情况下都是唯一的。用户在何种情况下,都不能修改

Silicon Labs新推出EFR32BG22芯片性能强劲,详细对比nRF52832和CC2640R2F

SIG最新推出了BLE 5.2协议,定义了低功耗蓝牙的双向功率控制协议(LE Power Control),可用于实现多种应用场景,有助于在保持连接的情况下进一步降低功耗并提高设备连接的稳定性和可靠性。蓝牙5.2版本中新增的功能包括LE同步信道(LE Isochronous Channels), 增强版ATT(Enhanced ATT)及LE功率控制(LE Power Control)。 依

nRF52832低功耗蓝牙5.0芯片介绍

nRF52832通过对蓝牙5的支持,将蓝牙低能量SoCs提升到下一个水平。它的心脏有一个ARM Cortex M4 CPU,运 行在64MHz,在短时间内完成应用和沟通任务。这样可以使cpu处理更多的任务,或者恢复休眠模式,从而节省宝 贵的电池能量。 nRF52832和nRF52系列中的所有SoC都是基于闪存的SoC,是设备固件更新(DFU)的理想选择。DFU为您的产品中 运行的固件带来了全面的

nRF52832-Bluefruit52学习之Arduino开发(4)-- 蓝牙组网一拖8主从机模式(dual_roles_bleuart)

nRF52832技术交流群:680723714        nRF52832-Bluefruit52核心板详细介绍: https://blog.csdn.net/solar_Lan/article/details/88688451        github仓库地址:https://github.com/Afantor/Bluefruit52_Arduino.git

nRF52832-Bluefruit52学习之Arduino开发(3)-- 蓝牙组网一拖8主机模式(central_bleuart)

nRF52832技术交流群:680723714        nRF52832-Bluefruit52核心板详细介绍: https://blog.csdn.net/solar_Lan/article/details/88688451        github仓库地址:https://github.com/Afantor/Bluefruit52_Arduino.git

nRF52832-Bluefruit52学习之外设开发(1)-- MPU6050六轴模块

nRF52832技术交流群:680723714        nRF52832-Bluefruit52核心板详细介绍: https://blog.csdn.net/solar_Lan/article/details/88688451                                                  nRF52832驱动MPU6050