LPC1114自学教程_完整(上)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
PC1114 实验教程
来自NXP的ARMCortex-M0内核MCU;贞明电子实验板和ZLG教程全程助学;主频50MHz的32位微处理器让你更好的完成应用;32KFlash8KRAM以及全方位的片上外设让你的系统更简洁;良好的下载和调试方式和堪比8位MCU的价格让你使用更方便;
电子让生活更美好!天下的人&&贞明电子2011年1月16日
写在前面
自从LPC1768教程推出以来,受到不少网友的鼓励和支持。
因此,本人再次决定参照我设计的ARMCortex-M0实验板写一个教程,实验板采用底板+小板的方式,使得系统支持LPC1100系列,新塘M051系列和LPC1300系列的MCU。
由于支持型号众多,在此统一以LPC1114为基础撰写,有不同的地方随时指出来,以便区分。
虽然本教程是配套实验板写的,但是在本教程以及其他地方都会公布原理图,这样不但让大家知其然还要知其所以然。
因此不拥有开发板自己搭建系统同样能够好好的学习!这样方便了一些囊中羞涩的学生朋友。
如果你有足够的精力和时间完全可以自制一套LPC1114系统板,我在这里先鼓励辛苦的你了!
下面介绍一下我们的主角吧,请我们的LPC1114隆重登场,LPC1114拥有领先的ARMCortex-M0内核,以及NXP公司先进的制造工艺和强悍的外设,当然也少不了一条超低的价格哟(小声的说----目前的价格貌似在12RMB哟)!LPC1100系列Cortex-M0微控制器是为嵌入式系统应用而设计的高性能、低功耗的32位微处理器。
它是市场上定价最低的
32位微控制器解决方案。
主频高达50MHz,支持睡眠、深度睡眠和深度掉电3种低功耗模式。
同样还拥有丰富的外设,高达32KB片内flash,8KB片内ram,一路IIC、一路RS485、8通道10位ADC、两路SSP、4个通用定时器、多达42个IO口。
好了、LPC1114就介绍这么多,下面介绍一下开发板支持的LPC1343,其实LPC1343和LPC1114的封装和管脚以及片内的外设都兼容,所以说如果会了LPC1114几乎也就会了LPC1343,LPC1343是ARMCortex-M3内核,主频72MHz,除了拥有LPC1114有的所有片内外设以外,LPC1343还拥有USB接口,而且这个USB接口内置固化驱动,号称是业界最简单的MCU内置USB。
下一个上场的就是新塘的M051了同样又有Cortex-M0内核,拥有丰富的外设和超低的价格。
下面介绍一下本教程的安排:第一部分介绍实验板硬件结构、第二部分程序下载方式、第三部分在例程中学习内部资源。
至于芯片简介大家看手册就知道了,我就不多说了。
编译环境(可以使用Keil4、
IAR、LPCXpresso)的介绍和LPC1768的差不多看看我的那一个手册就知道了(本教程主要以keil4.10开发环境作介绍)。
还有ZLG的LPC1100系列教程很好,已经整理成一个PDF 了,希望初学者可以结合着本教程看,zlg教程上有的东西本教程就不在重述了。
最后感谢一下ZLG提供的中文资料和教程,感谢一下本人辛苦的码字,感谢一下你用XXX的眼神和XXX的心情看完我在这里的啰嗦。
祝你学习愉快!
天下的人
贞明电子
2011年1月16 日
*************
om
第一部分硬件电路
一、LPC1114核心小板硬件电路在LPC1114的核心小板上有复位电路、时钟电路、滤波电容、LPC114芯片和一个ISP下载口。
如下图所示:
ISP 下载口电路图:
二、新塘核心小板电路在新塘的M051小板上同样是拥有复位电路、时钟电路、滤波电路、SW下载口和M051系列芯片,电路图如下图所示:
三、管脚关系下面要介绍的所有电路中管脚都是以LPC1114为基准的,M051和LPC1114的管脚关系下面一张图会分配清楚的。
蓝色字是LPC1114的管脚,红色的是M051的管脚,原理图中其余地方的管脚和LPC1114的管脚对应。
四、LPC1114的RS232串口下载电路图在使用NXP的芯片的时候可以通过NXP 的串口(ISP)下载软件FlashMagic下载程序,在硬件上我们优化了这种简易的下载方式,使得我们只需要一条串口线就可以进行NXP的M0开发,这是多么的方便。
下面就是串口通讯和nxp芯片下载的电路图。
从图中我们可以看出,电路主要由2个部分组成,上一部分主要是串口通讯和下载时的数据通讯,下面一部分是通过串口的DTR和RTS信号控制控制器(MCU)的复位和ISP使能管脚,使芯片进入串口ISP模式。
在使用的时候需要将S_D的1-2,3-4短接。
五、USB接口电路在如今的开发板中有USB口已经不是什么新鲜事了,带USB口的处理器很多,但是在我们的LPC1114和新塘的M051中目前还没有支持USB口的,我在这里留下USB口,一个是为LPC1343使用,还有一个目的就是开发板取电。
小声的说一声LPC1343支持USB下载哟,操作方法很简单哟,插上USB,并且选择主板供电是USB供电,然后将ISP引脚通过一条杜邦线连到地,插上电脑的USB
口,这样你就可以在你的电脑上看见一个虚拟的移动存储器了,把里面的固件删除,复制上你的新固件(程序),整个下载过程就完成了,怎么样简单吧!如果还不明白那就看看ZLG或者NXP关于USB下载的文档哈!
六、EEPROM24c0224c02是一种IIC协议的EEPROM存储芯片,芯片本身很便宜,在开发板上的地位却不低,几乎所有的开发板都有它的踪迹,这是由于2个原因,一是通过一个IIC总线的器件可以学习IIC协议和内置IIC控制器的学习,二是在MCU运行的过程中有很多数据是需要EEPROM保存的。
基于这两个原因这个小芯片一直存在于各个开发板就不奇怪了。
下面是24c02部分的原理图。
七、SPIFlash存储器SPI接口的Flash存储器,这类Flash有着管脚少,占用管脚少的特点,容量一般1Mb到几Mb,在开发板中用于存储一些字库和图片什么的还是相当不错的。
下面是他的原理图:
八、扩展接口在我们的开发板中有一个扩展接口,这个扩展接口很有用,不但有大量的IO口还有SPI总线口和电源口,可以扩展不同的硬件,包括彩色液晶、2.4G 无线收发器等等。
下面是接口原理图:
九、LED指示灯在我们的开发板上有3个普通LED灯,是通过IO口直接控制的,采用的是灌电流的方式驱动的,即高电平熄灭,低电平点亮。
电路原理图如图所示:
十、按键电路开发板上有3个普通按键,通过这3个普通的按键可以做按键实验,以及GPIO中断的实验,熟悉按键的读取方式,以及GPIO的中断使用,因为每个按
键都有外部中断功能,可以设置边沿触发及电平触发方式。
连接管脚如图所示:
十一、SD卡接口本开发板支持大容量的SD卡读写,这样我的再多的数据都可以通过SD卡保存了,一些图片等信息也可以通过存储在SD卡中保存。
SD卡通过SPI 总线操作。
接口原理图如下:十二、可控硅控制电路本开发板上使用的是双向可控硅,可以控制220V交流电,是交流220V用电设备中常用的控制电子开关,特别适合于电阻性负载,可以通过PWM实现电阻性
调温,调光等等。
具有开关频率快,使用时间长的优点。
Moc3021是光耦隔离。
十三、双路基于MOS管的H桥无论是在功率控制电路还是在电机控制电路中,H桥都是很常用的控制方式,具有电流方向和PWM调节的功能,相比普通三极管式H 桥,MOS管H桥有很大
的优点,导通电阻小使得MOS管可以通过很大的电流而发热量很小,损耗小,控制频率高。
板载H桥可以控制电阻性发热负载和小功率电机,用于直流调光,智能小车电机驱动等。
2路H桥均有光耦隔离保证了MCU的安全工作。
其原理图如下:
十四、全彩和白光调光LED实验板上除了有3个普通贴片LED作为指示灯以外,还有一个RGB三色LED灯,和一个白色的LED灯,这两个LED灯都是用于景观照明的功率型LED灯,其中RGB全彩LED通过调节红绿蓝三色LED的PWM占空比可以实现调
光以实现任意颜色的发光,调节控制白光的PWM占空比可以调节白光的亮度实现调光的目的,原理图如下:
十五、旋转编码器本开发板配备一个旋转编码器,可以无限制的向左和向右旋转,以向系统反馈旋转信息,旋转编码器取代了一般电位器的功能,而且能够不限圈数的调节及大地方便了使用。
十六、红外接收头在现代家居中遥控器是必不可少的东西,而遥控器的数据传输采用的是加入载波
的红外信号,本开发板有一个遥控器数据接收头,可以方便的读出各个遥控器的按键值,从而为我们的设备遥控打下了基础。
十七、ADC测光测温电路
在开发板中有一个测温或者测光电路,是通过系统MCU的AD采集电压实现测温或者测光的,这个电路具有简单实用的优点。
第二部分新建工程与下载程序LPC1114的开发环境有很多种如keil4、IAR、NXP公司的LPCXpresso,也包括周立功公司的TKStudio。
本教程就以最常用的Keil4.11开发环境的使用、新建工程、仿真设置及程序下载作介绍。
八、安装Keil4.11软件
1.打开keil4.11的安装程序,点击"Next",出现如下图所示:
十一、选择同意打勾,点击"Next"如下图所示
3.点击"Next"后出现如下图所示,选择需要的安装路径
4.点击"Next"直到安装结束
5.使用MDK411注册机破解Keil4,破解方法请参考网络二、设置keil与仿真器的连接在安装完keil4后,下面就介绍怎样新建工程,方法其实大家都很熟悉的,和51单片机一样。
四、打开keil4,选择"project->CreateNewproject",并输入文件名,选择保存路径。
五、我们这里使用的是LPC1114芯片,在这里选择NXP的芯片"LPC1114x301",选择正确的芯片后,点击确定。
如下图所示:
2 3.在确认后出现如下提示框,是否加载LPC11xx的启动文件,在这里我们点击“是”。
1 4.在Target1->SourceGroup中添加main.c文件,右击Source,点击"AddFilestoGroup",也可以添加Group进行代码分组管理,使代码结构更有条理。
2 5.对keil文件输出及仿真设置,点击来对keil进行设置,通过设置,keil在编译后可以输出hex文件,用于下载到MCU。
在LPC1343芯片中,可以需要通过设置输出bin文件用于USBISP下载,在此不作介绍。
6.Jlink 在keil4中的设置,首先需要在电脑上安装Jlink的驱动软件V4.14版本,安装方法,在这里省略。
第一步,将Jlink与电脑USB连接,点击Keil设置中"OptionforTarget"选项,在Debug里设置使用硬件仿真器,并选择
"Cortex-M/RJ_LINK/J-Trace",点击下拉菜单旁的"Setting",在Port选项中选择"SW"模式,因为LPC1114不支持JTAG方式仿真。
并在“DownloadOptions”中在"VerifyCodeDown"和"DownloadtoFlash"前打钩。
设置如下图所示:
17.在"FlashDownload"中添加器件,如下图所示
28.设置"Utilities"选项中设置如下:
在进行如上设置后,点击确定就可以进行仿真或者Jlink下载功能了。
三、使用FlashMagic和USB转串口下载程序(ISP)
在没有仿真器的情况下如何给LPC1114下载程序?
NXP的LPC系列内建ISPBootloader来允许用户使用FlashMagic来升级
Flash。
只需对MCU和UART进行简单的连接。
在使用Cortex-M0 开发板和USB2COM 的情况下,连接串口,然后进入自动ISP 模式。
LPC1114的UART是3.3V的电平,也可以承受5V。
USB2COM的UART接口是5V的。
Cortex-M0开发板与USB2COM的连接如下:
USB2COM Cortex 开发板
GND GND
DTR RST
RTS P0.1
TX P1.6
RX P1.7
设置UART的注意事项:如果你不知道USB转串口的波特率和COM端口号,你可以进入Windows设备管理器,查看设备的属性窗口,在“PORT
(COM&LPT)”选项里,在“端口设置”标签可以找到和修改相关的信息。
步骤:
1 1.按上面的连接方式连接USB2COM的UART接口至Cortex-M0开发板的ISP接口。
2 2.配置Flashmagic
(1)开始FlashMagic
(2)点击“SelectDevice”按钮,并从弹出的窗口选择相应的设备,在这里我们使用LPC1114/301
1(3)设置波特率(BaudRate:)为“115200”,晶振为12MHz
1(4)选择“EraseblocksusedbyHexfile”复选框
2(5)当你创建工程用“Browse”按钮选择firmeware.hex文件创建的地址,这是一个编译后要写入设备Flash的代码。
(6)选择“Verifyafterprogrammingbutton”最终设置如下图所示:
(7)烧写设备烧写提供的固件到设备,只需要点击“Start”按钮。
(8)断开DTR和RST的连接。
这里由于上位机软件的缺陷导致,在自动下载后没有抬高DTR电平,使RST仍然处于复位状态,此时断开连接,恢复了RST的电平,使系统正常工作。
第三部分实验例程
实验一、GPIO实验,测试LED在做GPIO实验之前我们需要了解一下LPC1114的GPIO相关的知识,首先大多数的管脚都是复用管脚,那么每个管脚都有一个专门的寄存器管理这个管脚到低是选择那一个功能,在一般的情况下上电复位后大多数都是默认为数字IO连接到管脚,只有几个P0-0;P0-4(开漏);P0-5(开漏);P0-10(默认SWCLK);P0-11;P1-0;P1-1;P1-2;P1-3(SWDIO)是特殊管脚,在用到这些管脚的数字IO时我们需要参考手册的第七章----IO配置,通过配置各个管脚对应的IO配置寄存器设置成数字IO就可以使用了。
让然在使用别的复用功能时也一样首先需要设置IO配置寄存器将管脚设置在你需要的复用功能上。
下面就该了解一下通用GPIO的寄存器了,在通用的GPIO寄存器中分两部分,一部分是数字功能,一部分是中断功能(这一节暂且不讨论),数字功能主要由2个寄存器构成,一个是方向寄存器DIR一个是数据寄存器DATA,方向寄存器配置成0则是输入状态,配置成1则是输出状态,DATA是GPIO上读入或者写出的数据,因此如果要配置P0口为输出则写法如下:LPC_GPIO0->DIR=0xfff;如果要输出高电平则写法如下:LPC_GPIO0->DATA=0xfff;
下面我们看具体例程:
intmain(void)
{
SystemInit(); //系统初始化,包括使能时钟
GPIOInit(); //GPIO初始化,使能GPIO模块时钟
GPIOSetDir(PORT2,8,1); //设置P2.8为输出,LED1
GPIOSetDir(PORT2,9,1); //设置P2.9为输出,LED2
GPIOSetDir(PORT3,4,1); //设置P3.4为输出,LED3
//调用头文件中函数输出方法GPIOSetValue(PORT2,8,0);//设置P2.8输出0,点亮LED1GPIOSetValue(PORT2,9,0);//设置P2.9输出0,点亮
LED2GPIOSetValue(PORT3,4,0);//设置P3.4输出0,点亮LED3delay_ms(500);//直接使用寄存器
LPC_GPIO2->DATA|=(((1<<8)|(1<<9)));//P2.8,P2.9输出1,LED1,LED2灭LPC_GPIO3->DATA|=(1<<4);//LED3灭delay_ms(500);
while(1)
{GPIOSetValue(PORT2,8,0);//设置P2.8输出0,LED1亮
GPIOSetValue(PORT2,9,1);//设置P2.9输出1,LED2灭
GPIOSetValue(PORT3,4,1);//设置P3.4输出1,LED3灭delay_ms(500);
GPIOSetValue(PORT2,8,1);//设置P2.8输出1,LED1灭
GPIOSetValue(PORT2,9,0);//设置P2.9输出0,LED2亮
GPIOSetValue(PORT3,4,1);//设置P3.4输出1,LED3灭
delay_ms(500);
GPIOSetValue(PORT2,8,1);//设置P2.8输出1,LED1灭
GPIOSetValue(PORT2,9,1);//设置P2.9输出1,LED2灭
GPIOSetValue(PORT3,4,0);//设置P3.4输出0,LED3亮
delay_ms(500);
}}通过阅读代码我们不难发现出现了连个新函数,一个是GPIOSetDir(),一个是GPIOSetValue();通过看函数名我们知道一个是配置方向,一个是设定输出值的函数,这两个函数是在工程加载的GPIO.c文件中定义的这个文件最初是由NXP公司提供的,因此我们可以选择使用或者不是用来操作我们的GPIO口。
SystemInit();这个函数是系统初始化函数,函数里定义了关于倍频系统寄存器设置等等信息,我们普通用户只需要调用就可以了,这个函数在
system_LPC11xx.c文件中定义,如果以后一些应用需要修改这个函数那么可以到这个文件中修改。
实验二、GPIO输入,测试KEY
在这个实验中我们将使用GPIO的输入功能来读取按键的键值,在按键状态的读取中,我们常常需要消除按键的机械抖动和按键松开检测,在这一个实验代码中我们可以看到这样一个完整的过程。
下面是这个工程的主函数:
intmain(void)
{
SystemInit(); //系统初始化,包括使能时钟
GPIOInit(); //GPIO初始化,使能GPIO模块时钟
GPIOSetDir(PORT2,8,1); //设置P2.8为输出,LED1
GPIOSetDir(PORT2,9,1); //设置P2.9为输出,LED2
GPIOSetDir(PORT3,4,1); //设置P3.4为输出,LED3
LPC_IOCON->PIO2_11=0x00;//设置P2.11为GPIO功能
LPC_IOCON->PIO1_4=(1<<7);//注意:当有AD功能的引脚作为输入时,
需要配置为数字输入。
LPC_IOCON->PIO2_11=0x00;//设置P2.11为GPIO功能GPIOSetDir(PORT2,11,0);//设置P2.11为输入
KEY1GPIOSetDir(PORT1,4,0);//设置P1.4为输入
KEY2GPIOSetDir(PORT3,5,0);//设置P3.5为输入
KEY3GPIOSetValue(PORT2,8,1);//灭3个灯
GPIOSetValue(PORT2,9,1);GPIOSetValue(PORT3,4,1);delay_ms(1000);wh ile(1){
if((LPC_GPIO2->DATA&(1<<11))==0)//如果按键1被按下
{delay_ms(10);//延时消抖if((LPC_GPIO2->DATA&(1<<11))==0)//如果还是按下状态{
while((LPC_GPIO2->DATA&(1<<11))==0);//等待松开按键
LPC_GPIO2->DATA^=(1<<8);//LED1闪烁1次}
}
if((LPC_GPIO1->DATA&(1<<4))==0)//如果按键2被按下
{delay_ms(10);if((LPC_GPIO3->DATA&(1<<5))==0)//如果还是按下状态while((LPC_GPIO3->DATA&(1<<5))==0);//等待松开按键
LPC_GPIO2->DATA^=(1<<9);//LED3闪烁1次
//延时消抖
}
if((LPC_GPIO3->DATA&(1<<5))==0)
{delay_ms(10);//延时消抖if((LPC_GPIO1->DATA&(1<<4))==0)//如果还是按下状态while((LPC_GPIO1->DATA&(1<<4))==0);//等待松开
按键LPC_GPIO3->DATA^=(1<<4);//LED2闪烁1次
}
}}在这个主函数中我们使用了函数delay_ms();这个函数的主要作用就是软件延时,虽然不精确也很占用系统资源,但是在我们简单的应用和测试的过程中是非常有用的一个函数,函数源代码如下:
__inlinevoiddelay_ms(uint32_ta)//1ms延时函数{uint32_ti;while(--a!=0){ for(i=0;i<5500;i++
);}
}由函数定义(__inline)可知,这定义的是一个内联函数,在C++语法中有介绍,在函数代码短小调用平凡的代码中,使用内联函数是非常合理的安排,这是一个用空间开销(一般是增加空间开销,当然代码量少也可能不增加空间开销,因为函数调用的空间开销也是有的)来换取时间开销的方法。
实验三、GPIO中断,测试KEY
在这个实验中要涉及到GPIO的中断功能,具体寄存器的名称和意义可以参考芯片参考手册的第六章的通用输入输出的相关说明和解释。
在这里我们使用NXP公司提供的GPIO.C中的函数来完成我们的实验。
主函数所在的文件的所有代码如下:/****************************************************
*名称:
GPIO 测试文件
*
*
功
能:测试GPIO中断*
*
备注:
2011.1.9
*
*贞明电子:
*************************************** ***************//****************头文件调用&&宏定义
****************/#include"LPC11xx.h"#include"GPIO.H"/**************** ***全局变量定义*******************/
/**********************函数声明
********************/__inlinevoiddelay_ms(uint32_ta);/*************** *******主函数**********************/intmain(void){
SystemInit();//系统初始化,包括使能时钟GPIOInit();//GPIO初始化,使能GPIO模块时钟GPIOSetDir(PORT2,8,1);//设置P2.8为输出,
LED1GPIOSetDir(PORT2,9,1);//设置P2.9为输出,LED2
GPIOSetDir(PORT3,4,1);//设置P3.4为输出,LED3LPC_IOCON->PIO2_11=0x00;//设置P2.11为GPIO功能LPC_IOCON->PIO1_4=(1<<7);//注意:当有AD功能的引脚作为输入时,
需要配置为数字输入。
LPC_IOCON->PIO2_11=0x00;//设置P2.11为GPIO功能GPIOSetDir(PORT2,11,0);//设置P2.11为输入
KEY1GPIOSetDir(PORT1,4,0);//设置P1.4为输入
KEY2GPIOSetDir(PORT3,5,0);//设置P3.5为输入
KEY3GPIOSetValue(PORT2,8,1);//灭3个灯
GPIOSetValue(PORT2,9,1);GPIOSetValue(PORT3,4,1);//GPIO中断的初始化GPIOSetInterrupt(PORT2,11,0,0,1);//端口号,位地
址,sense,single/doublee,上
升/下降沿
GPIOSetInterrupt(PORT3,5,0,0,1);GPIOSetInterrupt(PORT1,4,0,0,1);G PIOIntEnable(PORT2,11);//使能该端口中断
P2_11GPIOIntEnable(PORT3,5);//使能该端口中断P3_5(LPC1343为
P2_5)GPIOIntEnable(PORT1,4);//使能该端口中断
P1_4delay_ms(1000);while(1){}
}/**********************函数定义
********************//*********************************************** *****
*
称:延时函数*
名
*
数:延时时间*
参
*
备注:内联函数*
*****************************************************/
__inlinevoiddelay_ms(uint32_ta)//1ms延时函数{uint32_ti;while(--a!=0){ for(i=0;i<5500;i++);}}
/****************************************************//********
************中断服务函数
******************//*******************************************
*********
*名称:PIOINT1_IRQHandler*
*参数:无*
*备注:使用GPIO一个管脚(端口1的管脚4)作为中断源
******************************************************/voidPIOINT1_IR QHandler(void)//中断服务函数{
uint32_tregVal;regVal=GPIOIntStatus(PORT1,4);//读取该IO组某位的中断状态if(regVal){
LPC_GPIO2->DATA^=(1<<9);//P2_9闪动1次LED2 GPIOIntClear(PORT1,4);//清除中断标志}return;
} /***************************************************** *名称:PIOINT2_IRQHandler*
*参数:无*
*备注:使用GPIO一个管脚(端口2的管脚11)作为中断源
*******************************************************/
voidPIOINT2_IRQHandler(void)
{uint32_tregVal;regVal=GPIOIntStatus(PORT2,11);if(regVal){ LPC_GPIO2->DATA^=(1<<8);//P2_8闪动1次LED1
GPIOIntClear(PORT2,11);}return;
}
/****************************************************
*
*名称:PIOINT2_IRQHandler*
*参数:无*
*备注:使用GPIO一个管脚(端口3的管脚5)作为中断源
*******************************************************/voidPIOINT3_I RQHandler(void){
uint32_tregVal;regVal=GPIOIntStatus(PORT3,5);if(regVal){
LPC_GPIO3->DATA^=(1<<4);//P3_4闪动1次LED3
GPIOIntClear(PORT3,5);}return;
}
通读代码我们注意到了这个代码比前面的多了几个函数,一个是GPIOSetInterrupt();这个函数是用于设置GPIO中断的函数,参数的设置方法可以参考源文件的说明。
第二个函数是GPIOIntEnable();这个函数的功能是使能中断。
在这个文件中还有一个很重要的函数就是中断函数,void
PIOINT1_IRQHandler(void)这里涉及到LPC1114芯片的中断函数的写法,在
ARMCortex-M0系列芯片中MDK编程的启动文件startup_LPC11xx.s都给我们做了很多事情,将启动代码和中断系统一些事都做好了,因此我们在函数中写中断函数只需要按照固定的函数名写就是了,类似voidPIOINT1_IRQHandler(void)的写法,不同的中断函数,函数名称不一样,如何确定函数名称呢,我们在MDK中打开startup_LPC11xx.s中的77行到108行就是外部中断函数的定义,我们只需要复制这里面的名字来写出中断函数的形式就可以使用了!这极大的方便了我们编写代码。
在进入端口中断后,还需要通过中断状态寄存器来判断是哪一个端口号产生的中断。
实验四、UART,串口1
串口是我们数据调试必不可少的工具,具有使用方便,需要硬件少等特点,同时也可以作为modem、485、GPS、TC35i、蓝牙的通信接口,从而丰富了外部功能及应用的扩展。
NXP的LPC1114同样提供了关于串口操作的文件UART.c,这里面定义了我们常用的函数,比如串口初始化UARTInit(115200);比如UARTSend();串口发送等函数。
这个实验代码就是基于这个文件来实现的。
实验源代码如下:
/****************************************************
*名称:
UART 测试文件
*
*
功
能:UART 串口发送* *
备注:
2011.1.9
*
*贞明电子:
*************************************** ***************//****************头文件调用&&宏定义
****************/#include"LPC11xx.h"#include"GPIO.H"#include"UART.h"/ *******************全局变量定义
*******************/#defineBUFSIZE10externvolatileuint32_tUARTCount;e xternvolatileuint8_tUARTBuffer[BUFSIZE];
/**********************函数声明
********************/__inlinevoiddelay_ms(uint32_ta);/*************** *******主函数**********************/intmain(void){
SystemInit();//系统初始化,包括使能时钟UARTInit(115200);//初始化波特率为115200#ifMODEM_TESTModemInit();#endifwhile(1){
if(UARTCount!=0)//将发送的数据返回
{LPC_UART->IER=IER_THRE|IER_RLS;//DisableRBRUARTSend((uint8_t*)UARTBu ffer,UARTCount);UARTCount=0;LPC_UART->IER=IER_THRE|IER_RLS|IER_RB R;//
Re-enableRBR}UARTSend("贞明电子:
\r\n",42);delay_ms(1000);
}}/**********************函数定义
********************//*********************************************** *****
*
称:延时函数*
名
*
数:延时时间*
参
*
备注:内联函数*
*****************************************************/__inlinevoiddel ay_ms(uint32_ta)//1ms延时函数
{uint32_ti;while(--a!=0){
for(i=0;i<5500;i++);}}在这些代码里有两句代码比较特殊,分别是externvolatileuint32_tUARTCount;externvolatileuint8_tUARTBuffer[BUFSI ZE];这两句实际上是定义了一个外部变量,一个是简单的32位int型变量UARTCount,串口接收计数,一个是8位的数据缓冲区UARTBuffer,定义外部变量的目的是使这些变量既可以在主函数中访问也可以在UART.C文件中访问。
LPC_UART->IER=IER_THRE|IER_RLS;
UARTSend((uint8_t*)UARTBuffer,UARTCount);UARTCount=0;LPC_UART->IER=IE R_THRE|IER_RLS|IER_RBR;
这几句代码是串口数据接收后数据的处理,通过计算机发送下来的数据就在第二句的UARTBuffer缓存中,在这里我们可以将数据从缓存中复制到别的地方使用也可以将数据再返回到PC机,这里我们就是将数据再返回回去。
UARTCount变量是接收数据计数的。