标题:
STC12C5A60S2片内ad程序数码管显示
[打印本页]
作者:
腾飞的龙
时间:
2015-7-28 20:11
标题:
STC12C5A60S2片内ad程序数码管显示
/*(1)
P1_ADC_EN:特殊功能寄存器
P1.x作为A/D转换输入通道来用允许特殊功能寄存器。
相应位为“1”时,对应的P1.x口作为A/D转换使用
,内部上拉电阻自动断开。
(2)ADC_CONTR:特殊功能寄存器
CHS2/CHS1/CHS0是模拟输入通道选择,
CHS2/CHS1/CHS0的取值如下表所示
CHS2 CHS1 CHS0 模拟输入通道选择
0 0 0 选择P1.0为A/D输入
0 0 1 选择P1.1为A/D输入
0 1 0 选择P1.2为A/D输入
0 1 1 选择P1.3为A/D输入
1 0 0 选择P1.4为A/D输入
1 0 1 选择P1.5为A/D输入
1 1 0 选择P1.6为A/D输入
1 1 1 选择P1.7为A/D输入
ADC_START是模拟/数字转换(ADC)启动控制位,设置为1时,开始转换。
ADC_FLAG是模拟/数字转换结束标志位,当A/D转换完成后,ADC_FLAG=1。
(3)ADC_DATA:A/D转换结果特殊功能寄存器
模拟/数字转换结果计算公式为 结果=256×Vin/Vcc
Vin是模拟输入通道输入电压,Vcc为单片机实际工作电压,
用单片机工作电压作为模拟参考电压 */
//2、STC12C5A60S2内ADC采样电压值,
//先采样30次然后去掉上下10个再取平均值
//STC12C5A60S2内ADC采样
#include <reg51.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
#define segp P0 //数据端口
#define scanp P2 //位端口
sbit wei=P0^6;
sbit duan=P0^7;
sbit fmq =P1^7;
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82, 0xf8,0x80,
0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //不带点共阳段驱动信号
uchar code tab_d[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //带点共阳段驱动
uchar code scan[]={0xfe,0xfd,0xfb,0xf7};
//位扫描驱动信号
uint display[4]={0,0,0,0}; //初始显示数字
uint con=0, _data=0,data2=0; //con显示循环变量_data为ADC采样值临时变量data2显示数据临时变量
//下面五行为ADC定义
sfr P1ASF=0x9d;
sfr ADC_CONTR=0xbc;
sfr ADC_RES=0xbd;
sfr ADC_RESL=0xbe;
sfr AUXR1=0xa2;
/*sfr P1_ADC_EN=0x97;
sfr ADC_CONTR=0xc5;
sfr ADC_DATA=0xc6;*/
void t0_t1_init();//t0显示扫描定时器和t1串口比特率定时器初始化函数
void adc_init(); //adc初始化函数
void uart_out(uchar byte); //串口发送字节函数
uint average(uint buffer[30]); //采样数据处理函数
void AD(); //电压采样30次函数
void delay1ms(uchar x); //延时函数
void beep()
{
fmq=0;
delay1ms(100);
fmq=1;
delay1ms(100);
}
void main()
{
t0_t1_init();
adc_init();
while(1)
{
AD();
if(data2>4700|data2<4000)
beep(); //报警
}
}
/////////定时器初始化///////
void t0_t1_init()
{
SCON=0x50;
PCON=0;
TMOD=0x21;
TH1=TL1=0xe6;
TH0=0xf0;
TL0=0x60;
EA=ET0=1;
// ES=1;
TR1=1;
TR0=1;
}
////ADC初始化///////
void adc_init()
{
P1ASF=0x01;//启动P10为ADC模拟输入口把内部上拉电阻断开
P1ASF=0x02; //启动P11为ADC模拟输入口把内部上拉电阻断开
AUXR1&=0xfb; //adrj_0 高8位在ADC_RES
ADC_RES=0; //初值
//开启ADC电源 并设置转换周期为540个时钟周期转换一次。
//SPEED_1_1,chs000(选择AD采样通道p10)
//ADC_POWER=1; CHS2,1,0为0,用p1.0作为输入。SPEED1,0
ADC_CONTR=0x80;//用p1.0作为输入
ADC_CONTR=0x81;//用p1.1作为输入
delay1ms(2);
// IE|=0xa0;
}
//////采集30次电压值//////
void AD()
{
char i; uint temp_buf[30]={0};
for(i=0;i<30;i++)
{
ADC_CONTR |=0x08; //开启转换
while((ADC_CONTR&0x10)==0);
ADC_CONTR &=0xe7; //清除标志
temp_buf[i]=ADC_RES; //取出数值到temp_buf
}
_data=average(temp_buf); //采样30次后的数据代入处理函数处理后返回处理后的数值,给下面用串口发送出去
uart_out(_data);
}
////先对整个数组的三十个值进行从小到大的排列,
////// ///再去掉最大5个和最少5个再求平均值;函数返回temp值///
uint average(uint buffer[30])
{
uchar i,j;
uint temp;
for(i=1; i<30; i++)
for(j=29; j>=i; --j)
{
if(buffer[j-1] > buffer[j])
{
temp = buffer[j-1];
buffer[j-1] = buffer[j];
buffer[j] = temp;
}
}
temp = 0;
for(i=5; i<25; i++)
{
temp += buffer[i];
}
temp = (uint)(((float)temp) / 20 + 0.5);
return(temp);
}
///显示数据处理及扫描显示中断服务函数////
void t0_4ms(void) interrupt 1
{
data2=_data;
data2=_data*19.53;
display[0]=tab_d[data2/1000]; //用带小数点的段码
display[1]=tab[(data2/100)%10]; //用不带小数点的段码
display[2]=tab[(data2/10)%10];
display[3]=tab[data2%10];
TH0=0xf0;
TL0=0x60;
if(++con==5) con=1;
// segp=0xff;
wei=1;
P2=scan[con-1];
wei=0;
duan=1;
P2=display[con-1];
duan=0;
delay1ms(10) ;
P2=0xff;
// segp=display[con-1];
// scanp=scan[con-1];
}
//串口发送节字函数////
void uart_out(uchar byte)
{
SBUF=byte;
while(TI==0);
TI=0;
}
///1ms延时////
void delay1ms(uchar x)
{
uchar i,j;
for(i=0;i<x;i++)
for(j=0;j<250;j++);
}
复制代码
作者:
h1314258
时间:
2015-8-6 16:30
188.///1ms延时////
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1