硬件设计
附:http://www.jh-tec.cn/archives/7305
大家好,之前讲过几篇数字表都是电压表,而且都是直流电压,今天讲一下交流的电压电流表。本次设计的主要难度在于硬件电路设计,需要实现交流转直流,然后用ADC采集回去之后再换算。本次采用的核心处理芯片仍然是51单片机,ADC采用的是凌力尔特的LTC1865。该芯片的主要性能如下:
- 采用 MSOP 封装的 16 位、250ksps ADC
- 单 5V 电源
- 低电源电流:850μA (典型值)
- 自动停机功能可把电源电流减小至 2μA (在 1ksps)
- 真正的差分输入
- 单通道 (LTC1864) 或双通道 (LTC1865) 版本
- SPI/MICROWIRE™ 兼容型串行 I/O
- 12 位 LTC1286 / LTC1298 的 16 位升级版器件
- 与 12 位 LTC1860 / LTC1861 引脚兼容
- 保证工作至 +125°C (MSOP 封装)
总体分为了以下几部分:数码管显示、MCU控制电路、AD转换电路、交流电流转换电路、交流电压转换电路、电流有效值测量、电压有效值测量、电流电压相位转换电路。具体仿真电路图如下所示:
1表示此时的电流:
2表示此时的电压:
程序设计
#include<regx51.h>
#include<intrins.h>
#include<absacc.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
#define addo (5.0/65535.0)
uchar vol[]="Voltage:";//定义串口通信的电压提示语
uchar cur[]="Current:";//定义串口通信的电流提示语
uchar pf[]="Power Factor:";//定义串口通信的功率因数提示语
uchar num[10]={'0','1','2','3','4','5','6','7','8','9'};//定义串口通信的数字字符查表传送
sbit DIN = P2^0;
sbit CS = P2^1;
sbit CLK = P2^2;
sbit SDO = P2^3;
sbit SCK = P2^4;
sbit CONV = P2^5;
sbit SDI=P2^6;
uint High,Low;
sbit K=P3^2;
bit choose=1;//定义A/D转换器通道选择变量
double t=0;
static unsigned char disbuf[8] = {1,2,3,4,5,6,7,8};//数码管显示缓冲数据
/*延时函数*/
void delay_ms(uint n)
{
uchar i;
while(n--)
{
for(i=0;i<100;i++);
}
}
/*定时器T0初始化 */
void Init_T0()
{
TMOD=0x09;
TH0=0;
TL0=0;
}
/*数码管进行显示*/
void WriteByte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
DIN = ((dat<<i)&0x80)?1:0;
CLK = 0;
_nop_();
CLK = 1;
_nop_();
}
}
void MAX7221_WRITE(uchar addr,uchar dat)
{
CS = 0;
WriteByte(addr);
WriteByte(dat);
CS = 1;
}
void MAX7221_Initial(void)
{
MAX7221_WRITE(0x0A,0x07);
MAX7221_WRITE(0x0B,0x07);
MAX7221_WRITE(0x0C,0x01);
MAX7221_WRITE(0x0F,0x00);
MAX7221_WRITE(0x09,0xff);
}
void display(uchar *str)
{
uchar i;
for(i=0;i<8;i++)
{
MAX7221_WRITE(i+1,str[i]);
}
}
/*A/D转换读取转换值*/
uint LTC1864_READ(void)
{
uchar i;
uint temp = 0;
CONV = 0;
CONV = 1;
_nop_();_nop_();_nop_();
CONV = 0;
SDO = 1;
for(i=0;i<16;i++)
{
SCK = 1;
_nop_();
SCK = 0;
_nop_();
if(i==0)
{
SDI=1;
}
if(i==1)
{
choose= !choose;
SDI=choose;
}
temp <<= 1;
if(SDO==1)
{
temp |= 0x0001;
}
}
CONV = 1;
return temp;
}
/*电流值进行数码管转换显示*/
void HEXTOBCD_I(uint temp)
{
disbuf[0] = temp/10000;
disbuf[1] = (temp%10000/1000)|0x80;
disbuf[2] = temp%1000/100;
disbuf[3] = temp%100/10;
disbuf[4] = temp%10;
disbuf[5] = 15;
disbuf[6] = 15;
disbuf[7] = 1;
}
/*电压值进行数码管转换显示*/
void HEXTOBCD_V(uint temp)
{
disbuf[0] = temp/10000;
disbuf[1] = temp%10000/1000;
disbuf[2] = (temp%1000/100)|0x80;
disbuf[3] = temp%100/10;
disbuf[4] = temp%10;
disbuf[5] = 15;
disbuf[6] = 15;
disbuf[7] = 2;
}