📄 new2_uart.c
字号:
//加定时器已完成 现在的采样频率为32Hz
//主体部分已经完成,Ka已经计算正确,给P2端口赋值能正确显示,但通过Ka给P2传递
//增益时,P2输出亦正确,调整PI算法已调整,振级表是使用自己编写的一个,P0输出
//正确了(实施办法是将P0赋值位置提前就解决了)
#include<stdio.h>
#include<aduc842.h>
#include<math.h>
#define KP 0.5//暂定Kp=5
#define KI 0.5//暂定Ki=5
sfr templ=0x86;
sfr temph=0x85;
void DELAY(int length);
void adc_chan(int chan);// 选择通道
void adc_ini();
void adc_start();
void config();
void uart_ini();
void dac_ini();
void port_ini();
//void TIC_ini();
//void TIC_start();
void readval();//读取AD转换值并转为10进制数子函数
void pi();//PI算法子程序
float Lookuptab(unsigned char voltab);//查表子程序
int K;
int Kout1=0;//将Ka1值进行翻转准备输出到P0口
int Kout2=0;//将Ka2值进行翻转准备输出到P2口
int xdata num1[8];//用作暂时存储Ka1值以便今后进行翻转方便
int xdata num2[8];//用作暂时存储Ka2值以便今后进行翻转方便
int xdata i;
int Ka1,Ka2;
int tempval;
float code Table[18]={0.3,0.6,1.0,1.3,1.6,2.0,2.3,2.6,3.0,3.3,3.6,4.0,4.3,4.6,5.0,5.3,5.6,6.0};//自己暂定的振级表,可以根据实际值修改
//float code Table[6]={1,2,3,4,5,6};
float UDA;//UDA为DAC0输出
float UIK=0;//UI的初值设为0
float xdata MK;//该值为采样保存的电压值
float RK;
float EK;
float UPK;
float UK;
int xdata level1;
int xdata level2;
void adc_int() interrupt 6 //ADC转换完,进入中断
{
I2CCON=0x0C8;//灯灭
DELAY(2000);
I2CCON=0x048;//灯亮
temph=ADCDATAH;
templ=ADCDATAL;//转换值暂存到temp中
ADCI = 0;//可要可不要,如果不进入ADC中断,则须用户手动清零
return;
}
void uart_int() interrupt 4
{
Ka1 = SBUF;
RI = 0;
}
void adc_chan(int chan)
{
ADCCON2 = chan;
}
void adc_ini()
{
ADCCON1 = 0x02C; // 暂停AD
EA = 0; // 中断不使能
EADC = 0; // ADC中断不使能
}
void adc_start()
{
ADCCON1 = 0x0AC; // 启动AD,使用内部参考电压
EA = 1; // 中断使能
EADC = 1; // ADC中断使能
}
void config()
{
CFG842 = 0x41; //暂定
PLLCON = 0x03; //工作频率=2.097152 MHz
}
void uart_ini() //串口初始化
{
T3CON = 0x083;
T3FD = 0x02D;
SCON = 0x050;
}
void dac_ini()
{
DACCON = 0x0D;//DAC0 12位异步 0-Cref=5v
//DACCON = 0x2D;//DAC0 12位异步 0-Vdd
}
void port_ini()//根据需要设置AD7520增益值
{
P0&=0x00;
P2&=0x00;
//P2|=0x64;//0110,0100
//P2|=0xC4;//1110,0101
}
void readval()
{
tempval=(int)temph*256;//强制转换为整形数
tempval+=(int)templ;//此时计算的是十进制的AD结果,比如若temph:templ=03ff,则对应于1023
}
float Lookuptab(unsigned char voltab)
{
return Table[voltab];
}
void pi()
{
//UDA=5;//UDA为方便计算设置的一个变量
//UK=UDA;//调试时先可直接把Uk=5v来计算,等到完成后在应用下面的PI算法
// DELAY(500);
// if(level2 == 0) {RK=Lookuptab(0);}
// else if(level2 == 1) {RK=Lookuptab(1);}
// else if(level2 == 2) {RK=Lookuptab(2);}
// else if(level2 == 3) {RK=Lookuptab(3);}
// else if(level2 == 4) {RK=Lookuptab(4);}
// else {RK=Lookuptab(5);}//这段程序目的是查表确定振动的给定参考值以便与采集来的数据比较
DELAY(500);//进入PI运算
switch (level2)
{
case 0:
{
if (0<=MK&MK<=0.3) {//Ka2=0x55;
RK = Lookuptab(0);}
else if (0.3<MK&MK<=0.6){//Ka2=0xAB;
RK = Lookuptab(1);}
else {//Ka2=0xFF;
RK = Lookuptab(2);}
break;
}
case 1:
{
if (1<MK&MK<=1.3) {//Ka2=0x55;
RK = Lookuptab(3);}
else if (1.3<MK&MK<=1.6){//Ka2=0xAB;
RK = Lookuptab(4);}
else {//Ka2=0xFF;
RK = Lookuptab(5);}
break;
}
case 2:
{
if (2<MK&MK<=2.3) {//Ka2=0x55;
RK = Lookuptab(6);}
else if (2.3<MK&MK<=2.6){//Ka2=0xAB;
RK = Lookuptab(7);}
else {//Ka2=0xFF;
RK = Lookuptab(8);}
break;
}
case 3:
{
if (3<MK&MK<=3.3) {//Ka2=0x55;
RK = Lookuptab(9);}
else if (3.3<MK&MK<=3.6){//Ka2=0xAB;
RK = Lookuptab(10);}
else {//Ka2=0xFF;
RK = Lookuptab(11);}
break;
}
case 4:
{
if (4<MK&MK<=4.3) {//Ka2=0x55;
RK = Lookuptab(12);}
else if (4.3<MK&MK<=4.6){//Ka2=0xAB;
RK = Lookuptab(13);}
else {//Ka2=0xFF;
RK = Lookuptab(14);}
break;
}
default:
{
if (5<MK&MK<=5.3) {//Ka2=0x55;
RK = Lookuptab(15);}
else if (5.3<MK&MK<=5.6){//Ka2=0xAB;
RK = Lookuptab(16);}
else {//Ka2=0xFF;
RK = Lookuptab(17);}
break;
}
}
EK=RK-MK;
UPK=KP*EK;
if (UPK>=0.1&UPK<=0.15) {Ka2=0xBB;}
else if(UPK>=0&UPK<=0.1) {Ka2=0xE1;}
//K=(UPK/UDA*1024);//现将()内表达式的值取整,此值处理后即为送往AD7520的增益值,
printf("K=%04X\n",K);
//Ka2=K>>2;//因为电路板上低两位已拉高,所以只需要高8位
//Ka2 = 0xAA;
//Ka2=0x00;
//Ka&=0x00FF;//只用了低八位
//Ka = 0x0064;//为测试方便
}
void main(void)//主程序开始
{
DELAY(100);
config();
adc_ini();
adc_chan(0);
uart_ini();
dac_ini();
port_ini();//p0和p2的初始化
printf("P0=%02BX\n",P0);
//DELAY(2000);
//TIC_ini();
//DELAY(2000);
//P0&=0x00;//如果要调整P0口增益值,则打开此句
//DELAY(2000);
//P0|=0xFF;//第一级AD7520增益先设为不放大,即放大倍数为(1023/1024)
//DELAY(2000);
//printf("P0=%02BX\n",P0);
//printf("UIK=%f\n",UIK);
DAC0H=0x07;
DAC0L=0xFF;//AC0输出恒值2.5v
//i=0;
//adc_start();
//SCONV = 1; //启动AD转换
/////////////////初始化
for (i=0;i<8;i++)
{
num1[i] = 1;
}
level2 = 1;//初始设定等级为等级1
MK=1.1;//初始设定值为1.1v
K=0xFF;
Ka1=0xFF;//初始化p0口的值
Ka2=0xFF;//初始化p2口的值
//Ka = 0x0064;//0110,0100 用于测试用,并不是实际值
//////////////////////////////初始化完成
while(1){ //连续进行AD转换
adc_start();
SCONV = 1; //开始一次转换
DELAY(1000); //调延迟,等待转换完毕
if (ADCI == 0) //中断处理完毕标志,进行输出
{
printf("temph=%02BX,templ=%02BX\n",temph,templ);//串口输出转换值
printf("UIK=%f\n",UIK);
readval();
DELAY(500);
MK=(float)tempval*5/4096;//必须强制转换为浮点数,否则结果不对
// if(0<=MK&MK<=1) {level2 = 0; Ka1=0x2A;}//Ka1的值未确定,暂时以0x00代替
//else if(1<MK&MK<=2) {level2 = 1; Ka1=0x55;}
//else if(2<MK&MK<=3) {level2 = 2; Ka1=0x80;}
//else if(3<MK&MK<=4) {level2 = 3; Ka1=0xAB;}
//else if(4<MK&MK<=5) {level2 = 4; Ka1=0xD5;}
//else {level2 = 5; Ka1=0xFF;}//这段程序目的是查表确定振动的给定参考值以便与采集来的数据比较
DELAY(80000);
if (Ka1==0x2A) {level2 = 0;}
else if(Ka1==0x55) {level2 = 1;}
else if(Ka1==0x80) {level2 = 2;}
else if(Ka1==0xAB) {level2 = 3;}
else if(Ka1==0xD5) {level2 = 4;}
else {level2 = 5;}
pi();
printf("MK=%f\n",MK);
printf("RK=%f\n",RK);
printf("EK=%f\n",EK);
printf("UPK=%f\n",UPK);
//printf("UIK=%f\n",UIK);
//printf("UK=%f\n",UK);
printf("Ka1=%04X\n",Ka1);
printf("Ka2=%04X\n",Ka2);
/////将Ka值进行翻转并输出到P0口
//方法一
num1[0]=Ka1&0x01;
num1[1]=Ka1&0x02;
num1[2]=Ka1&0x04;
num1[3]=Ka1&0x08;
num1[4]=Ka1&0x10;
num1[5]=Ka1&0x20;
num1[6]=Ka1&0x40;
num1[7]=Ka1&0x80;
for (i=0;i<8;i++)
{
if (num1[i]==pow(2,i))
num1[i]=1;
else num1[i]=0;
}
Kout1 = 0;
for (i=0;i<8;i++)
{
Kout1 +=pow(2,(7-i))*num1[i];
}
P0 = Kout1; //本应该为此句,再次利用下句做以简单替代用于测试
num2[0]=Ka2&0x01;
num2[1]=Ka2&0x02;
num2[2]=Ka2&0x04;
num2[3]=Ka2&0x08;
num2[4]=Ka2&0x10;
num2[5]=Ka2&0x20;
num2[6]=Ka2&0x40;
num2[7]=Ka2&0x80;
for (i=0;i<8;i++)
{
if (num2[i]==pow(2,i))
num2[i]=1;
else num2[i]=0;
}
Kout2 = 0;
for (i=0;i<8;i++)
{
Kout2 +=pow(2,(7-i))*num2[i];
}
P2 =Kout2; //本应该为此句,再次利用下句做以简单替代用于测试
//P2|=Ka;//正式给端口赋值,产生AD7520增益
//P2^=Ka;//正式给端口赋值,产生AD7520增益
DELAY(500);
printf("P2=%02BX\n",P2);//显示P2口置位是否正确
printf("P0=%02BX\n",P0);
printf("num1[0]=%d\n",num1[0]);
printf("num1[1]=%d\n",num1[1]);
printf("num1[2]=%d\n",num1[2]);
printf("num1[3]=%d\n",num1[3]);
printf("num1[4]=%d\n",num1[4]);
printf("num1[5]=%d\n",num1[5]);
printf("num1[6]=%d\n",num1[6]);
printf("num1[7]=%d\n\n",num1[7]);
DELAY(1000);
}
}
}
void DELAY(int length)//延迟函数
{
while (length >=0)
length--;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -