NRF52840学习历程(十二) QDEC_正交编码器_EC11

时间在2021年2月7日,寒假放假在家好好学一学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(官方文档)

扫描二维码关注公众号,回复: 12684067 查看本文章

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 26 27 30 31

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

 

添加WS2812B 幻彩RGB

DAT ->25(1路)

DAT->15(第2路)

 

添加正交编码器: (与LED冲突,最好把LED的跳线帽拔掉)

A相 ->13

B相 ->14

------------------------------------------------------------------------------

------------------------------------------------------------------------------

 

 

正交编码器(QDEC)

QDEC通过采样QDEC相位输入引脚(A和B)来解码增量运动编码器的输出。

片外正交编码器是一种输出两种波形、相位的增量式运动编码器

A和B相的两个输出波形总是90度的相位,这意味着一个总是在另一个之前改变电平。运动的方向由这两种波形中哪一种首先改变水平来表示。当两个波形同时切换时,可能会发生无效的跃迁。如果车轮相对于为解码器设置的采样速率旋转得太快,可能会发生这种情况,如果滑轮相对于为解码器设置的采样速率旋转得太快,可能会发生这种情况

QDEC通过采样QDEC相位输入引脚(A和B)在采样寄存器中指定的固定速率解码芯片外编码器的输出。

如果采样器的值需要改变,QDEC应该使用STOP任务停止。然后可以在接收到停止事件时更改SAMPLEPER,并使用START任务重新启动QDEC。如果不这样做,可能会导致不可预测的行为。

只有当QDEC停止时,更改其他寄存器(LEDPOL, REPORTPER, DBFEN and LEDPRE)是很好的做法

当启动时,解码器对两种输入波形进行连续采样,并将当前采样对(n)与前一采样对(n-1)进行比较解码。

下表描述了示例对的解码过程

 

可以看出 输出ACC状态就可以知道正/反转

判断标准为 1)当ACCDBL为NO change的时候, 判断 ACC即可

 

 

代码如下:

中断函数


int16_t p_acc;
uint16_t p_accdbl;

void MY_QDEC_INTERRUPT(nrfx_qdec_event_t event)
{
	static uint8_t flag=0;;
	static int cnt = 0;
	if(NRF_QDEC_EVENT_REPORTRDY  == event.type)
	{
		nrfx_qdec_disable();//关闭QDEC正交编码器

//		int8_t  dat;
//		dat = nrf_qdec_sample_get();
//		printf("ACC:%d\r\n", dat );
		
		p_acc = event.data.report.acc;
		p_accdbl = event.data.report.accdbl;
//		printf("p_acc=%d,p_accdbl=%d\r\n", p_acc,p_accdbl);

		nrfx_qdec_enable();//启动QDEC正交编码器
		
		if(0==p_accdbl)
		{
			if(p_acc<0)
				cnt++;
			else 
				cnt--;
		}
		printf("cnt=%d\r\n",cnt);
	}	
}

初始化


void QDEC_INIT(void)
{
	nrfx_qdec_config_t p_config;
	p_config.dbfen = true; // 打开双采样过滤器
	p_config.interrupt_priority = 3; //中断优先等级
	p_config.ledpol = NRF_QDEC_LEPOL_ACTIVE_LOW ;//QDEC LED active on output pin low.
	p_config.ledpre = 0; //Time (in microseconds) how long LED is switched on before sampling
	p_config.psela = 13; //A引脚
	p_config.pselb = 14; //B引脚
	p_config.pselled = 0xffffffff; //不要灯(第31位为1即可不要灯)
	p_config.reportper = NRF_QDEC_REPORTPER_80 ;//每80个采样次数,产生一个报告中断
	p_config.sampleper = NRF_QDEC_SAMPLEPER_2048us; //大概2ms采样一次
	p_config.sample_inten = 0;
	
	nrfx_qdec_init(&p_config,MY_QDEC_INTERRUPT); //写入寄存器,配置中断事件
	
	nrfx_qdec_enable();//启动QDEC正交编码器
	printf("nrfx_qdec_enable_OK\r\n");
}

主函数

	QDEC_INIT();

	while(1)
	{		
//		printf("hello world! \r\n");		
	}

------------------------------------------------------------------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------------------------------------------------------------

代码讲解

正交编码器初始化

1开启滤波器,注意开了滤波器之后,LED会一直出于开启状态(我这边没有开启LED引脚,而且用的是机械式编码器,不是光电鼠标编码器)

2和3:配置A,B相IO引脚,这个引脚随便设的

4:不要LED灯

5:每80个报告产生一次中断, 报告产生时间为80 *2ms =160ms左右,又开启了滤波器,可能时间还会延迟一倍

6: 每次对A,B相采样的时间间隔为2ms左右

7: 不要开采样中断,开了会每2ms(就是上面NRF_QDEC_SAMPLEPER_2048us)产生一次中断的,没什么用,不要开

8:把配置写入寄存器, 配置中断函数

9 开启编码器,跑起来

 

这个为中断函数:

1定义了获取两个变量, 至于为什么定义, 看下面的图

2 为触发的QDEC中断函数入口

3 当产生报告之后(我这边配置的是80个报告), 再来判断ACC

4 采集完之后, 先关掉编码器,这样防止下次数据入来

5 获取上面图的两个数据值

6 然后开启编码器,继续下次采集

7 为按上图ACCDBL的要求来的, 至于正还是反, 自己测试之后调整就好

8 输出cnt变化值

 

 

实验结果:

其中1为正转

2看到是有抖动, 无法避免, 你别转太快就不会产生

3是正转, 也有1个抖动, 别转太快

4是反转

 

 

最后 EC11的电路设计也有讲究,最好加上一阶RC滤波

还有,EC11的工作电压手册上面是5V,我这边用3.3V也是可以的, 因为nrf52840单片机是3.3V电平

 

 

代码我就不给了, 你们按我上面给的两段代码就能够用了,而且讲解的也很详细了,其他人的资料都没有给能用的代码, 我这边还是找数据手册一次次看过来尝试出来的

猜你喜欢

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