“基于Andriod的数据采集系统”程序设计说明
1 工程文件下载:
2 程序设计流程图

3 数码管显示部分程序设计
Ø 设计思路:利用定时器0进行数码管动态扫描显示,在对应的中断函数中调用函数Timer0_Handler(),该函数专门用于数码管的显示。
关键代码
voidInit();//初始化推挽和设置中断,函数实现略
voidTimer0Init(void);//初始化推挽和设置中断,函数实现略
voidTimer0_Handler() //用于数码管显示,在定时器0的中断函数中调用
{
//数码管位选信号
pos ++;
if(pos == 8)
{
pos = 0;
}
P0 = 0;
P2 = pos;
switch(pos)
{
//只要修改Value_Temp或Value_Light的值,数码管显示即发生相应的改变
case 0: P0 =segtable[Value_Temp%1000/100]; break;
case 1: P0 =segtable[Value_Temp%100/10]; break;
case 2: P0 = segtable[Value_Temp%10];break;
case 5: P0 =segtable[Value_Light%1000/100]; break;
case 6: P0 =segtable[Value_Light%100/10]; break;
case 7: P0 =segtable[Value_Light%10]; break;
default: P0 = 0; }
}
4 A/D测量部分程序设计
Ø 设计思路:由于只有一个ADC,所以需交替地来测量光照和温度的值。
为了获取更为准确和稳定的数值,程序不是以一次的AD测量数值作为光照/温度新的测量数据,而是进行2000次AD测量并同时累计测量结果,然后再将2000次测量数据的均值来作为新的测量数据,更新显示
关键代码
voidADCInit() //初始化ADC并开启AD测量
{
P1ASF&= 0x00; //将P1口作为模拟功能A/D使用
ADC_RES= 0; //寄存器ADC_RES和ADC_RESL保存A/D转化结果
ADC_RESL = 0; //初始赋值0
CLK_DIV |= 0x20; //ADRJ=1:ADC_RES[1:0]存放高2位ADC结果,DC_RESL[7:0]存放低8位ADC结果
if(flag== 0)
{
P1ASF|= 0x10;
ADC_CONTR= 0x8c; //CHS=100选择P1^4作为A/D输入使用,测光照
}
else
{
P1ASF|= 0x08;
ADC_CONTR= 0x8b; //ADC_POWER=1打开A/D转换器电源;ADC_START=1启动模拟转换器ADC;CHS=011选择P1^3作为A/D输入使用,测温度
}
}
voidADC_Handler() //ADC中断处理函数
{
unsigned intadc_value;
adc_value =ADC_RES*256+ADC_RESL; //获取转化后的值
if(flag == 0) //判断是光照或是温度的测量结果
{
Sum_Light +=adc_value;
Count_Light++;
}
else
{
Sum_Temp +=(adc_value>>2);
Count_Temp++;
}
//累计测量次数达到2000则计算一次均值,并重新计数
if(Count_Light> 2000)
{
Value_Light= (Sum_Light+Count_Light/2)/Count_Light;
Count_Light= 0;
Sum_Light =0;
Flag_Send=1;
}
if(Count_Temp> 2000)
{
Value_Temp =tempdata[(Sum_Temp+Count_Temp/2)/Count_Temp];
Count_Temp =0;
Sum_Temp =0;
Flag_Send=1;
}
}
voidADC_isr() interrupt 5 //ADC的中断函数
{
ADC_Handler(); //处理检测到的数据
ADC_CONTR &= ~0X10; //转换完成后,ADC_FLAG清零
//flag反转,实现光照和温度的交替测量
flag = ~flag;
//重新开始ADC测量
ADCInit();
}
5 串口通信部分程序设计
Ø 设计思路:每更新一次光照或温度的测量数据,即通过串口将当前数据发送出去,同时更新数码管的显示;使用定时器2作为波特率发生器,波特率与蓝牙模块一致,设置为9600
Ø 关键代码
void Uart2Init(void) //波特率为9600bps@11.0592MHz
{
S2CON = 0x50; //8位数据,可变波特率
AUXR |= 0x04; //定时器2时钟为Fosc,即1T
T2L = 0xE0; //设定定时初值
T2H = 0xFE; //设定定时初值
AUXR |= 0x10; //启动定时器2
}
void Uart2_SendData() //发送温度光照的数据,数据包传输所采用的格式/协议可自己拟定
{
//发送包头1
S2BUF = 0xAA;
while(!((S2CON&0x02)==0x02));
S2CON &= ~0x02;
//发送包头2
S2BUF = 0x55;
while(!((S2CON&0x02)==0x02));
S2CON &= ~0x02;
//发送亮度高8位
S2BUF = (Value_Light >> 8)& 0xff;
while(!((S2CON&0x02)==0x02));
S2CON &= ~0x02;
//发送亮度低8位
S2BUF = Value_Light & 0xff;
while(!((S2CON&0x02)==0x02));
S2CON &= ~0x02;
//发送温度高8位
S2BUF = (Value_Temp >> 8)& 0xff;
while(!((S2CON&0x02)==0x02));
S2CON &= ~0x02;
//发送温度低8位
S2BUF = Value_Temp & 0xff;
while(!((S2CON&0x02)==0x02));
S2CON &= ~0x02;
}
6 主函数
最后再简单了解下主函数
void main()
{
//调用初始化函数,对各个模块进行初始化
Timer0Init();
ADCInit(); //初始化ADC后即开启AD测量
Uart2Init();
Init();
while(1)
{
//不断检测测量值是否更新,如有新的测量值,则向上位机发送
if(Flag_Send == 1)
{
Flag_Send = 0;
Uart2_SendData(); //更新上位机数值
}
}
}

