目 录
论文总页数:18页
1 引言 1
1.1 课题背景 1
1.2 国内外研究现状 1
1.3 本课题研究的意义 1
2 系统框图及原理 1
3 磁场信号采集和处理 2
3.1 磁阻传感器 3
3.2 磁场测量ASIC 3
4 系统硬件 5
4.1系统控制器 5
4.1.1 控制器内部结构 5
4.1.2 控制器存储结构 5
4.1.3 控制器具体电路 6
4.2 系统扩展电路 7
4.2.1通信电路 8
4.2.2 指南针模块接口电路 8
4.2.3 实时时钟电路 9
4.2.4 液晶显示电路 10
4.2.5系统输入电路 11
5 系统软件 13
5.1 主监控程序 13
5.2 实时时钟驱动 13
5.3 人机界面驱动 14
5.3.1 液晶模块驱动 14
5.3.2 键盘驱动 14
5.4 指南针模块驱动 14
结 论 15
参考文献 16
致 谢 17
本课题研究的意义
本课题针对电子指南针的各个功能部件对电子指南针的关键部分做了详细的研究。电子指南针系统是一个典型的单片机系统,了解其工作原理及其信号处理流程有利于研究更加复杂的嵌入式系统,特别是系统中来自国外的磁传感器及其信号的采集芯片更是有利于研究磁场传感器的实现机理,以便将其更加广泛的应用。
2 系统框图及原理
电子指南针的系统主要由前端磁阻传感器、磁场测量专用转换芯片、单片控制器、辅助扩展电路、人机界面以及系统电源几个部分组成,系统结构如图2.1所示。
整个系统中前端的磁阻传感器负责测量地磁场的大小并将磁场的变化转化为微弱的电流的变化,专用的磁场测量芯片负责把磁阻传感器变化的电流(模拟量)转换成微控制器可以识别的数字量,然后通过芯片内部的SPI总线上传给微控制器。微控制器将表征当前磁场大小的数字量按照方位进行归一化等处理后通过直观的LCD进行方位显示,同时可以通过键盘控制微控制器进行相应的操作,本文转载自http://www.biyezuopin.vip/onews.asp?id=12673如将转换后的数据通过串口的形式发送到上位机。整个系统中还包含了实时时钟等一些辅助电路,使整个系统功能得到进一步的扩展。
/******************************************************************************************************************************
***模块名称: 测试主程序 ***
***模块功能: ***
***作 者: METAL MAX,CUIT(liyangbbs@126.com) ***
***调用方式: ***
***日 志: 日期 版本 修改人 记录 ***
*** 06/10/2008 V1.01 METALMAX 总体组合测试通过 ***
***备 注: ***
*****************************************************************************************************************************/
#include <reg52.h>
#include <stdio.h>
#include <math.h> /* T6963驱动库 */
#include "DriverT6963.h"
#include "DataBase.h"
#include "PCF8583.h"
#include "UART.h"unsigned char GblCnt = 0;
unsigned char T0IRQCNT = 0;
unsigned char oldtempx, oldtempy;
unsigned int Angle;
unsigned char keyflag = 0;
extern unsigned char COMBUF[10];
/******************************************************************************************************************************
**函数名称:delay() **
**函数功能:软件延迟 **
**入口参数:延迟时间倍数 **
**出口参数:无 **
**具体资源:无 **
**调用程序:无 **
**备 注:延时不精确 **
******************************************************************************************************************************/
void delay(unsigned int time)
{unsigned int i,j;for (i=0; i<time; i++) {for (j=0; j<1700; j++){;}}
}/******************************************************************************************************************************
**函数名称:DisCurTime() **
**函数功能:在指定位置显示实时芯片内的时间 **
**入口参数:显示位置x, y坐标 **
**出口参数:无 **
**具体资源:无 **
**调用程序:ReadPCF8583(), DisStr() **
**备 注: **
******************************************************************************************************************************/
void DisCurTime(unsigned char x, unsigned char y)
{unsigned char time[3];unsigned char dispBuff[9];ReadPCF8583(0x02, 3, time);dispBuff[8] = '\0'; /* 在数组最后单元放入标识符以便判断内容结束 */dispBuff[7] = (time[0] & 0x0f) + '0'; /* 提取秒个位 */dispBuff[6] = (time[0] >> 4) + '0'; /* 提取秒十位 */dispBuff[5] = ':';dispBuff[4] = (time[1] & 0x0f) + '0'; /* 提取分个位 */dispBuff[3] = (time[1] >> 4) + '0'; /* 提取分十位 */dispBuff[2] = ':';dispBuff[1] = (time[2] & 0x0f) + '0'; /* 提取时个位 */dispBuff[0] = ((time[2] >> 4) & 0x03) + '0'; /* 提取时十位 */DispStr(y*20+x, dispBuff);
}/******************************************************************************************************************************
**函数名称:显示日期 **
**函数功能:在指定位置显示实时芯片内的日期 **
**入口参数:显示位置x, y坐标 **
**出口参数:无 **
**具体资源:无 **
**调用程序:ReadPCF8583(), DisStr() **
**备 注: **
******************************************************************************************************************************/
void DisCurDate(unsigned char x, unsigned char y)
{unsigned char Date[2];unsigned char DisBuf[11];ReadPCF8583(0x05, 2, Date); /* 获取PCF8583的日期 */ DisBuf[4] = (Date[0] & 0x0f) + '0'; /* 提取日个位 */DisBuf[3] = ((Date[0] >> 4) & 0x03) + '0'; /* 提取日十位 */DisBuf[2] = '/';DisBuf[1] = (Date[1] & 0x0f) + '0'; /* 提取月个位 */DisBuf[0] = ((Date[1] >> 4) & 0x01) + '0'; /* 提取月十位 */DisBuf[5] = '/';DisBuf[6] = '2';DisBuf[7] = '0';DisBuf[8] = '0';DisBuf[9] = '8';DisBuf[10]= '\0'; /* 在数组最后单元放入标识符以便判断内容结束 */DispStr(y*20+x, DisBuf);
}/******************************************************************************************************************************
**函数名称:DisClock() **
**函数功能:绘制钟面 **
**入口参数:显示位置 **
**出口参数:无 **
**具体资源:无 **
**调用程序:Circle(), Line(), WriteEN(), EasyCH() **
**备 注: **
******************************************************************************************************************************/
void DrawClock(unsigned char x, unsigned char y, unsigned char r)
{Circle(x, y, r);Line(x, y-r, x, y-r+5, 0); /* 绘制0点处竖线 */Line(x, y+r, x, y+r-5, 0); /* 绘制6点处竖线 */Line(x-r, y, x-r+5, y, 0); /* 绘制9点处竖线 */Line(x+r, y, x+r-5, y, 0); /* 绘制3点处竖线 */WriteEN(198,'E');WriteEN(273,'S');WriteEN(189,'W');WriteEN(93,'N');EasyCH(3, 1, fang);EasyCH(3, 2, wei);
}/******************************************************************************************************************************
**函数名称:GraphicTest() **
**函数功能:显示子函数测试程序 **
**入口参数:无 **
**出口参数:无 **
**具体资源:无 **
**调用程序:显示子函数 **
**备 注: **
******************************************************************************************************************************/
void GraphicTest(void)
{Circle(80, 63, 60);Rectangle(0, 0, 159, 127, 0);Triangle(0, 0, 20, 30, 120, 50);Line(0, 0, 159, 127, 0);Line(0, 127, 159, 0, 1);
}/******************************************************************************************************************************
**函数名称:DisMain() **
**函数功能:主显示界面 **
**入口参数:显示位置 **
**出口参数:无 **
**具体资源:无 **
**调用程序:无 **
**备 注:仅用作测试使用 **
******************************************************************************************************************************/
void DisMain(void)
{Rectangle(0, 22, 159, 127, 0);DrawClock(113, 70, 45); Line(0, 115, 159, 115, 0);Line(64, 22, 64, 115, 0);
}/******************************************************************************************
***********************************/
void DisCurDirc(unsigned int Dir)
{unsigned char tempx, tempy;unsigned char Dir1, Dir2, Dir3;Dir1 = Dir/100 +'0'; /* 提取其各位 */Dir2 = (Dir%100)/10 + '0';Dir3 = (Dir%100)%10 + '0';WriteEN(122, Dir1);WriteEN(123, Dir2);WriteEN(124, Dir3);Dir = Dir/3; /* 不满3的倍数的按3的倍数算 */tempx = DirTbl[(Dir<<1)];tempy = DirTbl[((Dir<<1)+1)];LineClr(113, 70, oldtempx, oldtempy);Line(113, 70, tempx, tempy, 0); oldtempx = tempx;oldtempy = tempy;
}/******************************************************************************************************************************
**函数名称:SendAngle() **
**函数功能:向串口送当前角度值 **
**入口参数:当前角度 **
**出口参数:无 **
**具体资源:无 **
**调用程序:UartSendStr(), UartSendByte() **
**备 注: **
******************************************************************************************************************************/
void SendAngle(unsigned int Dir)
{unsigned char Dir1, Dir2, Dir3; unsigned char Str[] = "Current angle = 360 degree !";Dir1 = Dir/100 +'0'; /* 提取其各位 */Dir2 = (Dir%100)/10 + '0';Dir3 = (Dir%100)%10 + '0'; sprintf(Str, "Current angle = %c%c%c degree !", Dir1,Dir2,Dir3);UartSendStr(Str);UartSendByte(0x0d);UartSendByte(0x0a);
}/******************************************************************************************************************************
**函数名称:外部中断0 ISR **
**函数功能:获取键值 **
**入口参数:无 **
**出口参数:无 **
**具体资源:无 **
**调用程序:无 **
**备 注: **
******************************************************************************************************************************/
INT0IRQ (void) interrupt 0
{unsigned char keytmp;EA = 0;delay(10);keytmp = (P1 & 0xf8); /* 保留高5位 */if (keytmp == 0xf8) { /* 抖动 */EA = 1;}else {switch (keytmp) { /* Key1 */case 0x78 : keyflag = 1;break; /* Key2 */case 0xb8 : break; /* Key3 */case 0xd8 : break; /* Key4 */case 0xe8 : break; /* Key5 */case 0xf0 : break;default : break;}EA = 1;}
}/******************************************************************************************************************************
**函数名称:定时器0 ISR **
**函数功能:定时器0中断服务程序 **
**入口参数:无 **
**出口参数:无 **
**具体资源:无 **
**调用程序:无 **
**备 注: **
******************************************************************************************************************************/
T0IRQ (void) interrupt 1
{EA = 0;TR0 = 0;T0IRQCNT++;TR0 = 1;EA = 1;
}/******************************************************************************************************************************
**函数名称:GetAngle() **
**函数功能:获取方向角度 **
**入口参数:无 **
**出口参数:无 **
**具体资源:无 **
**调用程序:无 **
**备 注: **
******************************************************************************************************************************/
void GetAngle(void)
{unsigned char Dir1, Dir2, Dir3; Dir1 = COMBUF[0] - '0';if (Dir1 > 3) {}else {Dir2 = COMBUF[1] - '0';Dir3 = COMBUF[2] - '0'; Angle = Dir1 * 100 + Dir2 * 10 + Dir3;}
}/******************************************************************************************************************************
**函数名称:主测试函数 **
**函数功能: **
**入口参数:无 **
**出口参数:无 **
**具体资源:无 **
**调用程序:无 **
**备 注: **
******************************************************************************************************************************/void main(void)
{InitScreen();InitCOM();DisMain();EX0 = 1; /* 外部中断0开 */IT0 = 1; /* 外部中断0为边沿触发 */DisCurDate(0, 15); /* 显示系统日期 */Angle = 1;while(1){GetAngle();if (T0IRQCNT == 5) {DisCurDirc(Angle);}DisCurTime(11, 15); /* 显示系统时间 */ switch (keyflag) {case 1 : SendAngle(Angle);keyflag = 0;break;default : break;} }
}