程序设计目标及程序运行效果说明
程序设计目标:学会利用AD采集光敏电阻的值,实现类似按键计数的功能。
程序运行效果说明:当手指触摸到光敏电阻时,通过光照强度变化来控制数据的加然后在数码管上进行显示。
程序相关电路及工作原理说明
1.LED数码管电路
2.光敏电阻电路
3.工作原理
通过AD采集光敏电阻的值,检测AD求其平均值,这样可以达到稳定性。这个实验的关键就是确定合适的光照阀值,经过多次尝试摸索后将(light_old/light_new)>1.30,作为光照的阀值,此时默认为手指按下状态,计数器detelight+1。
测试方法
(1)用STC ISP默认设置,打开工程中的HEX并下载
(2)下载后观察现象为:通过用遮光板或者手指改变光敏电阻的光照强度,观察数码管计数的改变。
代码如下:
#include "STC15F2K60S2.H"
sbit SEL0=P2^0;
sbit SEL1=P2^1;
sbit SEL2=P2^2;
sbit SEL3=P2^3;
#define uint unsigned int
#define ulint unsigned long
//设置光照变量
uint l=0; //执行光的次数
ulint suml=0; //光AD值得总和
uint datelight=0; //计数变量
uint light_old=1; //上一次光强
uint light_new=1; //当前光强
//用于设置计数的显示的变量
uint light_bai=0; //百位
uint light_shi=0; //十位
uint light_ge=0; //个位
uint time=0; //延时
char segtable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void Delay(int n);
void SEG_Display();
void InitADC_light();
void date_processlight();
//初始化光ADC
void InitADC_light()
{
P1ASF=0xff;
ADC_RES=0;
ADC_RESL=0;
ADC_CONTR=0X8C;
CLK_DIV=0X20;
}
//对应光部分的处理数据
void date_processlight()
{
light_bai=datelight%1000/100;
light_shi=datelight%100/10;
light_ge=datelight%10;
}
//AD中断
void adc_isr()interrupt 5 using 1
{
time++;
IE=0x00; //关闭中断
if(time>2500)
{
light_new=(suml+l/2)/l; //四舍五入
suml=0;
l=0;
time=0;
if((light_old/light_new)>1.30)
datelight=datelight+1;
date_processlight();
time=0;
light_old=light_new;
}
//处理光部分的数据
l++;
suml+=ADC_RES*256+ADC_RESL; //求l次AD值的和
ADC_CONTR&=~0X10; //转换完成后,ADC_FLAG清零
ADC_CONTR|=0X08; //转换完成后,ADC_START赋1
IE=0xa0; //打开中断
}
//用于数码管显示
void weixuan(char i)
{
SEL2=i/4;
SEL1=i%4/2;
SEL0=i%2;
}
void SEG_Display()
{
P0=0;
weixuan(5);
P0=segtable[light_bai];
Delay(10);
P0=0;
weixuan(6);
P0=segtable[light_shi];
Delay(10);
P0=0;
weixuan(7);
P0=segtable[light_ge];
Delay(10);
}
//延时函数
void Delay(int n)
{
int x;
while(n--)
{
x=60;
while(x--);
}
}
void main()
{
P0M1=0x00; //设置P0为推挽模式,点亮数码管
P0M0=0xff;
P2M1=0x00;
P2M0=0x08; //将P2^3设置为推挽模式,其余为准双向口模式
SEL3=0; //熄灭LED灯
IE=0xa0; //EA=1打开总中断,EADC=1允许A/D转化中断,ET1=1允许T1中断
InitADC_light();
while(1)
SEG_Display();
}