📄 main.c
字号:
#include "AT89X52.H"
unsigned int U_set;
unsigned int I_set;
unsigned int U_real;
unsigned int I_real;
unsigned int DATA; //最后需要从DA输出的数 16位 ;
unsigned char select[]={0x01,0x02,0x04,0x08,0x10,0x20};//移位的控制码字~!
unsigned char displaycode[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //显示的码字 前10个为不带小数点,后10个带小数点 但是貌似反了 再斟酌一下
void inti() //单片机初始化
{
P1=0x00; //数码管片选端 全为0 因为为共阳极的
P0=0xff; //码字端全为1
//AD 初始化
// P2=0x00; //按键初始化
P3_4=1; // CS=1;
P3_1=1; //SCLK=1;
// P3_0=1; //AD_IN=1;
//DA初始化
P3_3=1; //DA片选 SYNC 为高电平
}
void delay2ms(void) //延时2ms秒子程序,用作数码管扫描
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=48;j>0;j--);
}
void delay10ms(void) //延时10ms秒子程序,用作键盘扫描
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=250;j>0;j--);
}
unsigned char keyscan()
{
if(P2_0==0)//键盘按下 显示低电平 key1;
{
delay10ms();//延迟10ms,看键盘是否真的按下。。
if(P2_0==0)
return(1);
} //key1 为"+"
else if(P2_1==0)
{
delay10ms();
if(P2_1==0)
return(2);
} //key2 为"-"
else if(P2_2==0)
{
delay10ms();
if(P2_2==0)
return(3);
} //key3为"set"
else if(P2_3==0)
{
delay10ms();
if(P2_3==0)
return(4);
} //key4为 sure
return(0);//无键盘按下时,返回0
}
void ledplay(unsigned short U_num,unsigned short I_num) //电流用 0 电压用 1 表示。
{
unsigned char i;
unsigned char temp;
U_num=(U_num<<6)>>6;
I_num=(I_num<<6)>>6;
//unsigned char select[]={0x01,0x02,0x04,0x08,0x10,0x20} //移位的控制码字~!
//unsigned char displaycode[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x40,0x89,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //显示的码字 前10个为不带小数点,后10个带小数点 貌似反了 已经移到最前边去了··
for(i=0;i<6;i++) //这一部分的代码貌似比较劣质 先看能调成功不嘛··
{
switch(i)
{
case 0:temp=U_num/100+10;break; //去U_num 的第也百位,并加小数点
case 1:temp=U_num/10-((U_num/100)*10);break; //去U_num 的第二位
case 2:temp=U_num%10; break; //去U_num 的第三位
case 3:temp=I_num/100+10;break; //取I_num 的第百位,并加小数点
case 4:temp=I_num/10-((I_num/100)*10); break; //取I_num 的第2位
case 5:temp=I_num%10; break; //取I_num 的第3位 10
}
P0=displaycode[temp]; //P0口输出对应的码字
P1=select[i]; //选择数码管
delay2ms();
}
}
void ledplay200ms(unsigned int U_num,unsigned int I_num)
{
unsigned char i;
for(i=20;i>0;i--) //再算一下 调整一下!
ledplay(U_num,I_num);
}
void key3process() //set 按键功能程序
{
// U_set=500;
while(1)
{
ledplay200ms(U_set,0);
if((keyscan())==1)
U_set=U_set+10;
else if((keyscan())==2)
U_set=U_set-10;
//显示设置的电压,电流显示为0
else if((keyscan())==4)
break;
}
;
}
//电压输出程序 DA 转化
//sbit SCLK = P3_1 ; // 时钟引脚 根据实际情况调整
//sbit SYNC_=P3_3 ; // 相当于片选引脚 根据实际情况调整
//sbit Dout_bit = P3_0; //输出数据位
//unsigned int DATA; //最后需要从DA输出的数 16位 ;
void U_numProcess()
{
// unsigned short U_ref=500; // 基准电压值,根据实际情况调整
unsigned int Dout_mid; //从U_num计算DATA的中间数
Dout_mid=U_set*4; // Dout_mid=(unsigned long)U_set*4096/1000; // 不确定这个算式是正确的,貌似溢出了··
DATA=((Dout_mid<<4)>>4)|0x0001; //算出最后输出的数 前4位为 0001 后12位为转换的数。
}
void Uout_inti()
{
P3_3=1; //SYNC_=1 片选为高电平(低电平为有效)
P3_1=1; //SCKL为高电平
}
void delay02ms() //还要在看一下 跟据实际情况调整 DA 的时间控制延迟函数
{
unsigned char i,j;
for(i=10;i>0;i--)
for(j=10;j>0;j--)
{;}
}
void Vout()
{
unsigned char i;
unsigned int check; //检验数。
check=0x8000;
U_numProcess(); //计算出最后从DA输出的数
Uout_inti(); //进行初始化
P3_3=0; //SYNC=0; 打开片选
delay02ms();
for(i=0;i<16;i++)
{
if((DATA&check)==check)
P3_0=1; //Dout_bit=1; //检验数为1,输出
else P3_0=0; //Dout_bit=0;
delay02ms();
delay02ms();
P3_1=0; //SCLK=0; //时钟下降沿 读数据
delay02ms();
delay02ms();
P3_1=1; //SCLK=1; //时钟上升沿
check=(check>>1); //check 右移一位
} //进行16次移位检验输出。
// P3_1=1 ; //SCLK=1
P3_3=1 ; // SYNC=1 关闭 完成DA转换
}
//对电压进行采样
///电压采样程序
//sbit SCLK=P3_1;
//sbit CS=P3_4;
//sbit AD_OUT=P3_5;
//sbit AD_IN=P3_0;
void ADU_inti()
{
P3_4=1; //CS=1;
P3_1=1; //SCLK=1;
P3_0=1; //AD_IN=1;
} //对AD 端口进行初始化
void U_select()
{
unsigned char i;
P3_4=0; // CS=0;
for(i=0;i<32;i++)
{
delay02ms();
delay02ms();
P3_1=~P3_1; // SCLK=~SCLK;
}
delay02ms();
//完成选择
P3_4=1; //CS=1;
// P3_1=1; //SCLK=1;
} //第一次 AD 不进行转换 只选择是进行U 还是 I 的转换。 AD_IN=1 的时候 选择IN4 AD_IN=0的时候选择IN1 ;
void U_convert()
{
unsigned char i;
unsigned int U_check=0;
unsigned int temp_check=0x0800;
ADU_inti();
U_select();
P3_4=0; //CS=0; //开启进行转换
for(i=0;i<8;i++) //前4个周期 空运做 不做任何工作 完成后 SCLK 处于高电平 下一个低电平 开始读取
{
delay02ms();
delay02ms();
P3_1=~P3_1; //SCLK=~SCLK;
}
for(i=0;i<12;i++)
{
delay02ms();
P3_1=(~P3_1); //SCLK=~SCLK; //高电平转换为低电平
delay02ms();
delay02ms();
P3_1=(~P3_1); //低电平转化为高电平
if(P3_5==1) //if(AD_OUT==1)
U_check=(U_check|temp_check);
temp_check=(temp_check>>1);
}
delay02ms();
P3_4=1; // CS=1; //完成转换 关闭片选,现在SCLK为高电平;
U_real=U_check/4; // U_real=U_check*1000/4096; //把转换获取的值赋给U_real;
}
//对电流进行采样
//sbit SCLK=P3_1;
//sbit CS=P3_4;
//sbit AD_OUT=P3_5;
//sbit AD_IN=P3_0;
void ADI_inti()
{
P3_4=1; // CS=1;
P3_1=1; // SCLK=1;
P3_0=0; // AD_IN=0;
} //对AD 端口进行初始化
void I_select()
{
unsigned char i;
P3_4=0;//CS=0;
for(i=0;i<32;i++)
{
delay02ms();
P3_1=~P3_1; // SCLK=~SCLK;
}
delay02ms();
//完成选择
// P3_1=1; // SCLK=1;
P3_4=1; // CS=1;
} //第一次 AD 不进行转换 只选择是进行U 还是 I 的转换。 AD_IN=1 的时候 选择IN4 AD_IN=0的时候选择IN1 ;
void I_convert()
{
unsigned char i;
unsigned int I_check=0;
unsigned int temp_check=0x0800;
ADI_inti();
I_select();
P3_4=0; //CS=0; //开启进行转换
for(i=0;i<8;i++) //前4个周期 空运做 不做任何工作 完成后 SCLK 处于高电平 下一个低电平 开始读取
{
delay02ms();
delay02ms();
P3_1=~P3_1; // SCLK=~SCLK;
}
for(i=0;i<12;i++)
{
delay02ms();
P3_1=(~P3_1); // SCLK=~SCLK; //高电平转换为低电平
delay02ms();
delay02ms();
P3_1=~P3_1; // SCLK=~SCLK;//低电平转化为高电平
if(P3_5==1) //if(AD_OUT==1)
I_check=(I_check|temp_check);
temp_check=temp_check>>1;
}
delay02ms();
P3_4=1; // CS=1; //完成转换 关闭片选,现在SCLK为高电平;
I_real=I_check/4; //把转换获取的值赋给I_real; 需要根据实际情况更改;
}
//主函数
//unsigned short U_set;
//unsigned short I_set;
//unsigned short U_real;
//unsigned short I_real;
void main()
{
unsigned temp;
U_set=500;
// U_real=300; //为了测试数据
// I_real=200; //为了测试数据
inti(); //对单片机进行初始化
while(1)
{
ledplay200ms(U_set,1); //
temp=keyscan();
if(temp==3)break;
} //等待初始化按键
key3process();
Vout(); //输出SET电压值
U_convert();
I_convert();
ledplay200ms(U_real,I_real);
while(1)
{
if((keyscan())==1)
{
U_set=U_set+10;
Vout();
U_convert();
I_convert();
// U_real=U_real+10; // 测试用
}
else if((keyscan())==2)
{
U_set=U_set-10;
Vout();
U_convert();
I_convert();
// U_real=U_real-10; //测试用
}
ledplay200ms(U_real,I_real);
}
//最外层循环
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -