第一组:实训指导老师:日期:目录绪论 (3)1.1概述 (3)1.2设计要求及主要功能介绍 (3)第二章系统总体方案设计 (4)2.1系统功能模块的划分 (4)2.2系统原理框图 (4)2.3系统仿真原理图 (5)2.4PCB原理图 (5)2.5PCB板 (6)2.6系统硬件设计 (6)2.7系统软件设计 (7)2.8硬件设计与调试 (13)2.9成果展示 (13)小组总结 (14)3.1小组成员有话说: (14)3.2小组总结 (15)3.3小组评分 (15)参考文献 (16)绪论1.1 概述单片机以其强大的控制能力已经被广泛应用于诸多领域,配以各种接口传感器可以实现系统的智能化。
无论是在工业控制领域、医疗卫生领域、还是在国防军事领域、航天航空领域,微控制器都起着举足轻重的作用。
从最初的8位控制器到现在的16位、32位控制器都还有很大的发展和应用空间。
本次实训以贴近实际为主,我们组就设计一个带有测温功能的电子万年历,再设计的过程中将所学的知识运用到实际中来,已达到培养我们运用知识解决实际问题的能力。
1.2 设计要求及主要功能介绍(1)显示实时时间。
由实时时钟芯片DS1302提供实时时间的数据。
(2)显示实时温度。
由温度测量芯片DS18B20提供实时温度的数据。
(3)参数修改。
由四个按钮来修改参数:加减按钮﹑定位按钮﹑确定按钮。
(4)通讯。
通过RX232串口与上位机的通讯,将数据上传给上位机。
第二章系统总体方案设计2.1 系统功能模块的划分按照设计要求,系统可以分为以下几个基本功能模块:显示模块参数修改模块﹑通讯模块等。
有些模块的功能是由硬件完成,有些模块的功能由软、硬件配合完成,有些模块则是由软件、硬件、机械三部分共同完成。
将系统拆分成以上的这些基本功能模块后,再根据各个模块所要完成的功能分别去设计,也就是按照“逐步求精”的思想去设计本系统,这将使设计工作细化,也有助于制定进度安排。
2.2 系统原理框图2.3 系统仿真原理图2.4 PCB原理图2.5 PCB板2.6系统硬件设计1)该项目的CPU使用AVR系列中的ATMEG16。
该芯片能存储16K的指令程序且程序不丢。
(并且我们有现成的针对AVR系列单片机的仿真软件和程序编写环境)2) 实时时间模块用美国DALLAS公司推出实时时间芯片DS1302,实时时钟电路DS1302是DALLAS公司的一种具有涓细电流充电能力的电路,主要特点是采用串行数据传输,可为掉电保护电源提供可编程的充电功能,并且可以关闭充电功能。
DS1302可以对年、月、日、周日、时、分、秒进行计时,且具有闰年补偿等多种功能。
3)实时温度模块用智能温度芯片DS18B20。
单线数字温度传感器DS18B20 就是一个1-wire 器件,该器件可把温度直接转换成串行数字信号供微机处理。
由于每片DS18B20 含有唯一的硅串行数,所以在一条总线上可挂接任意多个DS18B20 芯片。
从DS18B20 读出的信息或写入DS18B20 的信息,仅需要一根端口线,该端口线同时也可以向DS18B20 供电,从而无需额外电源。
DS18B20 提供9~12 位温度读数,构成多点温度检测系统而无需任何外围硬件。
4)参数修改模块采。
在该模块中采用四个功能各不相同的按键(加减参数按钮﹑定位修改按钮﹑确定修改按钮)。
2.7 系统软件设计该项目相对来说简单,软件也不复杂,我将软件分为如下模块:1)显示模块:void CanShuXianShi(int canshu, char dian){char i;lcd[0]=32; //编号的十位转变为ASCII码lcd[1]=32; //编号的个位转变为ASCII码lcd[2]=32; //空格canshu=canshu*6.25;if(canshu>=0) lcd[3]=32; //符号处理else{canshu=-canshu;lcd[3]=0x2d; //负号}lcd[4]=(uchar)(canshu/10000)+0x30; //参数的万位转变为ASCII码lcd[5]=(uchar)(canshu/1000%10)+0x30; //参数的千位转变为ASCII码lcd[6]=(uchar)(canshu/100%10)+0x30; //参数的百位转变为ASCII码lcd[7]=(uchar)(canshu/10%10)+0x30; //参数的十位转变为ASCII码lcd[8]=(uchar)(canshu%10)+0x30; //参数的个位转变为ASCII码//插入小数点for(i=9;i>9-dian;i--)lcd[i]=lcd[i-1];lcd[9-dian]=0x2e;for(i=4;i<8-dian;i++) //消除参数前面的0if(lcd[i]==48)lcd[i]=32;else break;}该函数将温度的值进行剥离,然后再将剥离的每位数填充在数组lcd[9]中,然后在主函数中一位一位的送显示。
2)参数修改模块if(PINB.0==0&&x==1){N++;delay_ms(10);}x=PINB.0;if(PINB.1==0&&y==1){ N--;delay_ms(10);}y=PINB.1;if(PINB.2==0&&y==1){ M++;delay_ms(10);if(M>5) M=0;}s=PINB.2;if(M==0) sss=N;if(M==1) mmm=N;if(M==2) hhh=N;if(M==3) yy=N;if(M==4) mm=N;if(M==5) dd=N;zhuanhuan(N);for(i=0;i<=1;i++)putchar(i,7,d[i]);putchar(3,7,M+0x30);if(PINB.3==0&&z==1){rtc_set_time(hhh,mmm,sss);rtc_set_date(dd,mm,yy);}z=PINB.3;该函数利用四个按键,加减按键用来增减需要修改的参数,定位按键用来定位需要修改参数的位置。
3)实时时间模块和温度测量模块利用库函数故不再累述。
4)12864显示器的模块函数.autowr){DATA_OUT=0xFF;//使用上拉电阻DATA_DIR=0x00;//设置端口输入CD=1;WR=1;RD=0;CE=0;if(autowr){while(DATA_IN&0x08==0x00);}else{while( (DATA_IN&0x01==0x00)|(DATA_IN&0x02==0x00) );}RD=1;DATA_DIR=0xFF;//设置端口输出}//----------------------------------//功能:向端口写命令//comm:待写命令//----------------------------------void wr_comm(uchar comm){chk_busy(0);//检测端口是否忙CD=1;//命令RD=1;CE=0;WR=0;DATA_OUT=comm;WR=1;}//----------------------------------//功能:向端口写命令//dat写命令//----------------------------------void wr_data(uchar dat){chk_busy(0);//检测端口是否忙CD=0;//数据RD=1;CE=0;WR=0;DATA_OUT=dat;WR=1;}//----------------------------------//功能:自动写数据//----------------------------------//功能:写一个数据和命令//dat:待写数据//comm:待写命令//----------------------------------void wr_od(uchar dat, uchar comm){wr_data(dat);wr_comm(comm);}//----------------------------------//功能:写两个数据和一个命令//datl,dath:待写数据//comm:待写命令//----------------------------------void wr_td(uchar datl, uchar dath, uchar comm) {wr_data(datl);wr_data(dath);wr_comm(comm);}//----------------------------------//功能:写一个16进制数据和一个命令//dat:待写数据//comm:待写命令//----------------------------------void wr_xd(uint dat,uchar comm){uchar datl,dath;datl=dat;dath=dat>>8;wr_td(datl, dath, comm);}void putchar(int x,int y,unsigned char zifu){wr_xd(STARTADD_T+16*y+x,0x24);wr_xd(0,0x20);wr_od(zifu-0x20,0xc0);}//----------------------------------//功能:点(x,y)位置的象素点//形参:x:水平位置坐标(0~127)// y:垂直位置坐标(0~63)// set:1-点黑, 0-点白//----------------------------------void PutPixel(int x, int y, int set){if(x<0 || x>=MAX_X || y<0 || y>=MAX_Y)return;else{uint addr=STARTADD_G;addr+=y*BYTES_PER_LINE;addr+=x/8;//计算x点左边有多少个完整的字节,并将作图地址定位到此处wr_xd(addr, 0x24);//地址指针定位if(set)//如果是点黑wr_comm(0xF8+(7-x%8));else//如果是点白wr_comm(0xF0+(7-x%8));}}//----------------------------------//功能:在(x,y)位置显示24*24点阵的汉字//形参:x:水平位置坐标(0~127)// y:垂直位置坐标(0~63)// zi:汉字点阵数组// size:点阵数// amp_x:水平放大倍数// amp_y:垂直放大倍数// color:是否反白显示//----------------------------------void Disp_HanZi(int x, int y, flash uchar zi[], int size, intamp_x, int amp_y, int color){int i, j, k, m, n;for(i=0; i<size; i++)//行for(m=0; m<amp_y; m++)//垂直放大for(j=0; j<size/8; j++)//列(字节数)for(k=0; k<8; k++)//象素for(n=0; n<amp_x; n++)//水平放大if( zi[i*size/8+j]&(0x80>>k) )//逐位判断,如果对应位为1,则点亮此点PutPixel(x+((j*8)+k)*amp_x+n, y+i*amp_y+m, !color);elsePutPixel(x+((j*8)+k)*amp_x+n, y+i*amp_y+m, color);}//----------------------------------//功能:LCD初始化函数//----------------------------------void Init_LCD(void){CTL_DIR=0xFF;DATA_DIR=0xFF;//设置端口输入CD=1;WR=1;RD=1;CE=1;wr_xd(STARTADD_T, 0x40); //置文本显示区首地址wr_xd(STARTADD_G, 0x42); //置图形显示区首地址wr_td(BYTES_PER_LINE, 0x00, 0x41); //置文本显示区宽度wr_xd(BYTES_PER_LINE, 0x43); //置图形显示区宽度wr_comm(0x80); //置"或"模式//wr_td(0x02, 0x00, 0x22); //置CGRAM偏置地址wr_comm(0x9C); //启用文本显示,启用图形显示}//功能:清屏函数//--------------------------------------------------------------------------void VLine(int x0, int y0, int y1, int color){uchar tmp;if(y0>y1){// 对y0、y1大小进行排列,以便画图tmp = y1;y1 = y0;y0 = tmp;}do{PutPixel(x0, y0, color); // 逐点显示,描出垂直线y0++;}while(y1>=y0);}2. 8 硬件设计与调试1)将设计好的PCB图打印在油墨纸上;2)用转印机将油墨纸上的图转印在双面印制板;3)用Fecl3溶液腐蚀印制板;4)将已腐蚀好的板子用去污粉洗净;5)用台钻将印制板上的焊盘打好;6)根据原理图在印制板上焊接电路;7)检查线路,确定无误后通电。