在智慧农业、工业控制等实际项目中,PIC16F1947 成为我近年来高频使用的核心芯片。其丰富的外设与双串口设计,非常适合构建多通道通信与控制系统。本次我将以一款实际投产数年的控制板为例,详解其电流互感器(5A/10A)数据采集。
该控制板集成了以下8大功能,覆盖多数物联网与工控场景:
1、6路继电器输出;
2、2路DC24V或12V直流电机正反转控制;
3、1路4G模块数据收发;
4、1路LORA无线数据收发或RS485数据收发;
5、2路无源开关量输入;
6、1路电流互感器(5A/10A)数据采集;
7、1路数模转换(数字量转4-20mA/0-5V/0-10V);
8、1路模数转换(4-20mA/0-5V/0-10V转数字量)。
一、 4-20mA/0-5V/0-10V**采集硬件电路:**

上图J2是4-20mA/0-5V/0-10V输入,为了电流电压输入通用,R22、R23是分压电阻,如果是4-20mA 输入,可采用图中的阻值,如果是0-5V或0-10V,R22、R23阻值最好都大于1K,不至于电流过大,可以自己计算两个阻值,保证VIN+输入在2V以内就可以, U4是18位A/D芯片MCP3421,VIN+、VIN-用作差分输入时可以到18位精度,VIN-接GND时可以到17位精度,R20、R21是两个10K上拉电阻,通过设置MCP3421寄存器可使参考电压为2.048V。
二、例程:
以下是采集示例(PIC16F1947采用16M主频),具体程序如下:
#include<pic16f1947.h>
__CONFIG(0x007c); //内部时钟16M
__CONFIG(0x1010); //内部时钟16M
unsigned char dres_485=1,sec_5s=0,half_sec=0 ,flag_rev=0,flag_rev2=0,leijia_tnt2,elecl,elech,elechh;
unsigned int time_tnt,time_tnt2,sec_05s,rev_rnt=0,rev_rnt2=0,tran_rnt=0,tran_rnt2=0,sec_1s=0;
unsigned char eeprom_e2[30]; //EEPROM缓存
unsigned long result_3421[30];
unsigned char trans[50];
unsigned char reciv[200]; //串口1接收缓存
unsigned char reciv2[200]; //串口2接收缓存
#define SDA RE3 //电流采集数据I/O
#define SCL RE2 //电流采集时钟I/O
#define byte unsigned char
void delay(unsigned int v)
{
while(v!=0)v--;
}
void somenop(void)
{
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
void I2CStart(void)
{
TRISE3=0;
SDA=1;
somenop();
SCL=1;
somenop();
somenop();
SDA=0;
somenop();
somenop();
SCL=0;
somenop();
}
void I2CStop(void)
{
SCL=0;
somenop();
SDA=0;
somenop();
somenop();
SCL=1;
somenop();
somenop();
SDA=1;
somenop();
// TRISC6=1;
}
void WaitAck(void)
{
unsigned char i=20;
TRISE3=1;
SDA=1;
somenop();
SCL=1;
/* lpp: if(SDA==0)
{
rc_flag=64;
}
else
{
SCL=0;
somenop();
somenop();
SCL=1;
somenop();
SCL=0;
goto lpp;
} */
while(i--){
if(SDA==1)
{
SCL=0;
somenop();
somenop();
SCL=1;
}
else
goto loop;
}
loop:
SCL=0;
somenop();
TRISE3=0;
return;
}
void SendAck(void)
{
SDA=0;
somenop();
SCL=1;
somenop();
somenop();
SCL=0;
somenop();
}
void SendNotAck(void)
{
SDA=1;
somenop();
SCL=1;
somenop();
somenop();
SCL=0;
somenop();
}
void I2CSendbyte(byte ch)
{
unsigned char i=8;
TRISE3=0;
while(i--)
{
SCL=0;
somenop();
if((ch&0x80)!=0)
{
SDA=1;
}
else SDA=0;
ch<<=1;
somenop();
SCL=1;
somenop();
somenop();
}
SCL=0;
somenop();
}
byte I2CRecebyte(void)
{
unsigned char i=8;
byte ddata=0;
TRISE3=1;
// SDA=1;
while(i--){
ddata<<=1;
SCL=0;
somenop();
SCL=1;
somenop();
somenop();
ddata|=SDA;
}
SCL=0;
somenop();
TRISE3=0;
return ddata;
}
void WRITE_MCP3421(unsigned char wr_data)
{
I2CStart();
I2CSendbyte(0xd0);
WaitAck();
I2CSendbyte(wr_data);
WaitAck();
I2CStop();
}
void READ_MCP3421(void)
{
I2CStart();
I2CSendbyte(0xd1);
WaitAck();
elechh=I2CRecebyte();
SendAck();
elech=I2CRecebyte();
SendAck();
elecl=I2CRecebyte();
SendAck();
mcp_busy=I2CRecebyte();
SendNotAck();
I2CStop();
}
void interrupt isr(void)
{
if(TMR1IF)
{
TMR1L=0xbf;
TMR1H=0xf9;
sec_05s+=1;
sec_1s+=1;
if(sec_05s>624) //0.5s
{
half_sec+=1;
sec_5s+=1;
sec_05s=0;
}
TMR1IF=0;
}
}
void main()
{
unsigned int i,j;
unsigned char tmp;
ANSELF=0;
ANSELG=0;
// ADCON0=0;
TRISC=0x80;
TRISB=0x87;
OPTION_REG&=0X7F;
WPUB7=1;
TRISD=0x00;
TRISE=0x00;
TRISF=0x00;
TRISG=0x0c;
// TRISG=0x00;
PORTC=0x38;
PORTD=0x00;
PORTE=0x00;
PORTF=0x00;
PORTG=0x00;
// OSCCON=0x0;
OSCSTAT=0xa0;
OSCCON=0x78; //内部时钟16M
// OSCCON=0xf0; //32M
// OSCSTAT=0xf0;//32M
PIE1=0x21;
INTCON=0x00;
T1CON=0x70;
TMR1IF=0;
TMR1L=0xbf; //0.8ms
TMR1H=0xf9;
TMR1IE=1;
T1CON=0x71;
PEIE=1;
GIE=1;
while(1)
{
asm("clrwdt");
if(sec_5s>3) //2秒采集一次
{
WRITE_MCP3421(0x8c); //设置17位A/D,参考电压2.048V
delay(10);
READ_MCP3421();
result_3421[1]=elechh;
result_3421[1]<<=8;
result_3421[1]|=elech;
result_3421[1]<<=8;
result_3421[1]|=elecl;
//根据采集数据计算电流或电压
}
}
}
三、本系列文章规划
《PIC单片机进阶实战》系列共六篇,后续将逐步展开以下内容:
|----|-------------------|---------------------------|
| 序号 | 主题 | 内容概要 |
| 1 | UART 通信 | 双串口配置、波特率转换、数据透传 |
| 2 | 4G 模块数据收发 | AT指令控制、4G模块数据透传 |
| 3 | 电流互感器数据采集 | 5A、10A电流采集 |
| 4 | 数模转换 | 12位模拟量输出4-20mA/0-5V/0-10V |
| 5 | 输入输出 | 开关量输入、控制继电器与直流电机 |
| 6 | 模数转换 | 4-20mA/0-5V/0-10V模拟量采集 |
附:《 PIC 单片机入门实战》共 8 篇文章与《 PIC 单片机进阶实战》共 6 篇文章内容来源于我自己画的电路原理图及程序,有对 PIC 单片机感兴趣想学习的朋友可以关注我,免费赠送资料(包括原理图、数据手册、各种例程等)。
有需要这两款控制板的朋友也可以关注联系我。
后续干货不断,咱们一起在单片机的世界里,共同进步。