当前位置:首页 > 单片机 > 单片机
[导读]  In my last post I implement "Key Debounce" with port polling, port polling is not very efficient. And this time, I will use change notification instead of port polling. It generates interrupt and

  In my last post I implement "Key Debounce" with port polling, port polling is not very efficient. And this time, I will use change notification instead of port polling. It generates interrupt and starts debounce when the level of digital port changes, so it will eliminate the MCU load of port polling.


  On my PIC32MZ EC Starter Kit, every I/O port pin (RAx-RKx) can be used as a change notification pin (CNAx-CNKx). The CN pins are configured as follows:


  1.Disable CPU interrupts.

  2.Set the desired CN I/O pin as an input by setting the corresponding TRISx register bits = 1.

  3.Enable the CN Module by setting the ON bit (CNCONx<15>) = 1.

  4.Enable individual CN input pins, enable optional pull-ups or pull-downs.

  5.Read the corresponding PORTx registers to clear the CN interrupt.

  6.Configure the CN Interrupt Priority bits, CNIP<2:0> (IPC6<20:18>), and Sub-priority bits,CNIS<1:0> (IPC6<17:16>).

  7.Clear the CN Interrupt Flag bit, by setting the CNIF bit (IFS1<0>) = 0.

  8.Configure the CN pin interrupt for a specific edge detect using the EDGEDETECT bit in the CNCONx register, and set up edge control using the CNENx/CNNEx bits.

  9.Enable the CN Interrupt Enable bit, by setting the CNIE bit (IEC1<0>) = 1.

10.Enable CPU interrupts.


  The CNSTATx registers indicate whether a change occurred on the corresponding pin since the last read of the PORTx bit. It is ridiculous that data sheet or reference manual mentions CNSTATx register but gives no figure or details. After so many times retry, I get to know it has to clear CNSTATx bit corresponding to CN pin in the CN interrupt service routine. Otherwise, the interrupt service routine may not work.


  Anyway, I get this change notification application work, and the following is the implementation.


  TIMER module:



void Timer1_Init(void)

{

T1CON = 0x8010;

PR1 = 0x30D3;

IPC1SET = 0x5;

TMR1 = 0;

IEC0SET = 0x10;

IFS0CLR = 0x10;

}


void Timer1_Write(unsigned int value)

{

TMR1 = value & 0xFFFF;

}


  KEY module ( enable change notification interrupt, debounce function):



#define DEBOUNCE_Input (PORTB & 0x1000)

#define DEBOUNCE_Open() ANSELB = 0xFFFFEFFF

#define DEBOUNCE_IOCtl() CNPUBSET = 0x1000

#define DEBOUNCE_Output LedState

#define DEBOUNCE_ThreholdLow 0

#define DEBOUNCE_ThreholdHigh 100

//extern volatile unsigned char DEBOUNCE_TimeFlag;

extern volatile unsigned char DEBOUNCE_EventStart;



  volatile unsigned char DEBOUNCE_EventStart;

//volatile unsigned char DEBOUNCE_TimeFlag;

unsigned long DEBOUNCE_PreInput;

unsigned int DEBOUNCE_Integrator;


void Key_Init(void)

{

DEBOUNCE_EventStart = 0;

DEBOUNCE_Integrator = DEBOUNCE_ThreholdHigh / 2;

//DEBOUNCE_TimeFlag = 0;

DEBOUNCE_Open();

DEBOUNCE_IOCtl();

DEBOUNCE_PreInput = DEBOUNCE_Input;

CNENBSET = 0x1000;

IPC29SET = 0x12000000;

IFS3CLR = 0x800000;

IEC3SET = 0x800000;

CNCONBSET = 0x8000;

}


void Key_Debounce(void)

{

if (DEBOUNCE_EventStart)

{

if (DEBOUNCE_Input == 0)

{

if (DEBOUNCE_Integrator-- == DEBOUNCE_ThreholdLow)

{

DEBOUNCE_Output = 0;

DEBOUNCE_PreInput = DEBOUNCE_Input;

DEBOUNCE_EventStart = 0;

DEBOUNCE_Integrator = DEBOUNCE_ThreholdHigh / 2;

}

}

else //if (DEBOUNCE_Input == 1)

{

if (DEBOUNCE_Integrator++ == DEBOUNCE_ThreholdHigh)

{

DEBOUNCE_Output = 1;

DEBOUNCE_PreInput = DEBOUNCE_Input;

DEBOUNCE_EventStart = 0;

DEBOUNCE_Integrator = DEBOUNCE_ThreholdHigh / 2;

}

}

}

}


  LED module:



#define LED_IOCTL() TRISHCLR = (1<<0)

#define LED_SETON() LATHSET = (1<<0)

#define LED_SETOFF() LATHCLR = (1<<0)

#define LED_ONOFF() LATHINV = (1<<0)

#define LED_OPEN() ANSELH &= 0xFFFFFFFE

typedef enum _LED_STATE_t {

/* Describe structure member. */

OFF = 0,


/* Describe structure member. */

ON = 1


} LED_STATE_t;

LED_STATE_t PreLedState, LedState;


void Led_Init(void)

{

LED_OPEN();

LED_IOCTL();

LED_SETON();

LedState = ON;

PreLedState = LedState;

}


void Led_Scheduler(void)

{

if (LedState != PreLedState)

{

LED_ONOFF();

PreLedState = LedState;

}

}


  MAIN module (main function, timer1 ISR, CNB ISR):



#include

#include "Led.h"

#include "Key.h"

#include "Timer.h"

#include "Interrupt.h"

#include

#include "ConfigurationBits.h"


void __ISR(_CHANGE_NOTICE_B_VECTOR,ipl4AUTO) CNB_Handler(void)

{

if ((CNSTATB & 0x1000) == 0x1000)

{

DEBOUNCE_EventStart = 1;

CNSTATBCLR = 0x1000;

unsigned long tmp = DEBOUNCE_Input;

}

IFS3CLR = 0x800000;

}


void __ISR(_TIMER_1_VECTOR,ipl1AUTO) Timer1_Handler(void)

{

//DEBOUNCE_TimeFlag = 1;

Key_Debounce();

Timer1_Write(0);

IFS0CLR = 0x10; // Clear flag

}


void main(void)

{

Led_Init();

Key_Init();

Timer1_Init();

Mvec_Interrupt();

while (1)

{

Led_Scheduler();

}

}


  The application runs well on PIC32MZ EC Starter Kit, SW1(connects to RB12) pressed, LED1(RH0) is off, SW1 released, LED1 is on.


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

Animoca Brands、 Hailstone Ventures 领投 香港2022年3月16日  /美通社/ -- 革命性数字资产交易所Wombat Exchange,宣布完成由区块链游戏巨头 Anim...

关键字: change 数字资产

(全球TMT2022年1月14日讯)近日,IBM Watson Advertisin(IBM)g宣布,其旗下The Weather Company的数据已可通过Amazon Web Services(AWS)的AWS...

关键字: change IBM AWS

点击上方蓝字关注我们!TechExchange是TI举办的一场为期三天的行业盛典,全球同步举行,通过线上主题演讲,技术分享,圆桌讨论和线上Demo等环节,携手全球从业者共同探讨行业最前沿的话题与应用。就在今晚,TILiv...

关键字: change

点击上方蓝字关注我们!TechExchange是TI举办的一场为期三天的行业盛典,全球同步举行,通过线上主题演讲,技术分享,圆桌讨论和线上Demo等环节,携手全球从业者共同探讨行业最前沿的话题与应用。就在今晚,TILiv...

关键字: change

谷歌刚刚发布了最新的Android 11测试版,即Android 11 Beta3。 这基本上是候选版本,因为它几乎是我们在未来几周内看到的最终版本。

关键字: android11 api beta exposure notification

Microchip公司的PIC32MZ EF系列是高达250MHz的集成浮点单元(FPU),具有广泛的外设和包括局域网(CAN)的极好的连接选择,工作电压2.1V到 3.6V,DSP增强核具有四

关键字: Microchip pic32mz 处理器

本月7日凌晨,Apple意外发布了iOS13.5的第二个Beta版本,iOS13.5beta4,在此之前,Apple还发布了iOS13.4.5的Beta版本,这次是iOS13.5。 从Beta3到Beta4的第二版,我不...

关键字: ios13.5 notification exposure

内容交换公司BDx开始扩张东南亚业务 香港2020年4月9日 /美通社/ -

关键字: change 数据中心 新加坡

  An interrupt is an internal or external event that requires quick attention from the controller. The PIC32MZ...

关键字: interrupt pic32mz timer tutorial

  In my older blog "PIC32MZ tutorial -- Key Debounce", I shows how to acheive key debounce with port...

关键字: interrupt pic32mz tutorial external
关闭
关闭