STM32F429--EXTI外部中断/事件控制器

发布者:caoxians4589最新更新时间:2022-01-27 来源: eefocus关键字:STM32F429  EXTI  外部中断  事件控制器 手机看文章 扫描二维码
随时随地手机看文章

EXTI:External interrupt /event controll

具体的表现形式为


导致                 

外部的高低电平变化------------->中断/事件发生(需要配置NVIC)


外部中断/事件控制器功能框图

在这里插入图片描述

具体可以分为两部分:

1- 中断(下图的1,2,3,4,5)

2- 事件(下图的1,2,3,6,7,8)

在这里插入图片描述

由上图可知,外部中断是挂载到APB总线上的,/23表示有23根结构相同的线。

(详情看stm32f4xx的中文参考手册第十章第二小节部分,下面对应的10.x.x代表手册对应章节部分)


1处:输入线

10.2.5 SYSCFG外部中断配置寄存器,16X9=144个GPIO口

在这里插入图片描述
在这里插入图片描述

与上图类似,总共16条

SYSCFG_EXTICR2 EXTIx x(4~7)

SYSCFG_EXTICR3 EXTIx x(8~11)

SYSCFG_EXTICR4 EXTIx x(12~15)

剩余的7条

在这里插入图片描述

2处:边沿检测电路

在这里插入图片描述

3处:软件中断屏蔽寄存器

在这里插入图片描述

事件屏蔽寄存器如下

在这里插入图片描述

4处:挂起寄存器

在这里插入图片描述

5处:NVIC

具体查看官方的misc.h54行,73行(有点多就不一一列举),或者看ARM-Cortex-M4内核的官方手册说明,看名字就可以知道大概意思了,下面是部分截图。

在这里插入图片描述

实验设计

需求

1.PA0连接到EXTI用于产生中断,PA0的电平变化通过按键来控制

2.产生一次中断,LED翻转一次

编程须知:

打开开发板原理图,PA0是按键的连接引脚,默认被地拉低低电平,需要上升沿触发

编程要点:

1.初始化要连接到EXTI的GPIO

2.初始化EXTI用于产生中断事件

3.初始化NVIC,用于处理中断

4.编写中断服务函数

5.main函数


1.bsp_led.c


#include "./led/bsp_led.h"   


 /**

  * @brief  初始化控制LED的IO

  */

void LED_GPIO_Config(void)

{

/*定义一个GPIO_InitTypeDef类型的结构体*/

GPIO_InitTypeDef GPIO_InitStructure;


/*开启LED相关的GPIO外设时钟*/

RCC_AHB1PeriphClockCmd ( LED1_GPIO_CLK|LED2_GPIO_CLK|LED3_GPIO_CLK|LED4_GPIO_CLK, ENABLE); 


/*选择要控制的GPIO引脚*/    

GPIO_InitStructure.GPIO_Pin = LED1_PIN;


/*设置引脚模式为输出模式*/

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;   

    

    /*设置引脚的输出类型为推挽输出*/

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    

    /*设置引脚为上拉模式*/

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;


/*设置引脚速率为2MHz */   

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; 


/*调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO*/

GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);

    

    /*选择要控制的GPIO引脚*/    

GPIO_InitStructure.GPIO_Pin = LED2_PIN;

    GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure);

    

    /*选择要控制的GPIO引脚*/    

GPIO_InitStructure.GPIO_Pin = LED3_PIN;

    GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStructure);

/*选择要控制的GPIO引脚*/    

GPIO_InitStructure.GPIO_Pin = LED4_PIN;

    GPIO_Init(LED4_GPIO_PORT, &GPIO_InitStructure);

/*关闭RGB灯*/

LED_RGBOFF;

/*指示灯默认开启*/

LED4(ON);

}


2.bsp_led.h


#ifndef __LED_H

#define __LED_H


#include "stm32f4xx.h"


//引脚定义

/*******************************************************/

//R 红色灯

#define LED1_PIN                  GPIO_Pin_10                 

#define LED1_GPIO_PORT            GPIOH                      

#define LED1_GPIO_CLK             RCC_AHB1Periph_GPIOH


//G 绿色灯

#define LED2_PIN                  GPIO_Pin_11                 

#define LED2_GPIO_PORT            GPIOH                      

#define LED2_GPIO_CLK             RCC_AHB1Periph_GPIOH


//B 蓝色灯

#define LED3_PIN                  GPIO_Pin_12                 

#define LED3_GPIO_PORT            GPIOH                       

#define LED3_GPIO_CLK             RCC_AHB1Periph_GPIOH


//小指示灯

#define LED4_PIN                  GPIO_Pin_11                 

#define LED4_GPIO_PORT            GPIOD                       

#define LED4_GPIO_CLK             RCC_AHB1Periph_GPIOD

/************************************************************/


/** 控制LED灯亮灭的宏,

* LED低电平亮,设置ON=0,OFF=1

* 若LED高电平亮,把宏设置成ON=1 ,OFF=0 即可

*/

#define ON  0

#define OFF 1


/* 带参宏,可以像内联函数一样使用 */

#define LED1(a) if (a)

GPIO_SetBits(LED1_GPIO_PORT,LED1_PIN);

else

GPIO_ResetBits(LED1_GPIO_PORT,LED1_PIN)


#define LED2(a) if (a)

GPIO_SetBits(LED2_GPIO_PORT,LED2_PIN);

else

GPIO_ResetBits(LED2_GPIO_PORT,LED2_PIN)


#define LED3(a) if (a)

GPIO_SetBits(LED3_GPIO_PORT,LED3_PIN);

else

GPIO_ResetBits(LED3_GPIO_PORT,LED3_PIN)

#define LED4(a) if (a)

GPIO_SetBits(LED4_GPIO_PORT,LED4_PIN);

else

GPIO_ResetBits(LED4_GPIO_PORT,LED4_PIN)


/* 直接操作寄存器的方法控制IO */

#define digitalHi(p,i) {p->BSRRL=i;}   //设置为高电平

#define digitalLo(p,i) {p->BSRRH=i;} //输出低电平

#define digitalToggle(p,i) {p->ODR ^=i;} //输出反转状态



/* 定义控制IO的宏 */

#define LED1_TOGGLE digitalToggle(LED1_GPIO_PORT,LED1_PIN)

#define LED1_OFF digitalHi(LED1_GPIO_PORT,LED1_PIN)

#define LED1_ON digitalLo(LED1_GPIO_PORT,LED1_PIN)


#define LED2_TOGGLE digitalToggle(LED2_GPIO_PORT,LED2_PIN)

#define LED2_OFF digitalHi(LED2_GPIO_PORT,LED2_PIN)

#define LED2_ON digitalLo(LED2_GPIO_PORT,LED2_PIN)


#define LED3_TOGGLE digitalToggle(LED3_GPIO_PORT,LED3_PIN)

#define LED3_OFF digitalHi(LED3_GPIO_PORT,LED3_PIN)

#define LED3_ON digitalLo(LED3_GPIO_PORT,LED3_PIN)


#define LED4_TOGGLE digitalToggle(LED4_GPIO_PORT,LED4_PIN)

#define LED4_OFF digitalHi(LED4_GPIO_PORT,LED4_PIN)

#define LED4_ON digitalLo(LED4_GPIO_PORT,LED4_PIN)



/* 基本混色,后面高级用法使用PWM可混出全彩颜色,且效果更好 */


//红

#define LED_RED 

LED1_ON;

LED2_OFF;

LED3_OFF


//绿

#define LED_GREEN

LED1_OFF;

LED2_ON;

LED3_OFF


//蓝

#define LED_BLUE

LED1_OFF;

LED2_OFF;

LED3_ON


//黄(红+绿)

#define LED_YELLOW

LED1_ON;

LED2_ON;

LED3_OFF

//紫(红+蓝)

#define LED_PURPLE

LED1_ON;

LED2_OFF;

LED3_ON


//青(绿+蓝)

#define LED_CYAN

LED1_OFF;

LED2_ON;

LED3_ON

//白(红+绿+蓝)

#define LED_WHITE

LED1_ON;

LED2_ON;

LED3_ON

//黑(全部关闭)

#define LED_RGBOFF

LED1_OFF;

LED2_OFF;

LED3_OFF


void LED_GPIO_Config(void);


#endif /* __LED_H */


3.bsp_exti.c

#include "bsp_exti.h"

//static关键字表明该函数仅在这个文件可以使用

//misc.h54行,misc.h的73行

static void EXTI_NVIC_Config(void)//内核中断外设,都在misc.c文件中,misc.h的73行

{

NVIC_InitTypeDef NVIC_InitStruct; //定义一个NVIC初始化结构体变量

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//优先级分组

NVIC_InitStruct.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;//中断源

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级

NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;//子优先级

NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//使能中断,大大门

NVIC_Init(&NVIC_InitStruct); //到此配置完毕

}


/*在stm32f4xx_exit.h文件的93行中,有EXTI初始化结构体

EXTI_InitTypeDef,然后初始化里面的成员,在80行。

值在105行*/

void EXTI_Key_Config(void)

{

/*定义一个GPIO_InitTypeDef类型的结构体*/

GPIO_InitTypeDef GPIO_InitStructure;

EXTI_InitTypeDef  EXTI_InitStruct;  //定义结构体变量


/*开启LED相关的GPIO外设时钟*/

RCC_AHB1PeriphClockCmd ( RCC_AHB1Periph_GPIOA, ENABLE);//打开AHB1总线时钟

/*选择要控制的GPIO引脚*/    

GPIO_InitStructure.GPIO_Pin =  KEY1_GPIO_PIN; //GPIOA的0脚

/*设置引脚模式为输入模式*/

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;   //输入模式

    /*设置引脚为浮空模式*/

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//浮空,在stm32f4xx.gpio.h文件110行位置

/*调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO*/

GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);//将引脚和结构体初始化完成


RCC_APB2PeriphClockCmd ( RCC_APB2Periph_SYSCFG, ENABLE);//用到了EXTI0,挂载到PLCLK2,要打开AHB2总线时钟

SYSCFG_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE); //作用:把PA0连接到EXTI0.

//param1:中断源端口  GPIOA  

   //param2:中断源引脚  PA0

   

EXTI_InitStruct.EXTI_Line = KEY1_INT_EXTI_LINE; //PA0,选择EXTI0为输入线

EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;//设置模式为中断模式,另一个是事件模式

        EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;//设置触发方式为上升沿触发

EXTI_InitStruct.EXTI_LineCmd = ENABLE;//使能,打开大门

EXTI_Init(&EXTI_InitStruct);//在stm32f4xx_exti.h文件,把配置好的成员写到寄存器里面,到此初始化完毕。

EXTI_NVIC_Config();//调用NVIC中断控制器初始化函数。

}


3.bsp_exti.h


#ifndef __BSE_EXTI_H 

#define __BSE_EXTI_H 


#include "stm32f4xx.h"


#define KEY1_GPIO_PIN             GPIO_Pin_0                 

#define KEY1_GPIO_PORT            GPIOA                      

#define KEY1_GPIO_CLK             RCC_AHB1Periph_GPIOA

#define KEY1_INT_EXTI_LINE        EXTI_Line0


#define KEY1_INT_EXTI_PORTSOURCE  EXTI_PortSourceGPIOA

#define KEY1_INT_EXTI_PINSOURCE   EXTI_PinSource0

#define KEY1_INT_EXTI_IRQ         EXTI0_IRQn


#define KEY1_INT_EXTI_IRQHANDLER  EXTI0_IRQHandler //宏定义中断函数名称




#define KEY2_GPIO_PIN             GPIO_Pin_13                 

#define KEY2_GPIO_PORT            GPIOC                      

#define KEY2_GPIO_CLK             RCC_AHB1Periph_GPIOC



void EXTI_Key_Config(void);


#endif /* __BSE_EXTI_H */


5.stm32f4xx_it.h下面补充编写中断服务函数(一般中断服务函数放在这个地方)


#include "stm32f4xx_it.h"

#include "bsp_led.h"

#include "bsp_exti.h"


/*中断服务函数都写在stm32f4xx_it.c这个函数里面

名字怎么写?看启动文件startup_stm32f429_439xx.s,93行,

这个很重要,如果写错会一直死循环!!!!!!!!!!!

写在文件stm32f4xx_it.c中的函数如下:*/

void KEY1_INT_EXTI_IRQHANDLER(void)

{

if( ( EXTI_GetITStatus(KEY1_INT_EXTI_LINE) ) != RESET )

{

/* 干活 */

LED1_TOGGLE;

}

EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);//清除中断标志位,勿忘勿忘

}


6.stm32f4xx_it.h 写着中断服务函数的名字及声明


#ifndef __STM32F4xx_IT_H

#define __STM32F4xx_IT_H


#ifdef __cplusplus

 extern "C" {

#endif 


/* Includes ------------------------------------------------------------------*/

#include "stm32f4xx.h"

[1] [2]
关键字:STM32F429  EXTI  外部中断  事件控制器 引用地址:STM32F429--EXTI外部中断/事件控制器

上一篇:STM32Keil下编程实现蜂鸣器长鸣
下一篇:STM32的RS485通信

推荐阅读最新更新时间:2024-11-21 13:39

STM8外部中断
GPIO_Init(KEY1_GPIO, KEY1_PIN, GPIO_MODE_IN_FL_IT); //初始化按键输入; GPIO_Init(KEY2_GPIO, KEY2_PIN, GPIO_MODE_IN_FL_IT); //初始化按键输入; GPIO_Init(KEY3_GPIO, KEY3_PIN, GPIO_MODE_IN_FL_IT); //初始化按键输入; EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC, EXTI_SENSITIVITY_RISE_ONLY); //设置制定端口的触发方式 ITC_SetSoftwarePriority(ITC_I
[单片机]
基于STM32F429芯片的单片机芯片内存映射图
一、如何控制单片机? 单片机的内存映射图解析 这里以STM32F429芯片为例,讲解下单片机芯片内存映射图。从此图中可以看到芯片的外设被分配了512M的空间,然而真正的外设其实没有使用到512M的内存空间。 然后我们操作外设时,只需要操作它对应的内存地址即可。更加详细的外设内存地址,可以参考芯片的用户手册(不是数据手册)的Memory map章节。 因为单片机是将外设映射到内存地址上,所以我们可以像操作内存一样来操作外设(写/读)。 我们在操作内存时是通过地址来进行操作的,由于单片机已经将外设与内存进行了映射,所以我们在操作单片机外设时只需要操作外设映射的内存地址就行。 内存如何操作? 在C语言中操作内存,我们可以用指针来
[单片机]
第30章 STM32F429的系统bootloader之串口IAP固件升级
30.1 初学者重要提示 学习本章节前,务必优先学习第28章。 本章用到的相关软件和文档下载:http://www.armbbs.cn/forum.php?mod=viewthread&tid=96573 。 本章节的串口IAP下载软件使用STM32CubeProg,此软件实现了之前的DfuSe,STLINK小软件和Flashloader三合一,并且支持外部EEPROM,NOR Flash,SPI Flash,NAND Flash等烧写,也支持OTA编程。 使用系统bootloader做串口IAP升级时,MicroUSB接口不要接线到电脑端,因为这会导致系统bootloader工作在USB DFU模式,无法再使用串口I
[单片机]
第30章 <font color='red'>STM32F429</font>的系统bootloader之串口IAP固件升级
关于51单片机“外部中断触发方式”的经验总结
51单片机的外部中断有两种触发方式可选:电平触发和边沿触发。选择电平触发时,单片机在每个机器周期检查中断源口线,检测到低电平,即置位中断请求标志,向CPU请求中断。选择边沿触发方式时,单片机在上一个机器周期检测到中断源口线为高电平,下一个机器周期检测到低电平,即置位中断标志,请求中断。 这个原理很好理解。但应用时需要特别注意的几点: 1) 电平触发方式时,中断标志寄存器不锁存中断请求信号。也就是说,单片机把每个机器周期的S5P2采样到的外部中断源口线的电平逻辑直接赋值到中断标志寄存器。标志寄存器对于请求信号来说是透明的。这样当中断请求被阻塞而没有得到及时响应时,将被丢失。换句话说,要使电平触发的中断被CPU响应并执行
[单片机]
stm32按键的检测(EXTI和Polling两种方式)
XTI Mode时,只要别漏下面这两行基本是没问题了. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); /* 复用时钟使能 */ GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1); /* 选择GPIO管脚用作外部中断线路 */ #include #include #define EXTI_Trigger_Mode #define KEY_RCC RCC_APB2Periph_GPIOB #define KEY_GPIO GPIOB #define KEY_PIN (GPIO_Pi
[单片机]
第7章 STM32F429下载和调试方法(IAR8)
7.1 初学者重要提示 如果使用JLINK调试下载STM32F429,可以使用JLINK V8,V9和V10。 如果使用STLINK调试下载STM32F429,推荐使用最新的电脑端驱动和对应的固件,详情见第2章的2.6小节。 JLINK无法下载解决思路以及常见问题整理,适用于其它LINK:http://www.armbbs.cn/forum.php?mod=viewthread&tid=21708 。 7.2 使用IAR调试和下载程序设置(JLINK) 调试下载STM32F429,可以使用JLINK V8,V9和V10,JLINK的驱动安装等相关文件已经在本教程第2章的2.5章节有说明 在上个章节里面,我们已经
[单片机]
第7章 <font color='red'>STM32F429</font>下载和调试方法(IAR8)
STM32F429和F103端口重映射
它自己默认每个管脚有自己的复用功能,但是这个管脚你用了,但你想要用它的其他功能,你就可以将这个功能重映射到其他管脚。使用复用功能是要保持一个功能使能,其他功能非使能状态 重映射指的是内部功能转移到别的引脚上去,芯片内部已经固定了只能映射到固定的地方。若使用TIM3重映射到其他引脚上,则先要配置TIM3重映射到该引脚,然后在按该引脚的复用功能配置 F103重映射实例: 1.打开重映射时钟和USART重映射后的I/O口引脚时钟, RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE); //使能对应IO口的时钟,因为是复用功能所以
[单片机]
<font color='red'>STM32F429</font>和F103端口重映射
基于S3C6410的ARM11学习(十六) 外部中断
中断的过程如下: 中断源检测中断信号产生,然后将中断信号发送给中断控制器,中断控制器判断该中断是否被屏蔽,从而决定该中断信号是否要发送给CPU。中断信号发送给CPU后,CPU对中断进行处理,也就是调用中断函数。 上述过程,基本上是嵌入式的通过中断处理过程,只是不同的嵌入式在这三部分配置有区别而已。 S3C6410共有64个中断源。 上图是S3C6410的中断控制器,这里就关心红色框部分。这两个是中断控制器,分别管理各自的32个中断。 这里,就截取了一部分的图。总共有64个中断,每个中断有自己的标号,以及自己的所属组,也是属于哪个中断控制器控制。标号是指在对应的中断控制器寄存器的哪一位或者是哪一个寄存器对应自己
[单片机]
基于S3C6410的ARM11学习(十六) <font color='red'>外部中断</font>

推荐帖子

史上最奇葩稳压输出
今天做了一个电路:变压器正负交流12V输入,接一个整流桥,算一算,就是得到30V左右的直流电压;后面接三个稳压芯片7815,7812,7805;上电,空载哦;我用万用表去测稳压怎么样,在7815的输出端,得到14.98V电压,感觉还可以;在7812的输出端,得到12.01V的电压,感觉还可以;在7805的输出端,问题来了,怎么是9.8V呢?我检查了电路,发现电路没错,我以为是芯片坏了,就从新换了一个7805的稳压片子;以为这下肯定是5V,然而,输出还是9.8V,百思不得解!!!看着
零下12度半 电源技术
【设计工具】System Debugging Tools
SystemDebuggingToolsquartusIIFPGA设计系统调试工具SystemDebuggingTools【设计工具】SystemDebuggingTools顶顶顶!
785180572 FPGA/CPLD
定义地址变量的问题
就是定义一个地址变量,以一个地址为起始地址然后随着存储数据的增加而增加地址,等到下次用的时候不能从起始地址开始而是要从上次用到的地址后面开始使用,请问这个地址变量应该怎样定义好呢?初学者,对于这样定义很不了解,请各位大虾多多帮忙!定义地址变量的问题使用绝对地址指针。之后再操作这个指针即可。。int*p;p=(int*)0x00001;p++;*p=你的数据;但是我要用到从基地址到最后的地址的所有数据,这样怎么实现?最后的*p只是最后的那个值啊while{
fjmcss 嵌入式系统
MSP430单片机理论知识点
纵观微处理器的发展,一是朝着具有复杂数据运算、高速通信、信息处理等功能的高性能计算机系统方向发展;二是产生了一种将中央处理器,存储器,I/O接口电路以及连接他们的总线都集成一块芯片上的计算机。单片机在设计上主要突出了控制功能,调整了接口配置,在单一芯片上制成了结构完整的计算机。目前最常用的3中可编程处理器:微控制器(MCU)、微处理器(MPU)、数字信号处理器(DSP);单片机可应用的领域:工业控制(工业机器人)、智能化仪器仪表(温度湿度的测量)、日常生活钟的电器产品(MP3)、计算机网络
fish001 微控制器 MCU
关于VxWorks BSP for PPC:怀疑程序在usrKernelInit 里出了问题,请诊断下.
调这个bsp一个月有余,无进展,很郁闷!我们买了块mPC860的目标板,它带了个bsp.我们自己又做了块MPC862的,两者几乎一样.然后,在原来的bsp基础上修改,没有调通.后来发现,在程序运行中,mpc860的bsp对这个函数qPriBMapCreate()进行了操作,而我们自己的bsp则没有.这个函数通过ida看了,没有上层函数调用,像个中断/异常服务函数.它应该是在usrKernelInit()执行的被执行的.急啊!关于VxWorksBSPforPPC:怀疑程序在u
sofy231 实时操作系统RTOS
可控硅控制罩极电动机
我做了一个可控硅控制负载的电路,负载中灯泡、普通电动机都能够正常启动,只有罩极电动机无法正常启动,哪位有遇到过这种情况的,帮忙讲解下原因?可控硅控制罩极电动机你实验一下。当启动以后在控制我试过的,没什么作用,我现在考虑是不是相位的问题,价格LC补偿电路不知道有没有效果?还是没用的我用可控硅测试过,应该是可以驱动的,你的罩极电机是多大功率的,我的罩极电机驱动做了小批量试验没有任何问题(大概四十个),但是目前产品上市后,有三个电机烧毁了,不知什么原因。
n672757282 模拟电子
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved