while rxdend(pin_rxd);什么意思?

while(pin_rxd);什么意思?-
while(pin_rxd);什么意思?
来源:www.zuowenzhai.com &&&作者:编辑&&&日期:
没有这个字,只有woodpecker这个字,意思是啄木鸟。啄木鸟科(学名:Picidae):是鸟纲鴷形目的1科,约有221种。体长 90~560毫米。该科鸟类头亦大,但颈较长,嘴强硬而直,呈凿形,舌长而能伸缩,先端列生短钩;脚稍短,具3或4趾;尾呈平尾或楔状,羽干坚硬富有弹性,在啄木时支撑身体。共有约34属221种。除大洋洲和南极洲外,均可见到。啄木鸟可以在树上凿孔钩虫,它的嘴巴又长又尖又硬,能一直插进坚硬的木质部,舌头又长又细,长了许多倒刺,表面布满一层粘液,可以准确无误地把害虫钩出来。主要吃隐藏在树干内部蛀食的天牛、透翅蛾、吉丁虫等害虫。被称为“森林医生”。该科鸟类头亦大,但颈较长,嘴强硬而直,呈凿形,鼻孔裸露;角舌骨延成环带状,两侧自咽喉绕过枕部至上嘴基。舌长而能伸缩,先端列生短钩;脚稍短,具3或4趾;初级飞羽9片。头骨为蜥腭型,锄骨被一些成对的骨片所代替,颌腭骨细小远离两侧,胸骨后端每侧有2切刻,胸骨柄分叉。腿肌肉缺栖肌和副股尾肌;尾呈平尾或楔状,尾羽大都12枚,羽干坚硬富有弹性,在啄木时支撑身体。 啄木鸟最为常见的是绿啄木鸟和斑啄木鸟。绿啄木鸟体羽主要是绿色,下体污灰色带有绿色沾染。雄鸟的头顶为红色,非常鲜艳。斑啄木鸟的体形略小,上体羽色是黑底有白斑,以翅膀上居多,下体棕白色,尾下部是红色,雄鸟的头的后部也是红色。还有一种体形更小的啄木鸟叫蚁鴷,也较为常见,它的羽色比较特别,上体是淡银灰色的底色,密布着暗褐色的斑纹,好像蛇皮的花纹,下体近白色。它不会攀登树木,也不啄木捕虫,却在地上觅食蚂蚁,所以也叫地啄木鸟。啄木鸟有极为高超的捕虫本领,它的嘴强直而尖,不仅能啄开树皮,而且也能啄开坚硬的木质部分,很像木工用的凿子,它的舌细长而柔软,能长长地伸出嘴的外面,还有一对很长的舌角骨,围在头骨的外面,起到特殊的弹簧作用,舌骨角的曲张,可以使舌头伸缩自如,舌尖角质化,有成排的倒须钩和粘液,非常适合钩取树干上的昆虫及幼虫。它们用嘴敲击树干,在寂静的林中发出“笃,笃……”的声音,如果发现树干的某处有虫,就紧紧地攀在树上,头和嘴与树干几乎垂直,先将树皮啄破,将害虫用舌头一一钩出来吃掉,将虫卵也用粘液粘出。当遇到虫子躲藏在树干深部的通道中时,它还会巧施“击鼓驱虫”的妙计,用嘴在通道处敲击,发出特异的、使害虫产生恐惧的击鼓声,使害虫在声波的刺激下,昏头转向,四处窜动,往往企图逃出洞口,而恰好被等在这里的啄木鸟擒而食之。它们一般要把整株树的小囊虫彻底消灭才转移到另一棵树上,碰到虫害严重的树,就会在这棵树上连续工作上几天,直到全部清除害虫为止。啄木鸟啄食的害虫包括森林中鞘翅目的象甲、伪步行甲、天牛幼虫、金龟甲,鳞翅目的逼债蛾、螟蛾,以及花蝽象、臭蝽象、蝗虫、蚂蚁、蛴螬、小囊虫、天牛幼虫、蛴螬、白蚁等。啄木鸟每天敲击树木约为500—600次,啄木的速度极快,几乎是音速的两倍,这样它的头部则不可避免地要受到非常剧烈的震动,但它既不会得脑震荡,也不会头痛。原来在啄木鸟的头上至少有三层防震装置,它的头骨结构疏松而充满空气,头骨的内部还有一层坚韧的外脑膜,在外脑膜和脑髓之间有一条狭窄的空隙,里面含有液体,减低了震波的流体传动,起到了消震的作用。由于突然旋转的运动比直线的水平运动更容易造成脑损伤,所以在它头的两侧都生有发达而强有力的肌肉,可以起到防震、消震的作用。这种精妙的防震设置原理,给防震工程学提供了安全运动防护帽和防震盔的正确设计方案,现代的防护帽都具有一个坚硬的外壳,里面为一个松软的套具,它们之间留有一定的空隙,帽中再加上一个防护领圈,以防止在突然碰撞时造成旋转运动。由于啄木鸟为保护树木所作出的巨大贡献,人们称它们为“森林卫士”或“树木医生”。在k国的一些古书里,很早就有关于啄木鸟啄木食虫的记载,例如《禽经》中有“ 志在木”,《异物志》中有“穿木食蠹”的记载,明朝李时珍的《本草纲目》则指出:“此鸟斫裂树木取蠹食故名”,还指出:“(啄木鸟)刚爪利嘴,嘴如锥,长数寸,舌长于嘴,其端有针刺,啄得蠹,以舌钩出”。此外还有“南山有鸟,其名啄木。饥则啄树,暮则巢宿。无干于人,惟志所欲,性清者荣,性浊者辱。”,以及“丁丁向晚急还稀,啄遍庭槐未肯归。终日为君除蠹害,莫嫌无事不频飞。”等歌咏啄木鸟的诗作,可见啄木鸟自古就受到人们的喜爱和赞美。元音字母组合oo在单字里发短元音/ʊ/的音,发音时,舌后部抬高,舌位中高,牙床半合,双唇呈圆形,小而突出,这个音大多出现在字中,也常出现在非重读的字末,但很少出现在字首,如:book 书wood 木头cookie 甜饼干,曲奇wool 羊毛foot 脚,英尺(英制长度单位)cook 烹调hook 钩住look 看希望我能帮助你解疑释惑。
<img alt="the entire cooler shroud uses rgb lightning while the custom ro" src="http://files.colabug.com/forum//b1zas2gqgik9g.jpg" />
<img alt="minimizes current drain from the power amplifier, while low rx c" src="http://pdf-html-new.icpdf.com/pdf_html/pdf6_html/AVAGO/HSMM-A100-U4PJ1_datasheet_1054048/pg_0001.png" />
<img alt="11b/g devices while operating in 802." src="http://image04.71.net/image04/95/98/71/42/d7fb-41f4-aea5-bb161aab8810.jpg" />
<img alt="while txif indicates the status of txreg, trmt (txsta 1>) shows" src="http://pdf-html.ic37.com/pdf_html/pdf6_html/MICROCHIP/PIC17LC756A-33I-L_datasheet_1057544/pg_0125.png" />
while(pin_rxd);什么意思?:
没有这个字,只有woodpecker这个字,意思是啄木鸟。 啄木鸟科(学名:Picidae):是鸟纲...
(编辑:qq网友)
&|&&|&&|&&|&&|&nbsp&|&当前位置: >>
LPC1768 教程
CortexNXP Cortex-M3 LPC1768 基础教程活生变改技科 好美更活生让子电作者: 作者:天下的人 时间: 时间:2010 年 9 月 2 日 邮箱: 邮箱:http://djbgreen.taobao.com 电子让生活更美好写在前面首先说一说为什么写这个教程,转眼间就毕业了,学校的日子还没 有过够。就要工作了,由于需要想要搞一搞 ARM M3,很显然芯片选型 落在了 STM32 和 NXP 的 LPC17XX 上了。 最后选择了 LPC1768 这款型号, 买开发板、学习(以前我只用过单片机和一点点 STM32) ,学习的过程 还算顺利,找到了 ZLG 翻译的中文资料和 3 个版本的例程。学习开始 了,从 LED 灯、串口、AD、到内部定时器等等。学习的过程夹杂着 心酸和喜悦,在学习的过程中发现网络上还没有现成的学习资料。市 场上的开发板的一部分不是自己开发的都是参考的 NXP 和 ARM 公司的 官方版本,其实这本身并没有什么不好,但是后面的问题出来了,程 序注释不详细,除了手册就没有参考资料了。所以在学习的过程中就 在想要是把自己学习的过程总结一下,出一点资料,为那些奋斗在学 习一线的电子爱好者出一份力,这是一件多么令人高兴的事呀!于是 有了今天这个教程的诞生。在这里首先要感谢的是 ZLG 公司为这个系 列芯片提供了中文参考资料,其次感谢该公司注释比较详尽的程序, 为我的学习和应用提供了不少帮助。 关于同是 ARM M3 内核的 STM32 和 LPC17XX 比较,我想大家争论最大 的地方是价格。我想说的是 LPC17XX 是 NXP 公司推出的基于 M3 内核比 较高端的芯片。应该拿 STM32 中高端芯片和 LPC17XX 比较。我曾经买 过几片 stm32f103VET6 是 100 脚 512KB flash、64KB SRAM、72MHz、AD、 DA、定时器、USB 从机和 FSMC。而 LPC 脚、512KB flash、 64KB SRAM、100MHz、AD、DA、32 位定时器、USB 主/从/OTG、以太网、天下的人(红豆电子)与贞明电子协同打造 1 电子让生活更美好电机控制 PWM、正交编码器接口等。STM32 有 FSMC 的优势,LPC1768 有以太网、 USB 主机等优势。 可能你要说 stm32F105 和 stm32f107 也有 带 USB 主机,以太网的。可是看看价格也差不多,这几个芯片目前的 价格都在 40 元左右。还有编程,stm32 有库,而 NXP 没有,但是我觉 得 NXP 的寄存器操作也很简单,不信试试就知道了。 下面说说本教程的主要内容安排:第一部分主要介绍 LPC1768 的特 点。第二部分介绍本教程使用的最小系统版的硬件电路。第三部分是 编译环境和下载程序介绍。第四部分是芯片编程介绍,第五部分是实 例详解。芯片内部功能和操作详解会柔和在实例的每一个实验中。最 后感谢一下辛苦的我自己,没有自己的辛勤劳动就没有这个教程。期 待早一点完成这个教程。注意:本教程叙述语言力求简洁大方,例程力求通俗易懂,可以不 注意 深入追究的东西(如协议内容)就不深入追究。本教程适合的对象是 学过或致力于学习单片机或对 ARM7、ARM cortex m3 有所了解的人或 想学 LPC17XX 的初学者适用。高手绕行。天下的人(红豆电子)与贞明电子协同打造2 电子让生活更美好第一部分 第一部分 LPC1768 介绍 1.1 简介 LPC1768 是 NXP 公司推出的基于 ARM Cortex-M3 内核的微控制器 LPC17XX 系列中的一员。LPC17XX 系列 Cortex-M3 微处理器用于处 理要求高度集成和低功耗的嵌入式应用。 LPC1700 系列微控制器的 操作频率可达 100MHz 新推出的 LPC1769 和 LPC1759 可达 120MHz) ( 。 ARM Cortex-M3 CPU 具有 3 级流水线和哈佛结构。LPC17XX 系列微 控制器的外设组件包含高达 512KB 的 flash 存储器、64KB 的数据 存储器、以太网 MAC、USB 主机/从机/OTG 接口、8 通道 DMA 控制 器、4 个 UART、2 条 CAN 通道、2 个 SSP 控制器、SPI 接口、3 个 IIC 接口、2 输入和 2 输出的 IIS 接口、8 通道的 12 位 ADC、10 位 DAC、电机控制 PWM、正交编码器接口、4 个通用定时器、6 输 出的通用 PWM、带有独立电池供电的超低功耗 RTC 和多大 70 个的 通用 IO 管脚。 1.2 特性(部分) 64KB 片内 SRAM 包括: 32KB 可供高性能 CPU 通过本地代码/数据总线访问; 2 个 16KB SRAM 模块、带独立访问路径、可进行更高吞吐量的操 作。这些 SRAM 可用于以太网、USB、DMA 存储器,以及通用指令和 数据存储。 串行接口: 以太网 MAC 带 RMII 接口和相关的 DMA 控制器;天下的人(红豆电子)与贞明电子协同打造 3 电子让生活更美好USB 2.0 全速从机/主机/OTG 控制器,带有用于从机、主机功能 的片内 PHY 和相关的 DMA 控制器; 4 个 UART、 带小数波特率发生功能、 内部 FIFO、 支持和 RS-485 DMA 支持。1 个 UART 带有 modem 控制 IO 并支持 RS-485,全部的 UART 都支持 IrDA; CAN 控制器,带有 2 个通道; SPI 控制器, 具有同步、 串行、 全双工通信和可编程的数据长度; 2 个 SSP 控制器,带有 FIFO,可按多种协议进行通信。其中一 个可选择用于 SPI,并且和 SPI 公用中断。SSP 接口可以与 GPDMA 控制器一起使用。 3 个增强型的 IIC 总线接口。 IIS 接口,用于数字音频输入和输出,具有小数速率控制功能。 IIS 接口可与 GPDMA 一起使用。IIS 接口支持 3 线数据发送和接收 或 4 线组合发送和接收连接,以及主机时钟输入输出; 其他外设: 4 个通用定时/计数器, 共有 8 个捕获输入和 10 个比较输出。 每 个定时器都有一个外部计数输入。 一个电机控制 PWM,支持三相的电机控制; 通过片内 PLL,没有高频晶振,CPU 页可以以最高频率运转。 第二个专用的 PLL 可用于 USB 接口,以允许增加主PLL的灵 活性;天下的人(红豆电子)与贞明电子协同打造4 电子让生活更美好器件选型表:方框图:天下的人(红豆电子)与贞明电子协同打造5 电子让生活更美好第二部分最小板硬件电路2.1 硬件电路简介 硬件电路基本结构图:EEPROM JTAG 微控制器 UART KEYRTC IO口 LED USB电源图 1 硬件电路基本结构图 硬件电路原理图:3V3 3V3 3V3 2 1 R12 680 R11 680 R10 680 R9 680 D5 LED2 D1 LED2 D2 LED2 D3 LED2 D4 LED2 R6 R5 R4 R3 R2 R1 10K 10K 10K 10K 10K 10K TRST TDI TMS TCK RTCK TDO RESET U1 JTAG 1 3 5 7 9 11 13 15 17 19 2 4 6 8 10 12 14 16 18 20 TDO TDI TMS TRST TCK P0.26 P0.25 P0.24 P0.23 VDDA VSSA VREF+ VREFR7 P0 P0.26 P0.25 P0.24 P0.23 VDDA VSSA VREF+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 RSTOUT VREFRESET P1.31 P1.30 P0.28 P0.27 GND P0.28 P0.27 P3.26 P3.25 3V3 C21 1 3 0.1uF 4 C22 5 0.1uF P0.10 11 P0.2 10 P0.11 12 P0.3 9 15 GND MAX3232CSE VU3 C1+ C1C2+ C2VCC V+ 16 C24 2 C23 0.1uF 14 RXD2 7 13 TXD2 8 6 C25 0.1uF ISP P0.2 1 P0.3 2 P2.10 3 RESET 4 S_COM RXD2 1 2 3 4 5 63,5;4,6选选选电0 1,3;2,4选选选电23V3GND3V3PLEDLED_POWER LED供电电电R8 680供电供电电电1 2 3 4 5 6 7 8 9P_BATT 1 2TDO/SWO TDI TMS/SWDIO TRST TCK/SWDCLK P0.26/AD0.3/AOUT/RXD3 P0.25/AD0.2/I2SRX_SDA/TXD3 P0.24/AD0.1/I2SRX_WS/CAP3.1 P0.23/AD0.0/I2SRX_CLK/CAP3.0 VDDA VSSA VREF+ NC RSTOUT VREFRTCX1 RESET RTCX2 VBAT P1.31/SCK1/AD0.5 P1.30/VBUS/AD0.4 XTAL1 XTAL2 P0.28/SCL0/USB_SCL P0.27/SDA0/USB_SDA P3.26/STCLK/MAT0.1/PWM1.3 P3.25/MAT0.0/PWM1.2 VDDIO_1 P0.29/USB_D+ P0.30/USB_DVSS_1 P1.18/USB_UP_LED/PWM1.1/CAP1.0 P1.19/MC0A/USB_PPWR/CAP1.1 P1.20/MCFB0/PWM1.2/SCK0 P1.21/MCABORT/PWM1.3/SSEL0 P1.22/MC0B/USB_PWRD/MAT1.0 P1.23/MCFB1/PWM1.4/MISO0 P1.24/MCFB2/PWM1.5/MOSI0 P1.25/MC1A/MAT1.1 P1.26/MC1B/PWM1.6/CAP0.0 VSS_2 VDDREG_1 P1.27/CLKOUT/USB_OVRCR/CAP0.1 P1.28/MC2A1.0/MAT0.0 P1.29/MC2B/PCAP1.1/MAT0.1 P0.0/RD1/TXD3/SDA1 P0.1/TD1/RXD3/SCL1 LPC/TXD2/SDA2/MAT3.0 P0.11/RXD2/SCL2/MAT3.0 P2.13/EINT3/I2STX_SDA LPC1768_1P2.12/EINT2/I2STX_WS P2.11/EINT1/I2STX_CLK P2.10/EINT0/NMI VDDIO_2 VSS_3 P0.22/RTS1/TD1 P0.21/RI1/RD1 P0.20/DTR1/SCL1 P0.19/DSR1/SDA1 P0.18/DCD1/MOSI0/MOSI P0.17/CTS1/MISO0/MISO P0.15/TXD1/SCK0/SCK P0.16/RXD1/SSEL0/SSEL P2.9/USB_CONNECT/RXD2 P2.8/TD2/TXD2 P2.7/RD2/RTS1 P2.6/PCAP1.0/RI1/TRACECLK P2.5/PWM1.6/DTR1/TRACEDATA0 P2.4/PWM1.5/DSR1/TRACEDATA1 P2.3/PWM1.4/DCD1/TRACEDATA2 VDDIO_3 VSS_4 P2.2/PWM1.3/CTS1/TRACEDATA3 P2.1/PWM1.2/RXD1 P2.0/PWM1.1/TXD1 P0.9/I2STX_SDA/MOSI1/MAT2.3 P0.8/I2STX_WS/MISO1/MAT2.2 P0.7/I2STX_CLK/SCK1/MAT2.1 P0.6/I2SRX_SDA/SSEL1/MAT2.0 P0.5/I2SRX_WS/TD2/CAP2 P0.4/I2SRX_CLK/RD2/CAP2.0 P4.28/RX_MCLK/MAT2.0/TXD3 VSS_6 VDDREG_2 P4.29/TX_MCLK/MAT2.1/RXD3 P1.17/ENET_MDIO P1.16/ENET_MDC P1.15/ENET_REF_CLK P1.14/ENET_RX_ER P1.10/ENET_RXD1 P1.9/ENET_RXD0 P1.8/ENET_CRS P1.4/ENET_TX_EN P1.1/ENET_TXD1 P1.0/ENET_TXD0 VDDIO_4 VSS_5 P0.3/RXD0/AD0.6 P0.2/TXD0/AD0.7 RTCK51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 99 98 100P2.12 P2.11 P2.10 VDDIO_2 VSS_3 P0.22 P0.21 P0.20 P0.19 P0.18 P0.17 P0.15 P0.16 P2.9 P2.8 P2.7 P2.6 P2.5 P2.4 P2.3 VDDIO_3 VSS_4 P2.2 P2.1 P2.0 P0.9 P0.8 P0.7 P0.6 P0.5 P0.4 P4.28 VSS_6 VDDREG_2 P4.29 P1.17 P1.16 P1.15 P1.14 P1.10 P1.9 P1.8 P1.4 P1.1 P1.0 VDDIO_4 VSS_5 P0.3 P0.2P3 3V3 C20 0.1uF P2.12 P2.11 P2.10 VDDIO_2 VSS_3 P0.22 P0.21 P0.20 P0.19 P0.18 P0.17 P0.15 P0.16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 P2.9 P2.8 P2.7 P2.6 P2.5 P2.4 P2.3 VDDIO_3 VSS_4 P2.2 P2.1 P2.0P2.0P2.1P2.2P2.3 GNDLEDPOWER_LEDBT1GNDJTAGGNDBattery3V3 R13 P2.10 10K S2 SW-PB GND INT0INT03V3 P2.11R14 10K S33V3 P2.12R15 10K S43V310K C10 S1 0.1uFVDDA 10 VSSA 11 VREF+ 12 13 RSTOUT 14 VREF- 15 RX1 16 RESET 17 RX2 18 VBAT 19 P1.31 P1.30 X1 X2 20 21 22 23 24 25 26 27IO&PIN3V3 C19 0.1uF P2 P0.9 1 P0.8 2 P0.7 3 P0.6 4 P0.5 5 P0.4 6 P4.28 7 VSS_6 8 VDDREG_2 9 P4.29 10 P1.17 11 P1.16 12 13 14 15 16 17 18 19 20 21 22 23 24 P1.15 P1.14 P1.10 P1.9 P1.8 P1.4 P1.1 P1.0 VDDIO_4 VSS_5 P0.3 P0.2SW-PBkey1SW-PB GNDkey22 1GNDSW-PBINT0&KEY3V3 0.1uF GND 3V3 COM 1 6 2 RTS 7 3 8 DTR 4 9 5 GNDIO&PINGNDC15 0.1uF P1 11 10 P3.26 P3.25 VDDIO_1 P0.29 P0.30 VSS_1 P1.18 P1.19 P1.20 P1.21 P1.22 P1.23 P1.24 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 P1.25 P1.26 VSS_2 VDDREG_1 P1.27 P1.28 P1.29 P0.0 P0.1 P0.10 P0.11 P2.13 GNDVDDIO_1 28 P0.29 29 P0.30 30 VSS_1 31 P1.18 P1.19 P1.20 P1.21 P1.22 P1.23 P1.24 P1.25 P1.26 32 33 34 35 36 37 38 39 40GNDC18 0.1uF 3V3 RX1 1IO&PINTXD2C14 10PF Y1 GNDGND2RX2 3V3 C17 0.1uF X2 GND X1C13 10PF C12D Connector 9C16 0.1uF 3V3VSS_2 41 VDDREG_1 42 P1.27 P1.28 P1.29 P0.0 P0.1 P0.10 P0.11 P2.13 43 44 45 46 47 48 49 50122PF Y2 GNDGND 3V3 R18 10K2IO&PINUART&ISPC11 22PFRTCKQ2 8050ISPR16 33KDTR Power_1 GND 1 2 3 GND1,2USB供供 2,3供电电电供供S_d 1 3 2 4P2.10 RESETQ1 8050 D6R17 33KRTSD7Diode 1N4148使使选电0下下下下,1,2;3,4一一一一电GND Diode 1N4148 GNDUSB_DVUSBC27 20pFP1.30 R19 22 R20R21 4k7C26 0.1uF J1 1 2 3 4 VBUS DD+ GND
power 1 3 2VCC 3V3 U2 C8 220uF C6 0.01uF C5 0.1uF 3 1 IN GND OUT OUT 2 4 C7 0.1uF 3V3 C9 220uF L1 10uH L3 10uH VDDA C1 0.1uF C2 1uF L2 10uH L4 10uH VREF+ C3 0.1uF C4 1uFP0.30 3V3 R26 4.7K P0.28 P0.27 R25 4.7K 8 6 5 4USB_D+P0.29 U4 VCC WP SCL A0 SDA A1 GND A2 24C02 PNP_8550 R23 GND 10k 7 1 2 3 C28 20pF22 R22 1K5REGMINA_POWER USB_DEVICEPOWER_S GND GNDVSSAVREF-GND 3V3 Q3USB_CONNECT S_USBR24 2KP2.91 2 3 GND2,3直电电电 1,2芯芯电电图 2 硬件电路原理图天下的人(红豆电子)与贞明电子协同打造 6 电子让生活更美好2.2 电源电路Power_11,2USB供供 2,3供电电电供供1 2 3VCC 3V3 power U2 1 3 2 C8 220uF C6 0.01uF C5 0.1uF 3 1 IN GND OUT OUT 2 4 C7 0.1uF 3V3 C9 220uF L1 10uH L3 10uH VDDA C1 0.1uF C2 1uF L2 10uH L4 10uH VREF+ C3 0.1uF C4 1uFREGMINA_POWERGND GNDVSSAVREF-POWER_SLPC17XX 系列微控制器在电源部分需要五种电压源对其供电, 分 别是: A、 内核和外部通路所需的 3.3V 电源 VDD(3V3) ; B、 内部稳压器所需的 3.3V 电源 VDD(REG) (3V3) ; C、 模拟部分(如片上 ADC 和 DAC)所需的 3.3V 电源; D、 模数转换器 ADC 所需的参考电源 VREFP; E、 实时时钟 RTC 所需的 3.3V 电源 VBAT; 在本设计中电源采用外部 5V 供电, 可以是 USB 取电也可以是电 源适配器供电。通过 Power_1 短路冒选择,若短路 1、2 则是 USB 取电。若短路 2、3 则是电源接口取电!电源进入目标板后首先经 过一个开关 POWER_S,控制电源的通断。然和经过 C5、C6、C8 三 个电容滤波, 输入
以获得 3.3V 电源。 LPC1768 具有独立 的模拟电源和 AD 输入参考电压,为了降低噪声和出错几率,模拟 电源和数字电源需要隔离,本设计的 L1-L4 就是将数字电源的高 频噪声和模拟电源隔离。
是 3.3V 稳压芯片输出电流高达 800mA。实时时钟 RTC 部分本部分采用纽扣电池供电,供电管脚连 接短路冒,不用时可以取掉。天下的人(红豆电子)与贞明电子协同打造 7 电子让生活更美好2.3 复位电路3V3 R7 10K C10 S1 0.1uFSW-PB GNDLPC17XX 系列微控制器拥有 4 个复位源, 分别是外部 RESET 复位, 看门狗复位,上电复位(POR)以及掉电检测复位(BOD) 。本部分 硬件电路完成上电复位和外部复位。 本设计中芯片的外部复位和上电复位由按键复位和 RC 复位电路 完成。芯片是低电平复位有效,当复位管脚上的低电平持续一定 的时钟周期就会发生芯片复位。上电时复位低电平时间由 RC 的值 决定。 手动复位时需要按下复位按键 S1, 当松开复位按键 S1 后复 位发生。 2.4 系统时钟电路天下的人(红豆电子)与贞明电子协同打造8 电子让生活更美好RX1 1C14 10PF Y1 GNDRX2 X12C13 10PF C12122PF Y2 GNDX22C11 22PFLPC17XX 包括 3 个独立的时钟源,分别为主时钟振荡器、RTC 时 钟振荡器和内部 RC 振荡器,在 LPC17XX 复位后,LPC17XX 将由内 部 RC 振荡器提供时钟直至由软件切换到另外的时钟振荡源为止, 这使得系统可以不依懒于外部时钟进行操作,而且使引导加载程 序可以在一个确定的频率下进行操作。 A、 内部 RC 振荡器 内部 RC 振荡器(IRC)可以作为看门狗的时钟源,也可以作为 时钟,驱动锁相环(PLL)提供给 CPU。IRC 的精度不足,因此不 能用于 USB 接口, 通常 IRC 频率是 4MHz, 在开机或者芯片复位时, LPC17XX 使用 IRC 作为时钟源, 之后可以通过软件切换使用其他的 时钟源。 B、 主晶振 主晶振可以用于使用或者不是用 PLL0 为 CPU 提供时钟, 其频率 范围是 1-24MHz,这个频率可以通过主 PLL(PLL0)倍频至更高的 频 率 直 到 CPU 最 大 频 率 。 通 常 把 主 晶 振 输 出 的 时 钟 称 为天下的人(红豆电子)与贞明电子协同打造 9 电子让生活更美好OSC_CLK,PLL0 输入引脚上的时钟称为 PLLCLKIN,ARM 处理器时钟 频率称为 CCLK, 当使用主晶振提供时钟并不激活 PLL 时, PLLCLKIN 和 CCLK 的值直接相等。 LPC17XX 的板上晶振可以工作在两种模式下: 从属模式 (一般使 用有源晶振的情况)和震荡模式(普通晶振) ,在从属模式下,输 入时钟信号(XTAL1 引脚)与一个 100pF 电容相连,其幅值不得少 于 200mV,XTAL2 引脚不连接。在震荡模式下,由于片内集成了反 馈电阻,所以主需要在外部连接一个晶振和电容就可以形成基本 模式震荡。本设计中使用震荡模式。 C、 RTC 晶振 RTC 晶振的频率是 32.768KHz, 一般用于给 RTC 实时时钟提供时 钟源,RTC 时钟源可以提供1Hz 给 RTC 并且可以输出 32KHz 的时 钟频率,作为 PLL0 和 CPU 或者看门狗定时器使用时钟源。 本设计中 Y1 是 RTC 时钟使用 32.768KHz 晶振, 是主晶振使用 Y2 12MHz 晶振。 2.5 JTAG 接口电路3V3 GND 3V3 3V3 R6 R5 R4 R3 R2 R1 10K 10K 10K 10K 10K 10K TRST TDI TMS TCK RTCK TDO RESET JTAG 1 3 5 7 9 11 13 15 17 19 2 4 6 8 10 12 14 16 18 20JTAGGND天下的人(红豆电子)与贞明电子协同打造10 电子让生活更美好采用 ARM 公司提出的标准 20 脚 JTAG 仿真调试接口,JTAG 信号 的定义及与 LPC1768 的连接如图。在 RTCK 引脚接一个 4.7K 的下 拉电阻,使系统复位后 LPC1768 内部 JTAG 接口使能,这样就可以 直接进行 JTAG 仿真调试了。 2.6 串口电路3V3 C21 0.1uF C22 0.1uF 1 3 4 5 U3 C1+ C1C2+ C2VCC V+ 16 C24 2 C23 0.1uF 14 RXD2 7 13 TXD2 8 GND MAX3232CSE V6 C25 0.1uF ISP P0.2 1 P0.3 2 P2.10 3 RESET 4 S_COM RXD2 1 2 3 4 5 63,5;4,6选选选电 0 1,3;2,4选选选电 20.1uF GND 3V3 COM 1 6 2 RTS 7 3 8 4 DTR 9 5 GNDP0.10 11 P0.2 10 P0.11 12 P0.3 9 1511 10TXD2D Connector 9GNDUART&ISPMax3232 是工作在 3.3V 的 RS232 电平转换芯片,内部有 2 组串 口转换电路,本设计中将 LPC1768 的串口 0 和串口 2 引出,通过 跳线帽复用一个串口头,当 S_COM 的 1、3,2、4 短路的时候选择 串口 2,3、5,4、6 短路的时候选择串口 0。在通过 RS232 串口 ISP 编程的时候必须将串口选择在串口 0 上。使用 TTL 电平通过 ISP 口进行 ISP 编程的时候没有这个限制。 由于在用串口 ISP 编程 的时候要使用到串口的 RTS 和 DTR 引脚,所以在进行串口 ISP 编 程的时候不能使用 3 线串口。必须使用支持 RTS 和 DTR 的串口。天下的人(红豆电子)与贞明电子协同打造11 电子让生活更美好2.7 按键电路R13 P2.10 10K S2 SW-PB GND INT0INT03V3 P2.11R14 10K S33V3 P2.12R15 10K S43V3SW-PBkey1SW-PB GNDkey22 1GNDINT0&KEYLPC1768 最小板上一个设有 3 个通用按键和一个复位按键, 其中 INT0 既可以做普通按键用也可以做外部中断使用。其余 2 个是普 通按键。设计上每一个按键都添加了一个 10K 的上拉电阻。 2.8 LED 显示电路3V3 3V3 R12 680 R11 680 R10 680 R9 680 D5 LED2 D1 LED2 D2 LED2 D3 LED2 D4 LED2PLEDLED_POWER LED供电电电2 1R8 680P2.0P2.1P2.2P2.3 GNDLEDPOWER_LEDLPC1768 最小板上有 4 个通用 LED 灯和一个电源指示灯,通用 LED 采用灌电流设计,并且有一个使能短路冒,当拔掉短路冒时 LED 电路断电。 2.9 EEPROM 电路3V3 R26 4.7K P0.28 P0.27 R25 4.7K 8 6 5 4U4 VCC SCL SDA GND 24C02 WP A0 A1 A2 7 1 2 3GND天下的人(红豆电子)与贞明电子协同打造12 电子让生活更美好LPC1768 支持 400K 高速模式的硬件 IIC 接口,所以设计了一片 24C02 为系统扩展一块电可擦除存储器。 用于系统保持掉电需要保 护的数据。 24C02 操作简便性能稳定, 是保存小量数据的不错选择。 为了减小总线操作功耗,总线的上拉电阻使用 4.7K。 2.10 USB 从机电路GND GND C26 0.1uF J1 1 VBUS 2 D3 D+ 4 GND
R22 1K5 GND 3V3 Q3USB_CONNECT S_USBVUSB USB_D-C27 20pFP1.30 R19 22 R20R21 4k7P0.30USB_D+P0.29 C28 20pF22USB_DEVICEPNP_k R24 2KP2.91 2 3 GND2,3直电电电为了实现 USB 数据通讯和 USB bootloader 下载程序,LPC1768 最小板板载了 USB 从机接口,此电路不但有 USB 总线的基本辅助 原件,还有一个 USB 全速配置端口,USB 主机的 D+和 D-总线是有 下拉电阻的, D+上出现上升沿时说明有一个 USB 全速设备插入, 当 当 D-上上出现上升沿时说明由一个 USB 低速设备插入。LPC1768 支持 USB 全速,因此需要在 D+上由一个 1.5K 的上拉电阻。如果 S_USB 2,3 脚短接,则 Q3 上电就导通,则无论何时接上 USB 接口 都将使 USB 主机认为有一个全速 USB 插入。如果 1,2 短接则受到 程序通过 P2.9 号管脚控制。这样可以使系统在做 USB 通讯时才让天下的人(红豆电子)与贞明电子协同打造 13 电子让生活更美好主机认为由一个 USB 全速设备插入。 2.11 LPC1768 芯片U1 TDO TDI TMS TRST TCK P0.26 P0.25 P0.24 P0.23 VDDA VSSA VREF+ VREFR7 10K C10 S1 0.1uF P1.31 P1.30 X1 X2 P0.28 P0.27 P3.26 P3.25 3V3 C15 0.1uF VDDIO_1 28 P0.29 29 P0.30 30 VSS_1 31 P1.18 P1.19 P1.20 P1.21 P1.22 P1.23 P1.24 P1.25 P1.26 32 33 34 35 36 37 38 39 40 20 21 22 23 24 25 26 27 1 2 3 4 5 6 7 8 9 TDO/SWO TDI TMS/SWDIO TRST TCK/SWDCLK P0.26/AD0.3/AOUT/RXD3 P0.25/AD0.2/I2SRX_SDA/TXD3 P0.24/AD0.1/I2SRX_WS/CAP3.1 P0.23/AD0.0/I2SRX_CLK/CAP3.0 VDDA VSSA VREF+ NC RSTOUT VREFRTCX1 RESET RTCX2 VBAT P1.31/SCK1/AD0.5 P1.30/VBUS/AD0.4 XTAL1 XTAL2 P0.28/SCL0/USB_SCL P0.27/SDA0/USB_SDA P3.26/STCLK/MAT0.1/PWM1.3 P3.25/MAT0.0/PWM1.2 VDDIO_1 P0.29/USB_D+ P0.30/USB_DVSS_1 P1.18/USB_UP_LED/PWM1.1/CAP1.0 P1.19/MC0A/USB_PPWR/CAP1.1 P1.20/MCFB0/PWM1.2/SCK0 P1.21/MCABORT/PWM1.3/SSEL0 P1.22/MC0B/USB_PWRD/MAT1.0 P1.23/MCFB1/PWM1.4/MISO0 P1.24/MCFB2/PWM1.5/MOSI0 P1.25/MC1A/MAT1.1 P1.26/MC1B/PWM1.6/CAP0.0 VSS_2 VDDREG_1 P1.27/CLKOUT/USB_OVRCR/CAP0.1 P1.28/MC2A1.0/MAT0.0 P1.29/MC2B/PCAP1.1/MAT0.1 P0.0/RD1/TXD3/SDA1 P0.1/TD1/RXD3/SCL1 P0.10/TXD2/SDA2/MAT3.0 P0.11/RXD2/SCL2/MAT3.0 P2.13/EINT3/I2STX_SDA LPC.12/EINT2/I2STX_WS P2.11/EINT1/I2STX_CLK P2.10/EINT0/NMI VDDIO_2 VSS_3 P0.22/RTS1/TD1 P0.21/RI1/RD1 P0.20/DTR1/SCL1 P0.19/DSR1/SDA1 P0.18/DCD1/MOSI0/MOSI P0.17/CTS1/MISO0/MISO P0.15/TXD1/SCK0/SCK P0.16/RXD1/SSEL0/SSEL P2.9/USB_CONNECT/RXD2 P2.8/TD2/TXD2 P2.7/RD2/RTS1 P2.6/PCAP1.0/RI1/TRACECLK P2.5/PWM1.6/DTR1/TRACEDATA0 P2.4/PWM1.5/DSR1/TRACEDATA1 P2.3/PWM1.4/DCD1/TRACEDATA2 VDDIO_3 VSS_4 P2.2/PWM1.3/CTS1/TRACEDATA3 P2.1/PWM1.2/RXD1 P2.0/PWM1.1/TXD1 P0.9/I2STX_SDA/MOSI1/MAT2.3 P0.8/I2STX_WS/MISO1/MAT2.2 P0.7/I2STX_CLK/SCK1/MAT2.1 P0.6/I2SRX_SDA/SSEL1/MAT2.0 P0.5/I2SRX_WS/TD2/CAP2 P0.4/I2SRX_CLK/RD2/CAP2.0 P4.28/RX_MCLK/MAT2.0/TXD3 VSS_6 VDDREG_2 P4.29/TX_MCLK/MAT2.1/RXD3 P1.17/ENET_MDIO P1.16/ENET_MDC P1.15/ENET_REF_CLK P1.14/ENET_RX_ER P1.10/ENET_RXD1 P1.9/ENET_RXD0 P1.8/ENET_CRS P1.4/ENET_TX_EN P1.1/ENET_TXD1 P1.0/ENET_TXD0 VDDIO_4 VSS_5 P0.3/RXD0/AD0.6 P0.2/TXD0/AD0.7 RTCK 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 99 98 100 P2.12 P2.11 P2.10 VDDIO_2 VSS_3 P0.22 P0.21 P0.20 P0.19 P0.18 P0.17 P0.15 P0.16 P2.9 P2.8 P2.7 P2.6 P2.5 P2.4 P2.3 VDDIO_3 VSS_4 P2.2 P2.1 P2.0 P0.9 P0.8 P0.7 P0.6 P0.5 P0.4 P4.28 VSS_6 VDDREG_2 P4.29 P1.17 P1.16 P1.15 P1.14 P1.10 P1.9 P1.8 P1.4 P1.1 P1.0 VDDIO_4 VSS_5 P0.3 P0.2 GND RTCK 3V33V3 C20 0.1uF供电供电电电P_BATT 1 2 BT1GNDBattery3V3VDDA 10 VSSA 11 VREF+ 12 13 RSTOUT 14 VREF- 15 RX1 16 RESET 17 RX2 18 VBAT 193V3 C19 0.1uFSW-PB GNDGNDGNDGNDC18 0.1uFGNDC16 0.1uF 3V3VSS_2 41 VDDREG_1 42 P1.27 P1.28 P1.29 P0.0 P0.1 P0.10 P0.11 P2.13 43 44 45 46 47 48 49 503V3 C17 0.1uFLPC1768上图就是 LPC1768 芯片管脚连接图,在每一对 VDD 和 VSS 之间 都有一个 0.1uF 的去耦电容,以保证芯片正常稳定工作。天下的人(红豆电子)与贞明电子协同打造14 电子让生活更美好第三部分 编译环境和程序下载 3.1 编译环境 LPC1768 的编译环境主要有 keil 或称 MDK 和 IAR,目前最新版 本 4.12(这里说的 keil 是指 keil 的 ARM 版本,不是指 keil 的 51 版本) 。这两个编译软件都是比较有名的编译器,其中用过 51 的人不会不知道 keil,当然 IAR 也是一个强大的编译器, 有良好的 C++支持能力。一般入门我们选择 keil,因为 keil 操作简单使用 方便。下面就介绍一下如何通过 keil 创建一个 LPC1768 的工程。 Keil 软件可以在官方网站上下载到限制版,当然你不喜欢限制版 那就找个国内的破解软件吧! Google 一下就出来了。 然后安装 keil 软件,一般 keil 被安装在 C:\keil 路径下,不要改变其默认路径 否则有可能出现编译头文件找不到路径的可能。安装好 keil 后会在桌面上出现快捷方式如图所示:。双击快捷方式将打开keil 软件,如下图所示,一般打开后显示上次关闭时的工程。新建工程步骤:天下的人(红豆电子)与贞明电子协同打造 15 电子让生活更美好A、点击 Project 菜单下的 New uVision Project。如图:B、出现保存工程的界面,保存到我们想要保存的路径下,文件 名即为本工程名, 注意工程文件众多建议新建一个空文件夹保存。C、选择芯片,在 NXP 列表下选择 LPC1768 芯片。然后点击 OK。 接下来出现的对话框选择“是” ;天下的人(红豆电子)与贞明电子协同打造16 电子让生活更美好D、到现在一个工程就创建好了:E、下面新建一个文件,点击 F、然后点击保存或者 File 菜单下的 New。,出现保存对话款,输入文件名以.c 为后17天下的人(红豆电子)与贞明电子协同打造 电子让生活更美好缀名。G、 接下来右键点击左侧 Target1 下的 Source Group1 的下拉菜 单的 Add File to Group…将我们刚刚新建的文件添加到工程。F、出现添加对话框后选择新建的文件或已有的 C 程序源文件, 然后点击 Add,点击 Add 后就可以点击 Add 下面的 Close 了。天下的人(红豆电子)与贞明电子协同打造18 电子让生活更美好接下来就可以编写程序了。编写好程序,点击编译 不过要想生成 hex 文件还要点击,配置工程 output。 Create 将HEX File 前方框打钩,然后点击 OK。这样工程在编译的时候就会自动生成 HEX 文件了。如果需要使 用 jlink 在 keil 环境下调试和下载程序,需要在 Debug 菜单下选 择 Use Cortex-M3 J-LINK 然后点击 Seting。 seting 下的 debug 在 菜单下的 Prot 选择 SW,MAX Clock 选择 3M,在 flash download 页面下点击 ADD,选择合适的型号和容量,点 OK 后到 Utilities天下的人(红豆电子)与贞明电子协同打造 19 电子让生活更美好菜单下选择 Use Cortex-M3 J-LINK。天下的人(红豆电子)与贞明电子协同打造20 电子让生活更美好接下来我们就可以使用下载程序和使用调试了。到此关于 keil 建立工程就介绍完了。 3.2 使用 JLINK 下载 Jlink 是调试 ARM 的一个很好的工具, 因其支持 ARM 家族, 同时 也支持 KEIL 和 IAR 等 IDE 环境,所以受到大多数的开发工程人员 的喜爱。上文介绍的基于 keil 的下载和调试就是基于 jlink 仿真 器的。Jlink 是 SEGGER 公司研制的,要使用 jlink 当然要安装该 公司推出的配套软件了。软件可以在官方网站上下载到。下面我 们将介绍如何用 jlink 官方提供的软件进行程序下载和读出。首先安装 JLinkARM,然后双击打开软件,打开后如图所示:使用之前要设置好目标芯片型号和通讯方式等参数,点击 下的 Project settings ,在弹出的对话框中点击 Target Interface 选择 SWD 和 Auto selection,然后选择 CPU 页面,在天下的人(红豆电子)与贞明电子协同打造 21 电子让生活更美好Device 中选择 LPC1768,然后确定。然后选择 File 下的 Open 打 开生成 HEX 文件,点击 Target 菜单下的 Auto 就可以了。呵呵, 这是最简单的方法,关于 MCU 编程、擦除、读出都在 Target 里实 现。只要认识英文就知道怎么操作了,不认识可以 Google。关于 jlink 烧写软件的介绍就到这里。 3.3 使用 NXP 公司提供的 ISP 软件下载程序 对于学生而言使用 NXP 公司的 ISP 软件下载无疑是最节省成本 的,只需要一个串口或者 USB 转串口。但是对于开发人员大多数 时候需要调试程序,建议还是用仿真器。使用之前要准备一条串 口线,RS232 或者 TTL 的都可以,但是要支持 RTS 和 DTR,不能使 用最简单的三线串口,硬件连接如果是 RS232 直接插上目标板就 可以了,如果是 TTL 那就是 DTR 控制复位,RTS 控制 ISP 管脚。打 开 Flash Magic 后如图所示:点击选择芯片, 点击天下的人(红豆电子)与贞明电子协同打造选择串22 电子让生活更美好口,选择波特率,一般波特率选择太低就会很慢,建议选择稍微高一点。在芯片擦除前面打钩 ,然后加载 hex 文件:在校验后编程前的方框打钩,然后点击开始。接下来就是等待编程结束了。 NXP 公司的 ISP 软件就介绍到这里, 在选型的时候可能你会注意 到支持众多 NXP 的芯片!天下的人(红豆电子)与贞明电子协同打造23 电子让生活更美好第四章 第四章 芯片编程介绍 4.1 系统文件介绍 在写程序的时候有一些东西是编译器自带的一些文件,比如芯 片的头文件,再比如汇编的启动代码,在 LPC17XX 里还有一个系 统初始化文件。在我们的工程里主要有 3 个头文件,2 个 C 文件, 1 个.S 文件。 分别是: LPC17xx.h 、 core_cm3.h、 system_LPC17xx.h; core_cm3.c 、 system_LPC17xx.c ; startup_LPC17xx.s ; 其 中 startup_LPC17xx.s 是 系 统 自 动 加 载 的 ARM 启 动 汇 编 代 码 。 LPC17XX.h 是芯片的头文件, 定义的是芯片寄存器的结构体。 有时 候有些寄存器和手册上写法有细微的区别,打开看一下就可以了 哈,需要注意的是 keil 在头文件里关于寄存器的定义都是以结构 体的方式定义的,所以我们在写程序的时候访问寄存器也要以寄 存器方式访问,比如在 GPIO 的操作的时候由一个名叫“FIODIR” 的方向寄存器,是一个 32 位的寄存器,对应一个 IO 口的 32 位, 如果某位为 1 则对应的管脚为输出模式,因此在访问的时候写法 如下: LPC_GPIO1-&FIODIR=0x000000 GPIO1 表示 P1 口,GPIO2 表示 P2 口,上面这行代码表示 P1 口 的低 8 位为输出模式。由于 keil 版本的原因可能有些版本定义结 构体的时候没有 LPC_这个部分使得访问 GPIO1 的写法如下: GPIO1-&FIODIR=0x000000 关于这个的确认可以打开 LPC17XX.h 看一下就知道了。还有一天下的人(红豆电子)与贞明电子协同打造 24 电子让生活更美好点需要注意的是在 keil 的头文件里定义寄存器是以 32 位的方式 定义的,所以不能使用手册中说明的字,半字的访问方式只能使 用 32 位的访问方式即:上图所示的 FIOxDIR0 是不能用的, 要访问端口 x 需要使用结构 体 方 式 , LPC_GPIOx-&FIODIR=0x; 不 能 写 成 FIOxDIR0=0x00; core_cm3.c、 core_cm3.h 分别是 ARM M3 外围驱动源代码和头文 件,在使用的过程中不需要修改什么,有兴趣的可以关注一下这 些代码的注释就知道这些代码是用来干什么的了。 system_LPC17xx.h、system_LPC17xx.c 这两个文件是与编程有非 常密切关系的文件。从名字上就可以知道是关于系统的文件,这 两个文件为我们提供了一个系统初始化函数,SystemInit();默认 使用外部晶振,外部晶振是 12MHz,使用 PLL0 倍频,LPC1700 的 系统初始化包括时钟配置、电源管理、功耗管理等。其中比较复 杂的是时钟配置,由于有 2 个 PLL,一个是主 PLL0,可以为系统 和 USB 提供时钟,一个是 PLL1 专门为 USB 提供 48M 时钟,可以不 使用。由于 LPC1700 的时钟灵活性较大,也使得配置时钟的过程 稍微复杂一些。但是我们的系统文件都将这些做好了,我们要修天下的人(红豆电子)与贞明电子协同打造 25 电子让生活更美好改时钟频率或者其他参数只需要修改对应的宏定义即可。另外该 文件还做了比较详尽的注释,只要潜心阅读没有太大难度的。在 LPC17xx.h 里有 core_cm3.h 和 system_LPC17xx.h 的调用, 因此我 们不需要在主函数里再次调用。如下面叙述一下关于 keil 文件调用的一些方法; 在单片机的使用过程中一般程序都不会很大,需要调用的文件 比较少,我曾经把所有的程序放在一个“.c”文件里,这样在程 序不大的时候比较方便,但是这样不便于代码的重用也不便于代 码的管理,况且一旦代码量一大,查阅起来相当的不便。因此需 要把一些功能独立的代码分立出去,这样就有了功能独立的“.h” 和“.c”文件。在使用的时候比较普遍的做法是将源代码放在一 个工程文件夹里的一个专门的文件夹,当然这个文件夹里还可以 再有文件夹比如头文件的文件夹和源代码的文件夹或者是功能不 同的代码的文件夹,我觉得无论如何至少应该将代码放在工程文 件夹里的独立文件夹里,不应该直接放在工程文件夹里。一个功 能独立的源代码通常由一个.h 文件和一个.c 文件构成。 他们的文 件名是一样的如 UART 的功能源代码可以是:UART.h”“UART.c” “ 和 , 在主函数的调用时一般是写成#include”UART.h”;然后将 UART.c 添加到工程,这样在主函数中就可以使用添加的代码了。当然也 可以直接将.h 和.c 文件都包含进来, 也是可以在主函数中使用的。天下的人(红豆电子)与贞明电子协同打造 26 电子让生活更美好在 ARM 编程的工程中一般文件都比较多,最好由一个层次和清晰 的结构,避免影响阅读和使用。具体详尽的说明可以阅读 keil 的 帮助和说明文档。4.2 LPC17xx 的基本使用介绍 在 LPC17xx 的编程过程中最基本的要注意的有两方面,一方面 是系统配置,另一方面是外围基础配置。系统配置包括系统时钟, 功耗管理,睡眠模式等等。外围的基础配置包括所使用模块的功 耗管理 (LPC17xx 出于降低总功耗的原因对每一个外设都有一个使 能方式的功耗管理,默认复位后有一些外设是默认开启的有一些 是默认关闭的,具体参见手册的第四章计时和功率控制的 4.8.9 外设功率控制寄存器 PCONP) 、时钟配置(外设时钟选择参见第 4 章计时和功率控制的 4.7.4 节外设时钟选择寄存器 PCLKSEL0 和 PCLKSEL1 的对应位) 管脚配置 、 (由于每一个管脚有多种功能因此 有专门的寄存器参见第 8 章引脚连接模块)等。 关于系统初始化: 关于系统初始化 在前面的介绍中我们知道 LPC17xx 只要有 3 个时钟源,分别是 内部 RC 振荡器、主晶振(1-24M) 、RTC 晶振,主晶振、RTC、内部 RC 都可以来驱动 PLL0 从而给 CPU 和片内外设提供时钟,当 PLL0 未连接时系统才可以安全的切换时钟源。时钟源的选择需要配置 时钟选择寄存器: 时钟源选择寄存器 (CLKSRCSEL,0x400FC10C)天下的人(红豆电子)与贞明电子协同打造 27 电子让生活更美好锁相环 PLL0 PLL0 接受输入的时钟范围是 32KHz-50MHz。 时钟源由 CLKSRCSEL 寄存器选择,输入频率可以倍频到一个较高的频率上,之后可以 通过分频为 CPU、 外设以及可选的 USB 子系统提供精确的时钟。 值 得注意的是 USB 子系统又有自己专用的 PLL。PLL0 可以产生最高 至 CPU 允许的最大 100M 的频率。 PLL0 的输入频率通过一个预分频器分频成为 PLL 内部频率,预 分频的值用变量 N 表示,范围 1-256 之间,然后通过一个电流控 制振荡器(CCO)倍频到范围 275-550M 之间,倍频器的值用 M 表 示,CCO 频率在通过 CPU 频率设置寄存器分频成为提供给 CPU 的 CCLK 时钟。 PPL 的使能是由 PLL0CON 寄存器控制,PLL0 倍频器和分频器的 值都是由 PLL0CFG 寄存器控制。为了防止 PLL0 参数发生意外改变 或 PLL0 失效,对这两个寄存器进行了保护。当 PLL0 提供芯片时 钟时,由于芯片的所有操作,包括看门狗定时器在内都依赖于它, 因此 PLL0 的设置的意外改变将导致 CPU 执行不期望的操作。 在芯片复位或者进入掉电模式后, PLL0 将被关闭或者屏蔽, PLL0 必须有软件配置、使能连接到系统中。PLL0 接口框图如图所示:天下的人(红豆电子)与贞明电子协同打造 28 电子让生活更美好下面描述 PLL0 涉及的寄存器及其功能描述 4.2.1 4.2.1、PLL0 控制寄存器 PLL0CON PLL0CO 寄存器可以用于使能和连接 PLL0、使能 PLL0 锁定到当 前倍频器和分配器值设定的频率上, 连接 PLL0 将使处理器和大多 数片内功能都根据 PLL0 的输出来工作。 PLL0CON 的更改只有在 对 对 PLL0CON 寄存器执行了正确的 PLL 馈送序列后才生效。PLL0 在作为时钟源之前必须进行设置使能并锁定。将振荡器时 钟切换到 PLL0 输出或者翻转过来,操作时,内部电路对操作进行 同步以确保不会产生干扰,硬件不能保证 PLL 在连接之前锁定或 在 PLL0 失去锁定时自动断开连接,在 PLL0 失去锁定的情况下、 振荡器很可能已近变得不稳定,这样即使断开 PLL0 页挽救不了这 种情况。 4.2.2 PLL0CFG 4.2.2、PLL0 配置寄存器 PLL0CFG PLL0CFG 是最新的 PLL0 配置值的保持寄存器,包含 PLL 倍频器天下的人(红豆电子)与贞明电子协同打造 29 电子让生活更美好和分配器的值,在执行正确的 PLL0 馈送序列之前改变 PLL0CFG 寄 存器的值不会生效。4.2.3 4.2.3、PLL0 状态寄存器 PLL0STAT PLL0STAT 为只读寄存器, 它是 PLL0 控制和配置信息的读回寄存 器,反映了正在使用真实 PLL0 的参数和状态。PLL0STAT 可能和 PLL0CON 和 PLL0CFG 中的值不同,这是因为没有正确的 PLL0 馈送 序列,这两个寄存器中的值并未生效。PLL0STAT 寄存器中的 PLOCK0 位连接到中断控制器, 这样可以使 用软件打开 PLL0,并连接到其他功能、不需要等待 PLL0 锁定。当 发生中断时(PLOCK0=1)可以连接 PLL0 并禁止中断,只能通过禁 止 PLL0 中断的方式返回。 PLL0 有 3 中可能的工作方式,由 PLLE0 和 PLLC0 位组合获得:天下的人(红豆电子)与贞明电子协同打造30 电子让生活更美好4.2.4 4.2.4、PLL0 馈送寄存器 PLL0FEED 必须将正确的馈送序列写入 PLL0FEED 寄存器才能使 PLL0CON 和 PLL0CFG 寄存器的更改生效,馈送序列如下: 将值 0xAA 写入 PLL0FEED 将值 0x55 写入 PLL0FEED 这两个写操作的顺序必须正确,而且在两次操作之间不需没有 其他的寄存器访问相同的地址空间,这就意味着尽量在执行 PLL0 馈送操作的时候禁止中断,不管写入的值不正确还是没有满足前 两个条件、对 PLL0CON 或者 PLL0CFG 寄存器的更改都不会生效。 4.2.5 4.2.5、PLL0 和掉电模式 掉电模式会自动关闭并断开 PLL0,从掉电模式唤醒不会自动的 恢复 PLL0 的设置,PLL0 的恢复必须由软件来完成。 4.2.6 4.2.6、PLL0 频率的计算当 LPC17xx 微处理器系统需要使用 PLL0 时, 应当按照一下原则 进行计算配置。天下的人(红豆电子)与贞明电子协同打造 31 电子让生活更美好确定应用是否需要 USB 口, 并且 USB 是否由 PLL0 提供时钟, USB 需要一个准确的 50%占空比 48M 的时钟信号,这就意味着 FCCO 必 须是 48M 的整倍数(96M)并且 FCC0 要相当准确; 确定处理器的时钟频率 CCLK,这可以根据对处理器的整体要求 来确定,外围器件的时钟频率可以低于处理器的频率。 选择 PLL 输入频率 FIN 的值; 计算 M 和 N 的值,以产生一个有效且精确的 FCCO 的频率。 PLL0 的输出频率公式为:FCCO=(2*M*FIN)/N 例如:系统不需要 USB 口,目标 CPU 的速度为 72M,32.768K 的 RTC 时钟作为系统的时钟源,M=(FCCO*N)/(2*FIN),可以产生 CPU 需 求频率并且 PLL0 可以正常操作范围内的最小 FCCO 频率是 288M (4*72M) 。由 N=1 开始计算,所以 M=288*10^6/(2*3.53. 计算所得不是一个整数,所以 CPU 的频率不是精确的 288M。 接下来介绍系统的初始化函数,System_LPC17xx.c 文件中的 void SystemInit (void)函数将繁琐的系统初始化工作都做好了,如果我们 还有一些特殊的要求可以直接修改该函数,就可以得到想要的设置。 函数源代码如下:void SystemInit (void) { #if (CLOCK_SETUP) /* Clock Setup 时钟配置 */ LPC_SC-&SCS = SCS_V if (SCS_Val & (1 && 5)) { /* If Main Oscillator is enabled 如果主振荡器使能 */ while ((LPC_SC-&SCS & (1&&6)) == 0); /* Wait for Oscillator to be ready 等待准备 */ } LPC_SC-&CCLKCFG = CCLKCFG_V /* Setup Clock Divider 时钟天下的人(红豆电子)与贞明电子协同打造 32 电子让生活更美好分频 */ #if (PLL0_SETUP) LPC_SC-&CLKSRCSEL = CLKSRCSEL_V /* Select Clock Source for PLL0 为 PLL0 选择时钟源 LPC_SC-&PLL0CFG = PLL0CFG_V /* configure PLL0 配置 PPL0 */ LPC_SC-&PLL0FEED = 0xAA; LPC_SC-&PLL0FEED = 0x55; LPC_SC-&PLL0CON = 0x01; /* PLL0 Enable PLL 使能 */ LPC_SC-&PLL0FEED = 0xAA; LPC_SC-&PLL0FEED = 0x55; while (!(LPC_SC-&PLL0STAT & (1&&26))); /* Wait for PLOCK0 */ LPC_SC-&PLL0CON = 0x03; /* PLL0 Enable & Connect PLL0 使能和连接 */ LPC_SC-&PLL0FEED = 0xAA; LPC_SC-&PLL0FEED = 0x55; while (!(LPC_SC-&PLL0STAT & ((1&&25) | (1&&24)))); /* Wait for PLLC0_STAT & PLLE0_STAT */ #endif #if (PLL1_SETUP) LPC_SC-&PLL1CFG = PLL1CFG_V LPC_SC-&PLL1FEED = 0xAA; LPC_SC-&PLL1FEED = 0x55; LPC_SC-&PLL1CON = 0x01; /* PLL1 Enable */ LPC_SC-&PLL1FEED = 0xAA; LPC_SC-&PLL1FEED = 0x55; while (!(LPC_SC-&PLL1STAT & (1&&10))); /* Wait for PLOCK1 */ LPC_SC-&PLL1CON = 0x03; /* PLL1 Enable & Connect */ LPC_SC-&PLL1FEED = 0xAA; LPC_SC-&PLL1FEED = 0x55; while (!(LPC_SC-&PLL1STAT & ((1&& 9) | (1&& 8)))); /* Wait for PLLC1_STAT & PLLE1_STAT */ #else LPC_SC-&USBCLKCFG = USBCLKCFG_V /* Setup USB Clock Divider */ #endif LPC_SC-&PCLKSEL0 = PCLKSEL0_V /* Peripheral Clock Selection */ LPC_SC-&PCLKSEL1 = PCLKSEL1_V天下的人(红豆电子)与贞明电子协同打造*/33 电子让生活更美好LPC_SC-&PCONP = PCONP_V /* Power Control for Peripherals */ LPC_SC-&CLKOUTCFG = CLKOUTCFG_V /* Clock Output Configuration */ #endif #if (FLASH_SETUP == 1) /* Flash Accelerator Setup */ LPC_SC-&FLASHCFG = FLASHCFG_V #endif }从代码和注释可以看出,这个函数完成了对时钟的配置、系统 功耗 PCONP、时钟输出、flash 加速等系统资源配置。如果需要修 改该文件内还有详细的修改方法说明。对于没有特殊要求的应用 完全可以直接使用该函数不需修改对系统进行初始化。 初始化系统介绍完了,下面介绍功耗管理、外围时钟配置和管 脚分配。 外设功率控制 外设的功率控制特性允许在应用中关闭不需要的外设,从而节 省额外的功耗。涉及的寄存器是 PCONP。 外设功率控制寄存器 PCONP-0x400FC0C4 可通过 PCONP 寄存器关闭特定外设模块的时钟源来关闭外设, 以实现节电的目的。有少数外设功能不能被关闭(如看门狗定时 器、引脚连接模块和系统控制模块) 。 某些外设(特别是那些含有模拟功能的外设)的功耗可能与时 钟无关。这些外设有独立的禁止控制,可以关闭其电路来减少功 耗。有关外设特定的节省功耗的信息,请参考描述该外设的相关 章节。PCONP 中的每个位都控制一个外设,如表 4.33 所示。天下的人(红豆电子)与贞明电子协同打造 34 电子让生活更美好如果外设控制位为 1,则外设被使能。如果外设控制位为 0,则 外设的时钟被禁止,以节省功耗。例如,如果 19 为 1,则 IIC1 接口使能。如果 19 位为 0,则 IIC1 接口禁止。 注:仅当外设在 PCONP 寄存器中使能时,才能够从外设寄存器 中有效读取和有效写入外设寄存器。 (在初始化一个外设模块时应 当首先设置相关的功率控制寄存器)天下的人(红豆电子)与贞明电子协同打造35 电子让生活更美好外设时钟控制 外设时钟控制涉及的寄存器有 2 个外设时钟选择寄存器。在复 位后寄存器是全 0,则对应的功能是所有外设时钟是系统时钟的 1/4,在一些应用中我们不需要配置时钟速度,但是有些应用如使 用定时器定时的时候我们需要准确的知道时钟周期或者需要较高 的时钟信号,这就需要配置这个寄存器。 外 设 时 钟 选 择 寄 存 器 0 和 1 ( PCLKSEL0-0x400fc1a8 和 PCLKSEL1-0x400fc1ac) 在外设时钟选择寄存器中,每组位控制了提供给对应外设的时 钟信号的速率。 注:RTC 模块的外设时钟固定为 CCLK/8.天下的人(红豆电子)与贞明电子协同打造36 电子让生活更美好外设时钟选择寄存器 1:从下面这个表格可以看出,每个外设对应的寄存器位如果是 00天下的人(红豆电子)与贞明电子协同打造 37 电子让生活更美好则表示对应的外设的时钟是 CCLK 的 1/4,01 则时钟是 CCLK 等。管脚输出配置: 引脚连接模块使得微控制器的大部分引脚具有 1 个以上的功能。 配置寄存器控制多路开关以实现引脚与片内外设之间的连接。 外设应优先连接到适当的引脚,再激活,需要的话使能相关中 断。任何一个没有映射到相关功能引脚的使能外设,都将被认为 是未定义的。 当选择了引脚上的一个功能时,该引脚上其它可用功能无效。 涉及的寄存器有:PINSEL0-PINSEL10; PINSEL 寄存器控制器件引脚的功能,如表 8.2 所示。这些寄存 器的每一组位对应着特定的器件引脚功能。仅当引脚选择 GPIO 功能时,GPIO 寄存器中的方向控制位才有 效。对于其它功能来说,方向是自动控制的。每个外围器件通常 有不同的引脚配置,因此每个引脚可能有不同的功能组合。 引脚模式选择寄存器 PINMODE 寄存器控制所有端口的工作模式。这包括使用片内上天下的人(红豆电子)与贞明电子协同打造 38 电子让生活更美好拉/下拉电阻的特性和特定的开漏操作模式。除过用于 IIC0 接口 的 IIC 引脚和 USB 引脚。不管该引脚选择用作何种功能,都可以 为每一个端口引脚选择片内上拉/下拉电阻。使用三个位来控制端 口引脚的模式,其中二个位位于 PINMODE 寄存器中,另一个位于 PINMODE_OD 寄存器中。在 PINSEL 寄存器中未使用的引脚看作为 保留位。当引脚处于逻辑高电平时,中继模式使能上拉电阻;当引脚处 于逻辑低电平时,使能下拉电阻。当引脚配置为输入且不是通过 外部驱动时,引脚将保持上一个已知状态。 PINMODE_OD 寄存器 控制端口的开漏模式。当引脚被配置为输出且值为 0 时,开漏模 式会正常地将引脚电平拉低。但是,如果输出引脚值为 1,则引 脚的输出驱动关闭,等同于改变了引脚的方向。这样的组合就模 拟了一个开漏输出。寄存器描述 引脚控制模块包含 11 个寄存器, 如表 8.5 所示。 在外部复位、 看门狗复位、上电复位(POR)和掉电检测复位(BOD)发生时, 该模块中的所有寄存器均复位为“0” 。天下的人(红豆电子)与贞明电子协同打造 39 电子让生活更美好引脚功能选择寄存器 0(PINSEL0 - 0x) PINSEL0 寄存器控制端口 0 低半部分的位功能。 仅当引脚选择 使用 GPIO 功能时,FIO0DIR 寄存器中的方向控制位才有效。对于 其它功能来说,方向是自动控制的。 对于 100 引脚封装,引脚 功能选择寄存器 0 的位功能描述如下表所述。天下的人(红豆电子)与贞明电子协同打造40 电子让生活更美好注:该部分的其它寄存器也类似引脚功能选择寄存器 0,在这 里就不一一列举了,需要详细的了解需参考英文技术手册或 ZLG 的中文技术手册的第 8 章引脚连接模块。 在使用一个片内外设的时候不但需要配置片内外设的寄存器, 还应该首先配置功耗控制、时钟选择和管脚配置,需要说明的是 在使用片内外设的时候应该首先配置功耗控制。天下的人(红豆电子)与贞明电子协同打造41 电子让生活更美好第五章 第五章 实例详解 本章将详细介绍立足于本设计的最小系统板的实例编程。在这里从 最简单的编程开始,尽量拥有详尽的注释,尽量做到功能结构完整, 言辞尽量准确无误。 5.1 实验 1―4LED 跑马灯 1 本实验使用连接在 P2 口上的 4 个 LED 灯实现跑马灯的效果。 由于 LED 是采用管电流方式设计的, 所以当 P2.0 输出低电平时第一个 LED 灯亮。 本实验设计的编程有系统初始化、通用 IO 口的初始化、系统软延时和 通用 IO 口的输出等。 首先如第 3 章所述建立一个工程并且设置好工程。在 Project 里面 新建一个组,命名为 Source(本实验的所有代码、包括头文件都放在 这里) ,新建一个 main.c 文件,添加进 Source 组。在 main.c 中添加 如下代码:#include &lpc17xx.h& // 包含头文件, 头文件内保护系统初始化头文件 void delay(void) //软延时函数,大工程中不建议使用,占用系统资源, { //M3 有系统节拍定时器,可以达到效果 uint32_ for(j = 3000000; j & 0; j--); } int main(void) { uint32_t i=0; //定义变量 SystemInit(); //系统初始化函数 LPC_SC-&PCONP|=(1&&15); //功耗控制,此处可以注释掉,因为复位后 GPIO 默认开启 LPC_GPIO2-&FIODIR=0x0000000F; //FIODIR 设置端口的输入输出 LPC_GPIO2-&FIOSET=0x0000000F; //GPIO 置位,当某位为 1 则置位,为 0 不变 while(1) {天下的人(红豆电子)与贞明电子协同打造 42 电子让生活更美好for(i = 0; i & 4; i++) { LPC_GPIO2-&FIOCLR = 1 && //GPIO 清零,为 1 清零,为 0 不变 delay(); } LPC_GPIO2-&FIOSET=0x0000000F; delay(); } }配置 keil 工程的选项,选择生成 HEX,配置仿真器 jlink。 在 Source 组里添加 system_LPC17xx.c 和 core_cm3.c(由于系统初 始 化 函 数 在 system_LPC17xx.c 中 定 义 , 要 调 用 该 函 数 则 要 访 问 system_LPC17xx.c,访问方式有 2 中一是工程中调用该文件对应的.h 文件然后在工程中添加.c 文件, 二是在工程中将.h 和.c 文件都调用) 。 编译,没有错误,下载到目标板上,可以看出 4 个 LED 灯依次被点亮, 然后熄灭,然后接着被依次点亮,循环。在程序中所偶寄存器的访问 都是基于结构体的,如 FIODIR 是 GPIO 的输入输出配置寄存器,访问 的 时 候 要 按 结 构 体 方 式 访 问 , 若 要 访 问 P1 口 则 有 LPC_GPIO1-&FIODIR=0x;由于 PCONP 在 LPC_SC 结构体定义的 所以访问时需要 LPC_SC-&PCONP;结构体的定义都是按照功能定义在 LPC17xx.h 里的,不明白的查看一下。 注:需要将 LED 闪烁改成一个 LED 依次点亮,可以将: LPC_GPIO2-&FIOCLR = 1 && 修改成: LPC_GPIO2-&FIOPIN =~( 1 && i); 下面介绍一下通用 GPIO 的有关寄存器和中断寄存器映射表:天下的人(红豆电子)与贞明电子协同打造 43 电子让生活更美好中断寄存器映射表:5.2 实验 2―4LED 跑马灯 2 通过上面一个实例我们很好的认识了 GPIO 的基本寄存器配置, 若需天下的人(红豆电子)与贞明电子协同打造 44 电子让生活更美好要从 GPIO 端口读入数据, 只需要将 FIODIR 配置成输入, 然和读 FIOPIN 即可。上一个实验使用的是软件延时的方法实现闪烁 LED 等的效果, 在需要定时的应用中,除非微小延时,一般不用软件延时,原因有 2 点,一是不准确,二是占用系统资源。所以下面介绍的一个 LED 实验 是使用 ARM Cortex-M3 内核带的一个系统节拍定时器的功能,实现延 时的目的。 系统节拍定时器,配置简单,使用方便,专为系统软件或系统管理 软件提供间隔中断。系统节拍定时器的时钟源可以是内核时钟,也可 以是 P3.26 选择 STCLK 功能提供的时钟。系统节拍定时器是一个 24 位 定时器,当计数值达到 0 时产生中断。系统节拍定时器的作用是为下 一次中断前提供一个固定时间间隔。由于定时器是 24 位的,在使用的 时候要注意定时长度的限制,不能超过界限。 系统节拍定时器的初始化函数在 core_cm3.h 里已经为我们写好。static __INLINE uint32_t SysTick_Config(uint32_t ticks) { if (ticks & SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ SysTick-&LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1&&__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ SysTick-&VAL = 0; /* Load the SysTick Counter Value */ SysTick-&CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_M /* Enable SysTick IRQ and SysTick Timer */ return (0); /* Function successful */ }天下的人(红豆电子)与贞明电子协同打造 45 电子让生活更美好主函数代码如下: #include &lpc17xx.h& // 包含头文件, 头文件内保护系统初始化头文件 //***************************************************** uint32_t msTicks,sign=0; //变量定义 //***************************************************** void SysTick_Handler(void) //系统节拍定时器中断函数 { msTicks++; //简单的定时++ 运算 if(msTicks==300) //定时满 500 次 一次 1ms 即 500ms 置位标志位 { sign=1; //标志位置位 msTicks=0; //定时变量 清零 } } int main(void) { uint32_t i=0; //定义变量 SystemInit(); //系统初始化函数 if (SysTick_Config(SystemCoreClock / 1000)) //系统节拍定时器初始化 函数在 core_cm3.h 里 { //设置节拍定时器 1ms 中断 注意系统节拍定时器只有 24 位 while (1); //不能越界 若越界则会出现此处的 whil(1)错误 } LPC_SC-&PCONP|=(1&&15); //功耗控制,此处可以注释掉,因为复位后 GPIO 默认开启 LPC_GPIO2-&FIODIR=0x0000000F; //FIODIR 设置端口的输入输出 LPC_GPIO2-&FIOSET=0x0000000F; //GPIO 置位,当某位为 1 则置位,为 0 不变 while(1) { if(sign==1) //如果标志位置位 表示定时时间到 { sign=0; //标志位清零 LPC_GPIO2-&FIOPIN =~( 1 && i); //GPIO2 管脚依次输出低电平 i++; //移位++ if(i==4) //4 位 满了 清零 i=0; } } }天下的人(红豆电子)与贞明电子协同打造 46 电子让生活更美好关于程序里面的变量定义的数据类型问题,个人认为在 8 位 MCU 里 使用 8 位变量处理速度比 16 位和 32 位变量快,而在 32 位 MCU 里处理 32 位变量的速度比 8 位变量的快,因此大多数情况是使用 32 位 int 型变量。关于变量定义的定义标识符,可以参见 core_cm3.c 调用的 stdint.h 文件里的定义,此处列举该文件里最常使用的几个: /* exact-width signed integer types */ typedef typedef typedef typedef signed signed short signed signed char int8_t; int int16_t; int int32_t; __int64 int64_t;/* exact-width unsigned integer types */ typedef unsigned typedef unsigned short typedef unsigned typedef unsigned char uint8_t; int uint16_t; int uint32_t; __int64 uint64_t;需要更详细的了解,可以打开此文件,该文件是 keil 自带的文件。5.3 实验 3-UART 的使用 无论在系统调试还是通讯中,串口都起着重要的作用。本实验将介 绍 LPC17XX 的串口使用。LPC17XX 处理器有 4 个符合 16C550 工业标准 的异步串口,UART0-UART3,其中 UART1 具有标准的 MODEM 接口和 RS-485/EIA-485 模式。LPC17xx 处理器的 4 个串口具有以下特征:天下的人(红豆电子)与贞明电子协同打造 47 电子让生活更美好* UART 具有独立的 16 字节 FIFO * 寄存器位置符合 16C550 工业标准; * 接收器 FIFO 触发点可为 1、4、8 和 14 字节; * 内置波特率发生器; * 包含实现软件流控制的机制; * UART3 包含了一个支持红外通信的 IrDA 模式; 基本配置: 功率:位于 PCONP 寄存器中,设置 PCUART0/2/3 位。 注:复位时,UART0 会被使能(PCUART0=1) ,且 UART2/3 会被禁能 (PCUART2/3=0) 外 设 时 钟 : 位 于 PCLK_SEL0 寄 存 器 中 , 选 择 PCLK_UART0 ; 在 PCLK_SEL1 寄存器中,选择 PCLK_UART2/3。 波特率:位于 U0/2/3LCR 寄存器; UART FIFO:使用 U0/2/3FCR 寄存器中的 FIFO 使能位启动 FIFO; 管脚:通过 PINSEL 寄存器选择 UART 管脚; 中断:将 U0/2/3LCR 寄存器中的 DLAB 位置 0,使能 UART 中断。 DMA:UART0/2/3 的发生和接受可通过 GPDAM 控制器进行操作。 UART 的寄存器列表如下:天下的人(红豆电子)与贞明电子协同打造48 电子让生活更美好在我们看来 UART 的寄存器配置比起 GPIO 来说复杂很多了,但是不 用担心 NXP 的工程师们早就给我们写好了 UART 功能函数文件,我们只 需要调用就能满足一般的应用,如果有特殊应用可以参照该文件自己 对照技术手册修改或编写出我们需要的程序即可。 下面就来看看为我们提供的 UART.h 和 UART.C 文件:天下的人(红豆电子)与贞明电子协同打造49 电子让生活更美好文件: UART.h 文件#ifndef __UART_H #define __UART_H #ifndef FALSE #define FALSE #endif #ifndef TRUE #define TRUE #endif #define IER_RBR #define IER_THRE #define IER_RLS #define #define #define #define #define #define #define #define #define #define #define #define #define IIR_PEND IIR_RLS IIR_RDA IIR_CTI IIR_THRE LSR_RDR LSR_OE LSR_PE LSR_FE LSR_BI LSR_THRE LSR_TEMT LSR_RXFE(0)(1)0x01 0x02 0x04 0x01 0x03 0x02 0x06 0x01 0x01 0x02 0x04 0x08 0x10 0x20 0x40 0x80 0x40#define BUFSIZEuint32_t UARTInit( uint32_t portNum, uint32_t Baudrate ); void UART0_IRQHandler( void ); void UART1_IRQHandler( void ); void UARTSend( uint32_t portNum, uint8_t *BufferPtr, uint32_t Length ); #endif /* end __UART_H */天下的人(红豆电子)与贞明电子协同打造50 电子让生活更美好UART.C 文件: UART.C 文件:#include &lpc17xx.h& #include &uart.h& #define UART0 LPC_UART0 #define UART1 LPC_UART1 #define PINCON LPC_PINCON volatile volatile volatile volatile uint32_t UART0Status, UART1S uint8_t UART0TxEmpty = 1, UART1TxEmpty = 1; uint8_t UART0Buffer[BUFSIZE], UART1Buffer[BUFSIZE]; uint32_t UART0Count = 0, UART1Count = 0;/******************************************************************* * Function name: UART0Handler ** Descriptions: UART0 interrupt handler ** parameters: None ** Returned value: None ******************************************************************** / void UART0_IRQHandler (void) { uint8_t IIRValue, LSRV uint8_t Dummy = D IIRValue = UART0-&IIR; IIRValue &&= 1; /* skip pending bit in IIR */ IIRValue &= 0x07; /* check bit 1~3, interrupt identification */ if ( IIRValue == IIR_RLS ) /* Receive Line Status */ { LSRValue = UART0-&LSR; /* Receive Line Status */ if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) ) { /* There are errors or break interrupt */ /* Read LSR will clear the interrupt */ UART0Status = LSRV Dummy = UART0-&RBR; /* Dummy read on RX to clear interrupt, then bail out */天下的人(红豆电子)与贞明电子协同打造 51 电子让生活更美好} if ( LSRValue & LSR_RDR ) /* Receive Data Ready */ { /* If no error on RLS, normal ready, save into the data buffer. */ /* Note: read RBR will clear the interrupt */ UART0Buffer[UART0Count] = UART0-&RBR; UART0Count++; if ( UART0Count == BUFSIZE ) { UART0Count = 0; /* buffer overflow */ } } } else if ( IIRValue == IIR_RDA ) /* Receive Data Available */ { /* Receive Data Available */ UART0Buffer[UART0Count] = UART0-&RBR; UART0Count++; if ( UART0Count == BUFSIZE ) { UART0Count = 0; /* buffer overflow */ } } else if ( IIRValue == IIR_CTI ) /* Character timeout indicator */ { /* Character Time-out indicator */ UART0Status |= 0x100; /* Bit 9 as the CTI error */ } else if ( IIRValue == IIR_THRE ) /* THRE, transmit holding register empty */ { /* THRE interrupt */ LSRValue = UART0-&LSR; /* Check status in the LSR to see if valid data in U0THR or not */ if ( LSRValue & LSR_THRE ) { UART0TxEmpty = 1; } else { UART0TxEmpty = 0; } }天下的人(红豆电子)与贞明电子协同打造52 电子让生活更美好} /******************************************************************* * ** Function name: UART1Handler ** Descriptions: UART1 interrupt handler ** parameters: None ** Returned value: None ******************************************************************/ void UART1_IRQHandler (void) { uint8_t IIRValue, LSRV uint8_t Dummy = D IIRValue = UART1-&IIR; IIRValue &&= 1; /* skip pending bit in IIR */ IIRValue &= 0x07; /* check bit 1~3, interrupt identification */ if ( IIRValue == IIR_RLS ) /* Receive Line Status */ { LSRValue = UART1-&LSR; /* Receive Line Status */ if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) ) { /* There are errors or break interrupt */ /* Read LSR will clear the interrupt */ UART1Status = LSRV Dummy = UART1-&RBR; /* Dummy read on RX to clear interrupt, then bail out */ } if ( LSRValue & LSR_RDR ) /* Receive Data Ready */ { /* If no error on RLS, normal ready, save into the data buffer. */ /* Note: read RBR will clear the interrupt */ UART1Buffer[UART1Count] = UART1-&RBR; UART1Count++; if ( UART1Count == BUFSIZE ) { UART1Count = 0; /* buffer overflow */ } } } else if ( IIRValue == IIR_RDA ) /* Receive Data Available */ {天下的人(红豆电子)与贞明电子协同打造 53 电子让生活更美好/* Receive Data Available */ UART1Buffer[UART1Count] = UART1-&RBR; UART1Count++; if ( UART1Count == BUFSIZE ) { UART1Count = 0; /* buffer overflow */ } } else if ( IIRValue == IIR_CTI ) /* Character timeout indicator */ { /* Character Time-out indicator */ UART1Status |= 0x100; /* Bit 9 as the CTI error */ } else if ( IIRValue == IIR_THRE ) /* THRE, transmit holding register empty */ { /* THRE interrupt */ LSRValue = UART1-&LSR; /* Check status in the LSR to see if valid data in U0THR or not */ if ( LSRValue & LSR_THRE ) { UART1TxEmpty = 1; } else { UART1TxEmpty = 0; } } } /******************************************************************* * ** Function name: UARTInit ** Descriptions: Initialize UART0 port, setup pin select, ** clock, parity, stop bits, FIFO, etc. ** parameters: portNum(0 or 1) and UART baudrate ** Returned value: true or false, return false only if the ** interrupt handler can&#39;t be installed to the ** VIC table ******************************************************************** / uint32_t UARTInit( uint32_t PortNum, uint32_t baudrate ) { uint32_t F天下的人(红豆电子)与贞明电子协同打造54 电子让生活更美好if ( PortNum == 0 ) { PINCON-&PINSEL0 = 0x; /* RxD0 is P0.3 and TxD0 is P0.2 */ UART0-&LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ /* By default, the PCLKSELx value is zero, thus, the PCLK for all the peripherals is 1/4 of the SystemFrequency. */ // Fdiv = ( SystemFrequency/4/16 ) / /*baud rate, Fpclk: 18MHz */ Fdiv = ( SystemCoreClock/4/16 ) / UART0-&DLM = Fdiv / 256; UART0-&DLL = Fdiv % 256; UART0-&LCR = 0x03; /* DLAB = 0 */ UART0-&FCR = 0x07; /* Enable and reset TX and RX FIFO. */ NVIC_EnableIRQ(UART0_IRQn); UART0-&IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART0 interrupt */ return (TRUE); } else if ( PortNum == 1 ) { PINCON-&PINSEL4 |= 0x0000000A; /* Enable RxD1 P2.1, TxD1 P2.0 */ UART1-&LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ /* By default, the PCLKSELx value is zero, thus, the PCLK for all the peripherals is 1/4 of the SystemFrequency. */ // Fdiv = ( SystemFrequency/4/16 ) / /*baud rate */ Fdiv = ( SystemCoreClock/4/16 ) / UART1-&DLM = Fdiv / 256; UART1-&DLL = Fdiv % 256; UART1-&LCR = 0x03; /* DLAB = 0 */ UART1-&FCR = 0x07; /* Enable and reset TX and RX FIFO. */ NVIC_EnableIRQ(UART1_IRQn); UART1-&IER = IER_RBR | IER_THRE | IER_RLS; /* interrupt */ return (TRUE); } return( FALSE ); } Enable UART1/******************************************************************* * ** Function name: UARTSend天下的人(红豆电子)与贞明电子协同打造 55 电子让生活更美好** ** Descriptions: Send a block of data to the UART 0 port based ** on the data length ** ** parameters: portNum, buffer pointer, and data length ** Returned value: None *************************************************************/ void UARTSend( uint32_t portNum, uint8_t *BufferPtr, uint32_t Length ) { if ( portNum == 0 ) { while ( Length != 0 ) { /* THRE status, contain valid data */ while ( !(UART0TxEmpty & 0x01) ); UART0-&THR = *BufferP UART0TxEmpty = 0; /* not empty in the THR until it shifts out */ BufferPtr++; Length--; } } else { while ( Length != 0 ) { /* THRE status, contain valid data */ while ( !(UART1TxEmpty & 0x01) ); UART1-&THR = *BufferP UART1TxEmpty = 0; /* not empty in the THR until it shifts out */ BufferPtr++; Length--; } } } /******************************************************************* * ** End Of File ******************************************************************/下面是我们的主函数:#include &lpc17xx.h& #include &uart.h& // 包含头文件, 头文件内保护系统初始化头文件 //包含串口所使用的头文件天下的人(红豆电子)与贞明电子协同打造 56 电子让生活更美好//***************************************************** uint32_t msTicks,sign=0; //变量定义 extern volatile uint32_t UART0C //串口接收数据计数 extern volatile uint8_t UART0Buffer[BUFSIZE]; //串口数据接受缓存 //extern volatile uint32_t UART1C //extern volatile uint8_t UART1Buffer[BUFSIZE]; unsigned char table[]={&LED 1 LIGHT!\n&}; //***************************************************** void SysTick_Handler(void) //系统节拍定时器中断函数 { msTicks++; //简单的定时++ 运算 if(msTicks==500) //定时满 500 次 一次 1ms 即 500ms 置位标志位 { sign=1; //标志位置位 msTicks=0; //定时变量 清零 } } int main(void) { uint32_t i=0; //定义变量 SystemInit(); //系统初始化函数 if (SysTick_Config(SystemCoreClock / 1000)) //系统节拍定时器初始化 函数在 core_cm3.h 里 { //设置节拍定时器 1ms 中断 注意系统节拍定时器只有 24 位 while (1); //不能越界 若越界则会出现此处的 whil(1)错误 } UARTInit(0,9600); //UART 初始化,第一个参数是端口,第二个参数是波特率 LPC_SC-&PCONP|=(1&&15); LPC_GPIO2-&FIODIR=0x0000000F; //FIODIR 设置端口的输入输出 LPC_GPIO2-&FIOSET=0x0000000F; while(1) { if(sign==1) //如果标志位置位 表示定时时间到 { sign=0; //标志位清零 LPC_GPIO2-&FIOPIN =~( 1 && i); i++; //移位++ if(i==4) //4 位 满了 清零 i=0; table[4]=i+0x30;天下的人(红豆电子)与贞明电子协同打造 57 电子让生活更美好UARTSend(0,table,15); //串口输出 } if ( UART0Count != 0 ) //判断是否有数据接受到 { LPC_UART0-&IER = IER_THRE | IER_RLS; /* Disable RBR */ UARTSend( 0, (uint8_t *)UART0Buffer, UART0Count ); //将接收的数据返回去 UART0Count = 0; LPC_UART0-&IER = IER_THRE | IER_RLS | IER_RBR; /* Re-enable RBR */ } } }该程序的现象是 LED 灯像实验 2 那样流动闪烁, 每移动一次就从 LED 串口向上发送一个字符串,告诉上位机此时是哪一个 LED 在亮。另外 这个程序也可接收数据, 并且将接收到的数据, 按原样返回到 PC 机端。 下面是 PC 机上串口调试工具在运行时的截图:天下的人(红豆电子)与贞明电子协同打造58 电子让生活更美好5.4 实验 4―按键实验 按键是常用的输入设备,在实际应用中得到广泛应用!其中用的比 较多的是独立按键和矩阵键盘,独立按键适合按键数量较少,矩阵键 盘时候按键较多的情况。独立按键的读取是比较容易的。由原理图可 知,我们的按键外部有上拉电阻,在没有按键按下的时候,读取端口 是高电平,在有按键按下的时候,按键所在端口是低电平。这样我们 的 IO 口就可以读出是否有按键按下了。然而按键是机械装置,在按下 和弹起时都有抖动。一般的防抖方法有硬件防抖和软件防抖,硬件防 抖是在按键输入 IO 口中加入施密特触发器,会引入硬件成本。而为了 节约成本一般采用软件防抖,软件防抖的一般方法是 2 次读取中间加 一个 ms 级延时,若 2 次读取都是低电平,则说明有键按下。在按键的 操作过程中我们一般还要求按键按下依次只读出一个按下状态,一般 的做法是:在按下键盘后就在程序中使用一个 while 循环等待按键的 松开,在低速 8 位单片机上这样做没什么不好,但是如果在 32 位 ARM 上这样做将是浪费了宝贵的时间片资源。本程序采用一种状态存储的 方法将上一次按键的状态存储,若这次检测到按键按下上一次也检测 到按键按下,那么我们认为按键没有被松开!不作处理。若这次按下 时读上一次保存的状态是没有被按下,那么这是一个新的按键信息, 应当被处理! 下面是按键实验的主函数:#include &lpc17xx.h& // 包含头文件, 头文件内保护系统初始化头文件 #include &uart.h& //包含串口所使用的头文件 //***************************************************** uint32_t msTicks,sign=0; //变量定义天下的人(红豆电子)与贞明电子协同打造 59 电子让生活更美好extern volatile uint32_t UART0C //串口接收数据计数 extern volatile uint8_t UART0Buffer[BUFSIZE]; //串口数据接受缓存 //extern volatile uint32_t UART1C //extern volatile uint8_t UART1Buffer[BUFSIZE]; unsigned char table[]={&key 0 down!\n&}; uint32_t key_old=0,LED=0x0000000f; //key_Old 保存按键上一次按下的 值 LED LED 灯的状态 //***************************************************** /****************** 函数声明区 *************************/ void key(void); /******** main **********************************/ int main(void) { SystemInit(); //系统初始化函数 UARTInit(0,9600); //UART 初始化,第一个参数是端口,第二个参数是波特率 LPC_SC-&PCONP|=(1&&15); //功耗控制,此处可以注释掉,因为复位后 GPIO 默认开启 LPC_GPIO2-&FIODIR=0x0000000f; //只将 P2 口的低 4 位设置成输出模式 LPC_GPIO2-&FIOSET=0x0000000F; //GPIO 置位,当某位为 1 则置位,为 0 不变 UARTSend(0,table,15); while(1) { key(); if ( UART0Count != 0 ) //判断是否有数据接受到 { LPC_UART0-&IER = IER_THRE | IER_RLS; /* Disable RBR */ UARTSend( 0, (uint8_t *)UART0Buffer, UART0Count ); //将接受的数据返回去 UART0Count = 0; LPC_UART0-&IER = IER_THRE | IER_RLS | IER_RBR; /* Re-enable RBR */ } } } /************************************************************/ void key(void) { uint32_t key=0,i=0; key=LPC_GPIO2-&FIOPIN; //读是否有按键按下 key=key&0x00001c00; //只观测三个按键的值,屏蔽其他位 if(key!=0x00001c00) //如果有按键按下天下的人(红豆电子)与贞明电子协同打造 60 电子让生活更美好{ for(i=0;i&5000;i++); //延时一小段时间 防止按键抖动 key=LPC_GPIO2-&FIOPIN; //再次读取端口状态 key=key&0x00001c00; //屏蔽其他位 if(key!=0x00001c00) //是否有按键按下 { switch(key) //判断是那一个按键 { case 0x: //第一个按键(P2.10)按下 if(1!=(key_old&1)) //查看上一次这个按键是否按下 如果上次也 是按下的 { //说明按键没有松开 不做处理 否则键按下 if((LED&1)==1) //LED 灯取反 LED&=~1; else LED|=1; key_old|=1; //将这一次按键的状态存储起来 table[4]=1+0x30; //修改字符串 UARTSend(0,table,15); //串口发送 } case 0x: //第二个按键(P2.11)按下 if(2!=(key_old&2)) { if((LED&2)==2) LED&=~2; else LED|=2; key_old|=2; table[4]=2+0x30; UARTSend(0,table,15); } case 0x00000c00: // 第三个按键(P2.12)按下 if(4!=(key_old&4)) { if((LED&4)==4) LED&=~4; else LED|=4; key_old|=4; table[4]=3+0x30; UARTSend(0,table,15); }天下的人(红豆电子)与贞明电子协同打造 61 电子让生活更美好 } LPC_GPIO2-&FIOPIN=LED; } } else { key_old=0; 下” ! } } /***********************************************************/ //没有键按下 更新上次按键“均没有被按 //更新 LED 状态5.5 实验 5―定时器实验 定时器/计数器是 MCU 内部的重要资源,一个强大的定时器/计数器 能够完成众多功能,给我们的应用带来极大的便利。在 LPC17XX 内部 含有 4 个 32 位通用定时器/计数器。4 个定时器/计数器,除了外设基 址之外完全相同。 个定时器最少有 2 个捕获输入和 2 个匹配输出, 4 并 且有多个引脚可以选择。定时器 2 引出了全部 4 个匹配输出。 32 位的定时器/计数器,带有一个可编程的 32 位预分频器。 计数器或定时器操作。 每个定时器包含 2 个 32 位的捕获通道, 当输入信号变化时捕捉定时 器的瞬时值。也可以选择产生中断。 4 个 32 位匹配寄存器,允许执行以下操作: 匹配时连续工作,在匹配时可选择产生中断; 在匹配时停止定时器运行,可选择产生中断; 在匹配时复位定时器,可选择产生中断; 有 4 个与匹配寄存器相对应的外部输出,这些输出具有以下功能: 匹配时设定为低电平;天下的人(红豆电子)与贞明电子协同打造 62 电子让生活更美好匹配时设为高电平; 匹配时翻转电平; 匹配时不执行任何操作; 这是 LPC17XX 定时器的基本特征,下面具体介绍一些定时器的寄存器 和使用方法。要使用定时器这个片内外设,依然需要如下外围配置:功 率(PCONP) 、外设时钟(PCLK_SEL0) 、引脚(PINSEL) 、中断、DMA(如 果使用的话) 。定时器/计数器寄存器列表:天下的人(红豆电子)与贞明电子协同打造63 电子让生活更美好下面主要介绍一下以上那些寄存器: IR 是中断寄存器,如何进入中断,和启动中断,我们的系统文件都 为我们做好了,比如要使能某个中断在初始化函数里只需要加上这样 一个函数:NVIC_EnableIRQ(TIMER0_IRQn);从函数名就可以看出是使 能中断的意思,这个函数在 core_cm3.h 中定义,这里面还有其他一些 关于中断的函数如禁止某个中断等,查阅一些就能看到。这里使能的 显然是 TINMER0,表示符“TIMER0_IRQn”是在 LPC17xx.h 中定义的, 这里有所有中断的表示方法。如果要使能其他中断只需要将函数括号 中的中断名修改成别的中断名即可(中断名在 LPC17XX.h 中查阅) 。说天下的人(红豆电子)与贞明电子协同打造 64 电子让生活更美好完了使能中断,下面是中断函数的形式:void TIMER0_IRQHandler (void),这是定时器 0 的中断服务函数的文件名,如果要写其他中断 的中断服务函数, 只需将 TIMER0_IRQ 修改成其他中断对应的名称即可。 对于定时器进入中断函数后需要想 IR 的对应位写入 1 来复位中断。 TCR 定时器控制寄存器,只有前 2 位有效,其余位保留,位 0 是计数 器使能,为 1 时使能,为 0 时禁止。位 1 是计数器复位,为 1 是发生 复位。 CTCR 计数器控制寄存器,有效的只有前 4 位,而在定时应用中只需 要将位 0 和位 1 设置成 00 即可。因为前 2 位是定时器模式选择,00 表示选择定时模式,其余都是计数模式。位 2,3 是计数输入选择。 MCR 匹配控制寄存器,一共 12 位有效,对 4 个匹配寄存器控制,每 一个匹配通道有 3 位控制,位 0 是 MR0 匹配时是否引发中断,位 1 是 MR0 匹配是是否引发 TC 复位,位 2 是 MR0 匹配时是否引发停止。以后 的位和这几位类似。引发停止时候单次定时使用,如果要重复定时, 且需要中断来处理事物那么只需要相应的位置 1 即可。 EMR 是外部匹配寄存器, EMR 的前 4 位里写入 1 可以在对应的管脚

我要回帖

更多关于 pin是什么意思 的文章

 

随机推荐