嵌入式技术论坛
直播中

万物死

8年用户 1317经验值
擅长:MEMS/传感技术
私信 关注
[经验]

如何去实现RTT与HT7017芯片之间的计量通讯呢

1.HT7017芯片介绍
1.1芯片简介
HT7017 是一颗带 UART 通讯接口的高精度单相多功能计量芯片。
芯片支持宽电压,工作电压范围是 3.0 ~5.5V。
工作晶振为 6MHz
1.2芯片特性
 三路 19 bits Sigma-Delta ADC;
 支持 8000:1 的动态范围;
 比 5000:1 版本芯片更好的小信号精度表现
 可以同时得到两路计量通道的有功功率、无功功率;
 支持有功、无功、视在功率和有功电能脉冲输出;
 能够同时得到三路 ADC 通道的有效值,及电压通道的频率;
 支持 UART 通讯方式;
 中断支持:过零中断,采样中断,电能脉冲中断,校表中断等;
 NORMAL 全速运行时功耗<4mA;
电源监测功能
 支持电压跌落(SAG)和峰值检测(PEAK)功能;
 新增计量可靠性机制
 支持锰铜掉火线检测功能
 提供校表参数的 CRC 校验
 提供 128 点的 ADC 波形缓存功能
 芯片封装:SSOP 16
1.3.整体框图

1.4.引脚定义

2.NUC980编程
2.1.定义计量信息结构体
typedef struct
{
    uint8_t  State;            //状态
    uint32_t Totalelc;           //电量值
    uint32_t RawTotalelc;              //寄存器电量值
    uint32_t Vol;            //电压值
    uint32_t RawVol;        //寄存器电压值
    uint32_t Cur;              //电流值
    uint32_t RawCur;              //寄存器电流值
    uint32_t Kw;              //功率
    uint32_t RawKw;              //寄存器功率
}ELMINFO;
2.2.定义计量参数寄存器
#define HEAD                    0x6A
#define MPREG_SPLI1             0x00
#define MPREG_SPLI2             0x01
#define MPREG_SPLU              0x02
#define MPREG_IDC               0x03
#define MPREG_UDC               0x04
#define MPREG_RMSI1             0x06
#define MPREG_RMSI2             0x07
#define MPREG_RMSU              0x08
#define MPREG_FREQU             0x09  
#define MPREG_POWERP1           0x0A
#define MPREG_POWERQ1           0x0B
#define MPREG_POWERS            0x0C
#define MPREG_ENERGYP           0x0D
#define MPREG_ENERGYQ           0x0E
#define MPREG_UDETCNT           0x0F
#define MPREG_POWERP2           0x10
#define MPREG_POWERQ2           0x11
#define MPREG_MAXUWAVE          0x12
#define MPREG_CRCCHECKSUM       0x15
#define MPREG_BACKUPDATA        0x16
#define MPREG_COMCHECKSUM       0x17
#define MPREG_SUMCHECKSUM       0x18
#define MPREG_EMUSR             0x19
#define MPREG_SYSSTA            0x1A
#define MPREG_CHIPID            0x1B
#define MPREG_DEVICEID          0x1C
2.3.定义电表较表参数寄存器
#define ECADR_EMUIE               0x30
#define ECADR_EMUIF               0x31
#define ECADR_WPREG               0x32
#define ECADR_SRST          0x33
#define ECADR_EMUCFG              0x40
#define ECADR_FREGCFG             0x41
#define ECADR_MODULEEN            0x42
#define ECADR_ANAEN               0x43
#define ECADR_IOCFG               0x45
#define ECADR_GP1                 0x50
#define ECADR_GQ1                 0x51
#define ECADR_GS1                 0x52
#define ECADR_GP2                 0x54
#define ECADR_GQ2                 0x55
#define ECADR_GS2                 0x56
#define ECADR_QPHSCAL             0x58
#define ECADR_ADCCON              0x59
#define ECADR_I2GAIN              0x5B
#define ECADR_I1OFF               0x5C
#define ECADR_I2OFF               0x5D
#define ECADR_UOFF                0x5E
#define ECADR_PQSTART             0x5F
#define ECADR_HFCONST             0x61
#define ECADR_DEC_SHIFT           0x64
#define ECADR_P1OFFSETH           0x65
#define ECADR_P2OFFSETH           0x66
#define ECADR_Q1OFFSETH           0x67
#define ECADR_Q2OFFSETH           0x68
#define ECADR_I1RMSOFFSET         0x69
#define ECADR_I2RMSOFFSET         0x6A
#define ECADR_URMSOFFSET          0x6B
#define ECADR_ZCROSSCURRENT       0x6C
#define ECADR_GPHS1               0x6D               
#define ECADR_GPHS2               0x6E
#define ECADR_PFCNT               0x6F            
#define ECADR_QFCNT               0x70
#define ECADR_ANACON              0x72
#define ECADR_SUMCHECKL           0x73
#define ECADR_SUMCHECKH           0x74
#define ECADR_MODECFG             0x75
#define ECADR_P1OFFSETL           0x76
#define ECADR_P2OFFSETL           0x77  
#define ECADR_Q1OFFSETL           0x78
#define ECADR_Q2OFFSETL           0x79
#define ECADR_UPEAKLV1            0x7A
#define ECADR_USAGLV1             0x7B
#define ECADR_UCYLEN              0x7C
2.4. HT7017写地址数据
void HT7017_UART_Write(uint8_t address, uint16_t data)
{
  uint8_t buf[256];
    uint8_t checksum=0;
    uint8_t dat8;
    uint8_t tmplen;
    uint16_t i;     
        buf[0]= HEAD;
    buf[1]=address|0x80;
    buf[2]=data>>8;
    buf[3]=data &0xff;
    for(i=0;i<4;i++)
    {
      checksum += buf;      
    }
    buf[4]=~checksum;
    UartFlush(DEV_UART5);
    UartWrite(DEV_UART5, buf, 5);
    for (i=0;i<1000;i++){                  
                rt_thread_mdelay(5);
        tmplen=UartRead(DEV_UART5,&dat8,1);
        if (tmplen != 0){
            if (dat8 == 0x54){
                break;
            }
        }
    }
    if(i == 1000){
        ErrRecvtimes++;
        if(ErrRecvTimes >= 20){
            ElmInfo.State = 1;
            ErrRecvTimes = 20;   
        }   
    }else{
        ElmInfo.State = 0;
        ErrRecvTimes = 0;
    }
}
2.5. HT7017读地址数据
uint32_t HT7017_UART_Read(uint8_t address)
{
        uint8_t buf[10];
    uint8_t checksum=0;
    uint8_t data[4];
    uint16_t j;
    uint32_t regdata=0;     
    uint8_t  tmpbuf[64]={0};
    uint16_t tmplen=0;
    uint8_t rcvbuf[64]={0};
    uint16_t rcvlen=0;
        buf[0]=HEAD;
    buf[1]=address&0x7F;//R+Address
    UartFlush(DEV_UART5);
    UartWrite(DEV_UART5, buf, 2);   
    for (j=0;j<1000;j++){                 
                rt_thread_mdelay(5);
        tmplen=UartRead(DEV_UART5, tmpbuf, 100);
        if (tmplen != 0){
            if (rcvlen+tmplen >= 64){
                return 0;
            }
            memcpy(rcvbuf+rcvlen,tmpbuf,tmplen);
            rcvlen += tmplen;
            if(rcvlen >= 4){
                 memcpy(data,rcvbuf,4);
                break;
            }
        }
    }
    if(j == 1000){
        ErrRecvTimes++;
        if(ErrRecvTimes >= 20){
            ElmInfo.State = 1;
            ErrRecvTimes = 20;   
        }   
    }else{
        ElmInfo.State = 0;
        ErrRecvTimes = 0;
    }   
    checksum =~(buf[0]+buf[1]+data[0]+data[1]+data[2]);
    regdata = 0xFFFFFFFF;
    if(checksum == data[3])
        regdata = ((data[0]<<16)|(data[1]<<8)|data[2])    ;
    return regdata;   
}
2.6.读取芯片电压
static uint32_t HT7017_ReadUrms(void)
{
static uint8_t i;
uint8_t j;
uint32_t TotalVol = 0;
uint32_t Temp;
static uint32_t rawvol[5];
Temp = HT7017_UART_Read(MPREG_RMSU);
if( Temp != 0xFFFFFFFF ){
    rawvol[ i % 5 ] = Temp;
    i++;
    if(i == 5)
     i = 0;
    for(j = 0; j < 5; j++ ){
        TotalVol += rawvol[j];
    }
    ElmInfo.RawVol = TotalVol / 5;
    ElmInfo.Vol = ElmInfo.RawVol / ParaGetVolFactor();
    return ElmInfo.RawVol;
}
    return ElmInfo.RawVol;
}
2.7.读取芯片电流
static uint32_t HT7017_ReadI1rms(void)
{
    static uint32_t rawcur[5];
    static uint8_t i;
    uint8_t j;
    uint32_t TotalCur = 0;
    uint32_t Temp;
    Temp = HT7017_UART_Read(MPREG_RMSI1);
    if( Temp != 0xFFFFFFFF ){
        rawcur[ i % 5 ] = Temp;
        i++;
        if(i == 5)
        i = 0;
        for(j = 0; j < 5; j++ ){
            TotalCur += rawcur[j];
        }
        ElmInfo.RawCur = TotalCur / 5;
        ElmInfo.Cur = ElmInfo.RawCur /ParaGetCurFactor();
        return ElmInfo.RawCur;
    }
    return ElmInfo.RawCur;
}
2.8.读取芯片功率
uint32_t HT7017_ReadPower(void)
{
    ElmInfo.RawKw = HT7017_UART_Read(MPREG_POWERP1);
    ElmInfo.Kw = ElmInfo.RawKw;
    return ElmInfo.RawKw;
}
2.9.读取芯片电量
uint32_t HT7017_ReadEnergp(void)
{
    uint32_t Temp = HT7017_UART_Read(MPREG_ENERGYP);
    if(Temp != 0xFFFFFFFF){
        ElmInfo.RawTotalelc = Temp;
    }
    return ElmInfo.RawTotalelc;
}
3.0.HT7017初始化
static void ElmInit(void)
{
    HT7017_UART_Write(ECADR_SRST, 0x55);
        rt_thread_mdelay(20);
    HT7017_UART_Write(ECADR_WPREG, 0xA6);
        rt_thread_mdelay(20);
    HT7017_UART_Write(ECADR_HFCONST, 0xA6);  
        rt_thread_mdelay(20);
    HT7017_UART_Write(ECADR_ADCCON, 0x00);  
        rt_thread_mdelay(20);
}
3.1.0.创建NUC980线程
static rt_thread_t meterid = RT_NULL;
#define THREAD_PRIORITY            20
#define THREAD_STACK_SIZE          512
#define THREAD_TIMESLICE           5
/* 线程1的入口函数 */
static void merter_entry(void * param)
{   
    rt_kprintf("meterthread started!:%d
");
    ElmInit();
    while(1)
    {
            HT7017_ReadUrms();
                rt_thread_mdelay(500);
        HT7017_ReadI1rms();
                rt_thread_mdelay(500);
        HT7017_ReadEnergp();
                rt_thread_mdelay(500);
    }
}
int meter_sample(void)
{  
    meterid= rt_thread_create("meter",
                            merter_entry,
                            RT_NULL,
                            THREAD_STACK_SIZE,
                            THREAD_PRIORITY,
                            THREAD_TIMESLICE);
    if(meterid!= RT_NULL)
    {
        rt_thread_startup(meterid);
    }
    return 0;   
}
3.2.0.导入 msh 命令列表中
MSH_CMD_EXPORT(meter_sample,meter thread sample);

原作者:Wogee

更多回帖

×
20
完善资料,
赚取积分