基于STC12C5A60S2设计的三相电流表Vref不采样的时候会从5V自动跳到0V
时间:10-02
整理:3721RD
点击:
没有采样值的时候不是应该显示0么,程序在下面,大神们帮看看。采样的
时候显示正常。不采样就从5V慢慢的跳到0V,是ADC的问题还是什么问题,
求大神解决。
代码如下:
/************************************************************
* STC12C5A60S2内置AD驱动程序 *
***********************************************************/
#include<intrins.h>
/*************用于配置P1口对应管脚为AD模拟输入口************/
#define ADC_PORT4 0X10
#define ADC_PORT5 0X20
#define ADC_PORT6 0X40
#define ADC_PORT7 0X80
#define ADC_PORTALL 0XFF
/*************用于获取对应通道的电压************************/
#define ADC_CH4 0X04
#define ADC_CH5 0X05
#define ADC_CH6 0X06
#define ADC_CH7 0X07
/**************定义AD转换速度*******************************/
#define ADC_SPEEDLL_540 0X00
#define ADC_SPEEDLL_360 0X20
#define ADC_SPEEDLL_180 0X40
#define ADC_SPEEDLL_90 0X60
/**************定义转换控制寄存器控制位**********************/
#define ADC_POWER 0X80 //电源控制位
#define ADC_FLAG 0X10 //转换结束标志位
#define ADC_START 0X08 //转换开始位
/**************内置ADC的初始化配置****************************/
void ADC_Init(unsigned char port)
{
P1ASF=port;//设置AD转换通道
ADC_RES=0;//清空转换结果
ADC_CONTR=ADC_POWER | ADC_SPEEDLL_540;//打开AD转化器电源
// IE=0XA0;//开启总中断,ADC中断
_nop_();
_nop_();
_nop_();
_nop_();
}
/***************获取ADC对应通道的电压值************************
** 函数说明 :每次只能获取一个通道的电压值,不同通道需要分别调用该函数获取
** 入口参数 :channel:获取该通道的电压值
** 出口参数 :result: 当前通道的电压值
****************************************************************/
float GetADCResult(unsigned char channel)//读取通道ch的电压值
{
unsigned int ADC_RESULT = 0;//用来存放结果
float result;
ADC_CONTR = ADC_POWER | ADC_SPEEDLL_540 | ADC_START | channel;//开始转换,并设置测量通道
_nop_();//需经过四个CPU时钟延时,上述值才能保证被设进ADC_CONTR控制寄存器
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR & ADC_FLAG));//等待转换结束
ADC_CONTR &= ~ADC_FLAG;//软件清除中断控制位
ADC_RESULT = ADC_RES;
ADC_RESULT = (ADC_RESULT << 2) | ADC_RESL; //默认数据存储方式:高八位在ADC_RES,低二位在ADC_RESL低二位
result = ADC_RESULT * 4.98 / 1024.0 ; //基准电压为电源电压5V,10的分辨率,即1024
return result;
}
#include<STC12C5A60S2.h>
#include<intrins.h>
#include<adc.h>
#define uchar unsigned char
#define uint unsigned int
sbit SCLK=P0^4;
sbit SI=P0^6;
sbit RCLK=P0^5;
sbit E1 = P1^1;
sbit E2 = P1^0;
sbit E3 = P4^2;
sbit E4 = P0^0;
sbit E5 = P0^3;
sbit E6 = P0^2;
sbit E7 = P0^1;
sbit E8 = P2^3;
sbit E9 = P2^1;
sbit E10 = P2^2;
sbit E11 = P2^4;
sbit E12 = P4^0;
sbit LED1 = P0^7;
sbit LED2 = P4^6;
sbit LED3 = P4^1;
sbit LED4 = P4^3;
sbit E13 = P2^0;
//uint LA1,LB1,LC1; //LA1,LB1,LC1分别是被测电流经过互感器变换的电压值
//uchar time;
//uchar i;
uchar code seg_tab[]={0xD7,0x14,0xCD,0x5D, //段码
0x1E,0x5B,0xDB,0x15,
0xDF,0x5F};
void delay(uint y)
{
unsigned int x,z;
for(x=y; x>0; x--)
for(z=110; z>0; z--);
}
void In_595(uchar dat) //595驱动
{
uchar i;
for(i=0;i<8;i++)
{
if((dat<<i)&0x80) //dat:要显示的数字。
{
SI=1; //SI: 串行数据输入端。
}
else
{
SI=0;
}
SCLK=0; //从SCLK产生一上升沿(移入数据)
_nop_(); //QA-->QB-->QC-->...-->QH;下降沿移位寄存器数据不变。
_nop_(); // (脉冲宽度:5V时,大于几十纳秒就行了。通常选微秒级)
SCLK=1;
}
}
void Out_595()
{
RCLK=0; //RCLK上升沿时移位寄存器的数据进入数据存储寄存器,
_nop_(); //下降沿时存储寄存器数据不变。通常我将RCK置为低点平
_nop_(); //RCLK产生一上升沿(输出数据)
RCLK=1;
_nop_();
_nop_();
RCLK=0;
}
//void time0_init() //初始化定时器0
//{
//TMOD=0x01;
// TH0=(65536-50000)/256;
// TL0=(65536-50000)%256;
// EA=1;
// ET0=1;
// TR0=1;
//}
void E_init() //初始化 E1 - E13为灭
{
E1 = 0;
E2 = 0;
E3 = 0;
E4 = 0;
E5 = 0;
E6 = 0;
E7 = 0;
E8 = 0;
E9 = 0;
E10 = 0;
E11 = 0;
E12 = 0;
E13 = 0;
}
void led_init() //初始化LED为灭
{
LED1 = 0;
LED2 = 0;
LED3 = 0;
LED4 = 0;
}
void init595() //初始化595
{
SCLK = 0;
SI = 0;
RCLK = 0;
}
void main()
{
float resA,resB,resC;
float LA2,LB2,LC2;
//time0_init();
E_init();
led_init();
P4SW= 0x70;
init595();
ADC_Init(ADC_PORT5 | ADC_PORT6| ADC_PORT7); //配置通道P1^5 ,P1^6,P1^7 为AD采集口
while(1)
{
resA=GetADCResult(ADC_CH7);
LA2 = resA ;//- 0.82;
E1 = 1; //数码管驱动显示三相电流
In_595(seg_tab[(uint)(LA2*1000)/1000]); //Vref为参考点位,还没测出来 ,以下同写
Out_595(); //resA/B/C-Vref=外部被测电(LA2/LB2/LC2)
delay(7);
E1 = 0;
delay(2);
E2 = 1;
In_595(seg_tab[(uint)(LA2*1000)%1000/100]);
Out_595();
delay(7);
E2 = 0;
delay(2);
E3 = 1;
In_595(seg_tab[(uint)(LA2*1000)%1000%100/10]);
Out_595();
delay(7);
E3 = 0;
delay(2);
E4 = 1;
In_595(seg_tab[(uint)(LA2*1000)%1000%100%10]);
Out_595();
delay(7);
E4 = 0;
delay(2);
resB=GetADCResult(ADC_CH6);
LB2 = resB ;//- 0.82;
E5 = 1;
In_595(seg_tab[(uint)(LB2*1000)/1000]);
Out_595();
delay(7);
E5 = 0;
delay(2);
E6 = 1;
In_595(seg_tab[(uint)(LB2*1000)%1000/100]);
Out_595();
delay(7);
E6 = 0;
delay(2);
E7 = 1;
In_595(seg_tab[(uint)(LB2*1000)%1000%100/10]);
Out_595();
delay(7);
E7 = 0;
delay(2);
E8 = 1;
In_595(seg_tab[(uint)(LB2*1000)%1000%100%10]);
Out_595();
delay(7);
E8 = 0;
delay(2);
resC=GetADCResult(ADC_CH5);
LC2 = resC ;//- 0.82;
E9 = 1;
In_595(seg_tab[(uint)(LC2*1000)/1000]);
Out_595();
delay(7);
E9 = 0;
delay(2);
E10 = 1;
In_595(seg_tab[(uint)(LC2*1000)%1000/100]);
Out_595();
delay(7);
E10 = 0;
delay(2);
E11 = 1;
In_595(seg_tab[(uint)(LC2*1000)%100/10]);
Out_595();
delay(7);
E11 = 0;
delay(2);
E12 = 1;
In_595(seg_tab[(uint)(LC2*1000)%1000%100%10]);
Out_595();
delay(7);
E12 = 0;
delay(2);
}
}
时候显示正常。不采样就从5V慢慢的跳到0V,是ADC的问题还是什么问题,
求大神解决。
代码如下:
/************************************************************
* STC12C5A60S2内置AD驱动程序 *
***********************************************************/
#include<intrins.h>
/*************用于配置P1口对应管脚为AD模拟输入口************/
#define ADC_PORT4 0X10
#define ADC_PORT5 0X20
#define ADC_PORT6 0X40
#define ADC_PORT7 0X80
#define ADC_PORTALL 0XFF
/*************用于获取对应通道的电压************************/
#define ADC_CH4 0X04
#define ADC_CH5 0X05
#define ADC_CH6 0X06
#define ADC_CH7 0X07
/**************定义AD转换速度*******************************/
#define ADC_SPEEDLL_540 0X00
#define ADC_SPEEDLL_360 0X20
#define ADC_SPEEDLL_180 0X40
#define ADC_SPEEDLL_90 0X60
/**************定义转换控制寄存器控制位**********************/
#define ADC_POWER 0X80 //电源控制位
#define ADC_FLAG 0X10 //转换结束标志位
#define ADC_START 0X08 //转换开始位
/**************内置ADC的初始化配置****************************/
void ADC_Init(unsigned char port)
{
P1ASF=port;//设置AD转换通道
ADC_RES=0;//清空转换结果
ADC_CONTR=ADC_POWER | ADC_SPEEDLL_540;//打开AD转化器电源
// IE=0XA0;//开启总中断,ADC中断
_nop_();
_nop_();
_nop_();
_nop_();
}
/***************获取ADC对应通道的电压值************************
** 函数说明 :每次只能获取一个通道的电压值,不同通道需要分别调用该函数获取
** 入口参数 :channel:获取该通道的电压值
** 出口参数 :result: 当前通道的电压值
****************************************************************/
float GetADCResult(unsigned char channel)//读取通道ch的电压值
{
unsigned int ADC_RESULT = 0;//用来存放结果
float result;
ADC_CONTR = ADC_POWER | ADC_SPEEDLL_540 | ADC_START | channel;//开始转换,并设置测量通道
_nop_();//需经过四个CPU时钟延时,上述值才能保证被设进ADC_CONTR控制寄存器
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR & ADC_FLAG));//等待转换结束
ADC_CONTR &= ~ADC_FLAG;//软件清除中断控制位
ADC_RESULT = ADC_RES;
ADC_RESULT = (ADC_RESULT << 2) | ADC_RESL; //默认数据存储方式:高八位在ADC_RES,低二位在ADC_RESL低二位
result = ADC_RESULT * 4.98 / 1024.0 ; //基准电压为电源电压5V,10的分辨率,即1024
return result;
}
#include<STC12C5A60S2.h>
#include<intrins.h>
#include<adc.h>
#define uchar unsigned char
#define uint unsigned int
sbit SCLK=P0^4;
sbit SI=P0^6;
sbit RCLK=P0^5;
sbit E1 = P1^1;
sbit E2 = P1^0;
sbit E3 = P4^2;
sbit E4 = P0^0;
sbit E5 = P0^3;
sbit E6 = P0^2;
sbit E7 = P0^1;
sbit E8 = P2^3;
sbit E9 = P2^1;
sbit E10 = P2^2;
sbit E11 = P2^4;
sbit E12 = P4^0;
sbit LED1 = P0^7;
sbit LED2 = P4^6;
sbit LED3 = P4^1;
sbit LED4 = P4^3;
sbit E13 = P2^0;
//uint LA1,LB1,LC1; //LA1,LB1,LC1分别是被测电流经过互感器变换的电压值
//uchar time;
//uchar i;
uchar code seg_tab[]={0xD7,0x14,0xCD,0x5D, //段码
0x1E,0x5B,0xDB,0x15,
0xDF,0x5F};
void delay(uint y)
{
unsigned int x,z;
for(x=y; x>0; x--)
for(z=110; z>0; z--);
}
void In_595(uchar dat) //595驱动
{
uchar i;
for(i=0;i<8;i++)
{
if((dat<<i)&0x80) //dat:要显示的数字。
{
SI=1; //SI: 串行数据输入端。
}
else
{
SI=0;
}
SCLK=0; //从SCLK产生一上升沿(移入数据)
_nop_(); //QA-->QB-->QC-->...-->QH;下降沿移位寄存器数据不变。
_nop_(); // (脉冲宽度:5V时,大于几十纳秒就行了。通常选微秒级)
SCLK=1;
}
}
void Out_595()
{
RCLK=0; //RCLK上升沿时移位寄存器的数据进入数据存储寄存器,
_nop_(); //下降沿时存储寄存器数据不变。通常我将RCK置为低点平
_nop_(); //RCLK产生一上升沿(输出数据)
RCLK=1;
_nop_();
_nop_();
RCLK=0;
}
//void time0_init() //初始化定时器0
//{
//TMOD=0x01;
// TH0=(65536-50000)/256;
// TL0=(65536-50000)%256;
// EA=1;
// ET0=1;
// TR0=1;
//}
void E_init() //初始化 E1 - E13为灭
{
E1 = 0;
E2 = 0;
E3 = 0;
E4 = 0;
E5 = 0;
E6 = 0;
E7 = 0;
E8 = 0;
E9 = 0;
E10 = 0;
E11 = 0;
E12 = 0;
E13 = 0;
}
void led_init() //初始化LED为灭
{
LED1 = 0;
LED2 = 0;
LED3 = 0;
LED4 = 0;
}
void init595() //初始化595
{
SCLK = 0;
SI = 0;
RCLK = 0;
}
void main()
{
float resA,resB,resC;
float LA2,LB2,LC2;
//time0_init();
E_init();
led_init();
P4SW= 0x70;
init595();
ADC_Init(ADC_PORT5 | ADC_PORT6| ADC_PORT7); //配置通道P1^5 ,P1^6,P1^7 为AD采集口
while(1)
{
resA=GetADCResult(ADC_CH7);
LA2 = resA ;//- 0.82;
E1 = 1; //数码管驱动显示三相电流
In_595(seg_tab[(uint)(LA2*1000)/1000]); //Vref为参考点位,还没测出来 ,以下同写
Out_595(); //resA/B/C-Vref=外部被测电(LA2/LB2/LC2)
delay(7);
E1 = 0;
delay(2);
E2 = 1;
In_595(seg_tab[(uint)(LA2*1000)%1000/100]);
Out_595();
delay(7);
E2 = 0;
delay(2);
E3 = 1;
In_595(seg_tab[(uint)(LA2*1000)%1000%100/10]);
Out_595();
delay(7);
E3 = 0;
delay(2);
E4 = 1;
In_595(seg_tab[(uint)(LA2*1000)%1000%100%10]);
Out_595();
delay(7);
E4 = 0;
delay(2);
resB=GetADCResult(ADC_CH6);
LB2 = resB ;//- 0.82;
E5 = 1;
In_595(seg_tab[(uint)(LB2*1000)/1000]);
Out_595();
delay(7);
E5 = 0;
delay(2);
E6 = 1;
In_595(seg_tab[(uint)(LB2*1000)%1000/100]);
Out_595();
delay(7);
E6 = 0;
delay(2);
E7 = 1;
In_595(seg_tab[(uint)(LB2*1000)%1000%100/10]);
Out_595();
delay(7);
E7 = 0;
delay(2);
E8 = 1;
In_595(seg_tab[(uint)(LB2*1000)%1000%100%10]);
Out_595();
delay(7);
E8 = 0;
delay(2);
resC=GetADCResult(ADC_CH5);
LC2 = resC ;//- 0.82;
E9 = 1;
In_595(seg_tab[(uint)(LC2*1000)/1000]);
Out_595();
delay(7);
E9 = 0;
delay(2);
E10 = 1;
In_595(seg_tab[(uint)(LC2*1000)%1000/100]);
Out_595();
delay(7);
E10 = 0;
delay(2);
E11 = 1;
In_595(seg_tab[(uint)(LC2*1000)%100/10]);
Out_595();
delay(7);
E11 = 0;
delay(2);
E12 = 1;
In_595(seg_tab[(uint)(LC2*1000)%1000%100%10]);
Out_595();
delay(7);
E12 = 0;
delay(2);
}
}
这个你直接把stc官方的程序拿来用就可以。不知道你的这个程序是不是官方的。