CC2540的ADCCON2和ADCCON3有什么区别

CC2541蓝牙学习——ADC - 推酷
CC2541蓝牙学习——ADC
CC2541的ADC支持多达14位的模拟数字转换与高达12位的有效位数。它包括一个模拟多路转换器,具有多达8个各自可独立配置的通道,一个参考电压发生器。转换结果通过DMA写入存储器。还具有若干运行模式。
ADC主要特性如下:
可选的抽取率,设置了7~12位的分辨率;
8个独立输入通道,可接受单端或差分信号;
参考电压可选为内部,外部单端,外部差分,或AVDD5;
产生中断请求;
转换结束时的DMA触发;
温度传感器输入;
电池测量功能。
P0引脚上的信号可以作为ADC输入来使用。在下面,这些引脚叫做AIN0—AIN7引脚,输入脚AIN0—AIN7与ADC连接。
输入脚可配置成单端或差动输入。如选择差动输入,包含成对输入AIN0-AIN1,AIN2-AIN3,AIN4-AIN5和AIN6-AIN7;注意这些引脚既不能加载负电压,也不能加载大于VDD的电压。
除了输入脚AIN0-AIN7外,片上的温度传感器也可以用来作为ADC温度测量的输入。如要实现这个功能,需设置寄存器TR0.ADCTM和ATEST.ATESTCTRL。
单端输入AIN0至AIN7可代表通道号0至7,通道号8至11分别代表差动输入AIN0-AIN1,AIN2-AIN3,AIN4-AIN5,AIN6-AIN7;通道12表示GND,通道13表示温度传感器,通道15表示AVDD5/3。这些值在ADCCON2.SCH和ADCCON3.SCH中设置。
我们看到ADCCON2和ADCCON3这两个寄存器的定义基本相同,但是用法不同, ADCCON2用于ADC序列转换的配置,而ADCCON3则用于单个ADC通道的配置 。所谓ADC序列就是多个ADC通道按照次序分别转换。注意: 不是同时转换的,从图1我们也可以看出,ADC的模拟输入接一个选择器,同一时刻只能选择一个通道接入进行ADC转换 。
如果选择片上的温度传感器作为ADC温度测量的输入,则需要通过配置寄存器TR0和ATEST来获得片上温度,不过这个温度测量误差很大,我们一般不用,这里也就不给出例程了。
启用片内温度采集配置寄存器:
1 TR0 |= 0x01;
2 ATEST |= 0x01;
1、ADC序列转换
ADC序列转换无需CPU的参与,ADC能够完成一个序列的转换,并通过DMA把结果写入内存。
寄存器APCFG影响转换序列,来自I/O引脚的8位模拟输入不一定是程序设置的模拟输入。如某一通道是序列的一部分,但在APCFG中相应模拟输入是禁止的,那此通道将被跳过。当使用差动输入时,两个输入脚在APCFG寄存器中必须被设置成模拟输入。
ADCCON2.SCH用来定义ADC输入的转换序列。如ADCCON2.SCH被设为小于8,转换序列包含一个通道(从0到ADCCON2.SCH中设置的通道号),当ADCCON2.SCH值设为8至12时,序列是差动输入,从通道8至程序设置的通道号;当大于12时,序列包含只选择的通道。
2、单个ADC转换
除了序列转换外,ADC可以通过编程执行单个转换。 通过写入ADCCON3寄存器可以触发一个转换,转换立即启动 ,除非一个转换序列正在进行中,这种情况下,当序列完成后,马上执行单个转换。
3、寄存器ADCCON1
ADC的数字转换结果可以通过寄存器ADCCON1获得,寄存器ADCCON1的定义如下图所示。
ADCCON1.EOC:转换结束状态位,当转换结束时设高电平,当读取ADCH时低电平。
ADCCON1.ST位用来启动序列转换的,当这位设高电平、ADCCON1.STSEL是11且当前无转换运行时序列启动开始。当序列转换结束时,这位自动清除为低电平。
&ADCCON1.STSEL位用来选择哪个事件将启动一个新的序列转换。此项选择有:外部引脚P2.0上升沿事件,之前序列的结束事件,定时器通道0比较事件,或ADCCON1.ST设1事件。
4、ADC转换结果
数字转换结果以2进制补码形式表示的,最高位是符号位。
对于单端输入配置,由于ADC输入不能接负电压,转换结果总是正的当输入信号等于参考电压VREF时达到最大转换结果。
对于差分输入配置,ADC输入电压为两个引脚的电压之差,两脚的输入信号不同,结果可能是负的;当采样率为512,模拟输入Vconv=VREF时,12MSB的数字转换结果为2047,当模拟输入等于-VREF时,转换结果为-2048。
通过读ADCCON2.SCH位,知道正在转换的是哪个通道,在序列转换中,ADCL和ADCH中的结果是前一个通道ADC转换的值。如转换序列已结束,ADCCON2.SCH将有一个大于最后通道数一个以上的值,但如最后写入ADCCON2.SCH中的通道数是12或更大,读回的是相同的值。
5、ADC参考电压
模数转换的参考电压可选择于内部产生电压,AVDD5脚电压,应用于AIN7输入脚的外部电压,或应用于AIN6-AIN7输入的差动电压。
内部参考电压对于CC2541来说是 1.25V ,比较小,能转换的最大模拟电压最大也只能是1.25V,AVDD5脚电压一般为3.3V,精度也不是很高。
转换结果的准确度依靠于参考电压的稳定性和噪声度,所以对于要求较高的ADC转换建议从AIN7输入脚接入高精度的参考电压。
6、ADC转换时间
ADC只能运行于32MHZ XOSC 。执行一个转换的时间依靠于被选择的采样率,一般上,转换时间由以下公式所得:
Tconv=(decimation rate+16)*0.25us.
可见分辨率越高,转换时间越长。
7、ADC中断
只有单通道ADC转换才有ADC中断,序列ADC转换没有ADC中断。
The ADC generates an interrupt when a single conversion triggered by writing to ADCCON3 has completed.No interrupt is generated when a conversion from the sequence is completed.
8、ADC DMA触发
每完成一个序列转换,ADC将产生一个DMA触发。单独转换完成不产生DMA触发。
在ADCCON2.SCH中设置8个通道,每个通道都有一个DMA触发。当通道转换中准备好一个采样时,将激活一个DMA触发。DMA触发命名为ADC_CHsd,s是单端通道,d是差动通道。
另外,当ADC序列转换通道中准备好一个新数据时,一个DMA触发(ADC_CHALL)将激活。
单个ADC转换读取ADC值的程序如下:
1 /******************************************************************************
2 *函 数 名:InitADC
能:ADC初始化
4 *入口参数:参考电压 reference、转换通道 channel、分辨率resolution
5 *出口参数:ADC转换结果
6 ******************************************************************************/
7 uint Read_advalue(uchar reference, uchar channel, uchar
resolution)
uchar tmpADCCON3 = ADCCON3;
APCFG |= 1 && //设置ADC输入通道,模拟I/O使能
= (reference | resolution | channel);
ADCIF = 0;
while(!ADCIF);
//等待 AD 转换完成
ADCL && 2;
//ADCL 寄存器低 2 位无效
value |= ((uint)ADCH && 6);
//连接AD转换结果高位和低位
21 //根据分辨率获得ADC转换结果有效位
switch(resolution)
case ADC_7_BIT:
value &&= 7;break;
case ADC_9_BIT:
value &&= 5;break;
case ADC_10_BIT: value &&= 4;break;
case ADC_12_BIT: value &&= 2;break;
ADCCON3 = tmpADCCON3;
return (value);
主程序:采集VDD值。
1 /******************************************************************************
2 *程序入口函数
3 ******************************************************************************/
4 int main(void)
//ADC转换值
InitClock();
//32MHz时钟
InitUART();
//UART0串口初始化
13 //ADC参考电压AVDD5引脚电源电压:3.3V,分辨率12位,采集通道:VDD/3,VDD=3.3V
vddvalue = Read_advalue(ADC_REF_AVDD5, 0x0f, ADC_12_BIT);
vddvalue = (vddvalue*33) && 11;
vddvalue = vddvalue*3;
buf[0] = vddvalue/10 + '0';
buf[1] = '.';
buf[2] =vddvalue%10 + '0';
UartSendString(buf,strlen(buf));
//串口上传采样VDD值
Delay1ms(2000);
//每隔2s上传一次值
这里给出协议栈的adc转换函数参照对比。
1 #include &hal_adc.h&
2 uint16 u16cvalu=HalAdcRead(HAL_ADC_CHANNEL_4,HAL_ADC_RESOLUTION_12);
3 分辨率设置为12位时,从源码可以看出,可用位是ADCH 8位+ADCH高4位,其中ADCH最高位是符号位,所以有11位的分辨率,0-2047
4 默认基准电压3.3V
5 uint16 HalAdcRead (uint8 channel, uint8 resolution)
reading = 0;
9 #if (HAL_ADC == TRUE)
adcChannel = 1;
/* store the previously set reference voltage selection */
reference = ADCCON3 & HAL_ADC_REF_BITS;
* If Analog input channel is AIN0..AIN7, make sure corresponing P0 I/O pin is enabled.
* does NOT disable the pin at the end of this function.
I think it is better to leave the pin
* enabled because the results will be more accurate.
Because of the inherent capacitance on the
* pin, it takes time for the voltage on the pin to charge up to its steady-state level.
* HalAdcRead() has to turn on the pin for every conversion, the results may show a lower voltage
* than actuality because the pin did not have time to fully charge.
if (channel & 8)
for (i=0; i & i++)
adcChannel &&= 1;
/* Enable channel */
ADCCFG |= adcC
/* Convert resolution to decimation rate */
switch (resolution)
case HAL_ADC_RESOLUTION_8:
resbits = HAL_ADC_DEC_064;
case HAL_ADC_RESOLUTION_10:
resbits = HAL_ADC_DEC_128;
case HAL_ADC_RESOLUTION_12:
resbits = HAL_ADC_DEC_256;
case HAL_ADC_RESOLUTION_14:
resbits = HAL_ADC_DEC_512;
/* read ADCL,ADCH to clear EOC */
tmp = ADCL;
tmp = ADCH;
/* Setup Sample */
adctemp = ADCCON3;
adctemp &= ~(HAL_ADC_CHN_BITS | HAL_ADC_DEC_BITS | HAL_ADC_REF_BITS);
adctemp |= channel | resbits | (reference);
/* writing to this register starts the extra conversion */
/* Wait for the conversion to be done */
while (!(ADCCON1 & HAL_ADC_EOC));
/* Disable channel after done conversion */
ADCCFG &= (adcChannel ^ 0xFF);
/* Read the result */
reading = (int16) (ADCL);
reading |= (int16) (ADCH && 8);
/* Treat small negative as 0 */
if (reading & 0)
reading = 0;
switch (resolution)
case HAL_ADC_RESOLUTION_8:
reading &&= 8;
case HAL_ADC_RESOLUTION_10:
reading &&= 6;
case HAL_ADC_RESOLUTION_12:
reading &&= 4;
case HAL_ADC_RESOLUTION_14:
reading &&= 2;
// unused arguments
103 #endif
return ((uint16)reading);
调试结果:显示VDD值3.3V。
关于程序注意以下几点:
1、要配置一个端口0脚为一个ADC输入, APCFG寄存器中相应的位必须设置为1 。这个寄存器的默认值选择端口0引脚为非ADC,即数字输入输出。 APCFG寄存器的设置将覆盖P0SEL的设置,所以无需再配置P0SEL ,另外对于I/O口作为外设功能,都无需配置方向,即无需配置寄存器PxDIR。
2、对于单次ADC转换的配置,只需要配置寄存器ADCCON3,无需配置寄存器ADCCON1和ADCCON2。对于判断转换是否结束,还有一种判断方法:
ADCCON1 |=0X30;
//ADC启动方式选择为ADCCON1.ST=1事件
ADCCON1 |= 0x40;
//启动转换
while(!(ADCCON1 & 0x80));
//等待 AD 转换完成
ADCCON1.STSEL是用于启动转换序列的触发方式的,对于单次ADC转换,个人感觉这样配置不好,以后对于单次ADC转换,不采用这种判断方式。
单次转换判断是否转换结束:判断ADC中断标志ADCIF。
3、ADCH的最高位是符号位,对于单次测量,结果总是正的,所以符号位总是0。14位的ADC转换值有效值并不是14位的。
有效分辨率如下:
00: 64 decimation rate (7 bits ENOB)----ADCH低7位
01: 128 decimation rate (9 bits ENOB)---ADCH低7位+ADCH高2位
10: 256 decimation rate (10 bits ENOB)--ADCH低7位+ADCH高3位
11: 512 decimation rate (12 bits ENOB)--ADCH低7位+ADCL高5位
例如:采集VDD/3值时,使用12位分辨率,参考电压AVDD5:3.3V
VDD/3 = vddvalue*3.3/2^11扩大10倍
VDD/3 = vddvalue*33/2^11为什么是除以2^11而不是2^12,因为最高位是符号位,12位分辨率实际上只有11位。
VDD = (vddvalue*33/2^11) * 3
4、差分输入可以用来做比较器。比如通道ADCCON3.ECH=1000,对应差分输入AIN0-AIN1。如果要比较一个模拟信号和另一个模拟信号的大小关系,只需要将这两个信号分别接入AIN0和AIN1,然后判断ADCH的最高位,如果是1,则AIN0&AIN1,如果是0,则AIN0&=AIN1。
5、最大转换电压等于参考电压,而参考电压的选择不能大于芯片的电源电压,一般为3.3V。虽然差分输入可以转换负电压,但是每一个模拟输入引脚都必须是正电压且小于电源电压VDD,负电压是指两个输入通道的差值。
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致蓝牙4.0(CC2540/CC2541)BLE协议栈开发(连载) - 单片机/MCU论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
蓝牙4.0(CC2540/CC2541)BLE协议栈开发(连载)
15:41:33  
98912&查看
本帖最后由 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, 下载次数: 11)
16:45 上传
未标题-1.jpg (75.96 KB, 下载次数: 9)
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, 下载次数: 7)
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, 下载次数: 10)
15:45 上传
引脚分布图:
& & 模块的引脚分布图如下,用户设计电路时需要参考此分布图:
图片3.jpg (165.91 KB, 下载次数: 8)
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, 下载次数: 8)
15:47 上传
BLE协议栈开发:
& & 本模块出厂时默认自带了基于BLE1.4.0协议栈开发的串口透传固件,如果用户不想使用自带的固件,必须先擦除模块上的固件,再将新开发的固件写入到模块。图为协议栈开发的参考设计。
图片5.jpg (264.69 KB, 下载次数: 9)
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  
PCB在线计价下单
板子大小:
板子数量:
PCB 在线计价
第二节&&MT254x蓝牙4.0模块的透传测试
& & 我们在使用蓝牙模块之前,先使用MT254x蓝牙4.0调试底板进行相关的测试。
test (75).jpg (448.56 KB, 下载次数: 9)
09:27 上传
& & MT254xCoreSTest是深圳市馒头科技有限公司设计的适用于MT254xCoreS模块的测试底板。其特有的DB9通用接口,方便用户在在使用MT254xCoreS模块之前进行相关测试,直接通过串口连接到电脑,使用上位机串口助手软件及时验证模块的功能完整性,快速地上手使用。这样用户就不需要自己去设计底板来使用本模块,降低了用户的使用成本。同时MT254xCo- reSTest测试底座的体积已经做到了最小化,对于大部分用户来说,这样的体积可以直接应用到产品中,或者嵌入到自己的产品中。如果用户对此底板有更高的要求,也可以联系馒头科技,在基于批量的情况下,可以进行底板的定制。测试底板正面:
1.jpg (106.85 KB, 下载次数: 14)
09:34 上传
测试底板反面:
2.jpg (97.29 KB, 下载次数: 8)
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, 下载次数: 6)
09:36 上传
7.jpg (31.72 KB, 下载次数: 7)
09:36 上传
8.jpg (71.92 KB, 下载次数: 11)
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, 下载次数: 8)
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, 下载次数: 192, 下载积分: 积分 -1 分
13:57 上传
点击文件名下载附件
下载积分: 积分 -1 分
3.79 MB, 下载次数: 206, 下载积分: 积分 -1 分
13:57 上传
点击文件名下载附件
下载积分: 积分 -1 分
58.29 KB, 下载次数: 109, 下载积分: 积分 -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, 下载次数: 7)
17:58 上传
3.& &&&打开BLE Device Monitor软件,自动扫描当前正在广播的设备。
3.jpg (110.82 KB, 下载次数: 8)
17:58 上传
4.& &&&成功扫描到一个MT-iBeacon基站设备,MAC地址为:7C:66:9D:9F:63:84。信号强度为-73。点击Connect按钮,向此设备发起连接。
4.jpg (75.99 KB, 下载次数: 8)
17:58 上传
5.& &&&连接上后,事件日志文本框中会提示,OAD support detected,说明此设备支持OAD无线升级。
5.jpg (133.2 KB, 下载次数: 10)
17:58 上传
6.& &&&在菜单栏Options——&GAPSettings设置选项中,按下图给出的值设置好。
6.jpg (119.91 KB, 下载次数: 8)
17:58 上传
7.& &&&在菜单栏File中点击Program(OAD),进行OAD升级过程。这时可以在弹出来的窗口看到Target Image中显示“Type: B Version:1”,那么需要选择iBeaconA-V2.0.bin作为升级固件。反之亦然。
7.jpg (130.1 KB, 下载次数: 9)
17:58 上传
8.& &&&在File Image中选择刚才下载的iBeaconA-V2.0.bin固件,然后点击Start开始升级。升级完成后MT-iBeacon设备会自动重启,BLE DeviceMonitor会失去与之的连接,这时可以单击左下角的Reset按钮,复位软件重新扫描当前的iBeacon设备,或者适用手机设备搜索该设备。如果能够搜索到则说明升级成功,可以发送AT指令查看固件版本号是否更新。
8.jpg (137.11 KB, 下载次数: 7)
17:58 上传
9.& &&&(重复7、8步骤会出现的另外一种情况)在菜单栏File中点击Program(OAD),进行OAD升级过程。这时可以在弹出来的窗口看到Target Image中显示“Type: A Version:1”,那么需要选择iBeaconB-V2.0.bin作为升级固件。
9.jpg (118.27 KB, 下载次数: 10)
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, 下载次数: 10)
20:37 上传
& & 这里我们将需要更新的固件A和B都拷贝到手机。1.1.1& &iPhone操作
1.打开Multitool,搜索设备
12.jpg (22.51 KB, 下载次数: 8)
20:37 上传
2. 连接iBeacon
& & 这步要确保iBeacon没有进行部署,否则无法连接上设备,如果已经进行了临时部署,可以将电池卸下重新安装后才可以连接。连接后可以看到如下界面,选择Update FW。
13.jpg (17.89 KB, 下载次数: 13)
20:37 上传
3.选择升级模式
& & 选择高速模式,并且进入固件选择。
14.jpg (21.46 KB, 下载次数: 11)
20:37 上传
4.选择Shared File
进入固件选择界面,这里注意,我们可以看到选择运行的固件为A固件,所以我们需要选择B固件进行更新(如果运行的是B固件,则需要选择A固件进行更新),我们选择Shared File。
15.jpg (20.76 KB, 下载次数: 3)
20:37 上传
5.固件选择
& & 选择B固件,进行升级。
16.jpg (20.89 KB, 下载次数: 7)
20:37 上传
6.正在升级
17.jpg (20.01 KB, 下载次数: 8)
20:37 上传
18.jpg (23.7 KB, 下载次数: 10)
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, 下载次数: 12)
17:51 上传
& & 根据原理图,P1.0对应的是LED2,这里我们能够看到LED2处于点亮的状态。
QQ图片54.jpg (44.89 KB, 下载次数: 6)
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, 下载次数: 11)
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, 下载次数: 9)
20:04 上传
但是参考cc2430芯片的说明书可以发现,对应的SLEEP寄存器则有说明,如下所示,这个是TI有意隐藏芯片细节,当SLEEPCMD.OSC_PD为0时,32MHz晶振与16MHz RC振荡器都会起振:
2.jpg (47.71 KB, 下载次数: 7)
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, 下载次数: 6)
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, 下载次数: 8)
11:19 上传
2.jpg (8.47 KB, 下载次数: 10)
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, 下载次数: 8)
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, 下载次数: 8)
11:36 上传
精彩继续更新。
11:08:07  
MT254X蓝牙4.0开发板第八课:CC2540内部温度传感器温度采集& & CC2540内部有一个温度传感器,我们这节使用这个传感器来采集芯片的温度,此传感器精度不高。不适合用于实际的工程中,这里只为演示AD采样。要使用内部的温度采集我们需要使用AD采样,所以我们需要先来了解CC2540的AD功能。在后续课程有对ADC的详细说明。& & ADC结构图如下所示:
1.jpg (18.86 KB, 下载次数: 10)
11:03 上传
& & ADC控制寄存器1如下图所示:
2.jpg (46.19 KB, 下载次数: 10)
11:03 上传
& & 我们使用手动触发的方式进行AD采样,所以STSEL = 11B,最低两位始终为1,最终ADCCON1=0x33。& & ADC控制寄存器3如图所示:
3.jpg (51.92 KB, 下载次数: 8)
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位精度,启动转换
& && &&

我要回帖

更多关于 空调变频和定频的区别 的文章

 

随机推荐