// 第一版 DIY GPS 记录器硬件完成, 征求大家的意见修改, 第二版酝酿中...
照片:http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584486NGAF0L.jpg
(原文件名:001.jpg)
直播预告:
1楼. GPS 解析
2楼. OLED 驱动与显示界面
3楼. SD卡读写
4楼. 蓝牙模块
5楼. 锂电池,充电与电量显示
6楼. :
编辑 09/20 21:22:
主板正面:
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584499OMV2LL.jpg
(原文件名:主板-1.jpg)
主板反面:
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584500Y5N488.jpg
(原文件名:主板-2.jpg)
编辑 09/20 21:31:
显示界面:
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584505L8W2VQ.jpg
(原文件名:显示.jpg)
编辑 09/20 21:37:
隆重介绍独家首创的 370C 固定方式, 大家有钱的捧个钱场, 没钱的捧个人场~~~
模块上有两个固定孔, 无奈找不到那么细的螺丝, 而且模块正面(屏蔽罩那面) 又是天线又是接口的, 根本是高低不平,
索性, 不要螺丝了, 直接安排两个排针伺候着, 外加双面胶若干...请看图!
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584508WWG3I8.jpg
(原文件名:GPS 固定1.jpg)
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584509QEQDPW.jpg
(原文件名:GPS 固定2.jpg)
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584510XE94OB.jpg
(原文件名:GPS 固定3.jpg)
山寨了点, 不过效果蛮好, 双面胶有点弹性, 还能避震...
板子上预留了天线孔:
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584511N0D43O.jpg
(原文件名:GPS 固定4.jpg)
编辑 09/20 22:01
10楼的同学问得好,
又到了隆重介绍独家首创的时间, 与这个3232密不可分的, 就是这个切换排针:
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584512VRDA62.JPG
(原文件名:切换1.JPG)
10个引脚,分别为:
蓝牙 Tx, GPS Rx, Max3232 Rout, MCU Rx, GPS Tx
GPS Tx,MCU Tx, Max3232 Tin, GPS Tx, 蓝牙 Rx
不同的跳线方法切换不同的连接:
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584513XB31Z3.jpg
(原文件名:切换.jpg) 1楼 GPS 数据解析
/*------------------------------------------------------
功能:GPS 数据解析
by wowbanui
2010年9月
说明:
GPS 数据解析是直接在串口中断中进行的, 一般编程中并不推荐这么做,
但是在这小项目中效果不错...
而且, 暂时没有容错设计, 也不对GPS语句的CheckSum值校验.
目前测试了一周, 未出现严重错误.
-------------------------------------------------------*/
// 先定义缩写:
#define UCHAR unsigned char
#define UINT unsigned int
//定义数据结构, GPRMC 语句中能解析的数据
typedef struct
{
UCHAR Block;
UCHAR BlockIndex;
UCHAR UTCTime; //hhmmss.mmm
UCHAR Status; //A- 有效定位 V-无效定位
UCHAR Latitude; //ddmm.mmmm
UCHAR NS; //N/S
UCHAR Longitude; //dddmm.mmmm
UCHAR EW; //E/W
UCHAR Speed; //速率000.0~999.9节
UCHAR Course; //航向000.0~359.9度
UCHAR UTCDate; //ddmmyy
}stru_GPSRMC;
typedef struct
{
UCHAR Block;
UCHAR BlockIndex;
// UCHAR UTCTime; //hhmmss.mmm RMC中已有, 所以不解析
// UCHAR Latitude; //ddmm.mmmm
// UCHAR NS; //N/S
// UCHAR Longitude; //dddmm.mmmm
// UCHAR EW; //E/W
UCHAR PositionFix; //0,1,2,6
UCHAR SateUsed; //00~12
// UCHAR HDOP; //0.5~99.9
UCHAR Altitude; //-9999.9~99999.9
}stru_GPSGGA;
typedef struct
{
UCHAR Block;
UCHAR BlockIndex;
UCHAR Mode; //A-自动 /M-手动
UCHAR Mode2; //0,1,2,3
UCHAR SateUsed;
UCHAR PDOP;
UCHAR HDOP;
UCHAR VDOP;
}stru_GPSGSA;
typedef struct
{
UCHAR SatelliteID;//卫星编号
// UCHAR Elevation; //0-90 degree //不显示GPS卫星的方位图, 所以不解析, 节省 5*12 RAM
// UCHAR Azimuth; //0-359 degree//需要解析时去除注释'//'和解析前的'//'即可
UCHAR SNR; //0-99 dbHz
}stru_SatelliteInfo;
typedef struct
{
UCHAR Block;
UCHAR BlockIndex;
UCHAR SateInView;
UCHAR GSVID;//当前 GSV语句编号
stru_SatelliteInfo SatelliteInfo;
}stru_GPSGSV;
//--------------------------------------------------------------
#define GPS_NULL 0x00 //GPS语句类型
#define GPS_GPGGA 0x01
#define GPS_GPGSA 0x02
#define GPS_GPGSV 0x04
#define GPS_GPRMC 0x08
UCHAR GPSDataType=GPS_NULL; //GPS语句类型
UCHAR GPSDataTypeStrBuff[]="$GPxxx,"; //GPS语句类型缓存, 判断类型时使用,
UCHAR GPSDataTypeStrBuffIndex=0; //GPS语句类型字符串的当前位置
UCHAR xdata MainDateTime[]="00/00/00 00:00:00\0"; //日期时间
UCHAR xdata MainDateTimeShort[]="00/00 00:00:00\0"; //日期时间
UCHAR xdata MainLatitude[]="N dd'mm'ss.ssss\"\0"; //纬度
UCHAR xdata MainLongitude[]="Eddd'mm'ss.ssss\"\0"; //经度
bit GPSDataStart=0; //GPS语句开始. 检测到 $ 时置1
bit ReciveFlag=0; //数据接收完成. 最后一条 GPRMC 语句发送完毕置1,
stru_GPSRMC xdata GPS_RMC_Data;
stru_GPSGGA xdata GPS_GGA_Data;
stru_GPSGSA xdata GPS_GSA_Data;
stru_GPSGSV xdata GPS_GSV_Data;
//------------------------------------------------------------------
/*-------------------------------------------------------
串口中断函数, 同时解析GPS数据到变量中
仅是字符串提取, 没有容错考虑, 不检查GPS语句后的CheckSum值
虽然语句比较多, 但如下图所示, 每次执行的只是其中一条支路
-------------------------------------------------------*/
解析框图:
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584531AZ7ZQB.png
(原文件名:GPS 解析框图.png)
void Serial() interrupt 4
{
LED_1=0;//串口数据指示灯
if (RI)
{
RI=0;
//判断是否是GPS语句:
if(GPSDataStart)
{ //已经判断到GPS语句头字符$,
switch(GPSDataTypeStrBuffIndex)
{ //已经读取了多少个表示GPS数据类型的字符
case 6:
{ //已经全部读取, 开始判断
if(GPSDataTypeStrBuff=='G'&&GPSDataTypeStrBuff=='A') GPSDataType=GPS_GPGGA;
if(GPSDataTypeStrBuff=='S'&&GPSDataTypeStrBuff=='A') GPSDataType=GPS_GPGSA;
if(GPSDataTypeStrBuff=='V') GPSDataType=GPS_GPGSV;
if(GPSDataTypeStrBuff=='C') GPSDataType=GPS_GPRMC;
if(SBUF==',') GPSDataTypeStrBuffIndex=255; //判断完毕, 数据接收开始
break;
}
case 255:
{ //GPS数据类型的字符全部读取并判断完毕, 正接收数据
switch(GPSDataType)
{ //该句的类型
case GPS_GPGGA:
{
switch(SBUF)
{
case '*': //语句结束
GPSDataStart=0;
break;
case ',': //该字段结束, 下一个
GPS_GGA_Data.Block++;
GPS_GGA_Data.BlockIndex=0; //字段索引置0:第一个字符
break;
default:
{ //字段字符
switch(GPS_GGA_Data.Block)
{ //判断当前处于哪个字段
// case 0:
// GPS_GGA_Data.UTCTime=SBUF;
// break;
// case 1:
// GPS_GGA_Data.Latitude=SBUF;
// break;
// case 2:
// GPS_GGA_Data.NS=SBUF;
// break;
// case 3:
// GPS_GGA_Data.Longitude=SBUF;
// break;
// case 4:
// GPS_GGA_Data.EW=SBUF;
// break;
case 5:
GPS_GGA_Data.PositionFix=SBUF;
break;
case 6:
GPS_GGA_Data.SateUsed=SBUF;
break;
// case 7:
// GPS_GGA_Data.HDOP=SBUF;
// break;
case 8:
GPS_GGA_Data.Altitude=SBUF;
break;
}
GPS_GGA_Data.BlockIndex++; //字段索引++, 指向下一个字符
}
}
break;
}
case GPS_GPRMC:
{
switch(SBUF)
{
// SerialSendChar(SBUF);
case '*':
{
GPSDataStart=0;
GPSDataTypeStrBuffIndex=0;
ReciveFlag=1; //接收完毕, 可以处理
break;
}
case ',':
{
GPS_RMC_Data.Block++;
GPS_RMC_Data.BlockIndex=0;
break;
}
default:
{
switch(GPS_RMC_Data.Block)
{
case 0:
GPS_RMC_Data.UTCTime=SBUF;
break;
case 1:
GPS_RMC_Data.Status=SBUF;
break;
case 2:
GPS_RMC_Data.Latitude=SBUF;
break;
case 3:
GPS_RMC_Data.NS=SBUF;
break;
case 4:
GPS_RMC_Data.Longitude=SBUF;
break;
case 5:
GPS_RMC_Data.EW=SBUF;
break;
case 6:
GPS_RMC_Data.Speed=SBUF;
break;
case 7:
GPS_RMC_Data.Course=SBUF;
break;
case 8:
GPS_RMC_Data.UTCDate=SBUF;
break;
}
GPS_RMC_Data.BlockIndex++;
}
}
break;
}
case GPS_GPGSA:
{
switch(SBUF)
{
case '*':
GPSDataStart=0;
break;
case ',':
GPS_GSA_Data.Block++;
GPS_GSA_Data.BlockIndex=0;
break;
default:
switch(GPS_GSA_Data.Block)
{
case 0:
GPS_GSA_Data.Mode=SBUF;
break;
case 1:
GPS_GSA_Data.Mode2=SBUF;
break;
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13: //2-13 是已使用的卫星ID, 保存于数组中
GPS_GSA_Data.SateUsed=SBUF;
break;
case 14:
GPS_GSA_Data.PDOP=SBUF;
break;
case 15:
GPS_GSA_Data.HDOP=SBUF;
break;
case 16:
GPS_GSA_Data.VDOP=SBUF;
break;
}
GPS_GSA_Data.BlockIndex++;
}
break;
}
case GPS_GPGSV:
{
switch(SBUF)
{
case '*':
GPSDataStart=0;
break;
case ',':
GPS_GSV_Data.Block++;
GPS_GSV_Data.BlockIndex=0;
break;
default:
{
switch(GPS_GSV_Data.Block)
{
case 1:
GPS_GSV_Data.GSVID=SBUF-'1'; //当前GPFSV语句的序号, 该序号计算出该组卫星数据应该存放于数组的哪个位置
break;
case 2:
GPS_GSV_Data.SateInView=SBUF;
break;
case 3:
GPS_GSV_Data.SatelliteInfo.SatelliteID=SBUF;
break;
// case 4:
// GPS_GSV_Data.SatelliteInfo.Elevation=SBUF;
// break;
// case 5:
// GPS_GSV_Data.SatelliteInfo.Azimuth=SBUF;
// break;
case 6:
GPS_GSV_Data.SatelliteInfo.SNR=SBUF;
break;
case 7:
GPS_GSV_Data.SatelliteInfo.SatelliteID=SBUF;
break;
// case 8:
// GPS_GSV_Data.SatelliteInfo.Elevation=SBUF;
// break;
// case 9:
// GPS_GSV_Data.SatelliteInfo.Azimuth=SBUF;
// break;
case 10:
GPS_GSV_Data.SatelliteInfo.SNR=SBUF;
break;
case 11:
GPS_GSV_Data.SatelliteInfo.SatelliteID=SBUF;
break;
// case 12:
// GPS_GSV_Data.SatelliteInfo.Elevation=SBUF;
// break;
// case 13:
// GPS_GSV_Data.SatelliteInfo.Azimuth=SBUF;
// break;
case 14:
GPS_GSV_Data.SatelliteInfo.SNR=SBUF;
break;
case 15:
GPS_GSV_Data.SatelliteInfo.SatelliteID=SBUF;
break;
// case 16:
// GPS_GSV_Data.SatelliteInfo.Elevation=SBUF;
// break;
// case 17:
// GPS_GSV_Data.SatelliteInfo.Azimuth=SBUF;
// break;
case 18:
GPS_GSV_Data.SatelliteInfo.SNR=SBUF;
break;
}
GPS_GSV_Data.BlockIndex++;
}
}
break;
}
default:
{ //GPS类型判断失败, 进入未接收到GPS语句($)的状态, 重新循环
GPSDataStart=0;
GPSDataType=GPS_NULL;
}
}
break;
}
default:
{ //未判断, 继续接收, Index++
GPSDataTypeStrBuff=SBUF;
GPSDataTypeStrBuffIndex++;
}
}
}
else
{ //未发现语句头字符, 继续接收并判断
if (SBUF=='$')
{ //接收到$, 下一个字符即为类型判断字符, 先进行相关变量初始化
GPSDataTypeStrBuff=SBUF;
GPSDataStart=1; //从头存放GPS类型字符到变量
GPSDataType=GPS_NULL;
GPSDataTypeStrBuffIndex=1;
GPS_RMC_Data.Block=0; //每种语句的标志位
GPS_RMC_Data.BlockIndex=0;
GPS_GSV_Data.Block=0;
GPS_GSV_Data.BlockIndex=0;
GPS_GGA_Data.Block=0;
GPS_GGA_Data.BlockIndex=0;
GPS_GSA_Data.Block=0;
GPS_GSA_Data.BlockIndex=0;
}
}
}
LED_1=1;
}
/*-------------------------------------------------------
获取纬度并转换成度分秒格式
算法(也谈不上算法~~)请看我的帖子 :
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4228218
-------------------------------------------------------*/
void GetLatitude()
{
unsigned long s;
MainLatitude=GPS_RMC_Data.NS; //北纬 南纬标志
MainLatitude=GPS_RMC_Data.Latitude; //度, 直接提取
MainLatitude=GPS_RMC_Data.Latitude;
MainLatitude=0x02; //度(°)符号
MainLatitude=GPS_RMC_Data.Latitude; //分, 直接提取
MainLatitude=GPS_RMC_Data.Latitude;
//直接提取后四位分并扩大10000倍为整数存于Long型, 避免小数运算
s=(GPS_RMC_Data.Latitude-'0')*1000+(GPS_RMC_Data.Latitude-'0')*100+
(GPS_RMC_Data.Latitude-'0')*10+(GPS_RMC_Data.Latitude-'0');
s*=60; //转换成单位 秒(")
//提取到字符串中
MainLatitude=s/100000+'0';
s=s%100000;
MainLatitude=s/10000+'0';
s=s%10000;
MainLatitude=s/1000+'0';
s=s%1000;
MainLatitude=s/100+'0';
s=s%100;
MainLatitude=s/10+'0';
s=s%10;
MainLatitude=s+'0';
}
/*-------------------------------------------------------
获取经度并转换成度分秒格式
算法(也谈不上算法~~)请看我的帖子 :
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4228218
-------------------------------------------------------*/
void GetLongitude()
{
unsigned long s;
MainLongitude=GPS_RMC_Data.EW;
MainLongitude=GPS_RMC_Data.Longitude;
MainLongitude=GPS_RMC_Data.Longitude;
MainLongitude=GPS_RMC_Data.Longitude;
MainLongitude=0x02;
MainLongitude=GPS_RMC_Data.Longitude;
MainLongitude=GPS_RMC_Data.Longitude;
s=(GPS_RMC_Data.Longitude-'0')*1000+(GPS_RMC_Data.Longitude-'0')*100+
(GPS_RMC_Data.Longitude-'0')*10+(GPS_RMC_Data.Longitude-'0');
s*=60;
MainLongitude=s/100000+'0';
s=s%100000;
MainLongitude=s/10000+'0';
s=s%10000;
MainLongitude=s/1000+'0';
s=s%1000;
MainLongitude=s/100+'0';
s=s%100;
MainLongitude=s/10+'0';
s=s%10;
MainLongitude=s+'0';
} 2楼:
OLED 驱动与显示界面:
这次用的是前端时间坛子里淘宝超值推荐的10块钱的128x128 三星OLED,
这个OLED那是相当超值啊, 就是引脚脆弱, 飞线难度是相当大, 所以这次一块做板, 但还是焊报废了一个..
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584516ILPBXY.jpg
(原文件名:OLED2.jpg)
编辑 09/20 22:11
OLED 需要15V的驱动电压, 某些自带了升压电路, 只需接个MOS管,电感,二极管即可, 这里用了最常见的 MC34063, 3.3V 升压至15V
如图所见, 电感的块头不小, 所以在板子上挖个窝, 让电感呆在里面, 使得总体厚度降低2mm 左右
编辑 09/21 10:35
OLED 初始化:
#define OLED_L P2
#define OLED_H P1
sbit OLED_CS = P3^3;
sbit OLED_RST = P3^4;
sbit OLED_RW = P3^5;
sbit OLED_EN = P3^6;
sbit OLED_A0 = P3^7;
/*-------------------------------------------------------
写入命令
-------------------------------------------------------*/
void OLED_CMD(UCHAR ucDat)
{
OLED_L=ucDat;
OLED_A0=0;
OLED_EN=1;
OLED_EN=0;
}
/*-------------------------------------------------------
写入数据/命令的参数
-------------------------------------------------------*/
void OLED_DATA(UCHAR ucDat)
{
OLED_L=ucDat;
OLED_A0=1;
OLED_EN=1;
OLED_EN=0;
}
/*-------------------------------------------------------
写入16位的数据, 颜色数据 RRRR RGGGGGGB BBBB
-------------------------------------------------------*/
void OLED_DATA16(UCHAR ucDatH,UCHAR ucDatL)
{
OLED_L=ucDatL;
OLED_H=ucDatH;
OLED_A0=1;
OLED_EN=1;
OLED_EN=0;
}
/*-------------------------------------------------------
OLED 初始化
-------------------------------------------------------*/
void OLED_Init()
{
UCHAR i,j;
OLED_RST=0; //OLED RESET
OLED_RST=1;
OLED_RW=0; //6800接口, 数据写入
OLED_CS=0; //片选
OLED_CMD(0x03); //03 号命令, 显示待机
OLED_DATA(0x00); //命令参数 0x00: Display Standby OFF
OLED_CMD(0x07); //07号命令 显示画面的尺寸
OLED_DATA(0x00);
OLED_DATA(0x00); //x 起始 00
OLED_DATA(0x07);
OLED_DATA(0x0F); //x 结束 127
OLED_DATA(0x02);
OLED_DATA(0x00); //y 起始 32
OLED_DATA(0x09);
OLED_DATA(0x0F); //y 结束 159
OLED_CMD(0x05); //05号命令, 写入方向
OLED_DATA(0x00);
OLED_CMD(0x04); //04号命令 屏幕刷新率
OLED_DATA(0x02); //参数 0x02: 默认,90Hz
OLED_CMD(0x1F); //1F号命令 Row overlap scan
OLED_DATA(0x00);
OLED_CMD(0x30); //30号命令 Row Internal Regulator
OLED_DATA(0x13); // 80%
OLED_CMD(0x1C); //1C号命令 预充电时间
OLED_DATA(0x00);
OLED_DATA(0x08);
OLED_CMD(0x1D); //1D号命令
OLED_DATA(0x05); //红
OLED_DATA(0x05); //绿
OLED_DATA(0x05); //蓝
OLED_CMD(0x0E); //0E号命令 点输出电流(每个点电流?)
OLED_DATA(0x04);
OLED_DATA(0x07);
OLED_DATA(0x05);
OLED_DATA(0x07);
OLED_DATA(0x05);
OLED_DATA(0x0F);
OLED_CMD(0x08); //接口设置
OLED_DATA(0x03); //16位数据接口
OLED_0A_XBOXSize(0,127,32,127+32); //设置写入范围
OLED_CMD(0x0C); //0C号命令 写入数据
for(i=0;i<88;i++) //0-87行, 清空
for(j=0;j<128;j++)
OLED_DATA16(0x00,0x00);
for(i=0;i<40;i++) //88-127行, EarthLogo
for(j=0;j<128;j++)
OLED_DATA16(EarthLogo,EarthLogo);
OLED_CMD(0x02); //02号命令 打开显示
OLED_DATA(0x01)
} 3楼. SD卡读写
以下图片都是在TF卡中的, 目前只实现了指定扇区的读写, 正在攻克 FAT16 文件系统...
所以下面是用WinHex查看了物理扇区直接显示.以便测试扇区读写代码..
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584525EX1L0O.JPG
(原文件名:SD-1.JPG)
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584526QCARGF.JPG
(原文件名:SD-2.JPG)
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584527QBTUMI.JPG
(原文件名:SD-3.JPG)
编辑 09/20 23:10
51单片机频率 22.1184M, 从TF卡读取一幅128x128的彩色图片(RGB565 16位,65536色, 64个扇区)并显示需要1-2秒
-- 是不是编程有问题?????? 4楼. 蓝牙模块
网上买的现成的模块, 转串口, 两个指示灯:
左边的: 连接成功指示
右边的: 连接中, 或者是连接完成的发送指示
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584520JY8ZQD.JPG
(原文件名:蓝牙.JPG) 5楼. 锂电池,充电与电量显示
电池: 三洋 8.6Wh, 约2300mAh
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584521IJN643.JPG
(原文件名:电池.JPG)
两颗TP4057
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584524ZDH2AL.JPG
(原文件名:充电.JPG)
TP4057单颗典型应用电路
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584713QPEJDD.png
(原文件名:TP4057.png)
Rprog电阻对应充电电流关系
prog电阻 电流
20k 50mA
10k 100mA
5k 200mA
3k 300mA
2k 400mA
1.6k 500mA
"双核"充电是根据网上介绍的, 两组直接并联,
TP4057 充电曲线
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584714Z8UFNA.png
(原文件名:TP4057 充电曲线.png)
电量显示, LM3914
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584523Y5QPR0.jpg
(原文件名:电量显示.jpg) 调试过程中功不可没: 最小系统版
应该算非常迷你了,
1. USB 5V 输入, LDO 输出3.3V, 3.3V有引脚引出
2. 电源指示灯
3. 复位电路与按钮
4. 8x4 + 4 引脚全部引出
5. 带 Max3232, 与单片机串口连接为跳线, 可以断开, 不影响端口其它用途
6. 兼容5V: 只需将 AMS1117 去掉, 直接短接输入输出, 当然, 单片机要换5V 的, 还有Max232
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584588BBJGTD.jpg
(原文件名:002-2.jpg)
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584589KQMSRM.jpg
(原文件名:003-2.jpg)
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584590E2AZC1.JPG
(原文件名:002.JPG)
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584591JWK3SC.JPG
(原文件名:003.JPG) 汽水,瓜子,要不要? 看直播看直播 烧饼摊位占位~ 也占位,并问问那个3232是干嘛的? 7楼,93#的来二两。 回复【11楼】1181zjf
-----------------------------------------------------------------------
这哥们还是开车来的呢 可惜是醉驾 漂亮 好东西
oled是不是要升压?
我还有两片
买的时候不知道这个要升压
纠结死了 回复【14楼】clever0725
好东西
oled是不是要升压?
我还有两片
买的时候不知道这个要升压
纠结死了
-----------------------------------------------------------------------
OLED 都要升压, 这个, 也不例外... 关注中。。。。 出套件不,哥们?要不卖两块板子给我 没人关注啊.... 要是再做小点,就更爽了。加油!!! 站位学习 秒 cool! LZ电池哪里买的?????? 回复【19楼】dxf5200
要是再做小点,就更爽了。加油!!!
-----------------------------------------------------------------------
可以的, 主板反面基本是空空的, 当初是考虑到电池大小(电池 63mm x 71mm), 将电池直接固定于主板反面. 所以板子就这么大了,
回复【23楼】liouravr
lz电池哪里买的??????
-----------------------------------------------------------------------
淘宝上买的, 要买的东西卖家没货了, 仅剩一片三洋电池, 便宜给我了. 做的很好啊。。赞一个。 mark!~~ 更新帖子不会上移么~~ 回复【27楼】wowbanui
更新帖子不会上移么~~
-----------------------------------------------------------------------
顶贴才行 继续关注。 LZ的液晶转接板 是套间吗?如果能连oled一起出售就好了
肯定有多余的大概得多少银子? 强帖要顶 楼主 把屏的链接 发上来吧
淘宝只找到了 96*64像素的 么有找到128*128的啊
要是真128*128的10块钱 确实超值了
给个链接吧 谢谢了先 回复【32楼】3466756555
楼主 把屏的链接 发上来吧
淘宝只找到了 96*64像素的 么有找到128*128的啊
要是真128*128的10块钱 确实超值了
给个链接吧 谢谢了先
-----------------------------------------------------------------------
这个屏是当初淘宝超值推荐板块里推荐的, 现在已经没有了, 当初也是要30元的, 是版主和卖家联系 Ourdev网友才有的优惠价, 而且每人限购5块. 关注!!!!!!!!!! 欢迎大家提意见~~ 不错,值得参考,有时间了也研究着做一个。
正考虑着用个大点的屏,用个arm,加个ad,做个示波器加gps,材料都齐,只欠东风! 显示图片慢大概是因为用SPI方式读取TF卡吧!你全屏填色块需要多久? 我用STM32+GPS做了一个自动校时万年历...体积太大不能拿着走懒得编地图功能干脆只要时间了. gps固定方式有意思,赞一下楼主的微距拍摄! 模块固定方式有搞头
无敌B T 跳线显神通
学习了~~~~ 回复【37楼】badlyby
显示图片慢大概是因为用spi方式读取tf卡吧!你全屏填色块需要多久?
-----------------------------------------------------------------------
全屏填色块的速度估摸在 5fps~8fps 左右
因为每次得送2字节的数据, 一共 128*128=16,384个点
现在是只刷新变动的部分
应该是到了51单片机的极限了 回复【40楼】format
模块固定方式有搞头
无敌b t 跳线显神通
学习了~~~~
-----------------------------------------------------------------------
好湿好湿 手机看的,先顶你,下次再细细看 看帖,,,看帖..... 超过24小时不能编辑了?... SD 卡扇区读写代码
//定义接口 模拟SPI 方式,
sbit TF_LED = P0^3;
sbit TF_DO = P0^4;
sbit TF_CLK = P0^5;
sbit TF_DI = P0^6;
sbit TF_CS = P0^7;
#define UCHAR unsigned char
#define UINT unsigned int
#define ULONG unsigned long
UCHAR bdata SD_DAT; //定义可位寻址的字节,
sbit SD_DAT7=SD_DAT^7;
sbit SD_DAT6=SD_DAT^6;
sbit SD_DAT5=SD_DAT^5;
sbit SD_DAT4=SD_DAT^4;
sbit SD_DAT3=SD_DAT^3;
sbit SD_DAT2=SD_DAT^2;
sbit SD_DAT1=SD_DAT^1;
sbit SD_DAT0=SD_DAT^0;
#define INIT_CMD0_ERROR 0x00
#define INIT_CMD1_ERROR 0x01
#define WRITE_BLOCK_ERROR 0x02
#define READ_BLOCK_ERROR 0x03
#define INIT_DELAY_TIME 100
void SD_InitDelay(UCHAR delay) //初始化SD卡的延迟函数
{
while(delay--);
}
void SD_WriteByteSlow(UCHAR ucWB)//初始化专用的写字节函数,初始化需要以低速进行,
{
UCHAR i;
for (i=0;i<8;i++)
{
ucWB<<=1;
TF_DI=CY;
TF_CLK=0;
SD_InitDelay(INIT_DELAY_TIME);
TF_CLK=1;
}
}
void SD_WriteByte(UCHAR ucWB)//正常写字节函数, 最大化效率
{
SD_DAT=ucWB;
TF_DI=SD_DAT7;TF_CLK=0;TF_CLK=1;
TF_DI=SD_DAT6;TF_CLK=0;TF_CLK=1;
TF_DI=SD_DAT5;TF_CLK=0;TF_CLK=1;
TF_DI=SD_DAT4;TF_CLK=0;TF_CLK=1;
TF_DI=SD_DAT3;TF_CLK=0;TF_CLK=1;
TF_DI=SD_DAT2;TF_CLK=0;TF_CLK=1;
TF_DI=SD_DAT1;TF_CLK=0;TF_CLK=1;
TF_DI=SD_DAT0;TF_CLK=0;TF_CLK=1;
}
UCHAR SD_ReadByteSlow(void)
{
UCHAR i,ucRB=0x00;
TF_DO=1;
for (i=0;i<8;i++)
{
TF_CLK=0;
ucRB<<=1;
SD_InitDelay(INIT_DELAY_TIME);
TF_CLK=1;
if (TF_DO) ucRB|=0x01;
else ucRB&=0xFE;
}
return ucRB;
}
UCHAR SD_ReadByte(void)
{
TF_DO=1;
TF_CLK=0;TF_CLK=1;SD_DAT7=TF_DO;
TF_CLK=0;TF_CLK=1;SD_DAT6=TF_DO;
TF_CLK=0;TF_CLK=1;SD_DAT5=TF_DO;
TF_CLK=0;TF_CLK=1;SD_DAT4=TF_DO;
TF_CLK=0;TF_CLK=1;SD_DAT3=TF_DO;
TF_CLK=0;TF_CLK=1;SD_DAT2=TF_DO;
TF_CLK=0;TF_CLK=1;SD_DAT1=TF_DO;
TF_CLK=0;TF_CLK=1;SD_DAT0=TF_DO;
return SD_DAT;
}
UCHAR SD_CmdSlow(UCHAR *ucCMD)//初始化使用的发送命令函数
{
UCHAR temp,retry=0,i;
TF_CS=1; //禁止SD卡片选
SD_WriteByteSlow(0xFF);//发送8个时钟信号
TF_CS=0; //使能SD卡片选
for (i=0;i<6;i++) //向SD卡发送6字节命令
{
SD_WriteByteSlow(*ucCMD);
ucCMD++;
}
//获得16位的回应忽略前一个字节.
do {
temp=SD_ReadByteSlow(); //读取后8位
retry++;
}while((temp==0xff)&&(retry<100));
return(temp);
}
UCHAR SD_Cmd(UCHAR *ucCMD)
{
UCHAR temp,retry=0;
TF_CS=1; //禁止SD卡片选
SD_WriteByte(0xFF); //发送8个时钟信号
TF_CS=0; //使能SD卡片选
for (temp=0;temp<6;temp++) //向SD卡发送6字节命令
{
SD_WriteByte(*ucCMD);
ucCMD++;
}
//获得16位的回应忽略前一个字节.
do {
temp=SD_ReadByte(); //读取后8位
retry++;
}while((temp==0xff)&&(retry<100));
return(temp);
}
UCHAR SD_Init()//初始化SD卡
{
UCHAR temp,retry;
UCHAR CMD[]={0x40,0x00,0x00,0x00,0x00,0x95};//0号命令
TF_CS=1;
for (temp=0;temp<0x0f;temp++)
{
SD_WriteByte(0xff); //发送至少74个时钟信号
}
TF_CS=0;
retry=0;
do{ //为了能够成功写入CMD0,在这里写200次
temp=SD_CmdSlow(CMD);
retry++;
if(retry==200) return(INIT_CMD0_ERROR);
}while(temp!=0x01); //回应01h,停止写入
TF_CS=1;
SD_WriteByteSlow(0xFF);
CMD = 0x41; //发送CMD1到SD卡
CMD = 0xFF;
retry=0;
do { //为了能成功写入CMD1,写100次
temp=SD_CmdSlow(CMD);
retry++;
if(retry==100) return(INIT_CMD1_ERROR);
}while(temp!=0x00); //回应00h停止写入
SD_WriteByteSlow(0xFF);
TF_CS=1;
return(0); //初始化成功
}
/*---------------------------------------------------
读取SD卡的CID寄存器16字节成功返回0
读取CIDCID寄存器存储了SD卡的标识码。每一个卡都有唯一的标识码。
CID寄存器长度为128位。它的寄存器结构如下:
名称 域 数据宽度 CID划分
生产标识号 MID 8
OEM/应用标识 OID 16
产品名称 PNM 40
产品版本 PRV 8
产品序列号 PSN 32
保留 -- 4
生产日期 MDT 12
CRC7校验合 CRC 7
未使用,始终为1 -- 1
----------------------------------------------------*/
UCHAR SD_ReadCID(UCHAR *Buffer)
{
UCHAR CMD[] = {0x4A,0x00,0x00,0x00,0x00,0xFF};//读取CID寄存器的命令
UCHAR retry,temp;
TF_CS=0;//打开片选
retry=0;
do
{
temp=SD_Cmd(CMD); //写入CMD
retry++;
if(retry==200)
{
return(READ_BLOCK_ERROR); //读块失败
}
}while(temp!=0);
while (SD_ReadByte()!= 0xfe); //一直读,当读到0xfe时,说明后面的是512字节的数据了
for(temp=0;temp<16;temp++) //将数据写入到数据缓冲区中
{
Buffer=SD_ReadByte();
}
SD_ReadByte();
SD_ReadByte(); //读取两个字节的CRC校验码,这里不用关心它们
TF_CS=1; //SD卡关闭片选
SD_WriteByte(0xFF); //按照SD卡的操作时序在这里补8个时钟
return 0;
}
UCHAR SD_WriteSector(ULONG addr,UCHAR *buffer) //向SD卡中的指定地址的扇区写入512个字节,使用CMD24
{
UCHAR temp,retry;
UINT i;
UCHAR pCmd[] = {0x58,0x00,0x00,0x00,0x00,0xff}; //CMD24
addr<<=9; //addr = addr * 512 将块地址(扇区地址)转为字节地址(这里就限制了最大寻址4G)
pCmd=((addr&0xff000000)>>24); //将字节地址写入到CMD24字节序列中
pCmd=((addr&0x00ff0000)>>16);
pCmd=((addr&0x0000ff00)>>8);
TF_CS=0;//打开SD卡片选
retry=0;
do
{
temp=SD_Cmd(pCmd);
retry++;
if(retry==200)
{
TF_CS=1; //关闭片选
return(temp); //命令写入失败
}
}while(temp!=0);
for(temp=0;temp<100;temp++) //这里要插入若干时钟信号
{
SD_WriteByte(0xff);
}
SD_WriteByte(0xFE);//写入开始字节 0xfe,后面就是要写入的512个字节的数据
for(i=0;i<512;i++) //将缓冲区中要写入的512个字节写入SD卡
{
SD_WriteByte(buffer);
}
SD_WriteByte(0xff);
SD_WriteByte(0xff); //两个字节的CRC校验码,不用关心
temp=SD_ReadByte(); //读取返回值
if((temp&0x1F)!=0x05) //如果返回值是 XXX00101说明数据已经被SD卡接受了
{
TF_CS=1;
return(WRITE_BLOCK_ERROR); //写块数据失败
}
while(SD_ReadByte()!=0xff); //0x00 SD卡忙, 0xFF就绪
TF_CS=1; //关闭片选
SD_WriteByte(0xff); //按照SD卡的操作时序在这里补8个时钟
return(0); //返回0,说明写扇区操作成功
}
UCHAR SD_ReadSector(ULONG addr,UCHAR *buffer)//从SD卡的指定扇区中读出512个字节
{
UINT j;
UCHAR time,temp;
UCHAR pCmd[]={0x51,0x00,0x00,0x00,0x00,0xff}; //CMD17
addr<<=9; //addr=addr*512 将块地址(扇区地址)转为字节地址
pCmd=((addr&0xff000000)>>24); //将字节地址写入到CMD17字节序列中
pCmd=((addr&0x00FF0000)>>16);
pCmd=((addr&0x0000FF00)>>8);
TF_CS=0;//打开片选
TF_LED=0;
time=0;
do
{
temp=SD_Cmd(pCmd); //写入CMD17
time++;
if(time==200)
{
return(READ_BLOCK_ERROR); //读块失败
}
}while(temp!=0);
while (SD_ReadByte()!= 0xfe); //一直读,当读到0xfe时,说明后面的是512字节的数据了
for(j=0;j<512;j++) //将数据写入到数据缓冲区中
{
buffer=SD_ReadByte();
}
SD_ReadByte();
SD_ReadByte();//读取两个字节的CRC校验码,不用关心它们
TF_CS=1;//SD卡关闭片选
SD_WriteByte(0xff);//按照SD卡的操作时序在这里补8个时钟
TF_LED=1;
return 0;
} 学习中,非常好 mark先 还算楼主识趣
把SD卡读写放上了~~~
偶喜欢
在顶顶你~~~~ 那个OLED 的升压效率不高, 是个耗电大户, 整个测下来电池那里电流大概260mA左右,
寻思了下版换上这个, 不带背光的LCD(其实是给我拆了), ST7565S控制器, 只有128*64
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584847BRRCWO.JPG
(原文件名:P1020581.JPG) 哥们,顶你!!
其实我的gps模块也是插针固定的。
正纠结于gps数据处理。。。。 其实那个电感并不需要这么大的。看看LM3S8962上面那个,又小又薄,但不知道在哪里买。纠结。 高,实在是高 回复【52楼】esdart
其实那个电感并不需要这么大的。看看lm3s8962上面那个,又小又薄,但不知道在哪里买。纠结。
-----------------------------------------------------------------------
34063的频率低,所以电感大, 这个3.3V升到15V算出来得330uH, 小的电流又达不到, 发烫...
其它芯片购买不方便, 同样纠结中... 不错 回复【54楼】wowbanui
回复【52楼】esdart
其实那个电感并不需要这么大的。看看lm3s8962上面那个,又小又薄,但不知道在哪里买。纠结。
-----------------------------------------------------------------------
34063的频率低,所以电感大, 这个3.3v升到15v算出来得330uh, 小的电流又达不到, 发烫...
其它芯片购买不方便, 同样纠结中...
-----------------------------------------------------------------------
这个忽略了,呵呵。 OLED模块和GPS固定方式很有新意 楼主,为何要画这个?
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584893TNG783.jpg
(原文件名:pcb.jpg) 这是我做的Logo而已, 没有其他用途,
或者, 铺满了接地应该有覆铜的效果~~
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584928WIQ69Z.jpg
(原文件名:LOGO.jpg)
看有没有人看得出是什么名堂?
还有个左下角的, 这个看的清楚点 -- 春丽~~
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584929QWRHFX.png
(原文件名:LOGO 春丽.png) 本来想放个这个上去, 不过估计实现起来有点...贵!...
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_584930VERZFI.jpg
(原文件名:春丽.jpg)
估计用三色套印的方法, 也可以, 刮3层丝印上去...嚯嚯 春丽
远看像蚂蚁的屁股戴着手套! 这个要顶一下!!! 回复【59楼】wowbanui
这是我做的logo而已, 没有其他用途,
或者, 铺满了接地应该有覆铜的效果~~
(原文件名:logo.jpg)
看有没有人看得出是什么名堂?
-----------------------------------------------------------------------
CF? 回复【61楼】72hour
春丽
远看像蚂蚁的屁股戴着手套!
-----------------------------------------------------------------------
开始我一直以为是只小蚂蚁,哈哈。 学到挺多的。记号 我想要那个电解电容的封装,给一个吧, 回复【66楼】hy8649241
我想要那个电解电容的封装,给一个吧,
-----------------------------------------------------------------------
电容是邮购部买的,那里阿莫给了封装:
http://www.mailshop.cn/product_detail.jsp?kind=normal&id=3504&class_id=3382&super_id=1650 回复【50楼】wowbanui
那个oled 的升压效率不高, 是个耗电大户, 整个测下来电池那里电流大概260ma左右,
寻思了下版换上这个, 不带背光的lcd(其实是给我拆了), st7565s控制器, 只有128*64
(原文件名:p1020581.jpg)
引用图片
-----------------------------------------------------------------------
我前不久烧写程序的时候木有拔下数据线
结果这个屏就挂了~~~~ 回复【68楼】format
我前不久烧写程序的时候木有拔下数据线
结果这个屏就挂了~~~~
-----------------------------------------------------------------------
下面这个单色的吗?
我烧程序时一直挂着数据线, 没事么~~ 回复【42楼】wowbanui
回复【40楼】format
模块固定方式有搞头
无敌b t 跳线显神通
学习了~~~~
-----------------------------------------------------------------------
好湿好湿
-----------------------------------------------------------------------
真的好湿 LZ好人啊!
赞一个,GPS学习中! 顶
请问楼主,系统别写采用了什么样的结构? 回复【72楼】zoto
顶
请问楼主,系统别写采用了什么样的结构?
-----------------------------------------------------------------------
没太明白意思... mark mark 回复【68楼】format
回复【50楼】wowbanui
那个oled 的升压效率不高, 是个耗电大户, 整个测下来电池那里电流大概260ma左右,
寻思了下版换上这个, 不带背光的lcd(其实是给我拆了), st7565s控制器, 只有128*64
(原文件名:p1020581.jpg)
<a class=tt16 onclick="fnquickimagequote(this,'files_33/ourdev_584847brrcwo.jpg','原文件名:p1020581.jpg')" href="###">引用图片</a>
----------------------------------------------------------------......
-----------------------------------------------------------------------
我那个屏是3.3V的,我用89s52S烧写的时候
屏电源已经拔下,但是还是烧了~~~~~ 中断函数里怎么放了那么多的东东?
比较欣赏模块化的设计。 回复【73楼】wowbanui
-----------------------------------------------------------------------
不好意思
我的意思是有没采用调度器或者操作系统之类 回复【77楼】undeadhuman
中断函数里怎么放了那么多的东东?
比较欣赏模块化的设计。
-----------------------------------------------------------------------
一开始也想设计成中断只负责接收, 然后专门用一个函数处理接收来的字符串, 无奈用的51单片机, 全部接收GPS语句的话内存吃紧,所以改成现在这样的,来之前就先让需要的数据对号入座,回头再挨个应用.
虽然中断里一大堆,但是从上面我画的框图看得出每一次中断实际执行的是其中的一条路线,所以每次执行的代码并不多. 回复【78楼】zoto
-----------------------------------------------------------------------
51单片机,没有操作系统.
main的框图大致如下:
http://cache.amobbs.com/bbs_upload782111/files_33/ourdev_585469OAHINL.png
(原文件名:框图.png) LM3914 要8元那?新版本,怎么样了? 哇靠 这个高端啊。。。什么蓝牙之类的都有。。。 回复【81楼】liouravr
lm3914 要8元那?新版本,怎么样了?
-----------------------------------------------------------------------
我买的9块...
新版本有两个方向,
一种方案是转向STM32平台,如此整个性能提升, TF卡操作更方便, 而且把LM3914省了, 电池电量直接采样电池的电压像手机一样显示在屏幕上(聚合物锂电池电量和电压的关系基本为线性的,一般情况采样电压即可估计剩余电量,LM3914也是量电压),还有更多其他功能,往功能强大耗电多的方向去
另一种是显示屏换成12864的,降低功耗,缩小板子面积,也想将LM3914换掉.往轻便低功耗待机时间长的方向去 回复【82楼】rayz82
哇靠 这个高端啊。。。什么蓝牙之类的都有。。。
-----------------------------------------------------------------------
其实这个我认为是整个板子上最简单的 -- 直接买的模块,布根线和GPS连接,其他什么都没做...
还忘了给蓝牙模块加个开关, 导致现在不用蓝牙它也在那里欢快地闪烁着.... LOGO上的子是CF? s=(GPS_RMC_Data.Latitude-'0')*1000+(GPS_RMC_Data.Latitude-'0')*100+
(GPS_RMC_Data.Latitude-'0')*10+(GPS_RMC_Data.Latitude-'0');
请问楼主:'0',什么意思? 回复【86楼】gyz1990
s=(gps_rmc_data.latitude-'0')*1000+(gps_rmc_data.latitude-'0')*100+
(gps_rmc_data.latitude-'0')*10+(gps_rmc_data.latitude-'0');
请问楼主:'0',什么意思?
-----------------------------------------------------------------------
是ASCII->数值的转换
GPS_RMC_Data.Latitude 里存放的是直接从GPS接收的字符,即 ASCII码值,比如里面存字符'1' 实际值就是 0x31
要得到这个数值的 1 得减去'0' 就是减去 0x30, 来参与运算
否则算出来的是错的 不错,支持一下! 我的第一版也基本完成了,没你的那么大气,属于mini型的
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4253431&bbs_page_no=1&bbs_id=9999 回复【89楼】soulcoffee CC
我的第一版也基本完成了,没你的那么大气,属于mini型的
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4253431&bbs_page_no=1&bbs_id=9999
-----------------------------------------------------------------------
彩屏放在这里太浪费了,我也打算做个低功耗,小型的, 用12864的LCD
交流交流~~
回复【90楼】hameyou
要是加个简单的地图就好了
-----------------------------------------------------------------------
这个51单片机估计没有戏了..
不过加蓝牙就是为这个的, 用S60的手机下个导航软件(如 高明,凯立德),就能通过蓝牙连接到GPS模块上,实现导航 标记学习 mark 很漂亮啊~~~~~~~~~~ 淫的一手好湿 既mark还顶。 125393257 强悍!!~ 强悍!!~ 不错,支持一下!