精华内容
下载资源
问答
  • [艾克姆科技]nRF52832开发指南下册 资料齐全
  • 艾克姆科技发布的基于SDK15.2编写的nRF52832开发电子书,优点:排版清晰,对库的应用流程和代码编写写的很清楚,入门必备。
  • [艾克姆科技]蓝牙4.x BLE开发笔记-基于nRF51822, 蓝牙教程,内容比较丰富,需要的可以下载。。。。。。。。。
  • 快速了解nRF52832的开发过程,可以参考和使用
  • 本文档以艾克姆科技IK-52832DK开发板为硬件平台,针对BLE开发,从基础概念和新建BLE工程模板开始,一步步讲解蓝牙BLE程序框架以及功能的实现
  • 艾克姆科技
  • nRF52832_guide_jb51.rar

    2020-12-04 10:10:33
    [艾克姆科技]nRF52832开发指南上下册,蓝牙开发技术文档,基于sdk15.0,针对艾克姆科技开发板,优点:排版清晰,对库的应用流程和代码编写写的很清楚,入门必备
  • nRF52832开发指南.rar

    2020-05-29 09:04:05
    [艾克姆科技]nRF52832开发指南上下册
  • nrf52832开发教程

    2018-08-16 09:35:14
    [艾克姆科技]Nordic多协议Soc:nRF52832开发教程(1-14章)
  • 艾克姆科技教程: nRF52840开发指南下册,非常好的中文示例和教程。基于Nordic的Nrf52840.
  • 艾克姆科技教程: nRF52840开发指南上册,非常好的中文示例和教程。基于Nordic的Nrf52840.
  • 1:[艾克姆科技教程]nRF52810开发指南 nRF52810开发指南-上册.pdf nRF52810开发指南-上册.pdf
  • nRF52832开发指南-上册

    2018-10-16 17:24:52
    基于Nordic 蓝牙低功耗/2.4GHz Soc-nRF52832 的开发指南,中文版。艾克姆科技教程: 非常好的中文示例和教程。
  • 艾克姆科技】nRF24LU1开发板的资料里没有usb键盘的程序,另外找到的程序不说引脚问题,只需要两个模块就麻烦。由dongle模块改成的按键触发,遇到的最大问题是字符不断重复的问题。其实深入了解了usb HID协议的话,...

    【艾克姆科技】nRF24LU1开发板
    【艾克姆科技】nRF24LU1开发板的资料里没有usb键盘的程序,另外找到的程序不说引脚问题,只需要两个模块就麻烦。由dongle模块改成的按键触发,遇到的最大问题是字符不断重复的问题。其实深入了解了usb HID协议的话,这也不是问题的。
    usb_send_packet
    (
    &radio_data[APP_DATA],
    USB_EP_KEYBOARD,
    8// (APP_KEYBOARD_PL_LENGTH - APP_DATA)
    );
    usb触发发送后,还需要改送一个全为0的空帧,否则电脑会认为你按下的键一直没有释放,故一直重复。发以下帧:
    usb_send_packet
    (
    empty_keybuf,
    USB_EP_KEYBOARD,
    8// (APP_KEYBOARD_PL_LENGTH - APP_DATA)
    );
    empty_keybuf为全为0,长度为8的数组。
    代码下载地址
    http://download.csdn.net/detail/u014516174/9848167

    展开全文
  • 这里使用艾克姆科技的例程,却无法成功运行,上了示波器才发现拉低时间无法达到18ms,因此无法唤醒DTH11。 总线由stm32拉低12ms左右之后就一直处于高电平。 原因在于艾克姆的延时函数是硬件延时(这断代码被写入到一...

    关于DTH11的介绍和使用方法可以随便搜索一下别的文章,直接搜索DTH11即可。
    这里使用艾克姆科技的例程,却无法成功运行,上了示波器才发现拉低时间无法达到18ms,因此无法唤醒DTH11。
    总线由stm32拉低12ms左右之后就一直处于高电平。
    原因在于艾克姆的延时函数是硬件延时(这段代码被写入到一个头文件,在主函数中引用),代码如下

    #ifndef _DELAY_H
    #define _DELAY_H
    
    #include "stm32f10x.h"
    
    //微秒软件延时函数
    __STATIC_INLINE void sw_delay_us(uint32_t number_of_us);
    //毫秒软件延时函数
    __STATIC_INLINE void sw_delay_ms(uint32_t number_of_ms);
    
    
    __STATIC_INLINE void sw_delay_us(uint32_t number_of_us)
    {
      //输入的延时时间为0的话,程序直接返回  
    	if(!number_of_us)
            return;
    __asm
        {
    loop:
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
    	NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        SUBS number_of_us, #1  //number_of_us减一
        BNE loop  //不等于0跳转到LOOP执行
        }
    }
    __STATIC_INLINE void sw_delay_ms(uint32_t number_of_ms)
    {
        sw_delay_us(1000*number_of_ms);
    }
    
    #endif
    

    尝试在调用sw_delay_ms()或者sw_delay_us() 时修改括号里面的值,但是都只能延时12ms左右(有大神知道原因请不吝指教一下)
    于是便使用了stm32内部的SysTick计时器,这里是按照非中断的方式使用
    代码可以按以下配置。
    头文件

    #include "stm32f10x.h"
    void delay_init(void);
    void delay_ms(vu32 nTime);
    void delay_us(vu32 nTime);
    

    源文件

    #include "stm32f10x.h"
    void delay_init(void)
    {
    	SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;		//时钟源为系统时钟168MHz
    	SysTick->LOAD = 167;					//重载值为168-1,每1us溢出一次
    }
    
    void delay_ms(vu32 nTime)
    {
    	nTime *= 1000;
    	SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;		//使能SysTick,开始计数
    	while(nTime--){
    		while((SysTick->CTRL&0X010000) == 0);		//等待COUNTFLAG标志位置1
    	}
    	SysTick->CTRL &= (~SysTick_CTRL_ENABLE_Msk);		//失能SysTick,停止计数
    }
    
    void delay_us(vu32 nTime)
    {
    	SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
    	while(nTime--){
    		while((SysTick->CTRL&0X010000) == 0);
    	}
    	SysTick->CTRL &= (~SysTick_CTRL_ENABLE_Msk);
    }
    

    这样延时函数就可以自己定比较准确时间了,DTH11被唤醒成功,具体的时钟配置应该还要根据各自的芯片手册调整,后面再更新文章。

    展开全文
  • nrf52832之GPIOTE组件

    2020-04-15 09:52:29
    参考资料:艾克姆科技 《nRF52832开发教程》 GPIOTE部分学习思维导图 GPIOTE原理 nRF52832寄存器类型 Task:任务寄存器,可以由程序或事件触发 Event:事件寄存器,事件可以产生中断和触发任务 Register:普通寄存器,...

    今日份流水账来咯!
    参考资料:艾克姆科技 《nRF52832开发教程》

    GPIOTE部分学习思维导图

    在这里插入图片描述

    GPIOTE原理

    nRF52832寄存器类型

    Task:任务寄存器,可以由程序或事件触发
    Event:事件寄存器,事件可以产生中断和触发任务
    Register:普通寄存器,和一般单片机的寄存器一样

    GPIOTE功能

    GPIOTE每个通道可以使用的Task有三个
    置位,清除,翻转
    GPIOTE每个同奥的事件可以由以下的输入状态产生
    上升沿,下降沿,任意电平跳变

    GPIOTE驱动库的使用

    任务/事件通道的分配

    用于驱动引脚输出的GPIOTE任务或者用于在输入引脚电平变换时产生事件的任务/事件通道数量时受限制的,驱动程序会管理这些通道,用户是决定不了哪个通道的,即通道分配由驱动程序完成,用户不能指定使用哪一个具体的通道

    重要的API函数

    //函数功能:初始化GPIOTE通道
    ret_code_t nrf_drv_gpiote_init  (void)
    //函数功能:初始化GPIOTE输出引脚
    ret_code_t nrf_drv_gpiote_out_init  (
        nrf_drv_gpiote_pin_t    pin,  //初始化引脚
        nrf_drv_gpiote_out_config_t const *     p_config   //初始化结构体
    )
    //nrf_drv_gpiote_out_config_t要包含以下三项内容
    //1)引脚的初始状态:高电平还是低电平
    //2)引脚动作:任务触发后引脚执行的动作,包括置位,清除和翻转
    //3)是否为GPIOTE引脚
    //函数功能:使能任务触发
    void nrf_drv_gpiote_out_task_enable (nrf_drv_gpiote_pin_t   pin)   
    

    应用步骤

    GPIOTE输出应用步骤

    注意:GPIOTE一般和PPI一起用,否则体现不了GPIOTE的优势

    (1)初始化GPIOTE模块(在一个程序中GPIOTE只能初始化一次)
    (2)初始化GPIOTE输出引脚
    (3)是否使能任务触发,虽然使用的GPIOTE模块,但是仍可设置是任务触发还是写GPIO寄存器,若使能了任务触发,则触发任务驱动引脚,否则写GPIO寄存器驱动引脚
    (4)使能任务触发

    GPIOTE输入应用步骤

    (1)初始化GPIOTE模块

    (2)配置引脚为GPIO输入

    ret_code_t nrf_drv_gpiote_in_init   (
        nrf_drv_gpiote_pin_t    pin,  //初始化的引脚
        nrf_drv_gpiote_in_config_t const *  p_config,  //GPIOTE输入初始化结构体
        nrf_drv_gpiote_evt_handler_t    evt_handler   //User function to be called when the configured transition occurs.翻译:用户函数被称为配置转变发生时
    )
    
    GPIOTE初始化结构体包括4项内容
    1)Sense 配置引脚的Sense功能
    	高电平到低电平的变化产生事件
    	低电平到高电平的变化产生事件
    	任意电平变化产生事件
    2)is_watcher 是否连接输入缓冲器
    3)pull 是否开启上拉电阻
    4)hi_accuracy 是否为高精度模式
    

    (3)使能该引脚所在GPIOTE通道的事件模式

    void nrf_drv_gpiote_in_event_enable (
        nrf_drv_gpiote_pin_t    pin,
        bool    int_enable   //True to enable the interrupt. Always valid for a high-accuracy pin,翻译:真正的启用中断,高精度引脚总是有效的
    )
    

    DEMO

    包括PPIGPIOTE两部分的应用

    #include <stdint.h>
    #include "nrf_drv_gpiote.h"
    #include "app_error.h"
    #include "nrf_drv_ppi.h"
    //定义引脚
    #define LED_2       18
    #define BUTTON_0    16
    //定义nrf_ppi_channel_t变量,用来保存PPI的信息
    nrf_ppi_channel_t my_ppi_channel;
    //初始化PPI
    void PPI_Config()
    {
        uint32_t err_code = NRF_SUCCESS;
        //1 初始化PPI
        err_code=nrf_drv_ppi_init();
        APP_ERROR_CHECK(err_code);
        //2 分配PPI通道
        err_code=nrf_drv_ppi_channel_alloc(&my_ppi_channel);
        APP_ERROR_CHECK(err_code);
        //3 配置PPI通道的EEP和TEP
        err_code=nrf_drv_ppi_channel_assign(my_ppi_channel,
                                   nrf_drv_gpiote_in_event_addr_get(BUTTON_0),
                                   nrf_drv_gpiote_out_task_addr_get(LED_2));
        APP_ERROR_CHECK(err_code);
        //4 使能PPI通道
        err_code=nrf_drv_ppi_channel_enable(my_ppi_channel);
        APP_ERROR_CHECK(err_code);
    }
    //初始化GPIOTE
    void GPIOTE_Config()
    {
        ret_code_t err_code;
        //LED初始化为输出引脚
        err_code=nrf_drv_gpiote_init();
        APP_ERROR_CHECK(err_code);
        //配置结构体
        nrf_drv_gpiote_out_config_t led_config=GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
        err_code=nrf_drv_gpiote_out_init(LED_2,&led_config);
        APP_ERROR_CHECK(err_code);
        //使能任务触发
        nrf_drv_gpiote_out_task_enable(LED_2);
        //BUTTON初始化为输入引脚
        nrf_drv_gpiote_in_config_t button_config=GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
        button_config.pull=NRF_GPIO_PIN_PULLUP;  //开启上拉电阻
        err_code=nrf_drv_gpiote_in_init(BUTTON_0,&button_config,NULL);
        APP_ERROR_CHECK(err_code);
        nrf_drv_gpiote_in_event_enable(BUTTON_0,true);
    }
    /****************************************************************
     * 描  述 : main函数
     * 入  参 : 无
     * 返回值 : 无
    *****************************************************************/
    int main(void)
    {
        //初始化GPIOTE
        GPIOTE_Config();
        //初始化PPI
        PPI_Config();  //一定要先初始化GPIOTE,然后进行PPI的初始化
        while (true)
        {
        }
    }
    
    展开全文
  • 作者:强光手电[艾克姆科技-无线事业部] 1. nRF51822寄存器类型  nRF51822的寄存器和一般的单片机有所差别,nRF51822的寄存器分为下面的三种类型。 Task :任务寄存器,可以由程序或事件触发。 Event:事件...

    版权声明:本文为博主原创文章,转载请注明作者和出处。    作者:强光手电[艾克姆科技-无线事业部]

    1. nRF51822寄存器类型

      nRF51822的寄存器和一般的单片机有所差别,nRF51822的寄存器分为下面的三种类型。

    • Task :任务寄存器,可以由程序或事件触发。
    • Event:事件寄存器,事件可以产生中断或触发任务。
    • Register:普通寄存器,和一般单片机的寄存器一样。

      Task和event使得操作片上外设十分方便简洁,只需进行少量的配置,即可轻松运用各种外设。同时,Task和event能有效减少CPU的占用时间,降低CPU的负荷。

      Task和Event更多的是用来和PPI(可编程外设互连)配合使用,通过PPI 将某个Event和Task连接起来,连接后,该Event即可触发对应的Task执行相应的功能。

      示例:实现每隔1S翻转一次指示灯的状态。

    •  一般的做法:配置定时器定时时间为1S,每秒产生一次中断,在中断服务程序中通过软件操作翻转指示灯的状态。在这个过程中,必须要通过软件操作才能实现。
    • 通过Task和Event实现:配置定时器的相关参数,配置GPIOTE的Task为翻转管脚状态,配置PPI的一个通道用于连接定时器的匹配事件和GPIOTE的Task。这样,当定时器产生匹配事件时,会自动触发GPIOTE的Task,在无需任何软件干预的情况下实现指示灯状态的翻转。

    2. GPIOTE(GPIO Tasks and Events)

    2.1 功能描述

      nRF51822在GPIO的基础上引入了任务和事件(GPIOTE)的概念,nRF51822的GPIOTE共有4个通道,每个通道都可以选择一个管脚,选择的管脚可以配置为Task mode或Event mode。需要注意的是:不能将某个管脚同时分配给多个GPIOTE通道,否则会导致无法预料的错误。

      GPIOTE通道的Task可以用来执行以下写操作:

    • 置位。
    • 清除。
    •  翻转。

      事件可以由以下的输入状态产生:

    • 上升沿。
    • 下降沿。
    • 任意电平跳变。 

    2.1.1 管脚Tasks和Events

      Tasks和Events通过CONFIG[n](n=0~3)配置,每个CONFIG[n]寄存器对应一组OUT[n] 任务寄存器和IN[n]事件寄存器。OUT[n]用于写管脚,IN[n]由管脚状态变化触发。

      当把某个管脚分配给OUT[n]任务或IN[n]事件后,该管脚就只能被GPIOTE模块写操作,正常的GPIO写入无效。

      一旦配置OUT[n]任务或IN[n]事件控制某个管脚,那么该管脚的输出值只能通过GPIOTE模块操作,使用GPIO的寄存器操作会被忽略。

      当GPIOTE通道被配置用于操作一个任务管脚时,CONFIG[n]寄存器中的OUTINIT决定了该管脚脚的初始值。可以通过配置OUTINIT来设置管脚初始化状态为高电平或是低电平。

    2.1.2 PORT事件

      GPIOTE除了4个通道外,还包含一个PORT事件。PORT事件由使用GPIO DETECT信号的多个管脚触发,PORT中的任意一个管脚上的上升沿都会触发PORT事件。

    可以设置一个或多个GPIO DETECT用来产生PORT事件,PORT事件可以作为唤醒源,也可以作为中断源产生中断。

    3. 按键实验程序

      本实验使用的程序是:nrf51-app-button-example-master。

    3.1 运行环境

    • 编译环境:MDK5。
    • SDK版本:SDK 8.0.0

    3.2 按键检测原理

      程序中对按键的处理如下:通过GPIOTE的PORT事件来检测有无按键按下,当检查到按键按下时,启动定时器开始计时(程序中设置的位50ms),在定时器超时中断中若检测到该按键仍然为按下的状态,则认为这是一个有效的按键。在这里使用定时器(软件定时器)是为了消除按键抖动。

     

     

                                                                    图1:按键检测和消抖

      若在第一个按键检测流程没有处理完时(该按键的定时器还在运行),又有一个按键按下,这时,定时器会重新开始计时,如下图所示。

                                                        图2:多个按键处理

    3.3 程序下载和验证

    3.3.1 程序下载

      本实验无需下载协议栈,如果开发板中已经下载了协议栈,需要通过nRF STUDIO进行擦除。

      程序可以用nRFgo Studio下载,也可以在MDK中直接下载调试,在这里我们用nRFgo Studio下载。切换到“Program Application”选项卡。点击“Browse…”按钮打开应用程序的HEX文件(位于“…\ nrf51-app-button-example-master\pca10028 \arm5\_build”目录下的 GPIOTE_BUTTON.hex)。点击“Program”下载程序。

    3.3.2 实验现象

      分别按下S1~S4按键,每按一次,对应的指示灯(D1~D4)状态会翻转一次。

     

    转载于:https://www.cnblogs.com/aikm/p/5063039.html

    展开全文
  • 作者:强光手电[艾克姆科技-无线事业部] 1.扫描请求和扫描响应  广播包含扫描请求SCAN_REQ和扫描响应SCAN_RSP。 扫描请求:由链路层处于扫描态的设备发送,链路层处于广播态的设备接收。 扫描响应:由链路层...
  • 作者:强光手电[艾克姆科技-无线事业部]  在使用EN-Dongle捕获和解析广播包之前,我们先了解一下BLE报文的结构,之后,再对捕获的广播包进行分析。在学习BLE的时候,下面两个文档是极其重要...
  • 艾克姆科技STC15W4K64的一块系统开发板 话不多说,直接上代码(模块化) 主函数代码如下 #include "timer.h" void main() { unsigned char time = 0; P0M0 = 0; P0M1 =1; //配置P0为准双向模式 Timer0_Init(); /...
  • 作者:强光手电[艾克姆科技-无线事业部]  在使用EN-Dongle捕获和解析广播包之前,我们先了解一下BLE报文的结构,之后,再对捕获的广播包进行分析。在学习BLE的时候,下面两个文档是极其重要的,这是SIG发布的蓝牙...
  • 本文转载于:强光手电[艾克姆科技-无线事业部] 原文链接:https://www.cnblogs.com/aikm/p/5021220.html 蓝牙4.0 BLE的开发过程中,使用抓包器进行抓包分析无疑会极大地提高我们的开发效率,同时能帮我们快速的...

空空如也

空空如也

1 2 3 4
收藏数 80
精华内容 32
关键字:

艾克姆科技