PIC32MZ tutorial -- Change Notification
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 = ;
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 = ;
DEBOUNCE_Integrator = DEBOUNCE_ThreholdHigh / ;
//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 == )
{
if (DEBOUNCE_Integrator-- == DEBOUNCE_ThreholdLow)
{
DEBOUNCE_Output = ;
DEBOUNCE_PreInput = DEBOUNCE_Input;
DEBOUNCE_EventStart = ;
DEBOUNCE_Integrator = DEBOUNCE_ThreholdHigh / ;
}
}
else //if (DEBOUNCE_Input == 1)
{
if (DEBOUNCE_Integrator++ == DEBOUNCE_ThreholdHigh)
{
DEBOUNCE_Output = ;
DEBOUNCE_PreInput = DEBOUNCE_Input;
DEBOUNCE_EventStart = ;
DEBOUNCE_Integrator = DEBOUNCE_ThreholdHigh / ;
}
}
}
}
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 = , /* Describe structure member. */
ON = } 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 <xc.h>
#include "Led.h"
#include "Key.h"
#include "Timer.h"
#include "Interrupt.h"
#include <sys/attribs.h>
#include "ConfigurationBits.h" void __ISR(_CHANGE_NOTICE_B_VECTOR,ipl4AUTO) CNB_Handler(void)
{
if ((CNSTATB & 0x1000) == 0x1000)
{
DEBOUNCE_EventStart = ;
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();
IFS0CLR = 0x10; // Clear flag
} void main(void)
{
Led_Init();
Key_Init();
Timer1_Init();
Mvec_Interrupt(); while ()
{
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.
PIC32MZ tutorial -- Change Notification的更多相关文章
- PIC32MZ tutorial -- OC Interrupt
In my previous blog "PIC32MZ tutorial -- Output Compare", I shows how to apply Output Comp ...
- PIC32MZ tutorial -- External Interrupt
In my older blog "PIC32MZ tutorial -- Key Debounce", I shows how to acheive key debounce w ...
- PIC32MZ tutorial -- Input Capture
Today I accomplish a simple application for PIC32MZ EC Starter Kit. This application uses Input Capt ...
- PIC32MZ tutorial -- Hello World
Today I implement "Hello World" on PIC32MZ EC starter kit. The application of "Hello ...
- PIC32MZ tutorial -- UART Communication
At this moment, I accomplish the interface of UART communication for PIC32MZ EC Starter Kit. This in ...
- PIC32MZ tutorial -- Watchdog Timer
Watchdog is a very necessary module for embedded system. Someone said that embedded system operates ...
- PIC32MZ tutorial -- Output Compare
Output Compare is a powerful feature of embedded world. The PIC32 Output Compare module compares the ...
- PIC32MZ tutorial -- 32-bit Timer
The microcontroller is PIC32MZ2048ECH144 on the PIC32MZ EC Starter Kit. This microcontroller has fou ...
- PIC32MZ tutorial -- Key Debounce
Today I accomplish a application on PIC32MZ EC Starter Kit. The feature of application is to light u ...
随机推荐
- 安装生物信息学软件-Biopython
其实好多东西装过好多次,然而每次都要翻文档,经常掉进前面掉进过的坑...所以这里重新写一份指南,以防下次再装又忘了(魂淡我并不想再装了啊不要立flag) 1. 安装biopython 1.1 因为bi ...
- (转)JQM 日期插件 mobiscroll Demo
(原)http://www.wglong.com/main/artical!details?id=11 JQM 日期插件 mobiscroll Demo 2013-04-25 / 分类:Jquery ...
- Android Performance Optimization
1.zipalign 2.ui优化 3.package size 4.RenderScript 5.Resource Shrinking & Code Shrinking 6.java cod ...
- js从后台无法取值问题
前台代码 <script type="text/javascript"> $(function () { var chart; $(document).ready(fu ...
- php-eclipse乱码处理
方法一:1)设置"eclipse目录下eclipse.ini文件"2)在文件结尾添加"-Dfile.encoding=UTF-8".3)重新启动eclipse, ...
- php get_magic_quotes_gpc()函数用法介绍
magic_quotes_gpc函数在php中的作用是判断解析用户提交的数据,如包括有:post.get.cookie过来的数据增加转义字符“\”,以确保这些数据不会引起程序,特别是数据库语句因为特殊 ...
- [专题汇总]AC自动机
1.The 2011 ACM-ICPC Asia Dalian Regional Contest ZOJ 3545 Rescue the Rabbit 简单的AC自动机+状压DP, 状态DP[nod ...
- 多线程、多进程、协程、缓存(memcache、redis)
本节内容: 线程: a:基本的使用: 创建线程: 1:方法 import threading def f1(x): print(x) if __name__=='__main__': t=thread ...
- Day19_IO第一天
1.异常 1.概念 程序出现不正常的情况 2.异常体系(掌握) Throwable |-Error ...
- excel曲线拟合怎么弄
在做社会调研或科学实验时常常需要把得到的实验数据拟合成曲线图,这样可以使结果形象易懂.下面将介绍怎么用excel来快速地进行曲线拟合.包括添加平滑曲线,线性,指数,幂,多项式(如二次曲线,三次曲线.. ...