[应用方案] Nano112 热表方案模板

[复制链接]
1484|5
 楼主| yiyigirl2014 发表于 2015-12-11 21:11 | 显示全部楼层 |阅读模式

1>,CPU 无事可做,就进入掉电状态。
2>,RTC 一秒钟唤醒 CPU 一次,处理完事情后,再次进入掉电状态。
3>,UART0,UART1,时钟为32768,掉电状态仍可接收数据,收到14个字节唤醒 CPU,不满14个字节时约10字节时长无后续数据,也唤醒 CPU。
4>,包含SPI1接口对 GP2 的读写代码。
  工程在 SampleCode 目录下
NANO102_112_低功耗工程模板.zip (423.7 KB, 下载次数: 232)

 楼主| yiyigirl2014 发表于 2015-12-11 21:12 | 显示全部楼层
  1. //=================================================================================================
  2. // CPU 用 HIRC/6 = 2MHz 工作, RTC 一秒钟唤醒 CPU 一次, PA3 接 KEY 也会唤醒 CPU
  3. // UART 2400接收10字节唤醒 CPU, 不到 10 字节, 255位无后续数据也会唤醒 CPU
  4. // 进入主循环之前,对GP22写入7个配置字, 并写入ID, 每秒读取 ID 显示在 LCD 上
  5. // Copyright (C) 2015 Nuvoton(SH) Technology Corp. All rights reserved
  6. //=================================================================================================
  7. #include "Nano1X2Series.h"
  8. #include "IP_Init.h"

  9. // GP22 的七个配置寄存器的值 ////////////////////////////////////////////////////////////
  10. uint8_t const GP22_reg0[] = {0x80, 0x83, 0x0B, 0x68, 0x0E};   
  11. uint8_t const GP22_reg1[] = {0x81, 0x21, 0x44, 0xC0, 0x0d};    // 第一个字节是 opcode  
  12. uint8_t const GP22_reg2[] = {0x82, 0xA0, 0x1E, 0x00, 0x0d};      
  13. uint8_t const GP22_reg3[] = {0x83, 0xF0, 0x92, 0x07, 0x0c};    // 最后一个字节是 ID
  14. uint8_t const GP22_reg4[] = {0x84, 0x20, 0x00, 0x20, 0x01};      
  15. uint8_t const GP22_reg5[] = {0x85, 0x50, 0x00, 0x00, 0x06};      
  16. uint8_t const GP22_reg6[] = {0x86, 0xC0, 0xC0, 0x60, 0x08};      

  17. uint8_t Str_Tx[] = {0xB7,0,0,0, 0,0,0,0} ;                 // 第一个字节是 opcode
  18. uint8_t SPI_Rx[64] = "          \nUART0 is OK now !" ;               // 接收缓存
  19. uint8_t COM0_Rx[64] ;                                      // 接收缓存
  20. uint8_t COM1_Rx[64] ;                                      // 接收缓存

  21. /// PA~PE都是16个GPIO, 没引出的脚也要配成输入并打开弱上拉 ///////////////////////////////
  22. void GpioInit(void)                                       
  23. {  
  24.   // PA 11GPIO, PA0~6,12~15
  25.   // PA0高接通V30, PA1,5_EPROM, PA2_EPROM_VCC, PA4_VCC_30,  这几个输出0
  26.   // PA12~PA14, PA15_GPIO接SPISS, PA3_KEY, PA6空
  27.   PA->DOUT      = 0xFFC8 ;  
  28.   PA->PMD       = 0x40000595 ;                             // PA3 OD 输出1
  29.   PA->PUEN      = 0x2FC8 ;                                 // 1使能弱上拉
  30.   SYS->PA_H_MFP = SYS_PA_H_MFP_PA14_MFP_SPI1_SCLK
  31.                 | SYS_PA_H_MFP_PA13_MFP_SPI1_MISO0
  32.                 | SYS_PA_H_MFP_PA12_MFP_SPI1_MOSI0 ;               
  33.   SYS->PA_L_MFP = 0 ;
  34.   
  35.   // PB 11个GPIO, PB0~3,6,10~15
  36.   // PB0,1空, PB2_GP22复位输出1, PB3_INT入,PB6_Tx, PB10_Rx,PB11~12空,PB15_LCD  
  37.   PB->DOUT      = 0xFFFF ;  
  38.   PB->PMD       = 0 ;
  39.   PB->PUEN      = 0x3A0F ;                                
  40.   PB->OFFD      = 0x80000000 ;                             // PB15 关数字输入                          
  41.   SYS->PB_L_MFP = SYS_PB_L_MFP_PB6_MFP_UART1_TX ;
  42.   SYS->PB_H_MFP = SYS_PB_H_MFP_PB15_MFP_LCD_S19
  43.                 | SYS_PB_H_MFP_PB14_MFP_UART0_TX  
  44.                 | SYS_PB_H_MFP_PB13_MFP_UART0_RX  
  45.                 | SYS_PB_H_MFP_PB10_MFP_UART1_RX ;                           
  46.   
  47.   // PC无10~13, 有12个GPIO,全是LCD接口
  48.   PC->DOUT      = 0xFFFF ;  
  49.   PC->PMD       = 0 ;                                    
  50.   PC->PUEN      = 0xFFFF ;
  51.   PC->OFFD      = 0xFFFF0000;                           
  52.   SYS->PC_L_MFP = 0x88888888;                              // seg11 ~ 18
  53.   SYS->PC_H_MFP = 0x88888888;                              // seg7 ~ 8
  54.   
  55.   // PD 有16个GPIO,  PD11/12是GPIO,其它全是LCD接口
  56.   PD->DOUT      = 0xE7FF ;  
  57.   PD->PMD       = 0 ;
  58.   PD->PUEN      = 0xE7FF ;
  59.   PD->OFFD      = 0xE7FF0000;
  60.   SYS->PD_L_MFP = 0x88888888;                              // seg6 ~ 0, COM3
  61.   SYS->PD_H_MFP = 0x88800888 | SYS_PD_H_MFP_PD12_MFP_CLK_Hz;  // COM2 ~ 0, V3 ~ 1
  62.   
  63.   // 64PIN 封装 PE 没引出, 也要配成输入打开弱上拉 ///////////////////////////////////////
  64.   PE->DOUT      = 0xFFFF ;  
  65.   PE->PMD       = 0 ;                                                   
  66.   PE->PUEN      = 0xFFFF ;
  67.   SYS->PE_L_MFP = 0 ;                        
  68.   SYS->PE_H_MFP = 0 ;
  69.   
  70.   // PF012345.  有6个GPIO  
  71.   PF->DOUT      = 0xFFFF ;  
  72.   PF->PMD       = 0 ;
  73.   PF->PUEN      = 0xFFFC ;                                 // PF01/02 关弱上拉
  74.   PF->OFFD      = 0x00030000 ;                             // PF01/02 关数字输入
  75.   SYS->PF_L_MFP = SYS_PF_L_MFP_PF1_MFP_X32_OUT
  76.                 | SYS_PF_L_MFP_PF0_MFP_X32_IN  ;
  77.   
  78.   PA->ISRC      = ~0 ;                                     // 清标志
  79.   PA->IMD       = 0 ;                                      // 边沿中断
  80.   PA->IER       = 0x00080008 ;                             // 上下沿中断                 
  81.   PA->DBEN      = 0x00000008 ;                             // 使能去抖
  82.   
  83.   GPIO->DBNCECON = 0x002F ;                                // HCLK 消抖 约 2.7 ms
  84.   NVIC_SetPriority(GPABC_IRQn, 2);
  85. //  NVIC->ISER[0] = 1<<GPABC_IRQn ;               
  86. }
  87. //// SPI1 少量数据收发, 不用中断, 代码简单 //////////////////////////////////////////////
  88. // 输入: pTr,  待发送的字符
  89. //       Num,  全双工收发送字符个数
  90. //       pRx,  接收字符存放地址
  91. void SPI1_TxRx(uint8_t *pTx, uint32_t Num, uint8_t *pRx )
  92. {
  93.   uint32_t Cnt = 6, CntRx = Num ;
  94.   
  95.   PA->DOUT &= ~0x8000 ;                                    // SS = 0 ;
  96.   while(Num){ --Num ;
  97.     SPI1->TX1 = *pTx++ ;      
  98.     if(--Cnt == 0) break ;
  99.   }
  100.   
  101.   while(CntRx){ --CntRx;
  102.     while(SPI1->STATUS & SPI_STATUS_RX_EMPTY_Msk) ;
  103.     *pRx++ = SPI1->RX1 ;      
  104.     if(Num){ --Num; SPI1->TX1 = *pTx++; }      
  105.   }
  106.   PA->DOUT |= 0x8000 ;                                     // SS = 1 ;
  107. }
  108. /////////////////////////////////////////////////////////////////////////////////////////
  109. int32_t main(void)                                                          
  110. {   
  111.   uint8_t *pStr ;
  112.   
  113.   SysClkInit() ;                                      
  114.   Timer1Init() ;                                           // Delayus()延时用 Timer1
  115.   RTC_Init();                                       
  116.   LCD_Init()   ;
  117.   SPI1_Init(3) ;                                           // SPI1 时钟是 HCLK 的3分频
  118.   PB->PMD |= 0x10 ;                                        // PB2控制GP22复位, 低有效
  119.                     // 与GPIO输出有关的外设配置放此
  120.   UART0_Init() ;  
  121.   UART1_Init() ;  
  122.   GpioInit() ;                                             // 配置GPIO
  123.   
  124.   UART0->THR = '\n' ; UART0->THR = 'O' ; UART0->THR = 'K' ;
  125.   UART1->THR = '\n' ; UART1->THR = 'O' ; UART1->THR = 'K' ;
  126.   
  127.   //// 写 GP22 的七个配置寄存器 /////////////////////////////////////////////////////////
  128.   SPI1_TxRx((uint8_t*)GP22_reg0, 5, SPI_Rx) ;
  129.   SPI1_TxRx((uint8_t*)GP22_reg1, 5, SPI_Rx) ;
  130.   SPI1_TxRx((uint8_t*)GP22_reg2, 5, SPI_Rx) ;
  131.   SPI1_TxRx((uint8_t*)GP22_reg3, 5, SPI_Rx) ;
  132.   SPI1_TxRx((uint8_t*)GP22_reg4, 5, SPI_Rx) ;
  133.   SPI1_TxRx((uint8_t*)GP22_reg5, 5, SPI_Rx) ;
  134.   SPI1_TxRx((uint8_t*)GP22_reg6, 5, SPI_Rx) ;
  135.   
  136.   Delayus(50000) ;                                         // 等 UART 发送结束
  137.   
  138.   COM0_Data.NumRx = 0 ;  COM0_Data.pRx = COM0_Rx ;   COM0_Data.NumRx = 60 ;
  139.   COM1_Data.NumRx = 0 ;  COM1_Data.pRx = COM1_Rx ;   COM1_Data.NumRx = 60 ;
  140.   
  141.   Event = 0 ;  pStr = 0 ;
  142.         while(1){
  143.     if((UART0->FSR & UART_FSR_RX_EMPTY_F_Msk) == 0) Event |= Event_UART0_Rx ;  
  144.     if((UART1->FSR & UART_FSR_RX_EMPTY_F_Msk) == 0) Event |= Event_UART1_Rx ;  
  145.     while(Event == 0){                                     // 无事可做, 休眠
  146.                         SYS_UnlockReg() ;
  147.         CLK->PWRCTL |= CLK_PWRCTL_PWRDOWN_EN ;             // 休眠功能使能位,自动清零
  148.         SCB->SCR    |= 0x04 ;                              // 掉电模式
  149.       SYS_LockReg() ;      
  150.                         __wfi() ;                                            // 进入休眠状态      
  151.     }
  152.     //// 任务 1, 优先级最高, 越靠后, 优先级最低 /////////////////////////////////////////   
  153.     if(Event & Event_RTC_INT){ Event &= ~Event_RTC_INT ;  
  154.       SPI1_TxRx((uint8_t*)Str_Tx, 8, SPI_Rx) ;            // 读出GP22的7个ID,显示在LCD上
  155.       LCD->MEM_0 = TabLCD[SPI_Rx[1]] ;  LCD->MEM_0 += TabLCD[SPI_Rx[2]] << 16 ;
  156.       LCD->MEM_1 = TabLCD[SPI_Rx[3]] ;  LCD->MEM_1 += TabLCD[SPI_Rx[4]] << 16 ;
  157.       LCD->MEM_2 = TabLCD[SPI_Rx[5]] ;  LCD->MEM_2 += TabLCD[SPI_Rx[6]] << 16 ;
  158.       LCD->MEM_3 = TabLCD[SPI_Rx[7]] ;  LCD->MEM_3 += TabLCD[8] << 16 ;
  159.     }
  160.     //// 任务 2 /////////////////////////////////////////////////////////////////////////
  161.     else if(Event & Event_KEY_PUSH){   
  162.       PE->DOUT   ^= 0x40 ;
  163.       
  164.       Event &= ~Event_KEY_PUSH ;                           // 才再次处理按键
  165.     }
  166.     //// 任务 3 /////////////////////////////////////////////////////////////////////////
  167.     else if(Event & Event_UART0_Rx){        
  168.       UART0->CTL  |= UART_CTL_WAKE_THRESH_EN_Msk ;         // 再次使能唤醒
  169.       if(pStr == 0) pStr = COM0_Rx ;                       // 接收数据的开头
  170.    
  171.       // 处理数据 /////////////////////////////////////////////////////////////
  172.       if(pStr != COM0_Data.pRx){                       
  173.         if((UART0->FSR & UART_FSR_TX_FULL_F_Msk) == 0)
  174.            UART0->THR = *pStr++ ;   
  175.       }
  176.       /////////////////////////////////////////////////////////////////////////
  177.       
  178.       if(((TIMER1->DR - Uart0_Tick)&0xFFFFFF) > 70000){    // 70ms 无后续数据   
  179.         pStr            = 0 ;                             
  180.         COM0_Data.NumRx = 0 ;                              // 接收的数据丢掉
  181.         COM0_Data.pRx   = COM0_Rx ;   
  182.         COM0_Data.NumRx = 60 ;                             // 重新开始接收最多60字节
  183.         Event          &= ~Event_UART0_Rx ;                // 可以休眠了
  184.       }
  185.     }
  186.     //// 任务 4 /////////////////////////////////////////////////////////////////////////
  187.     else
  188.       if(Event & Event_UART1_Rx){ Event &= ~Event_UART1_Rx ;
  189.         
  190.       UART1->CTL  |= UART_CTL_WAKE_THRESH_EN_Msk ;         // 再次使能唤醒
  191.       pStr = COM1_Rx ;  
  192.       while(pStr != COM1_Data.pRx){
  193.         while(UART1->FSR & UART_FSR_TX_FULL_F_Msk) ;
  194.         UART1->THR = *pStr++ ;
  195.         Delayus(70) ;
  196.       }
  197.       while((UART1->FSR & UART_FSR_TE_F_Msk) == 0) ;       // 等发送结束
  198.       COM1_Data.pRx = COM1_Rx ;   COM1_Data.NumRx = 30 ;   // 重新启动接收
  199.     }
  200.     /////////////////////////////////////////////////////////////////////////////////////
  201.     else Event = 0 ;               
  202.   }
  203. }


稳稳の幸福 发表于 2015-12-11 21:53 | 显示全部楼层
//// 写 GP22 的七个配置寄存器 /////////////////////////////////////////////////////////
  SPI1_TxRx((uint8_t*)GP22_reg0, 5, SPI_Rx) ;
  SPI1_TxRx((uint8_t*)GP22_reg1, 5, SPI_Rx) ;
  SPI1_TxRx((uint8_t*)GP22_reg2, 5, SPI_Rx) ;
  SPI1_TxRx((uint8_t*)GP22_reg3, 5, SPI_Rx) ;
  SPI1_TxRx((uint8_t*)GP22_reg4, 5, SPI_Rx) ;
  SPI1_TxRx((uint8_t*)GP22_reg5, 5, SPI_Rx) ;
  SPI1_TxRx((uint8_t*)GP22_reg6, 5, SPI_Rx) ;
原来通过此法,写入ID的。
Beckham_Owen 发表于 2015-12-12 21:32 | 显示全部楼层
这个热表是什么意思啊,不是太懂,楼主赐教
 楼主| yiyigirl2014 发表于 2015-12-22 14:55 | 显示全部楼层
Beckham_Owen 发表于 2015-12-12 21:32
这个热表是什么意思啊,不是太懂,楼主赐教

热冷计量表是对空调中对冷、热介质的一个计量设备,线性度优于0.5%,重复性精度优于0.2%,测量精度优于±1%为最佳。
643757107 发表于 2015-12-22 16:21 | 显示全部楼层
此问题,要认真了解热力表到底是什么借口,获取了数据后怎么换算,换算后怎么上传,上传后怎么解读与显示。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

230

主题

3676

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部