nordic 蓝牙是不是已经开发了很多蓝牙开发板,从头文件上看,

用Bluetooth Developer Studio缩短70%蓝牙开发时间-新闻-RF技术社区
用Bluetooth Developer Studio缩短70%蓝牙开发时间
发布时间: 09:20:18
来源:RF技术社区 ()
你知道吗?在物联网(IoT)世代,我们设计产品的过程将变得和以前大不相同。或许你已经听说过,这将是一个万物智能的时代,所有的硬件都可以拥有智能,你的衣服、杯子、咖啡机都可以被赋予可计算的智慧,以及与人交互的能力。我们所面临的物联网市场将不在是一个单一产品足以引爆的市场,而将是一个&长尾理论&(The Long Tail)的市场。
长尾理论?这和智能硬件开发扯得上半毛钱关系吗?是的,日前,蓝牙技术联盟(Bluetooth SIG)开发项目技术经理高文森在谈到IoT市场上创新型硬件开发时就表示,智能硬件的开发已不在是一个产品方案走遍天下的时代,随着低功耗蓝牙的出现,成就物联网时代的蓝牙硬件市场将是一个长尾的市场,早几年,大家提到蓝牙硬件开发,就想到蓝牙耳机,几乎一个方案就能copy在无数中国工厂中。而现在蓝牙遇到了广阔的IoT机遇,基于蓝牙连接技术的智能互联设备可能是一个牙刷、心率监测仪、门锁、灯泡等各种设备,开发方案将极具创新又各有差异,覆盖的领域也会千差万别,唯一不变的是,各位,留给我们的开发时间将更少了。我们的队伍还会加入很多&门外汉&设计师,可能对电子设计不熟,但同时又在自己领域是专家。共同的是,我们都希望快速开发出有创意的、符合市场需求的智能硬件产品。
谈正事,那么?如果你要开发一款基于蓝牙连接技术的智能硬件,你会怎么做?一页一页查Paper,从基础协议学起?要知道设计师的宝贵时间更应该留给功能的开发与实现,何况留给我们的时间并不多。当然,如果你是&蓝牙大神&,已经对最新公布、早先公布、形形色色的蓝牙profile烂熟于心,或者你想凭一己之力吃透厚厚一叠参考资料而不在乎开发时间。OK,请忽略下文内容。
或者你会,找厂家的参考设计或开发套件支持?这是一个好办法,今天,我们并不想否认这种常规的好方法,而是希望提供多一个更能加速开发的全新选择,并且这种选择完全可以叠加于厂家参考设计或开发套件支持的基础之上,并再次缩短开发时间。
好了,前面扯的有点多,该谈谈缩短开发时间的事了。这里提到的好方法就是蓝牙技术联盟最新为物联网产品开发推出的&Bluetooth Developer Studio&开发工具包。据蓝牙联盟官方公布:&Bluetooth Developer Studio&可有效缩减多达50%的蓝牙学习时间。来自初级用户和资深蓝牙开发者的反馈表明,&Bluetooth Developer Studio&更能够将蓝牙开发时间缩短多达70%。
缩短70%?究竟是如何做到的?简而言之,就是通过提供&代码实例&的方式,让开发者在&开发库&里找到符合自身开发项目大致想法的实例模板,通过简单拖放(图1),快速创建自己的项目,并在此基础上生成开发原型,设计师可进一步利用开发包进行原型验证和互操作性等测试(包括虚拟测试),工具也直接支持各家蓝牙原厂(蓝牙芯片和模块供应商)的解决方案,可选择具体的芯片/模块后自动生成代码文件,最终导入到原厂开发软件或开发板中进行进一步功能性开发等步骤,将设计直接变身产品。高文森演示并举例道,比如:我想设计一个&智能咖啡机&,有一块开发板并希望完成上面的软件。我可在工具包里检索到另一个家伙的智能咖啡机项目,用鼠标拖过来,修改定义一些我所需要的变量,大约15分钟的时间就可以搞定一个原型。然后基于原型,在里面进一步挑选原厂方案。比如要用Nordic的板做,Bluetooth Developer Studio就会自动生成适合Nordic的代码,我可以把代码直接放在Nordic开发板上。当然,开发包本身是图形化的界面,操作、生成都很简单。开发者也能轻松获得教程,易于学习。
图1 开发者在&开发库&里找到符合自身项目需要的实例模板,通过简单拖放,快速创建自己的项目
已经有那么多厂家开发套件,为何还要用蓝牙联盟的工具包?当然首先它是完全免费下载的(不论是现在的Beta版还是未来的正式版)。其次,这次由联盟来发布工具包主要是想填补一个空白,就是基于通用属性配置文件GATT(Generic Attribute Profile)的开发和调试。对此高经理也表示,有别于原厂的套件,联盟发布的工具包是希望更多提供对蓝牙协议层面的支持。利用原厂套件做开发前,设计师往往需要对最初的自定义配置文件(Profile)进行定义,需要理解很多的Profile文档,现在在下载实例的同时可以省略这一步,或设计师可以在已有配置文件的基础上加以创建新的应用,由此来大大节省开发时间。当然你的Profile也可以发布在平台中供更多人使用。
从编译角度看,这个工具的编译功能也是对原厂编译器某些方面的增强,你可以在工具中基于某个原厂的开发板生成代码,随后导入原厂的开发工具中进行进一步的性能开发、UI开发等,再用原厂的开发工具编译代码最终导入开发板,这样的流程可以节省很多开发时间。当然这款工具也能在快速出原型的基础上进行原型验证、互操作验证等虚拟测试。这也顺应目前在开发界很流行的快速迭代概念,需要很快的把设计概念变成产品来验证,这也对工具和开发流程提出新思路。
另外,这个工具也可利于不同厂家板子的选型,可以在原型设计后快速基于不同厂家的不同板子出代码,节省选型时间。当然这个工具对于蓝牙设计的初学者具有很大的指导性,蓝牙联盟希望通过Bluetooth Developer Studio工具降低蓝牙开发门槛、同时通过设计模板的方式加速开发、也提高开发质量。
谈了这么多,最后小编也想补充一句,作为设计师,难道你不好奇其他人的开发吗?设计库内的部分实例是基于开发者们上传的应用和参考设计,你可以借鉴或对其优化。
听上去设计库很强大,里面都有些什么?由于是一个开源的平台,所以&设计库&内最吸引人的部分就是&代码实例&模板了。据高经理介绍,设计库里有来自原厂的参考设计,也有来自开发者自己上传的设计。有些应用非常广泛,会形成类似标准的实例,会标有&Adopted&的标识,意味着这个东西是被蓝牙联盟所广泛采用的。有些则是基于设计师的上传,有其独特性。比如:心跳仪设计,如果大家基本都同意心跳仪应该有1、2、3种规范,投票通过了,这个叫&Adopted&。可能还会有一些厂商希望再加上5和6,这会是他自己定制的东西。目前开发库的分类有二十几类(图2),内容涵盖可穿戴产品、智能家居、健康产品等各类智能硬件,由于目前仅是Beta版且是完全开源的,相信这个设计库在未来会不断扩充壮大。
图2 目前开发库有二十几种分类,设计师自己构建的原型也可以在工具中进行分类发布
哪些原厂的蓝牙器件或板子可以在开发库中直接导出?据高经理介绍目前Bluetooth Developer Studio Beta版本已经得到四、五家原厂的支持(如Nordic、CSR,TI,Broadcom都已经支持或在筹备中),工具中可以支持他们市面上买得到的所有器型。同时还有更多的厂商正在和蓝牙技术联盟一起做研发。Bluetooth Developer Studio是个开源的项目,任何厂家想加入它的蓝牙芯片或模块都可以。国内有很多做芯片、模组厂商有自己的方案,都可以加入到蓝牙联盟的工具里,Bluetooth Developer Studio一样可以进行支持。
刚提到的工具自带测试有哪些?如何保证设计出来的产品互操作性、稳定性和用户体验?
据高经理介绍,在蓝牙设计中提高互操作性,也是提出这个开发工具的目的之一。整个工具内含一个测试平台。可以做两种测试:1.虚拟的测试。在你决定正式上传到平台之前,可以在那里测试一下。比如:模拟数据发送接收的过程是否顺畅。2.当你把原型做好后,可以互相连接,看能不能满足初始设计的一些想法。同时,你也可以把&原型&分享给整个开发社区。别的设计师可以在此基础上继续提高。这也是提高互操作性的一种方式。同样,对于用户体验,很大部分来自产品质量和稳定性,依然可以通过测试进行,测试平台可以测试用户不同的应用场景,来确定你设计的这个应用是否符合设计想法能并满足最终用户的体验。
嫌这些还不够?好吧。目前这是一个基于测试的Beta版本,从时间上看正式版本会在2015年7月底或8月初在全球正式发布。当然,无论是Beta版本还是正式版本,都会在蓝牙联盟网站上面向所有的蓝牙开发人员免费的进行下载。
最后再插播一条重要讯息,从蓝牙联盟方面最新透露的消息看,目前Mesh工作组正在进行积极工作,将于15年底完成Mesh原型和草案提交,预计,会在2016年年初把Bluetooth Smart Mesh自组网技术规范发布出来。届时,蓝牙又添IoT重要利器,有了自组网技术规范可能会对整个无线互联生态环境产生重大影响,当然目前看到影响最大的会在智能家居领域。看来蓝牙正陆续兑现着对IoT的战略大布局(关于蓝牙技术和IoT更详细介绍,请参考小编另一篇文章:蓝牙&凭什么&赢得万亿美金身价IoT青睐?)
聊了那么多,对Bluetooth Developer Studio做个小结:
基本上小编认为该工具的适用人群会包括:智能硬件设计者,创客们,学生,或其他想利用蓝牙做IoT智能硬件产品开发的工程师们。
Tel: 3-8070
备案号: 苏ICP备号-2蓝牙4.0(CC2540/CC2541)BLE协议栈开发(连载) - 单片机论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
蓝牙4.0(CC2540/CC2541)BLE协议栈开发(连载)
15:41:33  
75604&查看
本帖最后由 zzq宁静致远 于
15:01 编辑
& & 深圳市馒头科技蓝牙4.0开发板、蓝牙4.0模块、iBeacon基站学习开发群:MT254x蓝牙4.0系列:& && &&&MT254x蓝牙4.0开发板 低功耗 含LCD12864 独家视频教学&&开发板采购:/item.htm?spm=a1z10.1.w.GBF0qx&id=
& & 深圳市馒头科技有限公司带领大家掌控蓝牙4.0技术开发,洞悉蓝牙未来发展。
未标题-2.jpg (70.68 KB, 下载次数: 4)
16:45 上传
未标题-1.jpg (75.96 KB, 下载次数: 2)
16:45 上传
& & 蓝牙4.0是2012年最新蓝牙版本,是3.0的升级版本;较3.0版本更省电、成本低、3毫秒低延迟、超长有效连接距离、AES-128加密等;通常用在蓝牙耳机、蓝牙音箱等设备上。& & 蓝牙4.0最重要的特性是省电,极低的运行和待机功耗可以使一粒纽扣电池连续工作数年之久。此外,低成本和跨厂商互操作性,3毫秒低延迟、AES-128加密等诸多特色,可以用于计步器、心律监视器、智能仪表、传感器物联网等众多领域,大大扩展蓝牙技术的应用范围。& & 蓝牙4.0已经走向了商用,在最新款的Xperia Z、Galaxy S3、S4、Note2、SurfaceRT、iPhone 5、iPhone 4S、魅族MX3、Moto Droid Razr、HTC One X、小米手机2、The New iPad、iPad 4、 MacBook Air、Macbook Pro,Nokia Lumia系列以及台商ACER AS3951系列/Getway NV57系列,ASUS UX21/31三星NOTE系列上都已应用了蓝牙4.0技术。蓝牙4.0支持两种部署方式:双模式和单模式。双模式中,低功耗蓝牙功能集成在现有的经典蓝牙控制器中,或再在现有经典蓝牙技术(2.1+EDR/3.0+HS)芯片上增加低功耗堆栈,整体架构基本不变,因此成本增加有限。& & 单模式面向高度集成、紧凑的设备,使用一个轻量级连接层(Link Layer)提供超低功耗的待机模式操作、简单设备恢复和可靠的点对多数据传输,还能让联网传感器在蓝牙传输中安排好低功耗蓝牙流量的次序,同时还有高级节能和安全加密连接。& & 在CES2014上展示的各种智能穿戴设备,大多是采用蓝牙4.0作为传输方式。可以看到在未来的几年内蓝牙4.0以及后续的升级版本将会呈爆炸的发长趋势。& &
15:50:52  
第一节&&蓝牙4.0MT254x模块的介绍
& & MT254xCoreS一款蓝牙4.0单模模块,采用TI的是CC254x系列芯片(CC2540/41),引出所有IO,可以无缝的运行TI的BLE协议栈。这是一个CC254x的最小系统,集成系统时钟和板载天线,用户可以直接开发自己的BLE产品。1)速度:支持1Mbps数据传输率下的超短数据包,最少8个八组位,最多27个。所有连接都使用蓝牙2.1加入的减速呼吸模式(sniff subrating)来达到超低工作循环。2)跳频:使用所有蓝牙规范版本通用的自适应跳频,最大程度地减少和其他2.4GHz ISM频段无线技术的串扰。3)主控制:更加智能,可以休眠更长时间,只在需要执行动作的时候才唤醒。4)延迟:最短可在3毫秒内完成连接设置并开始传输数据。5)范围:提高调制指数,最大范围可超过100米(室内环境30米左右)。6)健壮性:所有数据包都使用24-bitCRC校验,确保最大程度抵御干扰。7)安全:使用AES-128 CCM加密算法进行数据包加密和认证。& & 拓扑:每个数据包的每次接收都使用32位寻址,理论上可连接数十亿设备;针对一对一连接优化,并支持星形拓扑的一对多连接;使用快速连接和断开,数据可以再网状拓扑内转移而无需维持复杂的网状网络。
图片1.jpg (17.93 KB, 下载次数: 1)
15:43 上传
晶振:& & 系统主时钟采用32M晶振,根据TI官方的参考设计,使用的是10ppm高精度的金属壳晶振。睡眠时钟使用的是32.768K的晶振,在系统睡眠时需要使用此晶振。天线:& & 蓝牙属于近场通讯,应用场合一般为室内等近距离通信,因此我们使用PCB天线。其通信范围经过实验测量空旷空间内可达100米,室内可达30米,完全能够满足通讯的需要,而且将天线集成在模块内部能够减小模块所占用的体积。电阻电容:& & 模块所使用的电子器件全部为村田的高精度元件。对外接口:& & 此模块采用3组1.27mm间距的半孔引出全部的24个IO,用户在使用时可以看成是SMT贴片元件,具体的封装可以使用我们提供的封装源文件,我们只提供Altium Designer(Version 14.2.4)的封装。如果用户使用的是其他软件,可以使用Altium Designer的“另存为”功能,然后选择需要的格式,保存即可。外观尺寸:& & 模块的外形尺寸如下,此模块采用1.27mm间距的半孔将所有IO全部引出,并且最大限度的控制了模块的体积,用户可以方便的将此模块集成到自己的产品中:
图片2.jpg (22.02 KB, 下载次数: 3)
15:45 上传
引脚分布图:
& & 模块的引脚分布图如下,用户设计电路时需要参考此分布图:
图片3.jpg (165.91 KB, 下载次数: 1)
15:46 上传
引脚功能说明:
& & 模块引脚名称&&
&&&&对应芯片引脚&&
GNDGND接地VCCVDD数字和模拟工作电压(2V~3.6V)DCP2.2调试接口时钟线DDP2.1调试接口数据线PIO0P2.0通用数字输入输出IO口PIO1P1.7通用数字输入输出IO口PIO2P1.6通用数字输入输出IO口PIO3P1.5通用数字输入输出IO口USB+USB_PCC2540:USB接口positive;CC2541:I2C接口SCLUSB-USB_NCC2540:USB接口negative;CC2541:I2C接口SDAPIO4P1.4通用数字输入输出IO口PIO5P1.3通用数字输入输出IO口PIO6P1.2通用数字输入输出IO口PIO7P1.1通用数字输入输出IO口PIO8P1.0通用数字输入输出IO口PIO9P0.7通用数字输入输出IO口PIOAP0.6通用数字输入输出IO口RTP0.5UART0的RTSCTP0.4UART0的CTSTXP0.3UART0的TXDATARXP0.2UART0的RXDATAWKP0.1唤醒模块、AT指令模式和透传模式切换LEDP0.0工作状态指示RSTRESET_N模块复位
模块透传功能:& & 模块正确上电后,默认工作于从机模式,对外广播数据,等待主机设备连接。由于WK引脚在芯片内部已经上拉,所以此时模块处于透传模式,详情请参考《MT254xCoreS-V1.0-AT指令手册》。若此时模块和远端设备连接上,用户通过串口发给模块的数据将直接转发给远端设备;如果模块不处于连接状态,用户发送的数据将被丢弃。图为透传功能使用的参考设计。
图片4.jpg (286.37 KB, 下载次数: 1)
15:47 上传
BLE协议栈开发:
& & 本模块出厂时默认自带了基于BLE1.4.0协议栈开发的串口透传固件,如果用户不想使用自带的固件,必须先擦除模块上的固件,再将新开发的固件写入到模块。图为协议栈开发的参考设计。
图片5.jpg (264.69 KB, 下载次数: 2)
15:49 上传
IO复用功能表:
&&Periphery/ Function&&P0P1P27654321076543210210ADCA7A6A5A4A3A2A1A0
TOperational amplifier
Analog comparator
USART 0 &&SPI&&Alt. 2
USART0 UART&&Alt. 2
USART 1 SPI&& &&Alt. 2
USART 1 UART&&Alt. 2
TIMER 1&&Alt. 2 43210
TIMER 3&&Alt. 2
TIMER 4&&Alt. 2
032-kHz XOSC
DCDD OBSSEL
& & 请各位读者一定要先熟悉这个模块的硬件和功能,我们下节给大家讲解如何使用透传功能。不要走开,下节更精彩。
09:53:44  
第二节&&MT254x蓝牙4.0模块的透传测试
& & 我们在使用蓝牙模块之前,先使用MT254x蓝牙4.0调试底板进行相关的测试。
test (75).jpg (448.56 KB, 下载次数: 2)
09:27 上传
& & MT254xCoreSTest是深圳市馒头科技有限公司设计的适用于MT254xCoreS模块的测试底板。其特有的DB9通用接口,方便用户在在使用MT254xCoreS模块之前进行相关测试,直接通过串口连接到电脑,使用上位机串口助手软件及时验证模块的功能完整性,快速地上手使用。这样用户就不需要自己去设计底板来使用本模块,降低了用户的使用成本。同时MT254xCo- reSTest测试底座的体积已经做到了最小化,对于大部分用户来说,这样的体积可以直接应用到产品中,或者嵌入到自己的产品中。如果用户对此底板有更高的要求,也可以联系馒头科技,在基于批量的情况下,可以进行底板的定制。测试底板正面:
1.jpg (106.85 KB, 下载次数: 6)
09:34 上传
测试底板反面:
2.jpg (97.29 KB, 下载次数: 2)
09:34 上传
1.& && &&&DB9通用母头:本接口输出或者输入的是232电平,方便用户直接连接到电脑端串口,接收或者发送数据,其他带有DB9接口(可以加串口延长线)的开发平台都可以直连使用。2.& && &&&MINIUSB插座:本接口一方面是给底板供电,另外USB的D-、D+两根数据线也连接到了MT254xCo-reS模块上,当模块的固件允许USB升级的时候,就可以通过当前接口进行USB升级固件。3.& && &&&按键:按键用于复位整个板载电路,包括MT254xCoreS模块。4.& && &&&P1和UART插针:P1和UART这两个插针上的引脚功能定义如下图,以及对应的原理图。其中WK引脚的功能详见《MT254xCoreS-AT指令手册》。如果用户需要使用DB9接口跟其他平台相连,即使用232电平通信,就需要分别使用跳帽将TX_TTL和TX_232相连,将RX_TTL和RX_232相连。如果用户需要使用TTL电平进行串口通信,则直接将接入TX_TTL和RX_TTL即可,无需跳帽。
6.jpg (47.83 KB, 下载次数: 1)
09:36 上传
7.jpg (31.72 KB, 下载次数: 1)
09:36 上传
8.jpg (71.92 KB, 下载次数: 2)
09:36 上传
接下来我们使用调试底板进行测试,在:/share/link?shareid=&uk=#dir/path=%2F%E6%9C%B1%E5%85%86%E7%A5%BAForARM%2F%E9%A6%92%E5%A4%B4%E7%A7%91%E6%8A%80%E8%93%9D%E7%89%994.0%E7%B3%BB%E5%88%97%2FMT254x%E8%93%9D%E7%89%994.0%E8%B0%83%E8%AF%95%E8%BD%AF%E4%BB%B6下载由馒头科技提供的PC端的蓝牙4.0调试软件和安卓端的app蓝牙4.0调试应用程序,IOS可直接下载LightBlue进行测试。
未标题-1.jpg (148.84 KB, 下载次数: 2)
09:39 上传
MT254x蓝牙4.0模块的AT指令如下:注意事项1)& && & 所有的AT指令中的符号,如问号(?)、冒号(:),都是英文半角格式,需要携带参数para的指令必须显式地添加中括号[],指令末尾不携带”\r\n”。所有的应答指令最后都有”\r\n”回车换行符,方便用户编程判断。2)& && & 模块工作模式a)& && &&&AT指令模式:用户可以操作或者设置本模块。b)& && & 透传模式:用户发往模块串口的数据将直接发送到远端蓝牙设备。3)& && & 模块工作状态a)& && &&&休眠:主机模式下,无串口数据传输,不扫描外部设备;从机模式下,无串口数据传输,不对外广播。b)& && & 待机:处于无连接状态,串口可以进行数据传输。c)& && &&&正常工作:可以进行AT指令模式和透传模式的所有操作。4)& && & WK管脚的功能说明WK管脚为输入管脚,用户输入高电平或者低电平,可以实现以下功能:a)& && &&&模块处于休眠状态时:用户只要修改了WK管脚的输入状态即反转了电平,模块将被唤醒至正常工作状态。此时如果设置了AT+NOTI[Y],用户将会收到OK+WAKE。b)& && & 模块处于正常工作状态时,WK管脚的电平决定了模块的工作方式:高电平——AT指令模式,低电平——透传模式。5)& && & LED管脚的功能说明LED管脚为输出管脚,显式模块当前工作状态:a)& && &&&待机状态慢闪——500ms脉冲。b)& && & 连接状态常亮——高电平。&&AT+ ——测试:& & 指令&&
&&&&应答&&
AT+OK无AT+HELP ——帮助查询:& & 指令&&
&&&&应答&&
AT+HELP帮助信息无AT+VERS ——软件版本查询:& & 指令&&
&&&&应答&&
AT+VERS版本信息无AT+NAME? ——查询/设置模块名称:& & 指令&&
&&&&应答&&
查询:AT+NAME?OK+GET:paraPara:模块名称&&最长允许15个字符,包括字母、数字、下划线。&&默认para=MT-BLE-DEV设置:AT+NAME[para]OK+SET:paraAT+RENEW ——恢复出厂设置:& & 指令&&
&&&&应答&&
AT+RENEW OK+RENEW无(此操作会导致模块重启)AT+RESET ——重启模块:& & 指令&&
&&&&应答&&
AT+RESETOK+RESET无AT+ROLE? ——查询/设置主从模式:& & 指令&&
&&&&应答&&
查询:AT+ROLE?OK+GET:paraPara:P,C&&P:从设备&&C:主设备&&默认para=P设置:AT+ROLE[para]OK+SET:paraAT+NOTI? ——查询/设置是否把当前连接状态通知给用户:& & 指令&&
&&&&应答&&
查询:AT+NOTI?OK+GET:paraPara:Y,N&&Y:通知用户&&N:不通知用户&&默认para=Y设置:AT+NOTI[para]OK+SET:para注意:设置了通知用户,连接成功会回复”OK+ CONN:S”,连接失败会回复”OK+ CONN:U”;在任何模式任何时候下,连接断开后会向上位机发送”OK+CONN:L”;详细可AT+CLEAR。AT+IMME? ——查询/设置模块工作方式:& & 指令&&
&&&&应答&&
查询:AT+IMME?OK+GET:paraPara:Y,N&&Y:上电立即自动工作&&N:上电暂不工作,等待用户的手动操作&&默认para=Y设置:AT+IMME[para]OK+SET:para注意:1)& && &&&模块主机模式下手动操作流程:a)& && && &AT+STARTb)& && &&&AT+DISCc)& && && &AT+CON/AT+CONN2)& && &&&模块从机模式下设置了AT+IMME[N]将不会自动广播,需发送AT+START启动广播。AT+START ——开始工作:& & 指令&&
&&&&应答&&
AT+START OK+START 无AT+TYPE? ——查询/设置模块密码验证类型:& & 指令&&
&&&&应答&&
查询:AT+TYPE?OK+GET:paraPara:N,Y&&N:连接不需要密码&&Y:连接需要密码&&默认para=N设置:AT+TYPE[para]OK+SET:para串口指令AT+BAUD? —— 查询/设置波特率:& & 指令&&
&&&&应答&&
查询:AT+BAUD?OK+GET:paraPara:A~G&&A:2400&&B:4800&&C:9600&&D:19200&&E:57600&&F:115200&&G:230400&&默认para=C设置:AT+BAUD[para]OK+SET:para注意:变更了波特率后,上位机在原有的波特率下无法接收到回复”OK+SET:para”,用户需要把上位机的波特率修改到相应的值后才能进行通信,这样即可验证波特率是否修改成功。AT+FLOW? ——查询/设置硬件流控:& & 指令&&
&&&&应答&&
查询:AT+FLOW?OK+GET:paraPara:N,Y&&N:关闭流控制&&Y:开启流控制&&默认para=N设置:AT+FLOW[para]OK+SET:paraAT+PARI? —— 查询/设置串口校验:& & 指令&&
&&&&应答&&
查询:AT+PARI?OK+GET:paraPara:A~C&&A:无校验&&B:偶校验&&C:奇校验&&默认para=A设置:AT+PARI[para]OK+SET:paraAT+STOP? —— 查询/设置停止位:& & 指令&&
&&&&应答&&
查询:AT+STOP?OK+GET:paraPara:A~B&&A:1位停止位&&B:2位停止位&&默认para=A设置:AT+STOP[para]OK+SET:para从机指令AT+ADVI? ——查询/设置广播时间间隔:& & 指令&&
&&&&应答&&
查询:AT+ADVI?OK+GET:paraPara:100~7000(单位:ms)&&默认para=100设置:AT+ADVI[para]OK+SET:para建议:虽然广播间隔越大模块越省电,但是苹果公司IOS系统建议最大广播间隔为1285ms,所以如果模块是用来和IOS设备连接,广播时间间隔尽量不要超过1285ms。AT+PWRM? ——查询/设置模块休眠方式:& & 指令&&
&&&&应答&&
查询:AT+PWRM?OK+GET:paraPara:Y,N&&N:不自动休眠,等待AT+ SLEEP命令进入休眠&&Y:自动休眠&&默认para=N设置:AT+PWRM[para]OK+SET:para连接相关指令AT+ISCON —— 查询当前模块是否处于连接状态:& & 指令&&
&&&&应答&&
AT+ ISCONOK+ ISCON:paraPara:Y,N&&Y:处于连接状态&&N:处于非连接状态AT+DISCON ——断开连接:& & 指令&&
&&&&应答&&
查询:AT+DISCONOK+DISCON无AT+CLEAR ——清除模块配对信息:& & 指令&&
&&&&应答&&
AT+CLEAR OK+CLEAR 无(清除成功连接过的设备地址信息)AT+RADD ——查询成功连接过的远程主机地址:& & 指令&&
&&&&应答&&
AT+RADDOK+RADD:paraPara:蓝牙设备MAC地址AT+SAVE? ——查询/设置模块成功连接后是否保存连接地址:& & 指令&&
&&&&应答&&
查询:AT+SAVE?OK+GET:paraPara:Y,N&&Y:保存&&N:不保存&&默认para=Y设置:AT+SAVE[para]OK+SET:para注意:如果用户希望每次上电的时候,模块直接去搜索可连接设备,而不是连接上次成功连接过的设备,可以先执行AT+CLEAR清除掉上次的地址,然后执行AT+SAVE[N]。AT+POWE? ——查询/设置模块发射功率:& & 指令&&
&&&&应答&&
查询:AT+POWE?OK+GET:paraPara:A~D&&A:-23dbm&&B:-6dbm&&C:0dbm&&D:4dbm&&默认para=C设置:AT+POWE[para]OK+SET:para模块信息相关指令AT+PASS? ——查询/设置配对密码:& & 指令&&
&&&&应答&&
查询:AT+PASS?OK+GET:paraPara:999&&密码必须是6位整数&&默认para=888888设置:AT+PASS[para]OK+SET:paraAT+UUID? ——更改服务UUID:& & 指令&&
&&&&应答&&
查询:AT+UUID?OK+GET:paraPara:0000~FFFE&&Para是2字节的十六进制数&&默认para=FFA0设置:AT+UUID[para]OK+SET:paraAT+CHAR? ——更改服务属性(characteristic):& & 指令&&
&&&&应答&&
查询:AT+CHAR?OK+GET:paraPara:0001~FFFE&&Para是2字节的十六进制数&&默认para=FFA1设置:AT+CHAR[para]OK+SET:paraAT+MAC ——查询本机MAC地址:& & 指令&&
&&&&应答&&
AT+MACOK+MAC:paraPara:蓝牙设备MAC地址AT+RSSI ——读取 RSSI 信号值:& & 指令&&
&&&&应答&&
AT+RSSIOK+RSSI:paraPara:信号强度,单位为db&&Para是一个负数,绝对值越小说明信号强度越大IO监控指令AT+LED? ——查询/设置LED输出状态:& & 指令&&
&&&&应答&&
查询:AT+LED?OK+GET:paraPara:S,N&&S:待机慢闪,连接后常亮&&N:待机不闪,连接后常亮&&默认para=S设置:AT+LED[para]OK+SET:para电源管理指令AT+BATC? ——查询/设置电量监控开关:& & 指令&&
&&&&应答&&
查询:AT+BATC?OK+GET:paraPara:Y/N&&N:电量监控关闭&&Y:电量监控开启&&默认para=N设置:AT+BATC[para]OK+SET:paraAT+BATT ——查询电量信息:& & 指令&&
&&&&应答&&
AT+BATTOK+BATT:paraPara:0~100(单位%)&&本指令只对电池供电方案有效,100%=3V,0%=2V模块出厂设置:
& & 属性&&
&&&&出厂值&&
模块名称MT-BLE-ADV主从模式从机模式通知状态模块连接时主动通知用户工作方式上电立即自动工作密码验证类型连接不需要密码串口波特率115200串口硬件流控制关闭串口校验方式无校验串口停止位1位默认广播时间间隔100ms功率设置0dbm休眠方式不自动休眠配对密码888888服务UUID0xFFA0服务属性0xFFA1
18:43:06  
这个必须跟帖啊
16:24:14  
22:24:12  
非常好,现在还不会用蓝牙,正好学学
13:57:44  
第三节&&蓝牙开发常用软件的使用(一)之USBDongle
具体详细操作请下载附件
1.1 抓包入门1.请用户先确认是从馒头科技购买的具有抓包功能的MT-USBDongle,或者用户自己更换成了具有抓包功能的固件,若不确定请联系客服。2.从中馒头科技蓝牙4.0系列——&MT-USBDongle——&抓包软件文件夹中下载TI官方提供的Packet Sniffer抓包工具,解压并安装。& && && && && && && && && && && & 3.启动软件,选择Bluetooth Low Energy选项,点击START。 4.插入MT-USBDongle到电脑USB接口,可以在PacketSniffer软件窗口底部Selectcapturing device中看到CC2540USB Dongle设备,如下图。选择该设备,然后单击菜单栏下面蓝色小三角按钮(开始抓包按钮)即可进行数据包的捕获。& &&&5.如果附近存在从机设备在广播信息,那么Packet Sniffer软件中就会显示其广播数据。点击蓝牙双竖条就可停止捕获。& &&&6.从软件捕获到的数据包中可以看到,每个数据包有很多段组成,这与蓝牙4.0BLE协议是对应的,由于蓝牙4.0协议栈采用分层结构实现的,所以数据包在显示时也是不同的层使用不同的颜色来表示,这样方便用户查看不同层的数据。数据包各字段含义如下表。
& & PktNumber&&
&&&&Time&&
&&Channel&&
&&Access Address&&
&&Adv PDU Type&&
&&Adv PDU Header&&
数据包序号数据包接收时间广播通道访问地址广播类型广播数据头&&AdvA&&
&&AdvData&&
广播设备的地址广播数据循环冗余校验接收的信号强度指示帧校验序列 1.2常用技能1. 当这个垃圾桶按钮按下时,每次开始捕获数据就会把上次捕获到的数据清空,刷新窗口重新显示。窗口左下角会显示捕获的包数量。& &&&& &&&
2. 当这个按钮按下时,数据显示的窗口滑块会在最下面,方面用户观察最近收到的数据包。& &&&3. 当这个按钮按下时,数据的颜色块会缩小,显示的更紧凑。& &&&
1.3 过滤器的使用1. 当附近有多个从机设备在广播时,如图(根据AdvA这个字段可以区别不同的广播设备),如果只想显示其中一个设备的数据,另外一个不显示,可以开启过滤器Display Filter。& &&&2. 在软件窗口下面,切换到Display Filter选项卡,在Field Name中选择ADV_IND AdvA,再点击右边的First按钮会在FilterCondition中显示AA1=x,将x改成你想要捕获的设备的地址,如0x7C669D9F6297,再单击Add,就会添加到下面的方框中,最后点击Apply Filter,开启过滤器。这时窗口就只会显示你想捕获的那个设备的数据包。& &&&3. 其他功能详细请参考《Packet Sniffer抓包工具用户手册》。1.4 抓取设备通信数据1. 打开抓包软件,将Radio Configuration中的Advertising Channel设置为38(2426MHz),启动抓包。然后再给BLE的从机和主机设备上电,让主机连接上从机,于是Packet Sniffer的窗口中就会出现如下数据。& &&&2.使用串口助手通过主机给从机发送透传数据,可以在抓取的数据包中看到发送的数据。& &&&3.再将主机切换工作模式到远控模式,发送AT+指令,得到回复OK\r\n,同样抓取的数据包中也可以看到。
13:57 上传
点击文件名下载附件
下载积分: 积分 -1 分
1.32 MB, 下载次数: 174, 下载积分: 积分 -1 分
13:57 上传
点击文件名下载附件
下载积分: 积分 -1 分
3.79 MB, 下载次数: 189, 下载积分: 积分 -1 分
13:57 上传
点击文件名下载附件
下载积分: 积分 -1 分
58.29 KB, 下载次数: 92, 下载积分: 积分 -1 分
18:02:28  
第四节&&iBeacon基站的空中无线升级
1.&&通过PC进行OAD无线升级需要MT-USBDongle,结合TI提供的BLE Device Monitor软件。用户可以到馒头科技淘宝旗舰店购买到MT-USBDongle,然后根据馒头团队撰写的《MT-USBDongle-用户手册》中“PC端调试开发功能”章节安装好BLE Device Monitor。
2.& & 在中下载到馒头科技提供的升级固件,A和B都要下载。
2.jpg (20.21 KB, 下载次数: 4)
17:58 上传
3.& &&&打开BLE Device Monitor软件,自动扫描当前正在广播的设备。
3.jpg (110.82 KB, 下载次数: 2)
17:58 上传
4.& &&&成功扫描到一个MT-iBeacon基站设备,MAC地址为:7C:66:9D:9F:63:84。信号强度为-73。点击Connect按钮,向此设备发起连接。
4.jpg (75.99 KB, 下载次数: 2)
17:58 上传
5.& &&&连接上后,事件日志文本框中会提示,OAD support detected,说明此设备支持OAD无线升级。
5.jpg (133.2 KB, 下载次数: 2)
17:58 上传
6.& &&&在菜单栏Options——&GAPSettings设置选项中,按下图给出的值设置好。
6.jpg (119.91 KB, 下载次数: 0)
17:58 上传
7.& &&&在菜单栏File中点击Program(OAD),进行OAD升级过程。这时可以在弹出来的窗口看到Target Image中显示“Type: B Version:1”,那么需要选择iBeaconA-V2.0.bin作为升级固件。反之亦然。
7.jpg (130.1 KB, 下载次数: 1)
17:58 上传
8.& &&&在File Image中选择刚才下载的iBeaconA-V2.0.bin固件,然后点击Start开始升级。升级完成后MT-iBeacon设备会自动重启,BLE DeviceMonitor会失去与之的连接,这时可以单击左下角的Reset按钮,复位软件重新扫描当前的iBeacon设备,或者适用手机设备搜索该设备。如果能够搜索到则说明升级成功,可以发送AT指令查看固件版本号是否更新。
8.jpg (137.11 KB, 下载次数: 1)
17:58 上传
9.& &&&(重复7、8步骤会出现的另外一种情况)在菜单栏File中点击Program(OAD),进行OAD升级过程。这时可以在弹出来的窗口看到Target Image中显示“Type: A Version:1”,那么需要选择iBeaconB-V2.0.bin作为升级固件。
9.jpg (118.27 KB, 下载次数: 2)
17:58 上传
10.& &&&在File Image中选择刚才下载的iBeaconB-V2.0.bin固件,然后点击Start开始升级。升级完成后MT-iBeacon设备会自动重启,BLE DeviceMonitor会失去与之的连接,这时可以单击左下角的Reset按钮,复位软件重新扫描当前的iBeacon设备,或者适用手机设备搜索该设备。如果能够搜索到则说明升级成功,可以发送AT指令查看固件版本号是否更新。
11.& &&&注意:7-8步骤和9-10步骤,是用户在升级过程中会遇到的两种情况,用户只要执行了其中一种就可以完全升级成功。
20:41:36  
第五节&&iBeacon基站通过iPhone实现无线升级
& & 为了使用iPhone或者iPad对iBeacon进行固件更新,首先要确认手机为iPhone4S及以上,系统为IOS7及以上,在AppStore里搜索下载Multitool,这个APP是TI免费提供的,可以直接下载安装。安装好这个APP后,PC上需要使用iTunes将固件拷贝到手机。
1.1.1& &iTunes操作
11.jpg (82.99 KB, 下载次数: 1)
20:37 上传
& & 这里我们将需要更新的固件A和B都拷贝到手机。1.1.1& &iPhone操作
1.打开Multitool,搜索设备
12.jpg (22.51 KB, 下载次数: 1)
20:37 上传
2. 连接iBeacon
& & 这步要确保iBeacon没有进行部署,否则无法连接上设备,如果已经进行了临时部署,可以将电池卸下重新安装后才可以连接。连接后可以看到如下界面,选择Update FW。
13.jpg (17.89 KB, 下载次数: 3)
20:37 上传
3.选择升级模式
& & 选择高速模式,并且进入固件选择。
14.jpg (21.46 KB, 下载次数: 2)
20:37 上传
4.选择Shared File
进入固件选择界面,这里注意,我们可以看到选择运行的固件为A固件,所以我们需要选择B固件进行更新(如果运行的是B固件,则需要选择A固件进行更新),我们选择Shared File。
15.jpg (20.76 KB, 下载次数: 2)
20:37 上传
5.固件选择
& & 选择B固件,进行升级。
16.jpg (20.89 KB, 下载次数: 1)
20:37 上传
6.正在升级
17.jpg (20.01 KB, 下载次数: 1)
20:37 上传
18.jpg (23.7 KB, 下载次数: 1)
20:41 上传
17:56:33  
本帖最后由 zzq宁静致远 于
19:56 编辑
MT254X蓝牙4.0开发板第二课:点亮LED
& & 经过前面一系列的准备,我们这堂课程开始MT254X蓝牙4.0开发板的第一课,在进行本堂课程之前,大家必须先下载上一堂课程的视频进行搭建好编译环境,下载地址:/share/link?shareid=&uk=#dir/path=%2F%E6%9C%B1%E5%85%86%E7%A5%BAForARM%2F%E9%A6%92%E5%A4%B4%E7%A7%91%E6%8A%80%E8%93%9D%E7%89%994.0%E7%B3%BB%E5%88%97%2F%E8%93%9D%E7%89%994.0%E8%AF%BE%E7%A8%8B
& & 编译环境搭建好之后,我们开始编写程序。其实大家有了之前单片机编写程序的基础,我相信转到蓝牙4.0应该不难。
LED.c文件:
/******************************************************************************
& && && && && && &版权所有 (C), , 深圳市馒头科技有限公司
******************************************************************************
&&文 件 名& &: LED.c
&&版 本 号& &: V1.0
&&作& & 者& &: 朱兆祺
&&生成日期& &: 日
&&功能描述& &: 点亮一个LED
&&函数列表& &:
& && && && &&&main
&&修改历史& &:
&&1.日& & 期& &: 日
& & 作& & 者& &: 朱兆祺
& & 修改内容& &: 创建文件
******************************************************************************/
/*----------------------------------------------*
* 包含头文件& && && && && && && && && && && &&&*
*----------------------------------------------*/
#include &ioCC2540.h&
#include &delay.h&
/*****************************************************************************
函 数 名&&: main
功能描述&&: 主函数,C程序入口
输入参数&&: void
输出参数&&: 无
返 回 值&&:
修改历史& && &:
&&1.日& & 期& &: 日
& & 作& & 者& &: 朱兆祺
& & 修改内容& &: 创建
*****************************************************************************/
int main(void)
{
& & P1SEL &= ~0X03;& &&&// 将P1.1、0设置为IO功能
& & P1DIR |= 0X03;& && &// 设置P1.1、0为输出功能
& &
& & while(1)
& & {
& & P1&&= (P1 & 0XFC) | 0X01;& && && &// 设置P1.0输出高电平
& & }
& & return 0;
}复制代码& & 根据CC254X的数据手册,我们可以很快知道P1SEL是设置IO功能,P1DIR是设置输入输出。至于为什么程序是这么写,我们来看下,CC254X芯片的P1口一共有8个IO口,那就是说刚刚好由两位十六进制进行控制:(FF),这里仅仅是LED1和LED2,也就是P1.1和P1.0两个IO口,为了不影响其他引脚的使用,我们这里巧妙使用与或控制其功能。比如:P1 = (P1 & 0XFC) | 0X01;P1与上,这样不影响其他引脚的基础上,清除了P1.0和P1.1的输出,再或上0X01,这样将P1.0设置为高电平,根据原理图,高电平是点亮LED2.
QQ图片03.jpg (76.26 KB, 下载次数: 3)
17:51 上传
& & 根据原理图,P1.0对应的是LED2,这里我们能够看到LED2处于点亮的状态。
QQ图片54.jpg (44.89 KB, 下载次数: 2)
17:49 上传
& & 下节更精彩,有什么问题,大家直接在本帖提出,我将依次解答。
MT254X蓝牙4.0开发板第二课:点亮LED视频下载地址:/share/link?shareid=&uk=#dir/path=%2F%E6%9C%B1%E5%85%86%E7%A5%BAForARM%2F%E9%A6%92%E5%A4%B4%E7%A7%91%E6%8A%80%E8%93%9D%E7%89%994.0%E7%B3%BB%E5%88%97%2F%E8%93%9D%E7%89%994.0%E8%AF%BE%E7%A8%8B
15:57:32  
本帖最后由 zzq宁静致远 于
19:57 编辑
MT254X蓝牙4.0开发板第三课:控制LED
& & 我们上一堂课点亮了单个LED灯,我们这堂课接着控制LED灯。这堂课我们要完成的是LED闪烁10次,蜂鸣器响1s钟。这里我们先使用延时函数进行。
/******************************************************************************
& && && && && && &版权所有 (C), , 深圳市馒头科技有限公司
******************************************************************************
&&文 件 名& &: delay.h
&&版 本 号& &: V1.0
&&作& & 者& &:&&朱兆祺
&&生成日期& &: 日
&&功能描述& &: 主函数
&&函数列表& &:
& && && && &&&
&&修改历史& &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&朱兆祺
& & 修改内容& &: 创建文件
******************************************************************************/
#ifndef&&__DELAY_H__
#define&&__DELAY_H__
/*****************************************************************************
函 数 名&&: Delay1ms
功能描述&&: 延时函数
输入参数&&: unsigned int uiDelay:延时1ms的数量
输出参数&&: 无
返 回 值&&:
修改历史& && &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&朱兆祺
& & 修改内容& &: 创建
*****************************************************************************/
extern void Delay1ms(unsigned int uiDelay);
/* end&&file */复制代码延时函数的执行程序delay.c:
/******************************************************************************
& && && && && && &版权所有 (C), , 深圳市馒头科技有限公司
******************************************************************************
&&文 件 名& &: delay.c
&&版 本 号& &: V1.0
&&作& & 者& &:&&朱兆祺
&&生成日期& &: 日
&&功能描述& &: 主函数
&&函数列表& &:
& && && && &&&
&&修改历史& &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&朱兆祺
& & 修改内容& &: 创建文件
******************************************************************************/
/* 包含delay延时的头文件 */
#include &delay.h&
/*****************************************************************************
函 数 名&&: Delay1ms
功能描述&&: 延时函数
输入参数&&: unsigned int uiDelay:延时1ms的数量
输出参数&&: 无
返 回 值&&:
修改历史& && &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&朱兆祺
& & 修改内容& &: 创建
*****************************************************************************/
void Delay1ms(unsigned int uiDelay)
{
& &
& &
& & for ( ; uiDelay & 0; uiDelay--)
& & {
& && &&&/* 延时1ms */
& && &&&for (i = 0; i & 320; i++);
& & }
}
/* end&&file */复制代码& &大家要特别注意程序的可移植性和健壮性。主函数其实也很简单,也是依葫芦画瓢:
/******************************************************************************
& && && && && && &版权所有 (C), , 深圳市馒头科技有限公司
******************************************************************************
&&文 件 名& &: main.c
&&版 本 号& &: V1.0
&&作& & 者& &:&&朱兆祺
&&生成日期& &: 日
&&功能描述& &: 主函数
&&函数列表& &:
& && && && &&&
&&修改历史& &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&朱兆祺
& & 修改内容& &: 创建文件
******************************************************************************/
/* 包含CC254X的头文件 */
#include &ioCC2540.h&
#include &delay.h&
/*****************************************************************************
函 数 名&&: main
功能描述&&: 主函数
输入参数&&: 无
输出参数&&: 无
返 回 值&&:
修改历史& && &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&朱兆祺
& & 修改内容& &: 创建
*****************************************************************************/
int main(void)
{
& & /* 控制LED灯闪烁 */
& &
& & /* 驱动无源蜂鸣器 */
& &
& &
&&
& & /* 将P1.0、P1.1设置为IO口 */
& & P1SEL &= ~0x03;
& & /* 将P1.0、P1.1设置为IO口的输出 */
& & P1DIR |= 0x03;
& &
& & /* 将P2.0设置为IO口 */
& & P2SEL &= ~0x01;
& & /* 将P2.0设置为IO口输出 */
& & P2DIR |= 0x01;
& &
& & /* 主循环 */
& & while(1)
& & {
& && &&&/* LED1,LED2闪烁10次 */
& && &&&for (i = 0; i & 10; i++)
& && &&&{
& && && && &/* P1.0----LED2,P1.1----LED1 */
& && && && &/* P1.0,P1.1输出高电平,即点亮LED2,LED1 */
& && && && &/* FC :&&*/
& && && && &P1 = (P1 & 0xFC) | 0x03;
& && && && &Delay1ms(1000);
& && &&&
& && && && &/* P1.0,P1.1输出低电平,即熄灭LED2,LED1 */
& && && && &/* FC :&&*/
& && && && &P1 = (P1 & 0xFC) & (~0x03);
& && && && &Delay1ms(1000);
& && &&&}
& && &&&
& && &&&/* 给出500HZ的方波驱动 */
& && &&&for(j = 0; j & 1000; j++)
& && &&&{
& && && && &/* P2.0----蜂鸣器 */
& && && && &P2 = (P2 & 0xFE) & (~0x01);
& && && && &Delay1ms(1);
& && && && &P2 = (P2 & 0xFE) | 0x01;
& && && && &Delay1ms(1);
& && &&&}
& & }
& &&&
}
/* end&&file */复制代码这里需要注意的是,我们MT254X蓝牙4.0开发板使用的无源蜂鸣器,那么我们需要产生一个方波来驱动。如这代码:
& && &&&/* 给出500HZ的方波驱动 */
& && &&&for(j = 0; j & 1000; j++)
& && &&&{
& && && && &/* P2.0----蜂鸣器 */
& && && && &P2 = (P2 & 0xFE) & (~0x01);
& && && && &Delay1ms(1);
& && && && &P2 = (P2 & 0xFE) | 0x01;
& && && && &Delay1ms(1);
& && &&&}复制代码& &如果是有缘蜂鸣器,则没有那么麻烦,直接给出低电平驱动。为什么是低电平,我们看下原理图:
QQ图片03.jpg (18.93 KB, 下载次数: 2)
15:56 上传
& & 我们使用的PNP三极管,并且使用续流二极管保护蜂鸣器。我们MT254X蓝牙开发板从稳定性、安全性等多方面综合考虑,是一款出色的蓝牙开发板。
MT254X蓝牙4.0开发板第三课:控制LED视频下载地址:/share/link?shareid=&uk=#dir/path=%2F%E6%9C%B1%E5%85%86%E7%A5%BAForARM%2F%E9%A6%92%E5%A4%B4%E7%A7%91%E6%8A%80%E8%93%9D%E7%89%994.0%E7%B3%BB%E5%88%97%2F%E8%93%9D%E7%89%994.0%E8%AF%BE%E7%A8%8B
20:08:19  
MT254X蓝牙4.0开发板第四课:点亮LCD12864(1)上一堂课我们成功控制了LED和蜂鸣器,这一堂课我们马不停蹄接着LCD12864的控制。关于LCD12864的手册请大家在馒头电子科技有限公司百度官方网盘下载:/share/link?shareid=&uk=#dir/path=%2F%E6%9C%B1%E5%85%86%E7%A5%BAForARM%2F%E9%A6%92%E5%A4%B4%E7%A7%91%E6%8A%80%E8%93%9D%E7%89%994.0%E7%B3%BB%E5%88%97%2FMT254xBoard%E8%93%9D%E7%89%99%E5%BC%80%E5%8F%91%E6%9D%BFLCD12864的控制原理我们下一堂课详细讲解,这一堂课我们讲解外部晶振控制和点亮LCD12864。为了系统能够稳定的工作,首先我们将系统时钟切换到32M的外部晶振,为了自由配置所需要的时钟,主要借助于CLKCONCMD.OSC选择系统主时钟,而借助于CLKCONCMD.OSC32K则用于选择芯片32K时钟源!而低功耗模式设置时,需要借助于SLEEPCMD寄存器,在《CC253x-CC2540-41Applications User's Guide.pdf》中并没有说明SLEEPCMD第二位功能,如下所示:
1.jpg (36.63 KB, 下载次数: 2)
20:04 上传
但是参考cc2430芯片的说明书可以发现,对应的SLEEP寄存器则有说明,如下所示,这个是TI有意隐藏芯片细节,当SLEEPCMD.OSC_PD为0时,32MHz晶振与16MHz RC振荡器都会起振:
2.jpg (47.71 KB, 下载次数: 2)
20:05 上传
对于SLEEPSTA寄存器中BIT6/BIT5说明在cc2530说明书中也并没有说明,可以参考cc2430说明书中内容,其中第6位XOSC_STB表明外部高速32M晶振是否上电并稳定起振,当稳定时该位为1;同样对于第5位HFRC_STB则表明内部16MHz高速RC振荡器是否起振,并是否稳定,当16MHz RC振荡器稳定时该位为1。/*****************************************************************************
函 数 名&&: SysStartXOSC
功能描述&&: 启动外部晶振
输入参数&&: void
输出参数&&: 无
返 回 值&&:
修改历史& && &:
&&1.日& & 期& &: 日
& & 作& & 者& &: 朱兆祺
& & 修改内容& &: 创建
*****************************************************************************/
void SysStartXOSC(void)
{
& & SLEEPCMD &= ~0x04;& && && && && && && & // 启动所有晶振
& & while (!(SLEEPSTA & 0x40));& && && && & // 等待晶振稳定
& & CLKCONCMD = (CLKCONCMD & 0x80) | 0x49;&&// 使用16M晶振作为主时钟
& & while ((CLKCONSTA & ~0x80) != 0x49 );& &// 等待主时钟切换到16M晶振
& & CLKCONCMD = (CLKCONCMD & ~0x80) ;& && & // 使用外部32K晶振作为休眠时钟
& & while ( (CLKCONSTA & 0x80) != 0 );& && &// 等待睡眠时钟切换到外部32K晶振
& & CLKCONCMD = (CLKCONCMD & 0x80) ;& && &&&// 使用32M晶振作为主时钟
& & while ( (CLKCONSTA & ~0x80) != 0 );& &&&// 等待主时钟切换到32M晶振
& & SLEEPCMD |= 0x04;& && && && && && && &&&// 关闭未使用的晶振
}复制代码& & 按照上述方式配置后,我们就可以工作在外部的32M晶振上了,配置好系统时钟和SPI后,剩下的工作只需要按照液晶屏的说明书发送相应的指令就可以将液晶屏驱动起来了,具体的驱动代码详见下一堂课程。这里使用的是ASCII的点阵表,所以只能显示英文,如果需要显示中文,就需要中文字库的支持了。/*****************************************************************************
函 数 名&&: main
功能描述&&: 主函数
输入参数&&: 无
输出参数&&: 无
返 回 值&&:
修改历史& && &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&朱兆祺
& & 修改内容& &: 创建
*****************************************************************************/
int main(void)
{
& & /* 启动外部晶振 */
& & SysStartXOSC();
& &
& & /* LCD12864的初始化 */
& & LCD12864_Init();
& &
& & /* 清屏 */
& & LCD12864_Clear();
& &
& & while(1)
& & {
& && &&&/* 显示字符 */
& && &&&LCD12864_DisStr(3, &ShenZhenShiManTouKeJi&);
& & }
& &
& & return 0;
}复制代码& &这样我们就点亮的LCD12864屏幕,关于LCD12864的驱动原理,我们下一堂课详细讲解,不要走开,精彩在持续更新。
效果抢先看:
3.jpg (56.58 KB, 下载次数: 1)
20:08 上传
11:36:23  
MT254X蓝牙4.0开发板第五课:LCD12864(2)(LCD12864驱动)
& & 我们上一堂课程点亮了LCD12864,这堂课详细讲解下LCD12864的驱动程序。
/******************************************************************************
& && && && && && &版权所有 (C), , 深圳市馒头科技有限公司
******************************************************************************
&&文 件 名& &: Lcd12864.h
&&版 本 号& &: V1.0
&&作& & 者& &: 朱兆祺
&&生成日期& &: 日
&&功能描述& &: Lcd12864.c 的头文件
&&函数列表& &:
&&修改历史& &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&谢贤斌
& & 修改内容& &: 创建文件
******************************************************************************/
#ifndef __LCD12864_H__
#define __LCD12864_H__
/*----------------------------------------------*
* 包含头文件& && && && && && && && && && && &&&*
*----------------------------------------------*/
#include &common.h&
/*----------------------------------------------*
* 宏定义& && && && && && && && && && && && && &*
*----------------------------------------------*/
/*----------------------------------------------*
* 数据类型& && && && && && && && && && && && & *
*----------------------------------------------*/
/*----------------------------------------------*
* 外部变量说明& && && && && && && && && && && &*
*----------------------------------------------*/
/*----------------------------------------------*
* 内部函数原型说明& && && && && && && && && &&&*
*----------------------------------------------*/
/*----------------------------------------------*
* 全局变量& && && && && && && && && && && && & *
*----------------------------------------------*/
/*----------------------------------------------*
* 模块级变量& && && && && && && && && && && &&&*
*----------------------------------------------*/
/*----------------------------------------------*
* 常量定义& && && && && && && && && && && && & *
*----------------------------------------------*/
#ifdef __cplusplus
#if __cplusplus
extern &C&{
#endif
#endif /* __cplusplus */
extern void LCD12864_Clear(void);
extern void LCD12864_DisChar(uint8 line, uint8 col, char ch);
extern void LCD12864_DisStr(uint8 line, char* pStr);
extern void LCD12864_Init(void);
extern void SoftWaitUs(uint32 microSecs);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* __LCD12864_H__ */
复制代码& &这是我们LCD12864需要使用到的头文件中的函数声明。
& & 接下来我们详细看看LCD12864驱动程序的具体实现:
/******************************************************************************
& && && && && && &版权所有 (C), , 深圳市馒头科技有限公司
******************************************************************************
&&文 件 名& &: Lcd12864.c
&&版 本 号& &: V1.0
&&作& & 者& &: 朱兆祺
&&生成日期& &: 日
&&功能描述& &: LCD12864驱动
& && && && &&&//control
& && && && &&&P0.1 - LCD_MODE
& && && && &&&P1.2 - LCD_CS
& && && && &&&//spi
& && && && &&&P1.5 - CLK
& && && && &&&P1.6 - MOSI
&&函数列表& &:
&&修改历史& &:
&&1.日& & 期& &: 日
& & 作& & 者& &: 朱兆祺
& & 修改内容& &: 创建文件
******************************************************************************/
/*----------------------------------------------*
* 包含头文件& && && && && && && && && && && &&&*
*----------------------------------------------*/
#include &ioCC2540.h&
#include &Lcd12864.h&
#include &common.h&
/*----------------------------------------------*
* 宏定义& && && && && && && && && && && && && &*
*----------------------------------------------*/
/* LCD lines */
#define LCD12864_MAX_LINE& && && && && & 64
#define LCD12864_MAX_ROW& && && && && &&&128
#define HAL_LCD_FONT_LINES& && && && && & 8
#define HAL_LCD_FONT_ROWS& && && && && &&&6
/* LCD Max Chars and Buffer */
#define HAL_LCD_MAX_LINES& && && && &(LCD12864_MAX_LINE/HAL_LCD_FONT_LINES)& && & // 6*8点阵最大行数
#define HAL_LCD_MAX_CHARS& && && && &(LCD12864_MAX_ROW/HAL_LCD_FONT_ROWS)& && && &// 6*8点阵最大列数
/* LCD Control lines */
#define HAL_LCD_RS_PORT& && && && & 0
#define HAL_LCD_RS_PIN& && && && &&&1
#define HAL_LCD_CS_PORT& && && && & 1
#define HAL_LCD_CS_PIN& && && && &&&2
/* LCD SPI lines */
#define HAL_LCD_CLK_PORT& && && && &1
#define HAL_LCD_CLK_PIN& && && && & 5
#define HAL_LCD_MOSI_PORT& && && &&&1
#define HAL_LCD_MOSI_PIN& && && && &6
// 12864 命令
#define& & & & & & & & LCD_CMD_DISPLAY_ON& & & & & & & & & & & & & & & & 0xAF
#define& & & & & & & & LCD_CMD_DISPLAY_OFF& & & & & & & & & & & & & & & & 0xAE
#define& & & & & & & & LCD_CMD_BEGIN_LINE& & & & & & & & & & & & & & & & 0x40
#define& & & & & & & & LCD_CMD_PAGE_LINE& & & & & & & & & & & & & & & & 0xB0
#define& & & & & & & & LCD_CMD_ROW_HIG& & & & & & & & & & & & & & & & & & & & 0x10
#define& & & & & & & & LCD_CMD_ROW_LOW& & & & & & & & & & & & & & & & & & & & 0x00
#define& & & & & & & & LCD_CMD_READ_STATE& & & & & & & & & & & & & & & & 0x00
#define& & & & & & & & LCD_CMD_ROW_ADDR_NORMAL& & & & & & & & & & & & 0xA0& & & & & & & & // 从左到右
#define& & & & & & & & LCD_CMD_ROW_ADDR_REVERSE & & & & & & & & 0xA1& & & & & & & & // 从右到左
#define& & & & & & & & LCD_CMD_DISPLAY_NORMAL& & & & & & & & & & & & 0xA6
#define& & & & & & & & LCD_CMD_DISPLAY_REVERSE& & & & & & & & & & & & 0xA7
#define& & & & & & & & LCD_CMD_DISPLAY_POINT_ALL& & & & & & & & 0xA5
#define& & & & & & & & LCD_CMD_DISPLAY_POINT_NORMAL& & & & 0xA4
#define& & & & & & & & LCD_CMD_BIAS_SET& & & & & & & & & & & & & & & & 0xA2& & & & & & & & // 0XA2:BIAS=1/9 (常用)&&0XA3:BIAS=1/7
#define& & & & & & & & LCD_CMD_SOFT_RESET& & & & & & & & & & & & & & & & 0xE2
#define& & & & & & & & LCD_CMD_LINE_NORMAL& & & & & & & & & & & & & & & & 0xC0& & & & & & & & // 从上到下
#define& & & & & & & & LCD_CMD_LINE_REVERSE& & & & & & & & & & & & 0xC8& & & & & & & & // 从下到上
#define& & & & & & & & LCD_CMD_POWER_ONE& & & & & & & & & & & & & & & & 0x2C
#define& & & & & & & & LCD_CMD_POWER_TWO& & & & & & & & & & & & & & & & 0x2E
#define& & & & & & & & LCD_CMD_POWER_THREE& & & & & & & & & & & & & & & & 0x2F
#define& & & & & & & & LCD_CMD_CONTRAST_ONE_LEVEL& & & & & & & & 0x22&&// 0x20-0x27
#define& & & & & & & & LCD_CMD_CONTRAST_TWO_CMD& & & & & & & & 0x81&&// 0x00-0x3F
#define& & & & & & & & LCD_CMD_STATIC_PICTURE_ON& & & & & & & & 0xAD
& &/* SPI interface control */
#define LCD_SPI_BEGIN()& &&&HAL_CONFIG_IO_OUTPUT(HAL_LCD_CS_PORT,&&HAL_LCD_CS_PIN,&&0); /* chip select */
#define LCD_SPI_END()& && && && && && && && && && && && && && && && && && && &\
{& && && && && && && && && && && && && && && && && && && && && && && && && &&&\
&&asm(&NOP&);& && && && && && && && && && && && && && && && && && && && && &&&\
&&asm(&NOP&);& && && && && && && && && && && && && && && && && && && && && &&&\
&&asm(&NOP&);& && && && && && && && && && && && && && && && && && && && && &&&\
&&asm(&NOP&);& && && && && && && && && && && && && && && && && && && && && &&&\
&&HAL_CONFIG_IO_OUTPUT(HAL_LCD_CS_PORT,&&HAL_LCD_CS_PIN,&&1); /* chip select */& && && &\
}
/* clear the received and transmit byte status, write tx data to buffer, wait till transmit done */
#define LCD_SPI_TX(x)& && && && && && & { U1CSR &= ~(BV(2) | BV(1)); U1DBUF = while( !(U1CSR & BV(1)) ); }
/* Control macros */
#define LCD_DO_WRITE()& && &&&HAL_CONFIG_IO_OUTPUT(HAL_LCD_RS_PORT,&&HAL_LCD_RS_PIN,&&1);
#define LCD_DO_CONTROL()& && &HAL_CONFIG_IO_OUTPUT(HAL_LCD_RS_PORT,&&HAL_LCD_RS_PIN,&&0);
/*----------------------------------------------*
* 数据类型& && && && && && && && && && && && & *
*----------------------------------------------*/
/*----------------------------------------------*
* 外部变量说明& && && && && && && && && && && &*
*----------------------------------------------*/
/*----------------------------------------------*
* 内部函数原型说明& && && && && && && && && &&&*
*----------------------------------------------*/
static void LCD12864_Dat(uint8 data);
static void LCD12864_Cmd(uint8 cmd);
/*----------------------------------------------*
* 全局变量& && && && && && && && && && && && & *
*----------------------------------------------*/
/*----------------------------------------------*
* 模块级变量& && && && && && && && && && && &&&*
*----------------------------------------------*/
/*----------------------------------------------*
* 常量定义& && && && && && && && && && && && & *
*----------------------------------------------*/
/*全体ASCII 列表:5x7点阵库*/
const static uint8 aucAsciiTable5x7[][5]={
0x00,0x00,0x00,0x00,0x00,//space
0x00,0x00,0x4f,0x00,0x00,//!
0x00,0x07,0x00,0x07,0x00,//&
0x14,0x7f,0x14,0x7f,0x14,//#
0x24,0x2a,0x7f,0x2a,0x12,//$
0x23,0x13,0x08,0x64,0x62,//%
0x36,0x49,0x55,0x22,0x50,//&
0x00,0x05,0x07,0x00,0x00,//]
0x00,0x1c,0x22,0x41,0x00,//(
0x00,0x41,0x22,0x1c,0x00,//)
0x14,0x08,0x3e,0x08,0x14,//*
0x08,0x08,0x3e,0x08,0x08,//+
0x00,0x50,0x30,0x00,0x00,//,
0x08,0x08,0x08,0x08,0x08,//-
0x00,0x60,0x60,0x00,0x00,//.
0x20,0x10,0x08,0x04,0x02,///
0x3e,0x51,0x49,0x45,0x3e,//0
0x00,0x42,0x7f,0x40,0x00,//1
0x42,0x61,0x51,0x49,0x46,//2
0x21,0x41,0x45,0x4b,0x31,//3
0x18,0x14,0x12,0x7f,0x10,//4
0x27,0x45,0x45,0x45,0x39,//5
0x3c,0x4a,0x49,0x49,0x30,//6
0x01,0x71,0x09,0x05,0x03,//7
0x36,0x49,0x49,0x49,0x36,//8
0x06,0x49,0x49,0x29,0x1e,//9
0x00,0x36,0x36,0x00,0x00,//:
0x00,0x56,0x36,0x00,0x00,//;
0x08,0x14,0x22,0x41,0x00,//&
0x14,0x14,0x14,0x14,0x14,//=
0x00,0x41,0x22,0x14,0x08,//&
0x02,0x01,0x51,0x09,0x06,//?
0x32,0x49,0x79,0x41,0x3e,//@
0x7e,0x11,0x11,0x11,0x7e,//A
0x7f,0x49,0x49,0x49,0x36,//B
0x3e,0x41,0x41,0x41,0x22,//C
0x7f,0x41,0x41,0x22,0x1c,//D
0x7f,0x49,0x49,0x49,0x41,//E
0x7f,0x09,0x09,0x09,0x01,//F
0x3e,0x41,0x49,0x49,0x7a,//G
0x7f,0x08,0x08,0x08,0x7f,//H
0x00,0x41,0x7f,0x41,0x00,//I
0x20,0x40,0x41,0x3f,0x01,//J
0x7f,0x08,0x14,0x22,0x41,//K
0x7f,0x40,0x40,0x40,0x40,//L
0x7f,0x02,0x0c,0x02,0x7f,//M
0x7f,0x04,0x08,0x10,0x7f,//N
0x3e,0x41,0x41,0x41,0x3e,//O
0x7f,0x09,0x09,0x09,0x06,//P
0x3e,0x41,0x51,0x21,0x5e,//Q
0x7f,0x09,0x19,0x29,0x46,//R
0x46,0x49,0x49,0x49,0x31,//S
0x01,0x01,0x7f,0x01,0x01,//T
0x3f,0x40,0x40,0x40,0x3f,//U
0x1f,0x20,0x40,0x20,0x1f,//V
0x3f,0x40,0x38,0x40,0x3f,//W
0x63,0x14,0x08,0x14,0x63,//X
0x07,0x08,0x70,0x08,0x07,//Y
0x61,0x51,0x49,0x45,0x43,//Z
0x00,0x7f,0x41,0x41,0x00,//[
0x02,0x04,0x08,0x10,0x20,// 斜杠
0x00,0x41,0x41,0x7f,0x00,//]
0x04,0x02,0x01,0x02,0x04,//^
0x40,0x40,0x40,0x40,0x40,//_
0x01,0x02,0x04,0x00,0x00,//`
0x20,0x54,0x54,0x54,0x78,//a
0x7f,0x48,0x48,0x48,0x30,//b
0x38,0x44,0x44,0x44,0x44,//c
0x30,0x48,0x48,0x48,0x7f,//d
0x38,0x54,0x54,0x54,0x58,//e
0x00,0x08,0x7e,0x09,0x02,//f
0x48,0x54,0x54,0x54,0x3c,//g
0x7f,0x08,0x08,0x08,0x70,//h
0x00,0x00,0x7a,0x00,0x00,//i
0x20,0x40,0x40,0x3d,0x00,//j
0x7f,0x20,0x28,0x44,0x00,//k
0x00,0x41,0x7f,0x40,0x00,//l
0x7c,0x04,0x38,0x04,0x7c,//m
0x7c,0x08,0x04,0x04,0x78,//n
0x38,0x44,0x44,0x44,0x38,//o
0x7c,0x14,0x14,0x14,0x08,//p
0x08,0x14,0x14,0x14,0x7c,//q
0x7c,0x08,0x04,0x04,0x08,//r
0x48,0x54,0x54,0x54,0x24,//s
0x04,0x04,0x3f,0x44,0x24,//t
0x3c,0x40,0x40,0x40,0x3c,//u
0x1c,0x20,0x40,0x20,0x1c,//v
0x3c,0x40,0x30,0x40,0x3c,//w
0x44,0x28,0x10,0x28,0x44,//x
0x04,0x48,0x30,0x08,0x04,//y
0x44,0x64,0x54,0x4c,0x44,//z
0x08,0x36,0x41,0x41,0x00,//{
0x00,0x00,0x77,0x00,0x00,//|
0x00,0x41,0x41,0x36,0x08,//}
0x04,0x02,0x02,0x02,0x01,//~
};
const uint8 asciiTableSize = sizeof( aucAsciiTable5x7 ) / sizeof( aucAsciiTable5x7[0]);
/*****************************************************************************
函 数 名&&: SoftWaitUs
功能描述&&: 软件延时,us为单位, 系统时钟在32M时
输入参数&&: uint16 microSecs
输出参数&&: 无
返 回 值&&:
修改历史& && &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&谢贤斌
& & 修改内容& &: 创建
*****************************************************************************/
void SoftWaitUs(uint32 microSecs)
{
& & while(microSecs--)
& & {
& && &&&/* 32 NOPs == 1 usecs */
& && &&&asm(&nop&); asm(&nop&); asm(&nop&); asm(&nop&); asm(&nop&);
& && &&&asm(&nop&); asm(&nop&); asm(&nop&); asm(&nop&); asm(&nop&);
& && &&&asm(&nop&); asm(&nop&); asm(&nop&); asm(&nop&); asm(&nop&);
& && &&&asm(&nop&); asm(&nop&); asm(&nop&); asm(&nop&); asm(&nop&);
& && &&&asm(&nop&); asm(&nop&); asm(&nop&); asm(&nop&); asm(&nop&);
& && &&&asm(&nop&); asm(&nop&); asm(&nop&); asm(&nop&); asm(&nop&);
& && &&&asm(&nop&); asm(&nop&);
& & }
}
/*****************************************************************************
函 数 名&&: LCD12864_Cmd
功能描述&&: 发送控制命令
输入参数&&: uint8 cmd
输出参数&&: 无
返 回 值&&:
修改历史& && &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&谢贤斌
& & 修改内容& &: 创建
*****************************************************************************/
static void LCD12864_Cmd(uint8 cmd)
{
& & LCD_SPI_BEGIN();
& & LCD_DO_CONTROL();
& & LCD_SPI_TX(cmd);
& & //LCD_SPI_WAIT_RXRDY();
& & LCD_SPI_END();
}
/*****************************************************************************
函 数 名&&: LCD12864_Dat
功能描述&&: 发送数据
输入参数&&: uint8 data
输出参数&&: 无
返 回 值&&:
修改历史& && &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&谢贤斌
& & 修改内容& &: 创建
*****************************************************************************/
static void LCD12864_Dat(uint8 data)
{
& & LCD_SPI_BEGIN();
& & LCD_DO_WRITE();
& & LCD_SPI_TX(data);
& & // LCD_SPI_WAIT_RXRDY();
& & LCD_SPI_END();
}
/**************************************************************************************************
* @fn& && &HalLcd_HW_Init
* @brief& &Initilize HW LCD Driver.
* @param& &None
* [url=home.php?mod=space&uid=1141835]@Return[/url]&&None
**************************************************************************************************/
void LCD12864_Init(void)
{
& & PERCFG |= 0x02;& && & // 设置UART alt2 为 SPI
& & // 配置引脚为SPI功能
& & HAL_CONFIG_IO_PERIPHERAL(HAL_LCD_CLK_PORT,&&HAL_LCD_CLK_PIN);
& & HAL_CONFIG_IO_PERIPHERAL(HAL_LCD_MOSI_PORT, HAL_LCD_MOSI_PIN);
& & /* Configure SPI */
& & U1UCR&&= 0x80;& && &// 清除原来的数据
& & U1CSR&&= 0x00;& && &// SPI 主机模式
& & // 高位在前,第一个上升沿发送数据,波特率为2M
& & U1GCR&&= HAL_SPI_TRANSFER_MSB_FIRST | HAL_SPI_CLOCK_PHA_0 | HAL_SPI_CLOCK_POL_LO | 0x0F;
& & U1BAUD = 0xFF;
& & // CS RS 配置为输出
& & HAL_CONFIG_IO_OUTPUT(HAL_LCD_RS_PORT, HAL_LCD_RS_PIN, 1);
& & HAL_CONFIG_IO_OUTPUT(HAL_LCD_CS_PORT, HAL_LCD_CS_PIN, 1);
& & SoftWaitUs(15000); // 15 ms
& & LCD12864_Cmd(LCD_CMD_SOFT_RESET);& & & & //软复位
& & & & SoftWaitUs(15000); // 15 ms
& & & & LCD12864_Cmd(LCD_CMD_POWER_ONE);& & & & //升压步聚1
& & & & SoftWaitUs(15); // 15 us
& & & & LCD12864_Cmd(LCD_CMD_POWER_TWO);& & & & //升压步聚2
& & & & SoftWaitUs(15); // 15 us
& & & & LCD12864_Cmd(LCD_CMD_POWER_THREE);& & & & //升压步聚3
& & & & SoftWaitUs(150); // 15 us
& & & & LCD12864_Cmd(LCD_CMD_CONTRAST_ONE_LEVEL);& & & & //粗调对比度,可设置范围0x20~0x27
& & & & LCD12864_Cmd(LCD_CMD_CONTRAST_TWO_CMD);& & & & //微调对比度
& & & & LCD12864_Cmd(0x3a);& & & & //0x1a,微调对比度的值,可设置范围0x00~0x3f
& & & & LCD12864_Cmd(LCD_CMD_BIAS_SET);& & & & // 1/9偏压比(bias)
& & & & LCD12864_Cmd(LCD_CMD_LINE_NORMAL);& & & & //行扫描顺序:从上到下
& & & & LCD12864_Cmd(LCD_CMD_ROW_ADDR_REVERSE);& & & & //列扫描顺序:从左到右
& & & & LCD12864_Cmd(LCD_CMD_BEGIN_LINE);& & & & //起始行:第一行开始
& & & & LCD12864_Cmd(LCD_CMD_DISPLAY_ON);& & & & //打开显示
& & LCD12864_Cmd(LCD_CMD_DISPLAY_POINT_NORMAL);
& & LCD12864_Cmd(LCD_CMD_DISPLAY_NORMAL);& && & //设置为正显模式
& & & & SoftWaitUs(150); // 150 us
& &// LCD12864_Clear();
}
/*****************************************************************************
函 数 名&&: LCD12864_SetAddr
功能描述&&: 设置起始地址
输入参数&&: uint8 line
& && && && & uint8 col
输出参数&&: 无
返 回 值&&:
修改历史& && &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&谢贤斌
& & 修改内容& &: 创建
*****************************************************************************/
static void LCD12864_SetAddr(uint8 line, uint8 col)
{
& & uint8 ucLine, ucR
& & //line += 5;
& & col&&+= 4;
& & if((line &= LCD12864_MAX_LINE) || (col &= LCD12864_MAX_ROW))
& & {
& && &&&
& & }
& & ucLine = LCD_CMD_PAGE_LINE | (line&0x0f);
& & LCD12864_Cmd(ucLine);
& & SoftWaitUs(15);
& & ucRow = LCD_CMD_ROW_HIG | (col&&4);
& & LCD12864_Cmd(ucRow);
& & SoftWaitUs(15); // 15 us
& & ucRow = LCD_CMD_ROW_LOW | (col&0x0f);
& & LCD12864_Cmd(ucRow);
& & SoftWaitUs(15); // 15 us
}
/*****************************************************************************
函 数 名&&: LCD12864_Dis5X8
功能描述&&: 将一个字符用5*8的点阵显示
输入参数&&: char ch
输出参数&&: 无
返 回 值&&:
修改历史& && &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&谢贤斌
& & 修改内容& &: 创建
*****************************************************************************/
static void LCD12864_Dis5X8(char ch)
{
& & uint8 ucC
& & if((ch &= 0x20)&&(ch & 0x7f))
& & {
& && &&&uint8 ucChar = ch - 0x20;
& && &&&for(ucCnt=0; ucCnt&5; ucCnt++)
& && &&&{
& && && && &LCD12864_Dat( aucAsciiTable5x7[ucChar][ucCnt]);
& && &&&}
& && &&&//LCD12864_Dat(0x00);
& & }
& & else if(ch==0x00)& &&&//不需要显示,清空指定位置
& & {
& & & & & & & & for(ucCnt=0; ucCnt&5; ucCnt++)
& && &&&{
& && && && &LCD12864_Dat(0x00);
& && &&&}
& & & & }
& & LCD12864_Dat(0x00);
}
/*****************************************************************************
函 数 名&&: LCD12864_Clear
功能描述&&: 清屏
输入参数&&: void
输出参数&&: 无
返 回 值&&:
修改历史& && &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&谢贤斌
& & 修改内容& &: 创建
*****************************************************************************/
void LCD12864_Clear(void)
{
& & uint8 ucLine, ucR
& & for(ucLine=0; ucLine&LCD12864_MAX_LINE; ucLine++)
& & {
& && &&&LCD12864_SetAddr(ucLine, 0);
& && &&&for(ucRow=0; ucRow&LCD12864_MAX_ROW; ucRow++)
& && &&&{
& && &&&& & & & LCD12864_Dat(0x00);
& && &&&}
& & }
}
/*****************************************************************************
函 数 名&&: LCD12864_DisChar
功能描述&&: 在指定位置显示一个字符
输入参数&&: uint8 line
& && && && & uint8 col
& && && && & char ch
输出参数&&: 无
返 回 值&&:
修改历史& && &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&谢贤斌
& & 修改内容& &: 创建
*****************************************************************************/
void LCD12864_DisChar(uint8 line, uint8 col, char ch)
{
& & if (( line & HAL_LCD_MAX_LINES)&&(col & HAL_LCD_MAX_CHARS))
& & {
& && &&&LCD12864_SetAddr(line, col*HAL_LCD_FONT_ROWS);
& && &&&LCD12864_Dis5X8(ch);
& & }
}
/*****************************************************************************
函 数 名&&: LCD12864_DisStr
功能描述&&: 将字符串显示到指定行
输入参数&&: uint8 line& && && &显示的行 0~7
& && && && & char* pStr& && && &显示的字符串首地址
输出参数&&: 无
返 回 值&&:
修改历史& && &:
&&1.日& & 期& &: 日
& & 作& & 者& &:&&谢贤斌
& & 修改内容& &: 创建
*****************************************************************************/
void LCD12864_DisStr(uint8 line, char* pStr)
{
& & uint8 ucCnt = 0;
& & for ( ucCnt = 0 ; ucCnt & HAL_LCD_MAX_CHARS; ucCnt++ )
& & {
& && &&&if ( '\0' == *pStr )
& && &&&{
& && && && &
& && &&&}
& && &&&LCD12864_DisChar( line, ucCnt, pStr[ucCnt]);
& & }
& & for (&&; ucCnt & HAL_LCD_MAX_CHARS; ucCnt++ )
& & {
& && &&&LCD12864_DisChar( line, ucCnt, 0);
& & }
}
/*----------------------------------------------*
*& && && && &&&end of file& && && && && && && &*
*----------------------------------------------*/
复制代码
精彩继续更新。
13:27:54  
,,,,,,,,,,,
13:57:58  
猪,你的鼻子有两个孔,牛逼
11:29:29  
MT254X蓝牙4.0开发板第六课:独立按键之查询方式
& & 在MT254xboard上有一个独立按键KEY1,如图 ,独立按键和复位键在整个班子的左上角。按键通过P0.0口和CPU连接,在没有按键时为高电平,按下后为低电平。下面我们通过LCD来显示独立按键的状态。
1.jpg (30.65 KB, 下载次数: 1)
11:19 上传
2.jpg (8.47 KB, 下载次数: 1)
11:19 上传
& & 复制LCD12864工程,重命名为Key。我们先用查询的方式读取按键的状态。因为按键接入在P0.0口,所以我们读取P0.0口的电平即可知道按键的状态。uint8 KeyValue(void)& & & & & & & & & & & & & & & & // 读取按键状态
{
& & if((P0&0X01) == 0X00 )& && &// 按下为低电平
& & {
& && &&&return KEY_DOWN;
& & }
& & else
& & {
& && &&&return KEY_UP;
& & }
}
复制代码& & 这里我们在while循环中不断的读取按键状态,并且判断是否改变,如果改变则改变LCD的显示。int main(void)
{
& & uint8 OldKeyValue = 0;& & & & & & & &
& & uint8 NewKeyValue = 0;
& & SysStartXOSC();
& & LCD12864_Init();
& & LCD12864_DisStr(1, && & Key Test&);
& & & & // 按键初始化
& & P0SEL &= ~0X01;& & & & // 设置为 IO功能
& & P0DIR &= ~0X01;& & & & // 设置为输入功能
& & while(1)
& & {
& && &&&NewKeyValue = KeyValue();& &// 读取按键状态
& && &&&if(OldKeyValue != NewKeyValue)&&// 按键状态改变
& && &&&{
& && && && &OldKeyValue = NewKeyV&&// 保存当前按键状态
& && && && &if(OldKeyValue == KEY_DOWN)
& && && && &{
& && && && && & LCD12864_DisStr(3, && & Key Down &);
& && && && &}
& && && && &else
& && && && &{
& && && && && & LCD12864_DisStr(3, && & Key Up &);
& && && && &}
& && &&&}
& & }
& & return 0;
}
复制代码
3.jpg (45.85 KB, 下载次数: 1)
11:29 上传
精彩继续更新。
11:36:22  
MT254X蓝牙4.0开发板第七课:独立按键之中断方式& & 复制Key工程,重命名为KeyInterrupt。刚刚我们用查询的方式读取按键的状态。但是这种方式在实际的工程中没有实际的应用价值,下面我们采用外部中断的方式来读取按键的状态,每当按键按下时就会触发一次外部中断。为了P0.0口能够触发中断,我们需要进行如下配置:& & P0IEN |= 0X01;&&// P00 设置为中断方式
& & PICTL &=~ 0X01; // 下降沿触发
& & IEN1 |= 0X20;& &// 允许P0口中断
& & P0IFG = 0x00;& &// 清除中断标志位
& & EA = 1;& && && &// 开总中断复制代码& & 然后就需要编写中断服务函数了。这里注意一点,在IAR中的中断函数有点特殊,格式为:#pragma vector = 中断向量
__interrupt 函数
复制代码& & 所以我们的中断函数为:#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void)
{
& & if(0x01&P0IFG)
& & {
& && &&&NewKeyValue = KEY_DOWN;& &&&// 记录按键按下
& & }
& & P0IFG = 0;& && && && &&&//清中断标志
& & P0IF = 0;& && && && && &//清中断标志
}
复制代码& & 在中断中我们记录按键按下,等待应用程序处理。而在主函数中我们需要处理按键按下事件,主函数中我们对按键计数并且通过LCD显示。int main(void)
{
& & char LCDBuf[21]={0};& && && && &// 显存
& & int KeyCnt = 0;
& & SysStartXOSC();
& & LCD12864_Init();
& & LCD12864_DisStr(1, && & Key Test&);
& & P0SEL &= ~0X01; // 设置为IO功能
& & P0DIR &= ~0X01; // 设置为输入功能
& & P0IEN |= 0X01;&&// P0.0 设置为中断方式
& & PICTL |= 0X01;&&// 下降沿触发
& & IEN1 |= 0X20;& &// 允许P0口中断
& & P0IFG = 0x00;& &// 清除中断标志位
& & EA = 1;& && && &// 开总中断
& & sprintf(LCDBuf, && &Key Count : %d&, KeyCnt++);& & // 按键计数
& & LCD12864_DisStr(3, LCDBuf);
& & while(1)
& & {
& && &&&if(KEY_DOWN == NewKeyValue)&&// 按键按下
& && &&&{
& && && && &SoftWaitUs(25000);& && & // 延时防抖
& && && && &if((P0&0X01) == 0X00)& &// 再次确认按键是否按下
& && && && &{
& && && && && & sprintf(LCDBuf, && &Key Count : %d&, KeyCnt++);& & // 按键计数
& && && && && & LCD12864_DisStr(3, LCDBuf);
& && && && &}
& && && && &else
& && && && &{
& && && && && & NewKeyValue = KEY_UP;& &// 按键松开
& && && && &}
& && &&&}
& & }
& & return 0;
}
复制代码& & 实验现象如下,每按一次按键计数加1。
4.jpg (42.46 KB, 下载次数: 1)
11:36 上传
精彩继续更新。
11:08:07  
MT254X蓝牙4.0开发板第八课:CC2540内部温度传感器温度采集& & CC2540内部有一个温度传感器,我们这节使用这个传感器来采集芯片的温度,此传感器精度不高。不适合用于实际的工程中,这里只为演示AD采样。要使用内部的温度采集我们需要使用AD采样,所以我们需要先来了解CC2540的AD功能。在后续课程有对ADC的详细说明。& & ADC结构图如下所示:
1.jpg (18.86 KB, 下载次数: 1)
11:03 上传
& & ADC控制寄存器1如下图所示:
2.jpg (46.19 KB, 下载次数: 1)
11:03 上传
& & 我们使用手动触发的方式进行AD采样,所以STSEL = 11B,最低两位始终为1,最终ADCCON1=0x33。& & ADC控制寄存器3如图所示:
3.jpg (51.92 KB, 下载次数: 1)
11:05 上传
& & ADC参考电压使用内部电压,采用12位精度采集。采集温度通道。所以ADCCON3= 0x3e。这里注意一点,ADCCON2和ADCCON3的配置是一样的,我们这里用ADCCON3来配置。uint16 ADC_Read (uint8 channel)
{
& & int16&&reading = 0;
& & uint8&&adcChannel = 0x01&&
& & int16&&Result = 0;
& & if (channel &= 7)& &// 通道0-7需要通过P0.0-P0.7输入
& & {
& && &&&ADCCFG |= adcC
& & }
& & uint8 i=0;
& & do{
& && &&&ADCCON3 = channel | 0x20;& && && &&&// 12位精度,启动转换
& && &&&while (!(ADCCON1 & 0x80));& && && & // 等待转换完成
& && &&&// 读取采样结果
& && &&&reading = (int16)(ADCL);
& && &&&reading |= (int16)(ADCH && 8);
& && &&&reading &&= 4;& && && && && && && & // 丢弃低位
& && &&&Result +=& && && && && && &// 累加
& & }while(i++ & 10);& &// 连续采样10次
& & if (channel &= 7)
& & {
& && &&&ADCCFG &= (adcChannel ^ 0xFF);
& & }
& & return (Result/10);
}
复制代码& & 在读取温度值前,我们还需要使能温度传感器。int main(void)
{
& & float temp=0;
& & char LCDBuf[21] = {0};
& & SysStartXOSC();& && && &// 启动外部晶振
& & LCD12864_Init();& && &&&// LCD初始化
& & // 打开温度传感器
& & TR0 = 0x01;
& & ATEST = 0x01;
& & while(1)
& & {
& && &&&temp = (ADC_Read(TEMP_ADC_CHANNEL) - 1340) /10.0;
& && &&&sprintf(LCDBuf, && &temp : %0.1f&, temp); //
& && &&&LCD12864_DisStr(3, LCDBuf);
& && &&&SoftWaitUs(100000);
& & }
& & return 0;
}
复制代码& & 采集的温度显示在LCD上,可以看到温度在跳动,这是由于AD的误差太大导致的,这里只做一个简单的实验,如果需要工程应用,建议外接温度传感器。把手放在芯片上可以看到温度在上升。温度采集实验结果如下图所示:
4.jpg (47.64 KB, 下载次数: 1)
11:06 上传
精彩继续更新,请不要走开哦。
13:41:35  
非常不错。朱兆祺蓝牙4.0开发(连载),强烈支持。
16:50:45  
感谢分享好东西
Powered by

我要回帖

更多关于 nordic 蓝牙 的文章

 

随机推荐