




免费预览已结束,剩余25页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
SimpleAPP分析SimpleApp分析程序总是从helloword开始的,如果能找到一个例子开始,那么是最好不多的了,还好Ti为我们提供了很多的机会,让我们开始看一下simpleapp吧【Texas InstrumentsZStack-1.4.3-1.2.1ProjectszstackSamplesSimpleApp】SimpleApp里面有两个应用,一个是收集传感器的值,其中有一个传感器设备和一个收集设备;另一个应用时智能开关,有一个控制节点和一个灯节点。这里主要展示了如何网络建立,绑定和解绑定的演示以及开发一个自己的应用。双击打开Texas InstrumentsZStack-1.4.3-1.2.1ProjectszstackSamplesSimpleAppCC2430DBSimpleApp.eww工程,既然是51的内核那只能用C了,一个地球人都知道的原理就是C程序是从main()开始的,而且整个程序就是一个main()函数,那么好办了,我们找到main()然后分析它就可以看清楚整个程序的结构了。在工作空间中有8种项目配置,因为TI提供了两种开发板,所以实际上4种项目配置,分别配置成应用中4种设备。我们直接看智能灯的应用,跟这个应用相关的配置是(以DB开发板为原型):SimpleSwitchDB和SimpleControllerDB。SimpleSwitchDB是终端设备(我的理解是这里是灯的开关),SimpleControllerDB是控制设备是协调器或者路由器。这里之所以把和灯相连的设备作为协调器或者是路由器我认为是为了和家庭或者是场景中的其他设备进行交互所需要的。因为灯的状态还必须被其他的设备知道,就必须通知其他设备当前的状态!演示效果:控制设备-SW1:以协调器启动,SW2:以路由器启动启动控制设备将进入允许绑定状态,此时在10S内按动终端设备上的S1将发送绑定请求,成功绑定后LED1将点亮(如果打开节能选项,将是闪烁状态);按动终端设备上的S2将发送切换命令,将导致控制设备上的LED1开关状态的切换,按S3将此设备接绑定。效果清楚了接下来就是看看程序怎样了。找到ZMain.c,看看函数的描述Description: Startup and shutdown code for ZStack(启动和关闭Z-Stack)看来来对地方了哈。第一个宏:MINIMIZE_ROOT(line 126)如果定义这个宏那么ZMAIN中的API函数将被在ROOT段外实现以为用户提供更多的空间来定义自己的常量,默认这个编译选项是不定义的。所谓的ZMAIN API函数定义在line138-line144。在line152终于看到了期待的main()ZSEG int main( void ) / Turn off interrupts osal_int_disable( INTS_ALL ); / Initialize HAL /处理器运行时钟,LED IO口设置 HAL_BOARD_INIT(); / Make sure supply voltage is high enough to run zmain_vdd_check(); / Initialize stack memory zmain_ram_init(); / Initialize board I/O InitBoard( OB_COLD ); / Initialze HAL drivers HalDriverInit(); / Initialize NV System osal_nv_init( NULL ); / Determine the extended address zmain_ext_addr(); / Initialize basic NV items zgInit(); / Initialize the MAC ZMacInit();#ifndef NONWK / Since the AF isnt a task, call its initialization routine afInit();#endif / Initialize the operating system osal_init_system(); / Allow interrupts osal_int_enable( INTS_ALL ); / Final board initialization InitBoard( OB_READY ); / Display information about this device zmain_dev_info(); /* Display the device info on the LCD */#ifdef LCD_SUPPORTED zmain_lcd_init();#endif osal_start_system(); / No Return from here / main()2、osal_int_disable( INTS_ALL );/关中断/【OSAL.C】参数为INTS_ALL则关闭所有中断,否则关闭相应中断byte osal_int_disable( byte interrupt_id ) if ( interrupt_id = INTS_ALL ) HAL_DISABLE_INTERRUPTS();/关闭所有中断响应【hal_mcu.h】/#define HAL_DISABLE_INTERRUPTS() st( EA = 0; );/st的定义在【hal_defs.h】,其实就是为了保证宏能够准确的被执行用的/#define st(x) do x while (_LINE_ = -1); elsereturn ( INVALID_INTERRUPT_ID );/返回禁止相应的中断【ZComDef.h】/#define INVALID_INTERRUPT_ID 9 return ( ZSUCCESS );/执行成功就返回成功标志,其实按程序流程来看这个函数总是会返回成功标志的/#define ZSUCCESS 03、HAL_BOARD_INIT();/初始化板子硬件部分/板子初始化函数其实是一个宏,定义在【hal_board_cfg.h】“”符号其实是编译环境下面的行中断符,表示这一样没有结束,其实是一个“”。#define HAL_BOARD_INIT() uint16 i; SLEEP &= OSC_PD; /* turn on 16MHz RC and 32MHz XOSC */操作SLEEP寄存器,给16MHz高速振荡器和32M外部晶体振荡上电/【hal_mcu.h】 /#define OSC_PD 0x04 while (!(SLEEP & XOSC_STB); /* wait for 32MHz XOSC stable */ asm(NOP); /* chip bug workaround */ for (i=0; i504; i+) asm(NOP); /* Require 63us delay for all revs */ SLEEP寄存器中XOSC_STB位设置后还需要等待额外的64us,手册上是这么说的呵 CLKCON = (0x00 | OSC_32KHZ); /* 32MHz XOSC */设置32M和外部32.768K时钟为源 while (CLKCON != (0x00 | OSC_32KHZ); /等待时钟稳定 SLEEP |= OSC_PD; /* turn off 16MHz RC */关闭没有用到的时钟源/上面这段用来设置系统时钟,步骤为:所有时钟源上电;等待时钟稳定;延时64us等待确切的稳定;设置系统时钟和32K时钟的时钟源;等待设置完成,关闭没有用到的时钟源。 /* set direction for GPIO outputs */ LED1_DDR |= LED1_BV; /【hal_board_cfg.h】/ #define LED1_DDR P1DIR/ #define LED1_BV BV(0)/【hal_defs.h】/ #define BV(n) (1 (n);/这是将某位置位的宏 LED2_DDR |= LED2_BV; /【hal_board_cfg.h】/ #define LED2_DDR P1DIR/#define LED2_BV BV(1)/上面是对板上LED的初始化,完成的操作时将P1_0,P1_1设为输出(因为这两个IO口具有20ma的电流输出能力)!这里是跟硬件紧密相关的,需要根据自己硬件的具体情况来设。我的开发板上加上液晶指示的LED才两个,真是捉襟见肘啊,液晶背光灯接P2_0,调试LED接P1_0。设计的都不是很合理呢。看来在我的开发板上要完全的屏蔽掉LED2呢呵呵。进行相应更改:(这些更改都在文件hal_board_cfg.h中越在line94100)#define LED1_POLARITY ACTIVE_HIGH#define LED2_BV BV(0)#define LED2_SBIT P2_0#define LED2_DDR P2DIR /* configure tristates */ P2INP |= PUSH2_BV; /这是对Joystick的配置,在【hal_board_cfg.h】/#define PUSH2_BV BV(0);这里将Joystick的中心按键的IO设为三态状态,我的板子上没有这个东东哦,所以把Joystick也给屏蔽了,注释掉【hal_board_cfg.h】中约line120的东东 /* configure software controlled peripheral VDD */ /配置软件控制的外设VDD VDD_SW_DDR |= VDD_SW_BV; VDD_SW_SBIT = 0; /【hal_board_cfg.h】,这里实际上是将P1_2配置为输出,然后输出一个低电平/貌似我的板子上也用不到这个东西,屏蔽掉/#define VDD_SW_BV BV(2)/#define VDD_SW_SBIT P1_2/#define VDD_SW_DDR P1DIR/好了,以上就是硬件底层的一些初始化工作,主要是配置时钟和一些端口的状态。4、zmain_vdd_check();/确认VDD是否达到运行处理器的要求,如果没有达到就会闪烁LED/【ZMain.c】line210左右/重复检测VDD的状态,直到成功检测的次数达到规定过的要求为止。估计是等电源稳定吧,呵呵static ZSEG void zmain_vdd_check( void ) uint8 vdd_passed_count = 0; bool toggle = 0; while ( vdd_passed_count MAX_VDD_SAMPLES )/#define MAX_VDD_SAMPLES 3; 【ZMain.c】/循环检测3次 if ( HalAdcCheckVdd (ZMAIN_VDD_LIMIT) )/【ZMain.c】/ #define ZMAIN_VDD_LIMIT HAL_ADC_VDD_LIMIT_4/【hal_adc.h】/ #define HAL_ADC_VDD_LIMIT_4 0x04 vdd_passed_count+; / Keep track # times Vdd passes in a row MicroWait (10000); / 延时10毫秒/微秒级延时函数【OnBoard.h】/#define MicroWait(t) Onboard_wait(t)/void Onboard_wait( uint16 timeout ) while (timeout-) asm(NOP); asm(NOP); asm(NOP); else vdd_passed_count = 0; / Reset passed counter MicroWait (50000); / Wait 50ms MicroWait (50000); / Wait another 50ms to try again/ HalAdcCheckVdd ()【hal_adc.c】函数用来检查VDD是否大于或等于最小的要求bool HalAdcCheckVdd (uint8 limit) uint16 value; /如果芯片修订版本号小于REV_D(0x03)就直接完成电压检测并返回TRUE。CHVER是修订版本号寄存器,此寄存器是只读的。 if (CHVER REV_D)/检查芯片版本【hal_mcu.h】/#define REV_A 0x00/#define REV_D 0x03 return TRUE; /清除ADC中断标志 ADCIF = 0;/设置新的转换状态/【hal_adc.c】/使用内部1.25参考电压/ #define HAL_ADC_REF_125V 0x00 / #define HAL_ADC_DEC_064 0x00 /* Decimate by 64 : 8-bit resolution */8位精度/ #define HAL_ADC_CHN_VDD3 0x0f /* VDD/3 */以AVDD_SOC/3为输入,检测电压 ADCCON3 = (HAL_ADC_REF_125V | HAL_ADC_DEC_064 | HAL_ADC_CHN_VDD3);/等待转换完成 while ( !ADCIF );/取得转换值 value = ADCL; value |= (uint16) ADCH) = HalAdcVddLimitlimit );/ HalAdcVddLimit为一个数组static _code const uint16 HalAdcVddLimit = 0x369C, /* VDD Limit - 1.6v */ 0x3A06, /* VDD Limit - 1.7v */ 0x3D70, /* VDD Limit - 1.8v */ 0x40D9, /* VDD Limit - 1.9v */ 0x4443, /* VDD Limit - 2.0v */ 0x47AD, /* VDD Limit - 2.1v */ 0x4B17, /* VDD Limit - 2.2v */ 0x4E81, /* VDD Limit - 2.3v */ 0x51EA, /* VDD Limit - 2.4v */;/关于电池电压的测量与计算在文档:Using the ADC to Measure Supply Voltage.pdf中有详细的示例和说明,现在摘录其中一段解说一下:/ Max ADC input voltage = reference voltage = / (VDD/3) max = 1.25 V = max VDD = 3.75 V / 12 bits resolution means that max ADC value = 0x07FF = 2047 (dec) / (the ADC value is 2s complement) / Battery voltage, VDD = adc value * (3.75 / 2047)/其中有两点很重要:1、最大的ADC输入值=参考电压;2、ADC的值以2的补码形式储存,也就是说12位的精度因为有1位是符号位所以相对于精度为11,即211=2048。因为以VDD/3为输入电压,以内部1.25为参考电压,所以VDD/3最大值=1.25,得出最大的VDD=3.75;以12位精度计算,电压值划分为2.47等分,所以测出来的电压值为adc value*(3.75/2047)/注意这里并没有操作ADCCON1来启动ADC转换。让我们来看看原因:/数据手册133页ADCCON3中ECH的说明:/ Extra channel select. Selects the channel number of the extra conversion that is carried out after a conversion sequence has ended. This bit field must be written for an extra conversion to be performed. If the ADC is not running, writing to these bits will trigger an immediate single conversion from the selected extra channel. The bits are automatically cleared when the extra conversion has finished./这3位是用来选择转换序列完成以后额外的一次转换。其中有一句:If the ADC is not running, writing to these bits will trigger an immediate single conversion from the selected extra channel.(若ADC没有运行,对这几位的写入操作将会立即开始一个对指定通道的转换),这就是关键了,即使ADC没有运行,我们只要往这3位中写入我们希望转换的通道,那么ADC会马上开始运行,当然执行完毕后这几位会被清除。 /切换LED1和LED2 if (vdd_passed_count = 0) if (toggle = !(toggle) HAL_TOGGLE_LED1();/【hal_board_cfg.h】/#define HAL_TOGGLE_LED1() st( if (LED1_SBIT) LED1_SBIT = 0; else LED1_SBIT = 1; )/这句很明显了,就是切换LED1的状态。这里一直没有改变toggle的值,为什么还要对它做一个判断呢?搞不明白 else HAL_TOGGLE_LED2(); /关闭LED/【hal_board_cfg.h】/#define HAL_TURN_OFF_LED1() st( LED1_SBIT = LED1_POLARITY (0); )/#define HAL_TURN_OFF_LED2() st( LED2_SBIT = LED2_POLARITY (0); )/#define LED1_POLARITY ACTIVE_HIGH/#define LED2_POLARITY ACTIVE_LOW/#define ACTIVE_LOW !/#define ACTIVE_HIGH ! /* double negation forces result to be 1 */这里的宏定义真的是太繁琐了,真不晓得TI这样弄有多大的意义,转了两个弯才看明白原来LED1是高电平点亮 HAL_TURN_OFF_LED1(); HAL_TURN_OFF_LED2();5、zmain_ram_init();/初始化堆栈内存空间/初始化堆栈内存,以“高水位线”为准。这段程序真的是没有看懂,这段程序跟链接器,程序段在链接文件中的存放,以及IAR C/C+编译器都有莫大的关系,真的没看懂只知道是初始化了调用和返回时要用到的堆栈空间,暂时不管,用吧!static ZSEG void zmain_ram_init( void ) uint8 *end; uint8 *ptr; / Initialize the call (parameter) stack end = (uint8*)CSTK_BEG; / Lower end ptr = (uint8*)(*( _idata uint16*)(CSTK_PTR); / Upper end while ( -ptr end ) *ptr = STACK_INIT_VALUE; / Initialize the return (address) stack ptr = (uint8*)RSTK_END - 1; / Upper end while ( -ptr (uint8*)SP ) *(_idata uint8*)ptr = STACK_INIT_VALUE;6、/初始化板上的IO InitBoard( OB_COLD );/参数【OnBoard.h】#define OB_COLD 0#define OB_WARM 1#define OB_READY 2/【OnBoard.c】void InitBoard( byte level ) if ( level = OB_COLD ) /关中断,最初的时候已经见过了 osal_int_disable( INTS_ALL ); / 关闭所有的LED,调用了LED设置函数HalLedSet( HAL_LED_ALL, HAL_LED_MODE_OFF );/【hal_led.h】/ #define HAL_LED_ALL (HAL_LED_1 | HAL_LED_2 | HAL_LED_3 | HAL_LED_4),我这里呢只有两个LED,所以可以屏蔽掉LED3,LED4,或者将后两个LED也映射到前面两个LED(其实就是宏定义啦)/ #define HAL_LED_MODE_OFF 0x00/#define HAL_LED_MODE_ON 0x01/#define HAL_LED_MODE_BLINK 0x02/#define HAL_LED_MODE_FLASH 0x04/#define HAL_LED_MODE_TOGGLE 0x08/LED设置函数【hal_led.c】uint8 HalLedSet (uint8 leds, uint8 mode)#if (defined (BLINK_LEDS) & (HAL_LED = TRUE)/前提条件是定义了闪烁LED和LED硬件驱动服务使能;/ HAL_LED定义在【hal_board_cfg.h】#ifndef HAL_LED#define HAL_LED TRUE/当设为FALSE时就不使用LED#endif#if (!defined BLINK_LEDS) & (HAL_LED = TRUE)#define BLINK_LEDS#endif uint8 led; HalLedControl_t *sts;/ LED控制结构体typedef struct uint8 mode; /* 操作模式 */ uint8 todo; /* 剩余的闪烁周期数 */ uint8 onPct; /* 周期中所占的比例 */ uint16 time; /* 开关周期时间(msec) */ uint32 next; /* 下次改变的时间 */ HalLedControl_t; switch (mode) case HAL_LED_MODE_BLINK: HalLedBlink (leds, 1, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME);/LED设置的一些默认参数【hal_led.h】#define HAL_LED_DEFAULT_MAX_LEDS 4#define HAL_LED_DEFAULT_DUTY_CYCLE 5#define HAL_LED_DEFAULT_FLASH_COUNT 50#define HAL_LED_DEFAULT_FLASH_TIME 1000/LED闪烁函数【hal_led.c】void HalLedBlink (uint8 leds, uint8 numBlinks, uint8 percent, uint16 period)#if (defined (BLINK_LEDS) & (HAL_LED = TRUE)/同样先判断是否启用了LED并且使用LED闪烁功能 uint8 led; HalLedControl_t *sts; if (leds & percent & period)/判断参数的有效性,percent参数指明一个周期中LED将开启的时间 if (percent mode = HAL_LED_MODE_OFF; /*关闭先前的模式 */ sts-time = period; /* Time for one on/off cycle */ sts-onPct = percent; /* % of cycle LED is on */ sts-todo = numBlinks; /* Number of blink cycles */ if (!numBlinks) sts-mode |= HAL_LED_MODE_FLASH; /如果规定的次数未达到则继续闪烁 sts-next = osal_GetSystemClock(); /* Start now */读取当前系统时钟【OSAL_Timers.c】uint32 osal_GetSystemClock( void ) return ( osal_systemClock ); /static uint32 osal_systemClock; /这样看来第一次运行的时候osal_systemClock=0,系统中应该启动了定时器,用来记录系统运行时间。sts-mode |= HAL_LED_MODE_BLINK; /* Enable blinking */ leds = led;/屏蔽掉已设置好的这个LED led = 1;/检测下一个LED sts+; /真的是高手才能写出的函数啊!自叹,C语言编程能力还差的远啊 osal_set_event (Hal_TaskID, HAL_LED_BLINK_EVENT);/【hal_drivers.h】/#define HAL_LED_BLINK_EVENT 0x0002/extern uint8 Hal_TaskID;/此函数为用户设置任务标志【OSAL.c】/第一个参数是任务ID,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 游戏服务器监控软件创新创业项目商业计划书
- 野生动物友好型城市发展创新创业项目商业计划书
- 网红学生兴趣培养创新创业项目商业计划书
- 自动驾驶车辆仿真测试平台创新创业项目商业计划书
- 2025年新能源汽车充电设施布局与能源互联网融合研究报告
- 2025年工业互联网平台同态加密技术在工业大数据分析中的应用报告
- 2025年生态循环农业技术模式探索:经济效益评估与路径选择
- 2025年度城市燃气管道改造工程社会影响评估分析报告
- 民法典的课件模板
- 河南省巩义市市直高中2026届化学高一上期末综合测试试题含解析
- 祥康百年养生堂王晗老师讲座定稿版
- 数字填图DGSS操作步骤
- GB/T 457-2008纸和纸板耐折度的测定
- GB/T 40565.4-2021液压传动连接快换接头第4部分:72 MPa螺纹连接型
- GB/T 18608-2012原油和渣油中镍、钒、铁、钠含量的测定火焰原子吸收光谱法
- 核电质量保证-质量体系培训课件
- DB61-T 1587-2022家政服务员沟通服务规范
- 满堂脚手架方案
- DB32T 4353-2022 房屋建筑和市政基础设施工程档案资料管理规程
- T∕CGSS 004-2019 适老营养配方食品通则
- 碳碳复合材料课件
评论
0/150
提交评论