当前位置:文档之家› 2013年电子设计大赛G题总方案及原理图程序

2013年电子设计大赛G题总方案及原理图程序

2013年全国大学生电子设计竞赛手写绘图板(G题)【本科组】Dut physics1202class2013年9月7日摘要本作品以STC12C5A单片机为核心,对铜板这种小电阻在微弱变化下的精密测量,以实现对触点的精确定位。

用恒流源给覆铜板加稳恒电流,利用电桥和OP07对产生的电压信号进行采集和放大。

用单片机控制MOS开关控制覆铜板四角接线的开闭。

制作一个10cm*15cm的手写绘图板,并对板上任意位置进行坐标读取,分辨率小于10mm,并在12864的LCD显示器上进行显示。

关键字:STC12C5A,精密测量,LCD目录1系统方案 (1)1.1 铜板处理的论证与选择 (1)1.2 信号采集和放大的论证与选择 (1)1.3 开关控制模块的论证与选择 (1)1.4 电源模块的论证与选择 (2)1.5 控制系统的论证与选择 (2)2系统理论分析与计算 (2)2.1 左右方向及象限位置的确定 (2)2.2 坐标点测量的方法 (2)2.3 各点坐标采集的方法...................................................................... 错误!未定义书签。

3电路与程序设计. (3)3.1电路的设计 (3)3.1.1系统总体框图 (3)3.1.2 信号采集与放大子系统框图与电路原理图 (3)3.1.3 单片机控制子系统框图与电路原理图 (3)3.1.4电源 (4)3.2程序的设计 (4)3.2.1程序功能描述与设计思路 (4)3.2.2程序流程图 (4)4测试方案与测试结果 (6)4.1测试方案 (6)4.2 测试条件与仪器 (6)4.3 测试结果及分析 (6)4.3.1测试结果(数据) (6)4.3.2测试分析与结论 (7)附录1:电路原理图 (8)附录2:源程序 (9)手写绘图板(G题)【本科组】1系统方案本系统主要由铜板模块、信号采集和放大模块、开关控制模块、电源模块,控制模块组成,下面分别论证这几个模块的选择。

1.1 铜板处理的论证与选择由于测得的铜板电阻太小,现考虑以下方案。

方案一:采用在板上腐蚀网格或者有规律的数学图案,这种方法有利于增大铜板的测量电阻,利于在测量过程中电压的获取和计算,但是这种方案会使板面不够平稳,如果间隙不够小,就会导致分辨率太低,误差较大。

方案二:在铜板背后加电阻,可以增大电阻,但是由于电阻本身大小和要求数量,没发满足误差的要求。

方案三:利用RC振荡电路,用公式中的1/R对铜板电阻进行放大处理,测量。

但是测算麻烦,误差较大,且不是线性变化。

方案四:直接使用铜板使用恒流源和电桥法测量小电阻,对测量电压多级放大输出,实现电压测量。

综合以上三种方案以及题目中的要求,方案一不能使表笔在覆铜板上的任意位置接触,二三方案误差不好处理,故选择方案四。

1.2 信号采集和放大的论证与选择由于信号很小采集和放大都需要认真考虑,现考虑以下方案:方案一:用恒压源进行采集数据,并用2级运算放大器进行放大送入单片机。

这种方法由于铜板电阻太小,使用恒压源要么电流过大,要么误差很大没法精确测量。

方案二:用恒流源进行采集数据,一级使用电桥进行差分放大,将差值放大后输入第二级放大,这种方法既便于采集放大,也能提高精度。

综上我们选择第二种方案。

1.3 开关控制模块的论证与选择方案一:在铜板4个脚都采用4个采集放大电路,但是由于铜板电阻小,很容易由于导线长度的增大使铜板采集的信号误差变大。

方案二:只用一个采集放大电路,利用以IRF540n为核心的mos开关模块,让单片机通过此开关控制模块对测量线路的开闭进行控制。

方案二既简单也容易控制我们,所以我们选择方案二。

1.4 电源模块的论证与选择电源模块组要由恒流源,单电源变双电源电路组成。

恒流源是为铜板提供稳恒电流的,以测量电压信号。

单变双电源以TDA2030为核心的将赛组能提供的12v单电源变为±6v的双电源。

在最这个电源的同时,我们加进了为单片机提供5v电压的电源部分。

1.5 控制系统的论证与选择方案一:采用51系列的单片机作为主控器件,使用自己做的最小系统板,用来实现要达到的各种要求。

但88888888是AD转化需要另外做。

此方案规模小,成本低。

方案二:采用我们此前购买的以STC12系列的单片机带有10位的AD转换作为主控器件。

此方案方便快捷,只需对AD和单片机进行程序编写。

综合考虑,我们将方案一备用,采用方案二。

2系统理论分析与计算2.1 左右方向及象限位置的确定我们使用单片机控制开关实现对四角测量的通断,通过用第一角电压减去第二角电压是否大于0来确定上下方向,通过第二角和第三角的压差是否大于0来确定左右方向,然后实现象限位置的确定。

2.2 坐标点测量的方法我们在测试前将铜板用水将铜板上的氧化膜清除掉,但是由于铜板本身的各种原因,铜板上一点到四角的电阻是不均匀的,没办法实现根据各点电压计算距离,于是我们采用事先采集各点电压,在程序中使用查表的方法进行转换坐标,这样做尽管需要耗费单片机的内存,但是这种方法简单可行,精确度高,我们采用此方法。

2.3 各点坐标采集的方法在板子上画好坐标之后我们根据多次测试的结果以每0.5mm为单位进行多次采样并取平均值,然后建立各点的电压值表,电压值表见表一。

把这些数据写入单片机,当在表笔接触铜板时,根据输入的电压值查表找到对应的坐标然后送LCD显示。

3电路与程序设计3.1电路的设计3.1.1系统总体框图系统总体框图如图1所示,图1 系统总体框图3.1.2 信号采集与放大子系统框图与电路原理图图2 信号采集与放大子系统框图3.1.3 单片机控制子系统框图与电路原理图1、MOS 开关子系统框图图3 MOS 开关子系统框图2、单片机子系统电路图4 单片机子系统电路普通铜板Mos 开关放大采集 单 片 机显示器恒流源 单变双电源 5v 电源信号采集 铜板 电桥差分放大 二级放大 单片机4个MOS 输出端 恒流源单片机最小系统铜板四角低通滤波3.1.4电源电源由单电源变双电源、滤波部分、稳压部分组成。

为整个系统提供+5V,6V,+12V电压,确保电路的正常稳定工作。

单电源变双电源采用TDA2030实现12V 单电源变6V,由6V变5V采用LM2940稳压芯片为核心的电路实现。

3.2程序的设计3.2.1程序功能描述与设计思路1、程序功能描述程序部分由LCD12864的显示部分,开关的控制部分,AD转换,和电压数据的计算和处理。

2、程序设计思路LCD部分用P2口和P0的部分口实现对LCD的控制和写数据。

电压值处理部分事先将测得的数据写入程序,使用P1.0读取电压值在单片机内进行查表,计算处理后用LCD输出触点的左右侧,象限位置和坐标的信息。

开关部分将4个引脚置1,实现MOS管的通断。

按键部分使用中断,实现按键特定功能。

3.2.2程序流程图1、主程序流程图开始初始化液晶和AD转换轮流开启MOS开关采取数据启动10位AD转换对各角电压轮流采集并进行累加和取平均值对数据进行处理计算得出触点的左右,象限和坐标将上面的信息输入到LCD显示2、按键子程序流程图按键引发中断读取触点运动信息将触点运动曲线在LCD上显示出来RET3、MOS管开关和测量子程序流程图子程序入口先开启MOS1,使1角开始测量AD转换打开接受电压值进行AD转换在一段时间内对其连续测量,并取平均值再开启MOS2,使2角开始测量以下同上并循环省略4、数据处理和显示子程序流程图子程序入口得到4个角的压值,查表得出坐标值,比较1角和2角的压值,判断左右,比较1角和3角压值,判断上下根据得到的结果判断所在象限在LCD上显示得到的结果,坐标值,左右和象限位置RET4测试方案与测试结果4.1测试方案1、硬件测试对各个模块进行测试,测试通过后使用。

2、软件仿真测试对程序的错误和不能正确实现的部分进行调节和改正。

3、硬件软件联调对整体功能的实现进行进一步调节。

4.2 测试条件与仪器测试条件:检查多次,仿真电路和硬件电路必须与系统原理图完全相同,并且检查无误,硬件电路保证无虚焊。

测试仪器:高精度的数字毫伏表,模拟示波器,数字示波器,数字万用表,指针式万用表。

4.3 测试结果及分析4.3.1测试结果(数据)触点位置(cm)显示左右显示象限显示坐标(cm)(0,1)右一(0.5,1.5)(2,8)右一(1.5,8.5)触点位置(cm)显示左右显示象限显示坐标(cm)(—2,8)左二(—2.5,7.5)(2,—8)右四(3,—8.5)(6,6)右一(6.5,6.5)(6,—8)右四(6.5,—7.5)(—5,—5)左三(—4.5,—4.5)4.3.2测试分析与结论根据上述测试数据可以得出以下结论:1、表笔接触时有明显变化2、能正确显示左右和象限3、坐标误差基本能控制在5mm左右综上所述,本设计达到设计要求。

附录1:电路原理图恒流源电路图:单电源转双电源电路:采集放大电路:附录二:源程序第一部分main.c:void main(){ADC_int(0);set_timer_1();lcdinitc();while(1){dier_ping();}}第二部分delay.c#include”delay.h”void delayb(int z){int x,y;for(x=z;x>0;x--)for(y=120;y>0;y--);}第三部分12864.c#include"12864c.h"#include <STC12C5A.H>/*****************并行基本函数*******************/ /********************************************* LCD12864液晶测忙子程序(读状态)*********************************************/ uchar readstatus(){lcdrs=0;lcdrw=1;lcden=1;while ((P2&0x80)==0x80); //读忙return(P2);}/********************************************* LCD12864液晶命令写入子程序*********************************************/ void write_com(uchar com){readstatus();lcdrs=0;lcdrw=0;P2=com;delayb(10);lcden=1;delayb(10);lcden=0;}/********************************************* LCD12864液晶数据写入子程序*********************************************/ void write_date(uchar date){readstatus();lcdrs=1;lcdrw=0;P2=date;delayb(5);lcden=1;delayb(5);lcden=0;}/*uchar readdate(void){ uchar date;lcdrs=1;lcdrw=1;lcden=1;delayb(10);date=P2;delayb(10);return date;} *//*********************************************LCD12864液晶初始化子程序*********************************************/void lcdinitc(void){lcdpsb=1;//选择并口方式write_com(0x30);//选择八位数据delayb(10); //写的不要太频繁,适当加延时,省去了读忙write_com(0x0c);//显示开关光标delayb(10);write_com(0x01); //清屏delayb(10);}/*******************写位置*************************/ void write_posi(uchar x,uchar y)//设置坐标{uchar a=x;uchar b=y;switch(a){case 1 : write_com(0x80+b); break;case 2 : write_com(0x90+b); break;case 3 : write_com(0x88+b); break;case 4 : write_com(0x98+b); break;default: break;}//}/*********************************************LCD12864液晶数据显示子程序*********************************************/void Disp(uchar y,uchar x,uchar i,uchar *z){uchar Address;if(y==1){Address=0x80+x;} //Y判断第几行,X判断第几列,0x80为液晶行初始地址if(y==2){Address=0x90+x;}if(y==3){Address=0x88+x;}if(y==4){Address=0x98+x;}write_com(Address); //写入地址命令到LCD12864while(i) //写入显示数据的大小{write_date(*(z++)); //写入显示数据到LCD12864i--;}}第四部分addata.c#include "addata.h"#include "math.h"sfr AURX1=0xa2; //AD 转换结果存储方式控制位unsigned char Result[4];void ADC_int(uchar n)//第n 通道ADC 初始化函数{n&=0x07; //确保n=0----7通道AURX1|=0x04; //转换结果存储格式:数据的高2位放ADC_RES,低8位放ADC_RESLP1ASF=1<<n;//将P1.n 设为ADC 采样}uint ADC_GET(unsigned char n)//第n 通道ADC 采样函数{unsigned int adc_data;n&=0x07;//确保n=0----7通道ADC_RES=0;//清零ADC_RESL=0;//清零ADC_CONTR=0;//清零,以便重构ADC_CONTR|=(ADC_POWER|ADC_SPEED|n|ADC_START) ; //打开AD 转换电源、设定转换速度、设定通道号、AD 转换开始_nop_();_nop_();_nop_();_nop_();_nop_();//延时4个时钟周期左右while(!(ADC_CONTR&ADC_FLAG));//等待转换结束=0x10ADC_FLAG 位=1adc_data=(ADC_RES&0x03)*256+ADC_RESL;//转换结果计算,取高位结果存储器的低2位+ 低位结果存储器ADC_CONTR&=~ADC_FLAG;//清零转换结束标志位(ADC_FLAG 位=0)return adc_data;//返回ADC 的值(0----1023?}void Int_char(int data1){if(data1/1000){ Result[0]=data1/1000+'0';Result[1]=data1/100%10+'0';Result[2]=data1/10%10+'0';Result[3]=data1%10+'0';}else if(data1/100){ Result[0]=data1/100+'0';Result[1]=data1/10%10+'0';Result[2]=data1%10+'0';Result[3]='0'; }else if(data1/10){Result[0]=data1/10%10+'0';Result[1]=data1%10+'0';Result[2]='0';}else {Result[0]=data1%10+'0';Result[1]='0';}}void data_out(int x){ int _le1,_le2,_le3,_le4,i;int sum=0;switch(x){case 1: for(i=0;i<100;i++)sum+=ADC_GET(0);_le1=sum/100;sum=0;write_posi(1,0);if(_le4-_le1<0)write_date('-');elsewrite_date('+');Int_char(abs(_le4-_le1));di1=0;di2=1;di3=1;di4=1;write_posi(1,1);write_date(Result[0]);delayb(50);write_posi(1,2);write_date(Result[1]);delayb(50);write_posi(1,3);write_date(Result[2]);delayb(50);write_posi(1,4);write_date(Result[3]);delayb(500);break; case 2:di1=1;di2=0;di3=1;di4=1;for(i=0;i<100;i++)sum+=ADC_GET(0);_le2=sum/100;write_posi(2,0);if(_le2-_le1<0)write_date('-');elsewrite_date('+');Int_char(abs(_le1-_le2));sum=0;write_posi(2,1);write_date(Result[0]);delayb(50);write_posi(2,2);write_date(Result[1]);delayb(50);write_posi(2,3);write_date(Result[2]);delayb(50);write_posi(2,4);write_date(Result[3]);delayb(500);break; case 3:di1=1;di2=1;di3=0;di4=1;for(i=0;i<100;i++)sum+=ADC_GET(0);_le3=sum/100;write_posi(3,0);if(_le3-_le1<0)write_date('-');elsewrite_date('+');Int_char(abs(_le2-_le3));sum=0;write_posi(3,1);write_date(Result[0]);delayb(50);write_posi(3,2);write_date(Result[1]);delayb(50);write_posi(3,3);write_date(Result[2]);delayb(50);write_posi(3,4);write_date(Result[3]);delayb(500);break;case 4:di1=1;di2=1;di3=1;di4=0;for(i=0;i<100;i++)sum+=ADC_GET(0);_le4=sum/100;write_posi(4,0);if(_le3-_le4<0)write_date('-');elsewrite_date('+');Int_char(abs(_le4-_le1));sum=0;write_posi(4,1);write_date(Result[0]);delayb(50);write_posi(4,2);write_date(Result[1]);delayb(50);write_posi(4,3);write_date(Result[2]);delayb(50);write_posi(4,4);write_date(Result[3]);delayb(500);// write_date("左");break;}}第五部分interrupt.c#include "main.h"#include<STC12C5A.h>#include "delay.h"sbit led1 = P1^3;sbit led2 = P1^2;void diyi_ping(void);void dier_ping(void);void disan_ping(void);void set_timer_1(){ EA=1;EX0=1;TCON=0x00;}void int0() interrupt 0 using 0 //根据上表,3号中断类型号为TIMER1的,定时器1呀。

相关主题