打印
[应用方案]

Nano112 热表方案模板

[复制链接]
1155|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 | 只看该作者
//=================================================================================================
// CPU 用 HIRC/6 = 2MHz 工作, RTC 一秒钟唤醒 CPU 一次, PA3 接 KEY 也会唤醒 CPU
// UART 2400接收10字节唤醒 CPU, 不到 10 字节, 255位无后续数据也会唤醒 CPU
// 进入主循环之前,对GP22写入7个配置字, 并写入ID, 每秒读取 ID 显示在 LCD 上
// Copyright (C) 2015 Nuvoton(SH) Technology Corp. All rights reserved
//=================================================================================================
#include "Nano1X2Series.h"
#include "IP_Init.h"

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

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

/// PA~PE都是16个GPIO, 没引出的脚也要配成输入并打开弱上拉 ///////////////////////////////
void GpioInit(void)                                       
{  
  // PA 11GPIO, PA0~6,12~15
  // PA0高接通V30, PA1,5_EPROM, PA2_EPROM_VCC, PA4_VCC_30,  这几个输出0
  // PA12~PA14, PA15_GPIO接SPISS, PA3_KEY, PA6空
  PA->DOUT      = 0xFFC8 ;  
  PA->PMD       = 0x40000595 ;                             // PA3 OD 输出1
  PA->PUEN      = 0x2FC8 ;                                 // 1使能弱上拉
  SYS->PA_H_MFP = SYS_PA_H_MFP_PA14_MFP_SPI1_SCLK
                | SYS_PA_H_MFP_PA13_MFP_SPI1_MISO0
                | SYS_PA_H_MFP_PA12_MFP_SPI1_MOSI0 ;               
  SYS->PA_L_MFP = 0 ;
  
  // PB 11个GPIO, PB0~3,6,10~15
  // PB0,1空, PB2_GP22复位输出1, PB3_INT入,PB6_Tx, PB10_Rx,PB11~12空,PB15_LCD  
  PB->DOUT      = 0xFFFF ;  
  PB->PMD       = 0 ;
  PB->PUEN      = 0x3A0F ;                                
  PB->OFFD      = 0x80000000 ;                             // PB15 关数字输入                          
  SYS->PB_L_MFP = SYS_PB_L_MFP_PB6_MFP_UART1_TX ;
  SYS->PB_H_MFP = SYS_PB_H_MFP_PB15_MFP_LCD_S19
                | SYS_PB_H_MFP_PB14_MFP_UART0_TX  
                | SYS_PB_H_MFP_PB13_MFP_UART0_RX  
                | SYS_PB_H_MFP_PB10_MFP_UART1_RX ;                           
  
  // PC无10~13, 有12个GPIO,全是LCD接口
  PC->DOUT      = 0xFFFF ;  
  PC->PMD       = 0 ;                                    
  PC->PUEN      = 0xFFFF ;
  PC->OFFD      = 0xFFFF0000;                           
  SYS->PC_L_MFP = 0x88888888;                              // seg11 ~ 18
  SYS->PC_H_MFP = 0x88888888;                              // seg7 ~ 8
  
  // PD 有16个GPIO,  PD11/12是GPIO,其它全是LCD接口
  PD->DOUT      = 0xE7FF ;  
  PD->PMD       = 0 ;
  PD->PUEN      = 0xE7FF ;
  PD->OFFD      = 0xE7FF0000;
  SYS->PD_L_MFP = 0x88888888;                              // seg6 ~ 0, COM3
  SYS->PD_H_MFP = 0x88800888 | SYS_PD_H_MFP_PD12_MFP_CLK_Hz;  // COM2 ~ 0, V3 ~ 1
  
  // 64PIN 封装 PE 没引出, 也要配成输入打开弱上拉 ///////////////////////////////////////
  PE->DOUT      = 0xFFFF ;  
  PE->PMD       = 0 ;                                                   
  PE->PUEN      = 0xFFFF ;
  SYS->PE_L_MFP = 0 ;                        
  SYS->PE_H_MFP = 0 ;
  
  // PF012345.  有6个GPIO  
  PF->DOUT      = 0xFFFF ;  
  PF->PMD       = 0 ;
  PF->PUEN      = 0xFFFC ;                                 // PF01/02 关弱上拉
  PF->OFFD      = 0x00030000 ;                             // PF01/02 关数字输入
  SYS->PF_L_MFP = SYS_PF_L_MFP_PF1_MFP_X32_OUT
                | SYS_PF_L_MFP_PF0_MFP_X32_IN  ;
  
  PA->ISRC      = ~0 ;                                     // 清标志
  PA->IMD       = 0 ;                                      // 边沿中断
  PA->IER       = 0x00080008 ;                             // 上下沿中断                 
  PA->DBEN      = 0x00000008 ;                             // 使能去抖
  
  GPIO->DBNCECON = 0x002F ;                                // HCLK 消抖 约 2.7 ms
  NVIC_SetPriority(GPABC_IRQn, 2);
//  NVIC->ISER[0] = 1<<GPABC_IRQn ;               
}
//// SPI1 少量数据收发, 不用中断, 代码简单 //////////////////////////////////////////////
// 输入: pTr,  待发送的字符
//       Num,  全双工收发送字符个数
//       pRx,  接收字符存放地址
void SPI1_TxRx(uint8_t *pTx, uint32_t Num, uint8_t *pRx )
{
  uint32_t Cnt = 6, CntRx = Num ;
  
  PA->DOUT &= ~0x8000 ;                                    // SS = 0 ;
  while(Num){ --Num ;
    SPI1->TX1 = *pTx++ ;      
    if(--Cnt == 0) break ;
  }
  
  while(CntRx){ --CntRx;
    while(SPI1->STATUS & SPI_STATUS_RX_EMPTY_Msk) ;
    *pRx++ = SPI1->RX1 ;      
    if(Num){ --Num; SPI1->TX1 = *pTx++; }      
  }
  PA->DOUT |= 0x8000 ;                                     // SS = 1 ;
}
/////////////////////////////////////////////////////////////////////////////////////////
int32_t main(void)                                                          
{   
  uint8_t *pStr ;
  
  SysClkInit() ;                                      
  Timer1Init() ;                                           // Delayus()延时用 Timer1
  RTC_Init();                                       
  LCD_Init()   ;
  SPI1_Init(3) ;                                           // SPI1 时钟是 HCLK 的3分频
  PB->PMD |= 0x10 ;                                        // PB2控制GP22复位, 低有效
                    // 与GPIO输出有关的外设配置放此
  UART0_Init() ;  
  UART1_Init() ;  
  GpioInit() ;                                             // 配置GPIO
  
  UART0->THR = '\n' ; UART0->THR = 'O' ; UART0->THR = 'K' ;
  UART1->THR = '\n' ; UART1->THR = 'O' ; UART1->THR = 'K' ;
  
  //// 写 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) ;
  
  Delayus(50000) ;                                         // 等 UART 发送结束
  
  COM0_Data.NumRx = 0 ;  COM0_Data.pRx = COM0_Rx ;   COM0_Data.NumRx = 60 ;
  COM1_Data.NumRx = 0 ;  COM1_Data.pRx = COM1_Rx ;   COM1_Data.NumRx = 60 ;
  
  Event = 0 ;  pStr = 0 ;
        while(1){
    if((UART0->FSR & UART_FSR_RX_EMPTY_F_Msk) == 0) Event |= Event_UART0_Rx ;  
    if((UART1->FSR & UART_FSR_RX_EMPTY_F_Msk) == 0) Event |= Event_UART1_Rx ;  
    while(Event == 0){                                     // 无事可做, 休眠
                        SYS_UnlockReg() ;
        CLK->PWRCTL |= CLK_PWRCTL_PWRDOWN_EN ;             // 休眠功能使能位,自动清零
        SCB->SCR    |= 0x04 ;                              // 掉电模式
      SYS_LockReg() ;      
                        __wfi() ;                                            // 进入休眠状态      
    }
    //// 任务 1, 优先级最高, 越靠后, 优先级最低 /////////////////////////////////////////   
    if(Event & Event_RTC_INT){ Event &= ~Event_RTC_INT ;  
      SPI1_TxRx((uint8_t*)Str_Tx, 8, SPI_Rx) ;            // 读出GP22的7个ID,显示在LCD上
      LCD->MEM_0 = TabLCD[SPI_Rx[1]] ;  LCD->MEM_0 += TabLCD[SPI_Rx[2]] << 16 ;
      LCD->MEM_1 = TabLCD[SPI_Rx[3]] ;  LCD->MEM_1 += TabLCD[SPI_Rx[4]] << 16 ;
      LCD->MEM_2 = TabLCD[SPI_Rx[5]] ;  LCD->MEM_2 += TabLCD[SPI_Rx[6]] << 16 ;
      LCD->MEM_3 = TabLCD[SPI_Rx[7]] ;  LCD->MEM_3 += TabLCD[8] << 16 ;
    }
    //// 任务 2 /////////////////////////////////////////////////////////////////////////
    else if(Event & Event_KEY_PUSH){   
      PE->DOUT   ^= 0x40 ;
      
      Event &= ~Event_KEY_PUSH ;                           // 才再次处理按键
    }
    //// 任务 3 /////////////////////////////////////////////////////////////////////////
    else if(Event & Event_UART0_Rx){        
      UART0->CTL  |= UART_CTL_WAKE_THRESH_EN_Msk ;         // 再次使能唤醒
      if(pStr == 0) pStr = COM0_Rx ;                       // 接收数据的开头
   
      // 处理数据 /////////////////////////////////////////////////////////////
      if(pStr != COM0_Data.pRx){                       
        if((UART0->FSR & UART_FSR_TX_FULL_F_Msk) == 0)
           UART0->THR = *pStr++ ;   
      }
      /////////////////////////////////////////////////////////////////////////
      
      if(((TIMER1->DR - Uart0_Tick)&0xFFFFFF) > 70000){    // 70ms 无后续数据   
        pStr            = 0 ;                             
        COM0_Data.NumRx = 0 ;                              // 接收的数据丢掉
        COM0_Data.pRx   = COM0_Rx ;   
        COM0_Data.NumRx = 60 ;                             // 重新开始接收最多60字节
        Event          &= ~Event_UART0_Rx ;                // 可以休眠了
      }
    }
    //// 任务 4 /////////////////////////////////////////////////////////////////////////
    else
      if(Event & Event_UART1_Rx){ Event &= ~Event_UART1_Rx ;
        
      UART1->CTL  |= UART_CTL_WAKE_THRESH_EN_Msk ;         // 再次使能唤醒
      pStr = COM1_Rx ;  
      while(pStr != COM1_Data.pRx){
        while(UART1->FSR & UART_FSR_TX_FULL_F_Msk) ;
        UART1->THR = *pStr++ ;
        Delayus(70) ;
      }
      while((UART1->FSR & UART_FSR_TE_F_Msk) == 0) ;       // 等发送结束
      COM1_Data.pRx = COM1_Rx ;   COM1_Data.NumRx = 30 ;   // 重新启动接收
    }
    /////////////////////////////////////////////////////////////////////////////////////
    else Event = 0 ;               
  }
}


使用特权

评论回复
板凳
稳稳の幸福| | 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 | 只看该作者
这个热表是什么意思啊,不是太懂,楼主赐教

使用特权

评论回复
5
yiyigirl2014|  楼主 | 2015-12-22 14:55 | 只看该作者
Beckham_Owen 发表于 2015-12-12 21:32
这个热表是什么意思啊,不是太懂,楼主赐教

热冷计量表是对空调中对冷、热介质的一个计量设备,线性度优于0.5%,重复性精度优于0.2%,测量精度优于±1%为最佳。

使用特权

评论回复
6
643757107| | 2015-12-22 16:21 | 只看该作者
此问题,要认真了解热力表到底是什么借口,获取了数据后怎么换算,换算后怎么上传,上传后怎么解读与显示。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

213

主题

3538

帖子

10

粉丝