• Zigbee系列 学习笔记三(初始化程序解析)


     1 int main( void )
     2 {
     3   // Turn off interrupts
     4   osal_int_disable( INTS_ALL );
     5 
     6   // Initialization for board related stuff such as LEDs
     7   HAL_BOARD_INIT();
     8 
     9   // Make sure supply voltage is high enough to run
    10   zmain_vdd_check();
    11 
    12   // Initialize board I/O
    13   InitBoard( OB_COLD );
    14 
    15   // Initialze HAL drivers
    16   HalDriverInit();
    17 
    18   // Initialize NV System
    19   osal_nv_init( NULL );
    20 
    21   // Initialize the MAC
    22   ZMacInit();
    23 
    24   // Determine the extended address
    25   zmain_ext_addr();
    26 
    27 #if defined ZCL_KEY_ESTABLISH
    28   // Initialize the Certicom certificate information.
    29   zmain_cert_init();
    30 #endif
    31 
    32   // Initialize basic NV items
    33   zgInit();
    34 
    35 #ifndef NONWK
    36   // Since the AF isn't a task, call it's initialization routine
    37   afInit();
    38 #endif
    39 
    40   // Initialize the operating system
    41   osal_init_system();
    42 
    43   // Allow interrupts
    44   osal_int_enable( INTS_ALL );
    45 
    46   // Final board initialization
    47   InitBoard( OB_READY );
    48 
    49   // Display information about this device
    50   zmain_dev_info();
    51 
    52   /* Display the device info on the LCD */
    53 #ifdef LCD_SUPPORTED
    54   zmain_lcd_init();
    55 #endif
    56 
    57 #ifdef WDT_IN_PM1
    58   /* If WDT is used, this is a good place to enable it. */
    59   WatchDogEnable( WDTIMX );
    60 #endif
    61 
    62   osal_start_system(); // No Return from here
    63 
    64   return 0;  // Shouldn't get here.
    65 } // main()
    HAL_BOARD_INIT()关于LED灯的板级初始化
     1 #define HAL_BOARD_INIT()                                         
     2 {                                                                
     3   uint16 i;                                                      
     4                                                                  
     5   SLEEPCMD &= ~OSC_PD;                       /* turn on 16MHz RC and 32MHz XOSC */                
     6   while (!(SLEEPSTA & XOSC_STB));            /* wait for 32MHz XOSC stable */                     
     7   asm("NOP");                                /* chip bug workaround */                            
     8   for (i=0; i<504; i++) asm("NOP");          /* Require 63us delay for all revs */                
     9   CLKCONCMD = (CLKCONCMD_32MHZ | OSC_32KHZ); /* Select 32MHz XOSC and the source for 32K clock */ 
    10   while (CLKCONSTA != (CLKCONCMD_32MHZ | OSC_32KHZ)); /* Wait for the change to be effective */   
    11   SLEEPCMD |= OSC_PD;                        /* turn off 16MHz RC */                              
    12                                                                  
    13   /* Turn on cache prefetch mode */                              
    14   PREFETCH_ENABLE();                                             
    15                                                                  
    16   HAL_TURN_OFF_LED1();                                           
    17   LED1_DDR |= LED1_BV;                                           
    18   HAL_TURN_OFF_LED2();                                           
    19   LED2_DDR |= LED2_BV;                                           
    20   HAL_TURN_OFF_LED3();                                           
    21   LED3_DDR |= LED3_BV;                                           
    22                                                                  
    23   /* configure tristates */                                      
    24   P0INP |= PUSH2_BV;                                             
    25 }

    程序解读:16~21行代码,定义了三个LED灯的IO口,分别为P1_0、P1_1、P1_4。第24行代码,定义P0_0为三态

    HalDriverInit()初始化硬件层各驱动
     1 void HalDriverInit (void)
     2 {
     3   /* TIMER */
     4 #if (defined HAL_TIMER) && (HAL_TIMER == TRUE)
     5   #error "The hal timer driver module is removed."
     6 #endif
     7 
     8   /* ADC */
     9 #if (defined HAL_ADC) && (HAL_ADC == TRUE)
    10   HalAdcInit();
    11 #endif
    12 
    13   /* DMA */
    14 #if (defined HAL_DMA) && (HAL_DMA == TRUE)
    15   // Must be called before the init call to any module that uses DMA.
    16   HalDmaInit();
    17 #endif
    18 
    19   /* AES */
    20 #if (defined HAL_AES) && (HAL_AES == TRUE)
    21   HalAesInit();
    22 #endif
    23 
    24   /* LCD */
    25 #if (defined HAL_LCD) && (HAL_LCD == TRUE)
    26   HalLcdInit();
    27 #endif
    28 
    29   /* LED */
    30 #if (defined HAL_LED) && (HAL_LED == TRUE)
    31   HalLedInit();
    32 #endif
    33 
    34   /* UART */
    35 #if (defined HAL_UART) && (HAL_UART == TRUE)
    36   HalUARTInit();
    37 #endif
    38 
    39   /* KEY */
    40 #if (defined HAL_KEY) && (HAL_KEY == TRUE)
    41   HalKeyInit();
    42 #endif
    43 
    44   /* SPI */
    45 #if (defined HAL_SPI) && (HAL_SPI == TRUE)
    46   HalSpiInit();
    47 #endif
    48 
    49   /* HID */
    50 #if (defined HAL_HID) && (HAL_HID == TRUE)
    51   usbHidInit();
    52 #endif
    53 }

    程序解析:以上程序分别进行了,定时器,ADC,UART等接口初始化

      1 /* ------------------------------------------------------------------------------------------------
      2  *                                     Driver Configuration
      3  * ------------------------------------------------------------------------------------------------
      4  */
      5 
      6 /* Set to TRUE enable H/W TIMER usage, FALSE disable it */
      7 #ifndef HAL_TIMER
      8 #define HAL_TIMER FALSE
      9 #endif
     10 
     11 /* Set to TRUE enable ADC usage, FALSE disable it */
     12 #ifndef HAL_ADC
     13 #define HAL_ADC TRUE
     14 #endif
     15 
     16 /* Set to TRUE enable DMA usage, FALSE disable it */
     17 #ifndef HAL_DMA
     18 #define HAL_DMA TRUE
     19 #endif
     20 
     21 /* Set to TRUE enable Flash access, FALSE disable it */
     22 #ifndef HAL_FLASH
     23 #define HAL_FLASH TRUE
     24 #endif
     25 
     26 /* Set to TRUE enable AES usage, FALSE disable it */
     27 #ifndef HAL_AES
     28 #define HAL_AES TRUE
     29 #endif
     30 
     31 #ifndef HAL_AES_DMA
     32 #define HAL_AES_DMA TRUE
     33 #endif
     34 
     35 /* Set to TRUE enable LCD usage, FALSE disable it */
     36 #ifndef HAL_LCD
     37 #define HAL_LCD TRUE
     38 #endif
     39 
     40 /* Set to TRUE enable LED usage, FALSE disable it */
     41 #ifndef HAL_LED
     42 #define HAL_LED TRUE
     43 #endif
     44 #if (!defined BLINK_LEDS) && (HAL_LED == TRUE)
     45 #define BLINK_LEDS
     46 #endif
     47 
     48 /* Set to TRUE enable KEY usage, FALSE disable it */
     49 #ifndef HAL_KEY
     50 #define HAL_KEY TRUE
     51 #endif
     52 
     53 /* Set to TRUE enable UART usage, FALSE disable it */
     54 #ifndef HAL_UART
     55 #if (defined ZAPP_P1) || (defined ZAPP_P2) || (defined ZTOOL_P1) || (defined ZTOOL_P2)
     56 #define HAL_UART TRUE
     57 #else
     58 #define HAL_UART FALSE
     59 #endif
     60 #endif
     61 
     62 #if HAL_UART
     63 #ifndef HAL_UART_DMA
     64 #if HAL_DMA
     65 #if (defined ZAPP_P2) || (defined ZTOOL_P2)
     66 #define HAL_UART_DMA  2
     67 #else
     68 #define HAL_UART_DMA  1
     69 #endif
     70 #else
     71 #define HAL_UART_DMA  0
     72 #endif
     73 #endif
     74 
     75 #ifndef HAL_UART_ISR
     76 #if HAL_UART_DMA           // Default preference for DMA over ISR.
     77 #define HAL_UART_ISR  0
     78 #elif (defined ZAPP_P2) || (defined ZTOOL_P2)
     79 #define HAL_UART_ISR  2
     80 #else
     81 #define HAL_UART_ISR  1
     82 #endif
     83 #endif
     84 
     85 #if (HAL_UART_DMA && (HAL_UART_DMA == HAL_UART_ISR))
     86 #error HAL_UART_DMA & HAL_UART_ISR must be different.
     87 #endif
     88 
     89 // Used to set P2 priority - USART0 over USART1 if both are defined.
     90 #if ((HAL_UART_DMA == 1) || (HAL_UART_ISR == 1))
     91 #define HAL_UART_PRIPO             0x00
     92 #else
     93 #define HAL_UART_PRIPO             0x40
     94 #endif
     95 
     96 #else
     97 #define HAL_UART_DMA  0
     98 #define HAL_UART_ISR  0
     99 #endif
    100 
    101 /* USB is not used for CC2530 configuration */
    102 #define HAL_UART_USB  0
    103 #endif
    104 /*******************************************************************************************************
    105 */

    以上代码在hal_board_cfg.h中,定义了相应硬件接口。在HalDriverInit()函数中可以看到对应的硬件初始化。

    针对ADC初始化:

    1 void HalAdcInit (void)
    2 {
    3 #if (HAL_ADC == TRUE)
    4   adcRef = HAL_ADC_REF_VOLT;
    5 #endif
    6 }

    定义了ADC的参考电压源。

    针对UART的初始化:

     1 void HalUARTInit(void)
     2 {
     3 #if HAL_UART_DMA
     4   HalUARTInitDMA();
     5 #endif
     6 #if HAL_UART_ISR
     7   HalUARTInitISR();
     8 #endif
     9 #if HAL_UART_USB
    10   HalUARTInitUSB();
    11 #endif
    12 }

    有三种初始化方式,可以通过hal_board_cfg.h文件中的定义进行选择初始化。

    按键初始化:

     1 void HalKeyInit( void )
     2 {
     3   /* Initialize previous key to 0 */
     4   halKeySavedKeys = 0;
     5 
     6   HAL_KEY_SW_6_SEL &= ~(HAL_KEY_SW_6_BIT);    /* Set pin function to GPIO */
     7   HAL_KEY_SW_6_DIR &= ~(HAL_KEY_SW_6_BIT);    /* Set pin direction to Input */
     8 
     9   HAL_KEY_JOY_MOVE_SEL &= ~(HAL_KEY_JOY_MOVE_BIT); /* Set pin function to GPIO */
    10   HAL_KEY_JOY_MOVE_DIR &= ~(HAL_KEY_JOY_MOVE_BIT); /* Set pin direction to Input */
    11 
    12 
    13   /* Initialize callback function */
    14   pHalKeyProcessFunction  = NULL;
    15 
    16   /* Start with key is not configured */
    17   HalKeyConfigured = FALSE;
    18 }

    初始化中定义了P0_1和P2_0为按键控制接口

    关于DMA的配置过程:

     1 /*用于配置DMA的结构体
     2 -------------------------------------------------------*/
     3 #pragma bitfields=reversed
     4 typedef struct
     5 {
     6   unsigned char SRCADDRH;           //源地址高8位
     7   unsigned char SRCADDRL;           //源地址低8位
     8   unsigned char DESTADDRH;          //目的地址高8位
     9   unsigned char DESTADDRL;          //目的地址低8位
    10   unsigned char VLEN        :3;     //长度域模式选择
    11   unsigned char LENH        :5;     //传输长度高字节
    12   unsigned char LENL        :8;     //传输长度低字节
    13   unsigned char WORDSIZE    :1;     //字节(byte)或字(word)传输
    14   unsigned char TMODE       :2;     //传输模式选择
    15   unsigned char TRIG        :5;     //触发事件选择
    16   unsigned char SRCINC      :2;     //源地址增量:-1/0/1/2
    17   unsigned char DESTINC     :2;     //目的地址增量:-1/0/1/2
    18   unsigned char IRQMASK     :1;     //中断屏蔽
    19   unsigned char M8          :1;     //7或8bit传输长度,仅在字节传输模式下适用
    20   unsigned char PRIORITY    :2;     //优先级
    21 }DMA_CFG;

     使用DMA的基本流程是:配置DMA → 启用配置 → 启动DMA传输 → 等待DMA传输完毕。下面分别介绍:

    (1)配置DMA:首先必须配置DMA,但DMA的配置比较特殊:不是直接对某些SFR赋值,而是在外部定义一个结构体,对其赋值,然后再将此结构体的首地址的高8位赋给 DMA0CFGH,将其低8位赋给DMA0CFGL

    关于上面源码中对配置结构体的定义,需做两点说明:

    1)位域

      在定义此结构体时,用到了很多冒号(:),后面还跟着一个数字,这种语法叫“位域”:

      位域是指信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。

    2)抽象出常用函数

      细心的读者会发现,在对结构体赋值时,经常会涉及到将一个16位unsigned int 类型值分别赋予两个8位的unsigned char类型值,处理方法如下:

      dmaConfig.SRCADDRH=(unsigned char)((unsigned int)&sourceString>> 8);     //源地址
      dmaConfig.SRCADDRL=(unsigned char)((unsignedint)&sourceString);

      对于这类经常会用到的函数,我们不妨抽象出来作为一个通用函数,如下:  

      #define SET_WORD(destH,destL,word)
        do{
           destH=(unsigned char)((unsigned int)word >> 8);     
           destL=(unsigned char)((unsigned int)word);
        }while(0)

      以后每当你需要进行类似的分割操作时,直接调用即可,如下所示:

      SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL,&sourceString);

    (2)启用配置:首先将结构体的首地址 &dmaConfig 的高/低8位分别赋给SFR DMA0CFGH 和DMA0CFGL(其中的0表示对通道0配置,CC2530包含5个DMA通道,此处使用通道0)。然对DMAARM.0 赋值1,启用通道0的配置,使通道0处于工作模式。

    (3)开启DMA传输:对 DMAREQ.0 赋值1,启动通道0的DMA传输。

    (4)等待DMA传输完毕:通道0的DMA传输完毕后,就会触发中断,通道0的中断标志 DMAIRQ.0会被自动置1。然后对两个字符串的每一个字符进行比较,将校验结果发送至PC。

  • 相关阅读:
    运维IT必备程序安装包
    网络基础TCP三次握手四次挥手
    新建Weblogic域启动报BEA090403和BEA000386提示密码认证有问题
    Weblogic开发模式和生产产品模式互换
    web api 返回 去除双引号转义符
    freeswitch esl :Rejected by acl “loopback.auto“问题
    freeswitch SIP 服务器一些常用配置
    因果推断综述
    Django 项目配置拆分独立
    wayne编译支持k8s1.16+
  • 原文地址:https://www.cnblogs.com/killer-xc/p/4819215.html
Copyright © 2020-2023  润新知