没有人回答,我自己改进了一下,效果不很理想。有时1602液晶显示跑掉,通道号不变,继电器反应快了
这是STC12C5A60S2单片机的
#include"STC12C5A60S2.h" //头文件在STC公司主页上下载
#include"intrins.h"
unsigned char code LedChar[]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f };
unsigned char LedBuff[ ]={ 0x3f, 0x3f, 0x3f, 0x3f , 0x3f };
unsigned int g, a = 0, n=0 ;
unsigned char d , m=0;
float AD_val = 0;
//------------------------------------------------------------------------------
void AD_init();
void serial_init();
void delay(unsigned int b);
float AD_work(unsigned char channel);
unsigned int AD_get(unsigned char channel);
void display(unsigned int g );
//------------------------------------------------------------------------------
void main()
{
unsigned char j, e=0 ;
float b;
unsigned int Led[]={ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
TMOD = 0x01;
TH0 = 0xFC;
TL0 = 0x67;
TR0 = 1;
EA = 1;
ET0 = 1;
AD_init(); //A/D转换初始化
serial_init(); //串口初始化
while(1)
{
for(d =0;d <8;d++) //循环发送P1.0-P1.7的转换数值
{ b=AD_work(d );
a=(unsigned int)b ;
Led[d] = a;
if(j==0) { SBUF = d; while(!TI); TI=0; j++;}
if(j==1) { SBUF = a; while(!TI); TI=0; j++;}
if(j==2) { e = a>>8; SBUF = e; while(!TI); TI=0; j=0; n++;}
if(n>=640) { n=0; m=0; }
switch(m=n/80)
{
case 0:
g= Led[0] ;
display( g ) ;
break;
case 1:
g= Led[1] ;
display( g ) ;
break;
case 2:
g= Led[2] ;
display( g ) ;
break;
case 3:
g= Led[3] ;
display( g ) ;
break;
case 4:
g= Led[4] ;
display( g ) ;
break;
case 5:
g= Led[5] ;
display( g ) ;
break;
case 6:
g= Led[6] ;
display( g );
break;
case 7:
g= Led[7] ;
display( g ) ;
break;
}
}
}
}
void display(unsigned int g )
{
LedBuff[0] = LedChar[g%10];
LedBuff[1] = LedChar[g/10%10];
LedBuff[2] = LedChar[g/100%10];
LedBuff[3] = LedChar[g/1000%10];
LedBuff[4] = LedChar[m];
}
//------------------------------------------------------------------------------
unsigned int AD_get(unsigned char channel)
{
ADC_CONTR=0x88|channel; //开启AD转换1000 1000 即POWER SPEED1 SPEED0 ADC_FLAG ADC_START CHS2 CHS1 CHS0
_nop_(); _nop_(); _nop_(); _nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR 寄存器
while(!(ADC_CONTR&0x10)); //等待转换完成
ADC_CONTR&=0xe7; //关闭AD转换,ADC_FLAG位由软件清0
return(ADC_RES*4+ADC_RESL); //返回AD转换完成的10位数据(16进制)
}
//------------------------------------------------------------------------------
float AD_work(unsigned char channel)
{
float AD_val; //定义处理后的数值AD_val为浮点数
unsigned char i;
for(i=0;i<50;i++)
AD_val+=AD_get(channel); //转换100次求平均值(提高精度)
AD_val/=50;
//AD_val=(AD_val*5)/1024; //AD的参考电压是单片机上的5v,所以乘5即为实际电压值
return AD_val;
}
//------------------------------------------------------------------------------
void delay(unsigned int b) //延时约1ms
{
unsigned int i;
while (--b!=0)
for(i=600;i>0;i--); //1T单片机i=600,若是12T单片机i=125
}
//------------------------------------------------------------------------------
void AD_init()
{
P1ASF=0xff; //P1口全部作为模拟功能AD使用
ADC_RES=0; //清零转换结果寄存器高8位
ADC_RESL=0; //清零转换结果寄存器低2位
ADC_CONTR=0x80;//开启AD电源
delay(2); //等待1ms,让AD电源稳定
}
unsigned char j = 0 ;
void InterruptTimer0() interrupt 1
{
TH0 = 0xFC;
TL0 = 0x67;
P0 = 0xFF;
if(j == 0)
{P2=7; j++; P0=LedBuff[0];}
else if(j == 1)
{P2=6; j++; P0=LedBuff[1];}
else if(j == 2)
{P2=5; j++; P0=LedBuff[2];}
else if(j == 3)
{P2=4; j++; P0=LedBuff[3];}
else if(j == 4)
{P2=0; j=0; P0=LedBuff[4];}
}
void serial_init()
{
TMOD=0x20;
TH1=0xfd;
TL1=0xfd; //设置9600波特率
SCON=0x50; //串口方式1,允许接收
TR1=1;
}
void InterruptUART() interrupt 4 {}
|