nRF51822之PWM学习笔记
nRF51822外部中断学习总结

最近要用nRF51822进行项目的多任务调度,其中不可避免的要用到要用到nRF51822的相关中断首先,nRF51822是基于Cortex-M0架构的MCU,根据nRF51822的软件开发包中的core-m0.h文件夹,可以找到51822的相关中断编号定义(Interrupt Number Definition)[objc]view plain copy1.<span style="font-size:18px;">/* ------------------------- Interrupt Number Definition ------------------------ */2.3.typedef enum {4./* ------------------- Cortex-M0 Processor Exceptions Numbers ------------------- */5. Reset_IRQn = -15, /*!< 1 Reset Vector, invoked on Powerup and warm reset */6. NonMaskableInt_IRQn = -14, /*!< 2 Non maskable Interrupt, cannot be stopped or preempted */7. HardFault_IRQn = -13, /*!< 3 Hard Fault, all classes of Fault*/8. SVCall_IRQn = -5, /*!< 11 System Service Call via SVC instruction */9. DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor*/10. PendSV_IRQn = -2, /*!< 14 Pendable request for system service */11. SysTick_IRQn = -1, /*!< 15 System Tick Timer*/12./* ---------------------- nRF51 Specific Interrupt Numbers ---------------------- */13. POWER_CLOCK_IRQn = 0, /*!< 0 POWER_CLOCK*/14. RADIO_IRQn = 1, /*!< 1 RADIO*/15. UART0_IRQn = 2, /*!< 2 UART0*/16. SPI0_TWI0_IRQn = 3, /*!< 3 SPI0_TWI0*/17. SPI1_TWI1_IRQn = 4, /*!< 4 SPI1_TWI1*/18. GPIOTE_IRQn = 6, /*!< 6 GPIOTE*/19. ADC_IRQn = 7, /*!< 7 ADC*/20. TIMER0_IRQn = 8, /*!< 8 TIMER0*/21. TIMER1_IRQn = 9, /*!< 9 TIMER1*/22. TIMER2_IRQn = 10, /*!< 10 TIMER2*/23. RTC0_IRQn = 11, /*!< 11 RTC0*/24. TEMP_IRQn = 12, /*!< 12 TEMP*/25. RNG_IRQn = 13, /*!< 13 RNG*/26. ECB_IRQn = 14, /*!< 14 ECB*/27. CCM_AAR_IRQn = 15, /*!< 15 CCM_AAR*/28. WDT_IRQn = 16, /*!< 16 WDT*/29. RTC1_IRQn = 17, /*!< 17 RTC1*/30. QDEC_IRQn = 18, /*!< 18 QDEC*/31. LPCOMP_COMP_IRQn = 19, /*!< 19 LPCOMP_COMP*/32. SWI0_IRQn = 20, /*!< 20 SWI0*/33. SWI1_IRQn = 21, /*!< 21 SWI1*/34. SWI2_IRQn = 22, /*!< 22 SWI2*/35. SWI3_IRQn = 23, /*!< 23 SWI3*/36. SWI4_IRQn = 24, /*!< 24 SWI4*/37. SWI5_IRQn = 25 /*!< 25 SWI5*/38.} IRQn_Type;39.</span>在进行中断处理时,一般都要按照这个步骤:1、对要用到的中断初始化;2、对用到的中断进行使能;3、对中断进行优先级设置1、中断初始化nRF51822的外部I/O(暂时理解的程度以及用过的中断只有I/O中断,其他中断没有实践过)中断是基于任务和事件模式的。
PWM模块和时钟系统模块学习笔记

PWM模块1.PWM通道占空比寄存器PWM Channel Duty Register(PWMDTY)每个通道都有一个专用的用来设置占空比的寄存器PWMDTYx,PWMDTYx和PWMPERx 的值共同决定了占空比的值,就是说当每个通道的count的值计数到与PWMDTYx的值相等时,相应的输出信号就发生一次翻转。
如果你设置PWMPOL寄存器的某位PPOLx 的值为1,也就是开始的时候输出为高电平,然后当计数器数到与PWMDTYx的值后就翻转为低电平,那么PWMDTY寄存器的值就包含了高电平的时间,再结合占空比说明一下吧PPOLx=1:占空比=(PWMDTYx/PWMPERx)*100%PPOLx=0:占空比=(PWMPERx-PWMDTYx)/PWMPERx*100%2.PWM通道周期寄存器PWM Channel Period Registers(PWMPERx)每个通道都有一个专用的用来设置周期情况的寄存器(PWMPERx),这个寄存器的值就决定了PWM通道输出信号周期的长短,如果我们已经知道的参考时钟源的值,那么就可以计算出PWM输出信号的周期了,计算方法如下:PWMxPeriod=ChannelClockPeriod*PWMPERx(左对齐情况下即CAEx=0) PWMxPeriod=ChannelClockPeriod*PWMPERx*2(居中对齐情况下即CAEx=1) 3. PWM使能寄存器PWM Enable Register(PWME)PWME[7:0]分别控制着对应的8个通道的使能,例如:PWME_PWME0=0:禁止通道0的PWM输出PWME_PWME7=1: 使能通道7的PWM输出3.PWM极性寄存器PWM Polarity Register(PWMPOL)PWMPOL寄存器是用来控制PWM一开始输出时的信号高低情况,假如PPOLX设为1,则与之相应的PWM通道在开始的时候输出为高电平,然后等到计数器的值与你设置的那个PWM 信号的值(PWMDTYx)相等的时候就输出低电平。
NRF51822-Eval-Kit-用户手册

6
NRF51822 Eval Kit 用户手册
微雪电子
2.5 各程序功能简介
a) 以下所有程序路径为:<code path>\BLE4.0\nrf51822\Board\pca10001 且所有跳线都已连接。 b) 下表中的步骤序号,请参考表格下方的备注栏。 c) 操作涉及步骤②的,下载方法请参考上文“编译下载 ble_app_hrs 测试程序”。 d) 其他的程序下载方法请参考上文“编译下载 blinky_example 测试程序”
核心板介绍:
Core51822参数:
主控芯片:nRF51822 通信距离: 30m (条件: 空旷区域 / 1M速率) 工作频段:2.4GHz 工作电压:2.0V ~ 3.6V 温度范围:-40℃ ~ 85℃ 尺寸:24.5mm x 32.26mm(PCB) 接口: 除P0.26和P0.27外, 所有I/O 接口 排针间距:2.00mm 两侧排针间距:18.00mm 天线:板载天线
NRF51822 Eval Kit 用户手册
微雪电子
NRF51822 Eval Kit 用户手册
产品介绍:
nRF51822是一款为超低功耗无线应用(ULP wirelesss applications)打造的多协议单芯片解决方案。 它整合了Nordic一流的无线传送器,同时支持Bluetooth(R) low energy 和专用的2.4GHz协议栈。
微雪电子
图 5.
KEIL下载报错
答: 请确保正确安装SDK,Flash Dodnload 设置如下:
图 6.
Flash Dodnload 设置
8
NRF51822 Eval Kit 用户手册 问: 阅读完该手册后,如何进一步学习? 答: 请仔细阅读chip PDF文件夹中相关文档,以及官方提供的参考手册: 资料包\code\BLE4.0\Documentation\index.html。
nrf51822数据手册_引脚图_参数

RoHS and REACH statement
Nordic Semiconductor's products meet the requirements of Directive 2002/95/EC of the European
My Page account on our home page.
Main office: Otto Nielsens veg 12
7052 Trondheim Norway
Phone: +47 72 89 89 00 Fax: +47 72 89 89 89
Mailing address: Nordic Semiconductor
Version 3.3
Description
Added documentation for the nRF51822 CTAA version of the chip.
Added content: • Section 9.5 “CTAA WLCSP package” on page 71 • Section 11.9 “CTAA WLCSP package” on page 118
statement can be found on our website
.
Page 2
nRF51822 Product Specification v3.3
Datasheet Status
Status Objective Product Specification (OPS) Preliminary Product Specification (PPS)
• ARM® Cortex™-M0 32 bit processor • 275 μA/MHz running from flash memory • 150 μA/MHz running from RAM • Serial Wire Debug (SWD)
STM8学习笔记——PWM模块

STM8学习笔记——PWM模块首先将管脚配置为推挽输出。
下面以向上计数模式为例来讲述PWM 产生的原理:TIMx 开始向上计数,TIMx_CNT 为计数值,计数一次加1,TIMx_ARR 确定了计数的上限,达到上限后计数器从0 开始重新计数,所以一次PWM 频率就由TIMx_ARR 来确定了,即计数器时钟*(TIMx_ARR-1),频率确定了,接下来就是占空比。
占空比是由TIMx_CCRx 来确定的,PWM模式1 下当TIMx_CNT=TIMx_CCRx 时,输出OCiREF 无效电平,至于有效电平是0 还是1,要设置TIMx_CCERx,这样产生了一个PWM 波形,可以说配置非常灵活,当TIMx_CCRx 为0 时,占空比就为0,当TIMx_CCRx 大于TIMx_ARR 时,就一直输出高电平(占空比100%)。
下图是个例子:以下是我写的一个参考程序,测试通过void TIM1_Init(void){//定时器1 初始化CLK_PCKENR1|=0x80;//开启定时器1 外设时钟TIM1_EGR=0x01;//重新初始化TIM1 TIM1_EGR|=0x20;//重新初始化TIM1 TIM1_ARRH=0x00;//设定重装载值TIM1_ARRL=254; TIM1_PSCRH=0;//预分频TIM1_PSCRL=9; TIM1_CR1=0;//边沿对齐,向上计数} void TIM1_PWM_Init(){ //TIM1_CCER1=0x03;//低电平有效//TIM1_CCMR1=0x70;//PWM 模式2TIM1_CCER1=0x01;//高电平有效TIM1_CCMR1=0x60;//PWM 模式1TIM1_CCR1H=0;//占空比TIM1_CCR1L=50; TIM1_CR1|=0x01;//向上计数,无缓存,使能TIM1_BKR=0x80;//开启刹车}tips:感谢大家的阅读,本文由我司收集整编。
nrf51822学习笔记之PPI

Programmable Peripheral Interconnect (PPI)功能:PPI 可以实现不同的外设之间通过tasks和events进行自主互动,而不需要用到CPU。
The Programmable Peripheral Interconnect (PPI) enables different peripherals to interact autonomously with each other using tasks and events and without having to use the CPU.一个外设的event可以触发另外一个外设的task。
The PPI provides a mechanism to automatically trigger a task in one peripheral as a result of an event occurring in another peripheral.PPI通道的作用是使一个event链接着一个task,每个PPI通道由两个端点寄存器(end-point registers)组成:event端(EEP)和task端(TEP)。
A task is connected to an event through a PPI channel. The PPI channel is composed of two end-point registers, the Event End-Point (EEP) and the Task End-Point (TEP).一个外设的task 是通过该task的任务寄存器地址(the address of the task register)与TEP 相连的。
同理event…。
当应用程序存在实时要求(real-time constraints exist),又不需要CPU参与时,PPI可以实现外设之间的精确同步。
STM32- nRF51822蓝牙低功耗(BLE)系统解决方案

AN4605应用笔记STM32- nRF51822蓝牙低功耗(BLE)系统解决方案介绍本应用笔记介绍了蓝牙低功耗(BLE)嵌入式软件(X-CUBE-nRF51DRV)实现对STM32L0系列和nRF51822,并解释如何界面自己的应用程序,并创建BLE服务。
在X-CUBE-nRF51DRV主要特点如下:•与北欧提供的BLE型材兼容性•应用程序集成就绪•易于附加在STM32L0系列低功耗解决方案BLE•极低STM32L0 CPU负载(HRS 1秒更新率0.127%)•没有对STM32L0系列延迟要求•小STM32L0内存占用在X-CUBE-nRF51DRV软件是基于STM32CubeL0 HAL驱动程序(见第2节)。
同时提供了使用北欧BLE服务于客户STM32L0应用实例。
该参考硬件平台是STM32-nRF51822基于STM32Nucleo / 64上和Wavetek公司蓝牙LE与盾北欧BLE模块nRF51822。
注:X-CUBE-nRF51DRV可以移植到其它STM32系列。
目录1引用。
72 STM32Cube概述。
83,嵌入式软件的定义。
9 4入门。
114.1 BLE系统描述。
0.114.2特性。
0.114.3硬件/软件的快速设置。
125参考平台。
13 5.1接口描述。
13 5.2 UART 4线接口。
145.3重置系统。
145.3.1上电复位。
155.3.2系统复位。
155.4器件编程。
166嵌入式软件的描述。
186.1 UART接口。
186.1.1 BLE SD FW模块。
196.1.2低功耗经理。
206.1.3中断。
206.1.4语境经理。
206.1.5配置。
21当BLE功能使用6.1.6 STM32资源需求。
216.1.7集成。
226.1.8可移植性。
226.2定时器接口。
236.2.1 BLE SD FW模块。
256.2.2初始化。
256.2.3用户模块。
266.2.4中断。
46.2.5语境经理。
飞思卡尔初学之PWM调试笔记

飞思卡尔初学之PWM调试笔记M9S12XS128 单片机有8 个独立的PWM 输出通道,其中每相邻的两个可以级联成一个通道。
本文着重应用实践,理论性的东西少谈为妙,因为理论的东西资料上都有。
想借此平台记录下调试心得以免日后遗忘,因本人也是初学该款单片机,难免有错误之处,还希望达人指点。
PWM 应用步骤:一、PLL 初始化,这一步应该说不算PWM 设置的内容,但是又必须设置,因为这关系着PWM 周期值的计算。
从开发板上的晶振来看是16M,但是总线时钟却并不是16M,S12 单片机里面有个锁相环设置,要设置好了才准确。
具体这个PLL 函数我还没去了解。
现在是现成套用。
void PLL_Init(void) //PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1){ //锁相环时钟=2*16*(2+1)/(1+1)=48MHzCLKSEL=0X00;PLLCTL=0XE1;REFDV = 1; //总线时钟=48/2=24MHzSYNR = 2;_asm(nop); // BUS CLOCK=24M_asm(nop);while (!(CRGFLG & 0x08)) ;CLKSEL = 0x80; //选定锁相环时钟}用了这个PLL 初始化函数以后,总线时钟就是24M 了。
二、PWM 相关设置1、禁止PWM。
PWME2、选择时钟源。
PWMPRCLK, PWMSCLA, PWMSCLB ,PWMCLK。
其中通道0 、1、4、5 可以选择ClockA ClockSA。
通道2、3、6、7 可以选择ClockB ClockSB其中值得说明的是ClockA 或ClockB 是通过总线时钟预分频获得的。
ClockSA 或ClockB 是分别对ClockA ClockB 再次进行分频获得的。
分频系数的设置都有相应的寄存器进行设置。
后面会提到。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1 : 0);
Page 1
app_pwm.c
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 return; } /**函数描述:使能指定PWM实例IRQ * * 参数[in] p_instance PWM实例 */ __STATIC_INLINE void pwm_irq_enable(app_pwm_t const * const p_instance) { nrf_drv_timer_compare_int_enable(p_instance->p_timer, PWM_MAIN_CC_CHANNEL); } /**函数描述:除能指定PWM实例IRQ中断使能标识 * * 参数[in] p_instance PWM实例 */ __STATIC_INLINE void pwm_irq_disable(app_pwm_t const * const p_instance) { nrf_drv_timer_compare_int_disable(p_instance->p_timer, PWM_MAIN_CC_CHANNEL); }
//禁止定时器中断 nrf_drv_timer_compare_int_disable(m_instances[timer_instance_id]->p_timer, PWM_MAIN_CC_CHANNEL); app_pwm_cb_t * p_cb = (app_pwm_cb_t *)m_instances[timer_instance_id]->p_cb; //调用PWM完整周期结束回调函数 用于设置标志位 通知应用程序 p_cb->p_ready_callback(timer_instance_id); }
/**函数描述:在duty设置后,这个函数将会被中断函数调用 * * 参数[in] timer PWM模块使用的定时器 * 参数[in] timer_instance_id 定时器实例 */ void pwm_ready_tick(nrf_timer_event_t event_type, void * p_context) { uint32_t timer_instance_id = (uint32_t)p_context;
#define APP_PWM_CHANNEL_INITIALIZED #define APP_PWM_CHANNEL_UNINITIALIZED #define APP_PWM_CHANNEL_ENABLED #define APP_PWM_CHANNEL_DISABLED #define TIMER_PRESCALER_MAX #define TIMER_MAX_PULSEWIDTH_US_ON_16M
0xFFFFFFFFUL 2 3
static const app_pwm_t * m_instances[TIMER_COUNT]; //获取给定实例或者通道极性的宏 #define POLARITY_ACTIVE(INST,CH) (( ((app_pwm_cb_t*)(INST)->p_cb)->channels_cb[(CH)].polarity == \ APP_PWM_POLARITY_ACTIVE_LOW)?(0):(1)) #define POLARITY_INACTIVE(INST,CH) (( ((app_pwm_cb_t*)(INST)->p_cb)->channels_cb[(CH)].polarity == \ APP_PWM_POLARITY_ACTIVE_LOW)?(1):(0)) /**@brief Workaround for PAN-73. * * 参数[in] timer 定时器 * 参数[in] enable 使能或者除能 */ static void pan73_workaround(NRF_TIMER_Type { if (p_timer == NRF_TIMER0) { *(uint32_t *)0x40008C0C = (enable ? } else if (p_timer == NRF_TIMER1) { *(uint32_t *)0x40009C0C = (enable ? } else if (p_timer == NRF_TIMER2) { *(uint32_t *)0x4000AC0C = (enable ? }
H
}
D u
n u
o m e D
if (m_pwm_ready_counter[timer_instance_id]) { --m_pwm_ready_counter[timer_instance_id]; if (m_pwm_ready_counter[timer_instance_id]) { return; }
H
D u
channels_cb[APP_PWM_CHANNELS_PER_INSTANCE]; period; p_ready_callback; ppi_channels[2]; ppi_group; state;
ห้องสมุดไป่ตู้
n u
1 : 0); 1 : 0);
o m e D
* p_timer, bool enable)
/**函数描述:除能PWM通道PPI * * 参数[in] p_instance PWM实例 */ __STATIC_INLINE void pwm_channel_ppi_disable(app_pwm_t const * const p_instance, uint8_t channel) { app_pwm_cb_t * p_cb = (app_pwm_cb_t *)p_instance->p_cb; nrf_drv_ppi_channel_disable(p_cb->channels_cb[channel].ppi_channels[0]); nrf_drv_ppi_channel_disable(p_cb->channels_cb[channel].ppi_channels[1]); }
1 0 1 0 9 4095
#define APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE 2 #define APP_PWM_REQUIRED_PPI_CHANNELS_PER_CHANNEL 2 #define UNALLOCATED #define PWM_MAIN_CC_CHANNEL #define PWM_SECONDARY_CC_CHANNEL volatile uint8_t m_pwm_ready_counter[TIMER_COUNT]; typedef struct { uint32_t gpio_pin; uint32_t pulsewidth; nrf_ppi_channel_t ppi_channels[2]; app_pwm_polarity_t polarity; uint8_t initialized; } app_pwm_channel_cb_t; typedef struct { app_pwm_channel_cb_t uint32_t app_pwm_callback_t nrf_ppi_channel_t nrf_ppi_channel_group_t nrf_drv_state_t } app_pwm_cb_t;
app_pwm.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 #include #include #include #include #include #include #include #include #include #include #include "app_pwm.h" "nrf_drv_timer.h" "nrf_drv_ppi.h" "nrf_drv_common.h" "nrf_drv_gpiote.h" "nrf_gpiote.h" "nrf_gpio.h" "app_util.h" "app_util_platform.h" "nrf_assert.h" <stdio.h>
Page 2
app_pwm.c
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 /**函数描述:资源重新分配 * * 参数[in] p_instance PWM实例 */ static void pwm_dealloc(app_pwm_t const * const p_instance) { app_pwm_cb_t * p_cb = (app_pwm_cb_t *)p_instance->p_cb; for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE; ++i) { if (p_cb->ppi_channels[i] != (nrf_ppi_channel_t)(uint8_t)(UNALLOCATED)) { nrf_drv_ppi_channel_free(p_cb->ppi_channels[i]); } } if (p_cb->ppi_group != (nrf_ppi_channel_group_t)UNALLOCATED) { nrf_drv_ppi_group_free(p_cb->ppi_group); } for (uint8_t ch = 0; ch < APP_PWM_CHANNELS_PER_INSTANCE; ++ch) { for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_CHANNEL; ++i) { if (p_cb->channels_cb[ch].ppi_channels[i] != (nrf_ppi_channel_t)UNALLOCATED) { nrf_drv_ppi_channel_free(p_cb->channels_cb[ch].ppi_channels[i]); p_cb->channels_cb[ch].ppi_channels[i] = (nrf_ppi_channel_t)UNALLOCATED; } } if (p_cb->channels_cb[ch].gpio_pin != UNALLOCATED) { nrf_drv_gpiote_out_uninit(p_cb->channels_cb[ch].gpio_pin); p_cb->channels_cb[ch].gpio_pin = UNALLOCATED; } p_cb->channels_cb[ch].initialized = APP_PWM_CHANNEL_UNINITIALIZED; } nrf_drv_timer_uninit(p_instance->p_timer); return; }