NRF52840学习历程(十)PWM01_4通道独立控制(相同周期,但占空比不同)

时间在2021年2月5日,寒假放假在家好好学一学nRF52840

 

今天还在感冒,休息一波

 

开发板:初雪的100出头那块 NRF52840 EVAL KIT

下载工具:JINLK V11(最好是JLINK V9以上 也有人用JLINK OB也行,其他的下载器诸如STLINK,DAP不建议用)

版本号: KEIL5编程环境,CMSIS为5.3.0, NRF52840的CMSIS为8.35.0

参考资料: NRF52840-Eval-Kit-Schematic.pdf(原理图)

nRF5_SDK_17.0.2_d674dde(官方例程)

nRF5_SDK_17.0.0_offline_doc(官方文档)

nRF52840_PS_v1.1.pdf(官方数据手册)

 

已用IO

0.96OLED / 1.29彩色OLED

D0(CLK) -> 12

D1(SDA) -> 23

RES     -> 7

DC      -> 21

CS      -> 19

 

按键

KEY0 ->11

KEY1 ->24

KEY2 ->20

KEY3->17

 

LED

LED0 ->13

LED1->14

LED2->32+9=41

LED3->16

 

串口

TX ->6

RX ->8

 

ADC

光敏 -> 5

摇杆X -> 28

摇杆Y -> 29

 

IIC_0.96OLED

SDA -> 32

SCL -> 22

 

还没用到(空闲)

P0.0 1 2 3 9 10 15 25 26 27 30 31

P1.1 2 3 4 5 6 7 8 10 11 12 13 14 15

 

 

这一节是PWM 脉冲宽度调制

 

 

PWM模块

PWM 模块可以在 GPIO 上生成脉冲宽度调制信号。 该模块实现了一个向上或向下计数器,带有四个 PWM 通道,用于驱动分配的 GPIO。三个 PWM 模块可提供多达 12 个 PWM 通道,单个频率控制,最多可包含四个通道。每个模块的频率是相同的。此外,内置解码器和 EasyDMA 功能使得可以在没有 CPU 干预的情况下操纵 PWM 占空比。 从数据 RAM 读取任意占空比序列,可以链接以实现乒乓缓冲或重复进入复杂循环。

这里列出的是一个 PWM 模块的主要特征:

• 固定 PWM 基频,带可编程时钟分频器

• 最多四个 PWM 通道,具有独立的极性和占空比值                                                  

• PWM 通道上的边沿或中心对齐脉冲

• 数据 RAM 中定义的多个占空比数组(序列)

• 通过 EasyDMA 直接从存储器中自主且无干扰地更新占空比值

• 每个 PWM 周期可能会改变极性,占空比和基频

• 数据 RAM 序列可以重复或连接成循环

 

PWM周期和占空比

波形计数器负责以占空比产生脉冲。而占空比取决于比较值,并且取决于 COUNTERTOP 的频率。一个 PWM 模块有一个共用的 15 位计数器,带有四个比较通道。因此,所有四个通道将共享相同的周期(PWM 频率),但可以具有单独的占空比和极性

 

PWM解码模式

1:Common 模式:称为共用模式,四个 PWM 输出共用极性和比较值设置。

2:Grouped 模式:称为分组模式,每组半个字,两个 PWM 共用极性和比较值设置。

3:Single 模式:称为单信号独立模式,每个通道半个字,每个 PWM 独立的极性和比较值设置。

4:WaveForm 模式:称为波形模式。可以使用特殊操作模式。在此模式下,最多只能使能三个PWM 通道 OUT [0]至 OUT [2]。在 RAM 中,一次加载四个值:第一个,第二个和第三个位置用于加载极性和比较值设置,第四个 RAM 位置用于加载 COUNTERTOP 寄存器。这样,最多可以有三个 PWM 通道,其频率基在每个 PWM 周期的基础上发生变化。这种操作模式对于 LED 照明等应用中的任意波形生成非常有用。

 

理论不看了, 直接代码走起

先添加驱动文件

..\..\..\..\..\..\modules\nrfx\drivers\src\nrfx_pwm.c

添加SKD_CONFIG文件

 

 

同时再引入低速时钟,作为休眠时间跑的晶振

 

配置完成, 下面加入代码

NRF52840最多只有3个PWM控制器(每个控制器能控制最多4路,其中wave模式最多3路)

 

这边只用到PWM0控制器

static nrf_drv_pwm_t my_pwm0 = NRF_DRV_PWM_INSTANCE(0); // PWM控制器0,每个控制器可以有4路输出

然后初始化PWM

// 务必为全局变量,我试过放在局部init里面,结果一直调试失败,放全局才成功的
nrf_pwm_values_individual_t my_pwm_sequ_val; //独立模式下的PWM控制4通道的占空比

void MY_PWM_INIT(void)
{
	nrfx_pwm_config_t  p_config; //定义结构体
	p_config.base_clock = NRF_PWM_CLK_1MHz ; // PWM基本时钟: 16M/16 =1M
	p_config.count_mode = NRF_PWM_MODE_UP  ; //计数模式: 向上计数
	p_config.irq_priority = _PRIO_APP_LOWEST ; //中断优先级
	p_config.load_mode =  NRF_PWM_LOAD_INDIVIDUAL; // 加载模式: 独立模式,4通道分开输出
/*
RF_PWM_LOAD_COMMON 	//共同模式 四通道一同输出同一个PWM的
1st half word (16-bit) used in all PWM channels (0-3).

NRF_PWM_LOAD_GROUPED //分组模式 组1 和组2  输出同一个PWM, 其中组1是通道0和1,组2是通道2和3
1st half word (16-bit) used in channels 0 and 1; 2nd word in channels 2 and 3.

NRF_PWM_LOAD_INDIVIDUAL //独立模式, 四通道输出独立控制
1st half word (16-bit) used in channel 0; 2nd in channel 1; 3rd in channel 2; 4th in channel 3.

NRF_PWM_LOAD_WAVE_FORM 	//波形发生器模式,最多3个通道,第4个通道为设置何时复位/置位
1st half word (16-bit) used in channel 0; 2nd in channel 1; ... ; 4th as the top value for the pulse generator counter.
*/
	p_config.output_pins[0] = 13 ; //PWM通道0的引脚输出绑定
	p_config.output_pins[1] = 14;
	p_config.output_pins[2] = 41;
	p_config.output_pins[3] = 16;	
	p_config.step_mode = NRF_PWM_STEP_AUTO ;// 重复计数输出
	p_config.top_value = 10000;//脉冲计数的顶点值 1/1M *10000 = 10ms周期
	
	// 使用         PWM控制器0, 初始化内容写入寄存器, 事件中断函数
	nrf_drv_pwm_init(&my_pwm0,&p_config,MY_PWM_Interrupt);

	my_pwm_sequ_val.channel_0 = 1000;
	my_pwm_sequ_val.channel_1 = 3000;
	my_pwm_sequ_val.channel_2 = 6000;
	my_pwm_sequ_val.channel_3 = 9000;
	
	nrf_pwm_sequence_t 	p_sequence; //定义播放序列1的结构体
	p_sequence.end_delay = 0 ; //播放结束后 不延时
	p_sequence.length = 4 ;// 4通道都用上了
	p_sequence.repeats =  0 ; // 每个占空比重复时间次数
	p_sequence.values.p_individual = &my_pwm_sequ_val;

	// 单序列输出PWM          使用PWM0 ,把序列1内容写入结构体,播放次数,播完继续播(循环模式)
	nrf_drv_pwm_simple_playback(&my_pwm0, &p_sequence, 1,NRF_DRV_PWM_FLAG_LOOP);
}

主函数 和 中断

 

 

实验结果

占空比为10%, 30%,60%,90%

 

我拿数字示波器抓了下

 

可以看出, 周期为10ms , 对应代码的      p_config.top_value = 10000;//脉冲计数的顶点值 1/1M *10000 = 10ms周期

 

占空比为60% ,对应my_pwm_sequ_val.channel_2 = 6000;

 

代码链接

 

链接:https://pan.baidu.com/s/1eWX8JxsVaclXD0NVzvwNiw

提取码:ndqg

复制这段内容后打开百度网盘手机App,操作更方便哦

 

 

解压到这里

猜你喜欢

转载自blog.csdn.net/jwdeng1995/article/details/113694252