?? admain.c
字號:
/***********************************************************************
***********************************************************************/
#include <ADUC812.H>
#include <math.h>
sbit Run_Id=P2^5; //工作指示燈
sbit Ctrl1 =P2^6;
sbit Ctrl0 =P2^7;
sbit Adv0 =P1^2;
sbit Adv1 =P1^3;
#define RUN 0
#define STOP 1
#define V_ref 5 //5伏參考電壓
#define V_12 4095 //12位A/D轉換系數 1024=8位
#define ADIN_V0 0x02 //ad輸入通道號2
#define ADIN_V1 0x03 //ad輸入通道號3
unsigned int Ad_o[2];
unsigned int Da_i[2];
struct segment{
unsigned char V_start; //電壓啟示值*10 相當于0.1V為單位
unsigned char V_end; //電壓結束值*10
unsigned char mul_col; //成績系數*10
unsigned char add_col; //加法系數*10
}; //00,12,02,30 含義0v到1.2v 范圍內y=0.2x+3 單位V
struct segment Seg;
unsigned char DATA_U[64];
unsigned char Rptr,Wptr;
unsigned char DATA_W[16];
unsigned char Uptr,Ulen;
unsigned char flag,flag1,flag_s;
unsigned char time_p,time_r;
idata unsigned int temp_s[20];
//---ad-轉換返回int型整數----------------------------------------------
//ADC function and choose ADC0---ADC7 by Channel
unsigned int GetADC(unsigned char Channel) //ADIN_V0,V1
{
unsigned char *p;
unsigned char variable;
unsigned int ADC_value; //用指針將2個char類型數合并成一個int型數
p=(unsigned char *)&ADC_value;
ADCCON2=Channel;
SCONV=1;
while (SCONV)
{ }
SCONV=1;
while (SCONV)
{ }
variable=0x0F&ADCDATAH; //屏蔽ADC輸入的通道標識符號
*p=variable;
p++;
*p=ADCDATAL;
//Write_Serial(ADC_value);
return(ADC_value);
}
//----Da轉換----0-1--------------------
void SetDac(unsigned char num,unsigned int Da_data)
{
if(num==0)
{
DACCON=0x1F;
DAC0H=(unsigned char)((Da_data>>8) & 0x000f);
DAC0L=(unsigned char)(Da_data & 0x00ff);
}
else if(num==1)
{
DACCON=0x1F;
DAC1H=(unsigned char)((Da_data>>8) & 0x000f);
DAC1L=(unsigned char)(Da_data & 0x00ff);
}
}
//--------------------------------
void Delay(unsigned char D_time)
{
unsigned char i,j,k;
for(i=0;i<D_time;i++)
{
for(j=0;j<0xff;j++);
{
k=j;
k=i;
i=i;
}
}
}
//-----------------eeprom中的數據為10倍數--------------------
unsigned char Select_V(unsigned int Y) //查表找運算參數
{
unsigned long M;
unsigned char i,Vsel;
M=(unsigned long)Y*10*V_ref*2; //2-運放的倍數
M=M / V_12;
Vsel=(unsigned char)(M & 0x000000ff);
if(Vsel>100) Vsel=100;
for(i=0;i<20;i++)
{
EADRL=i;
ECON=0x01;
if((Vsel>=EDATA1)&&(Vsel<EDATA2))
{
Seg.V_start= EDATA1;
Seg.V_end = EDATA2;
Seg.mul_col= EDATA3;
Seg.add_col= EDATA4;
return 1;
}
}
return 0;
}
//------------------------------------------------------
unsigned char Write_f(unsigned char type,unsigned char Addr)
{
switch(type)
{
case 0: //全部擦除
ECON=0x06;
Delay(20); //20ms
ECON=0x03;
break;
case 1: //通過結構進行4字節寫操作
EADRL=Addr;
ECON=0x01;
EDATA1=Seg.V_start;
EDATA2=Seg.V_end ;
EDATA3=Seg.mul_col;
EDATA4=Seg.add_col;
ECON=0x05;
ECON=0x02;
ECON=0x03; //讀
break;
case 2: //只進行寫操作
EADRL=Addr;
ECON=0x02; //寫
ECON=0x03; //讀
break;
}
return 1;
}
//------Ad-Da轉化函數-------y=ax+b----------------------
void Calcu(unsigned char num)
{
unsigned long G;
unsigned int Y;
if(num==0)
{Y=GetADC(ADIN_V0);}
else if(num==1)
{Y=GetADC(ADIN_V1); } //讀取ad 轉換值
Ad_o[num]=Y;
if(Select_V(Y)==1); //查表找運算參數
{
G=Seg.add_col *V_12;
G=G/V_ref/2; //電壓〉點數 2--運放調整
Y=(unsigned int)((Seg.mul_col*Y+G)/10);
if(Y>=0x0FFF)
{
Y=0x0FFF;
}
if(Y<=0x0000)
{
Y=0x0000;
}
}
Da_i[num]=Y;
SetDac(num,Y);
}
void SystemInit() //系統初始化函數
{
TL2=0xDC;
TH2=0xFF;
RCAP2L=0xDC;
RCAP2H=0xFF;
T2CON=0x30; //set rate and start 9600
TR2=1;
SCON=0x50; //set serial port mode
ES=1; //允許串口中斷
TMOD=0x01; //定時器0工作在方式1 10ms
TL0=0xFF;
TH0=0xDB; //設定定時器初值
TR0=1;
ET0=1; //允許定時器0中斷
// EX1=1;
// EX0=1; //允許外部中斷
// IT0=1;
// IT1=1; //設置外部中斷為下降沿觸發方式
// PX1=1;
// PX0=1; //設定外部中斷優先位
ADCCON1=0x7c;
EA=1;
}
//--------------------------------------------
void Write_Serial(unsigned int T_Data) //串口發送函數 在發送的過程中沒有禁止中斷
{
unsigned char *p;
p=(unsigned char *)&T_Data;
DATA_W[0]=*p;
DATA_W[1]=*(p+1);
Uptr=0;
Ulen=2;
TI=1;
flag=1;
}
//---------------------------------------------
void W_Uart(unsigned char *p, unsigned char len) //串口發送函數 在發送的過程中沒有禁止中斷
{
unsigned char i;
for(i=0;i<len;)
{
DATA_W[i]=*p;
i++;
p++;
}
Uptr=0;
Ulen=len;
TI=1;
flag=1;
}
//###########################################
void main(void)
{
unsigned char i,k;
unsigned char len_r,count;
unsigned char Addr_P;
unsigned char temp_t;
unsigned char j;
SystemInit();
// P1^2=1; P1^3=1;
Rptr=Wptr=Uptr=0x00;
flag=flag1=0x00;
flag_s=0x00;
temp_t=0;
W_Uart("Aduc812 start",13);
//ptr =(unsigned char*)&Seg_r;
for(i=0;i<20;i++) { temp_s[i]=0x00;}
//--------初始化flash-----------
EADRL=0;
ECON=0x01;
if(EDATA1==0xff)
{
Write_f(0x00,0x00); //擦除flash
EADRL=0x9f;
for(i=0;i<16;i++)
{
EADRL=i;
EDATA1=i*10;
EDATA2=(i+1)*10;
EDATA3=10;
EDATA4=0;
ECON=0x02;
EADRL=0x9f;
}
}
EADRL=0x40;
ECON=0x01;
j=EDATA1;//j=EDATA1&0x01;
//------------------------------
while(1)
{
if(time_r==0){Run_Id=~Run_Id;time_r=10;}
if(Ctrl0)
{
if(GetADC(ADIN_V0)>0x0030)
{
i=j&0x1f;
if(i>20) i=20;
//SetDac(0,Da_i[i]);
SetDac(0,temp_s[i]);
}
else
{
SetDac(0,0x0000);
for(i=0;i<20;i++) { temp_s[i]=0x00;}
}
}
else
{
Calcu(0);
if(flag_s==1)
{
for(i=19;i>0;i--) { temp_s[i]=temp_s[i-1];}
temp_s[0]=Da_i[0];
flag_s=0;
if((j&0x80)!=0) temp_t++;
//if((temp_t>=0x64)&&((flag_u&0x01)==0x01))
if(temp_t>=0x64)
{
Write_Serial(Ad_o[0]); //test zhy
while(flag){;}
Write_Serial(Da_i[0]);
temp_t=0;
}
}
}
//-----------------------
if((time_p==0)&&(flag1>0))
{
flag1=0x00;
W_Uart("uart err",8);
Rptr=Wptr=0x00;
}
//-----------------------
if(Rptr!=Wptr)
{
time_p=0x80;
k=DATA_U[Rptr];
Rptr++;
if(Rptr>=64) {Rptr=0;}
switch(flag1)
{
case 0: //0xaa 頭 下載
if(k==0xaa) {flag1=0x01;}
else if(k==0xbb){flag1=0x10;}
else if(k==0xcc)
{
for(i=0;i<20;i++)
{
Write_Serial(temp_s[i]); //test zhy
while(flag){;}
}
/*EADRL=0x40;
ECON=0x01; //按頁擦
EDATA1=0x00;
EDATA2=0x00;
EDATA3=0xcc;
EDATA4=0xcc;
ECON=0x05; //按頁擦
ECON=0x02;
EADRL=0x9f; // 最后一頁
j=0;
W_Uart("ok" ,2);
Rptr=Wptr=0x00;
*/
}
else if(k==0xcd){flag1=0x20;}
break;
case 1:
if(k>0x00) //長度
{
flag1=0x02;
len_r=k;
if(len_r>60) {len_r=60;}
count=0x00;
Addr_P=Rptr;
}
else
{flag1=0x00;}
break;
case 2: //等待消息結束長度
count++;
if(count==len_r){flag1=0x03;}
break;
case 3: //數據下載完成 寫消息
Write_f(0x00,0x00); //擦除flash
Rptr=Addr_P;
count=len_r/4;
for(i=0;i<count;i++)
{
EADRL=i;
// ECON=0x01; //按頁讀
EDATA1=DATA_U[Rptr];
EDATA2=DATA_U[Rptr+1];
EDATA3=DATA_U[Rptr+2];
EDATA4=DATA_U[Rptr+3];
// ECON=0x05; //按頁擦
ECON=0x02;
EADRL=0x9F; // 最后一頁
Rptr=Rptr+4;
}
len_r=0;
Addr_P=0;
flag1=0x00;
Rptr=Wptr=0x00;
W_Uart("down ok" ,7);
break;
case 0x10: //讀frlash數據
flag1=0x00;
Rptr=Wptr=0x00;
len_r=0;
for(i=0;i<65;i++)
{
EADRL=i;
ECON=0x01;
Seg.V_start= EDATA1;
Seg.V_end = EDATA2;
Seg.mul_col= EDATA3;
Seg.add_col= EDATA4;
while(flag){;}
W_Uart((unsigned char*)&Seg ,4);
}
break;
case 0x20:
{
flag1=0x00;
EADRL=0x40;
ECON=0x01; //按頁讀
EDATA1=k;
EDATA2=0x0f;
EDATA3=0xcd;
EDATA4=0xcd;
ECON=0x05; //按頁擦
ECON=0x02;
EADRL=0x41; // 最后一頁
j=k;
W_Uart("ok" ,2);
Rptr=Wptr=0x00;
}
}
}
}
}
void S_int0() interrupt 0
{
}
void S_int1() interrupt 2
{
}
void Time0() interrupt 1
{
TL0=0xFF;
TH0=0xDB; //TH0=0xDB; //設定定時器初值
TR0=1; //停止計數
if(time_r>0){time_r--;flag_s=1;}
if(time_p>0){ time_p--;}
// flag_s=1;
}
void Uart_isr() interrupt 4
{
// unsigned char R_Data;
EA=0;
if(RI)
{
RI=0;
DATA_U[Wptr]=SBUF;
Wptr++;
if(Wptr>=64) Wptr=0;
}
if(TI)
{
TI=0;
if((Uptr<Ulen) && (flag==0x01))
{
SBUF=DATA_W[Uptr];
Uptr++;
}
else
{
flag=0;
}
}
EA=1;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -