刚学C写的东西,纪念下:)

2024-01-14 11:08
文章标签 东西 纪念 刚学

本文主要是介绍刚学C写的东西,纪念下:),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这个程序用来模拟从串口读出NMEA协议的数据并校检和解析~~

因为刚用C,C++写代码,写的应该还蛮难看的~~

#include <iostream>
#include <fstream>

#include <sys/select.h>


//author:snail
//070403

typedef unsigned char U8;
typedef signed int S32;
typedef unsigned short int U16;
typedef signed short int S16;
typedef unsigned int U32;



using namespace std;

//##################################################################################
//utility method!!!
//##################################################################################
void millisleep(int ms)                               //sleep some million seconds
{
    if (ms>0) {
        struct timeval tv;
        tv.tv_sec=0;
        tv.tv_usec=ms*1000;
        select(0, 0, 0, 0, &tv);
    }
}

unsigned char Hex2ToUint8(unsigned char *ahex) {
    unsigned char sum,Ch;

    if ((Ch=*ahex++)<='9')
        sum=Ch-'0';
    else
        sum=Ch-'A'+10;
    if ((Ch=*ahex)<='9')
        sum=sum*16+Ch-'0';
    else
        sum=sum*16+Ch-'A'+10;

    return sum;
}

int cstringToInt(char* str,char len) {
    int sum=0;
    for (char i=0; i<len; i++) {
        sum=sum*10+str[i]-'0';
    }
    return sum;
}

double cstringToDouble(char* str,char len) {
    char* dotPtr = strchr(str,'.');
    char intLen = dotPtr - str;
    char douLen = len -intLen -1;
    int douPart = cstringToInt(dotPtr+1,douLen);
    int div = 1;
    for (int i=0;i<douLen;i++) {
        div*=10;
    }
    return cstringToInt(str,intLen)+((double)douPart)/div;
}

double negcstringToDouble(char* str,char len) {
    if (*str=='-')return 0-cstringToDouble(str+1,len-1);
    else return cstringToDouble(str,len);
}

//##################################################################################
//utility method!!!
//##################################################################################









//###################################################################################
// NMEAæpackage checkSumæ
//###################################################################################
bool __gpsCheckSum(unsigned char *buf,unsigned char len) {
    cout << "begine  checkSum!!" << endl;

    unsigned char  i,chksum,value=0;

    chksum=Hex2ToUint8(&buf[len-2]);

    len-=3;
    for (i=1;i<len;i++)
        value^= buf[i];
    if (chksum==value)
        return true;
    return false;
}
//###################################################################################
//###################################################################################
//###################################################################################












//###################################################################################
//###########################struct    userfule data ################################
//###################################################################################
struct _NMEA_DATA {
    S32 Latitude;                     //1/60000 deg
    S32 Longitude;                    //1/60000 deg
    S16 Altitude;                     //mm
    U16 Speed;                        //km/h
    U16 Azimuth;                      //1e-5 deg
    U16 Year;
    U8 Mon;
    U8 Day;
    U8 Hour;
    U8 Min;
    U8 Sec;
    U8 GPSfix;                          //0=no fix,2=2D-fix,3=3D-fix,5=Time only fix
    U8 SVnum;                          //æ
};

void DEBUGINFO(_NMEA_DATA& data) {
    cout << "#######################################################################/n";
    cout << "receive a gps message!/n";
    cout << "Year: " << (int)data.Year <<"/n";
    cout << "Month: " << (int)data.Mon <<"/n";
    cout << "Day: " << (int)data.Day <<"/n";
    cout << "Hour: " << (int)data.Hour << "/n";
    cout << "Minute: " << (int)data.Min << "/n";
    cout << "Sec: " << (int)data.Sec << "/n";
    cout << "Sate: " << (int)data.SVnum << "/n";
    cout <<  "Latitude:"  << data.Latitude << '/n';
    cout <<  "Longitude:"  << data.Longitude << '/n';
    cout <<  "Speed:"   << data.Speed << '/n';
    cout <<  "Azimuth" <<data.Azimuth << '/n';
    cout << "GPSFix: " << ((data.GPSfix==1)?"fix":"notFix") << "/n";
    cout << "Altitude: " << data.Altitude << '/n';
    cout << "#######################################################################/n";
    millisleep(5000);
}
//###################################################################################
//###########################struct    userfule data ################################
//###################################################################################












//############################################################################################
//################################## vitrual    serialPort####################################
//############################################################################################
//############################################################################################
class SmallPort {
public:
    SmallPort(ifstream&stream):in(stream) {};
    int readLine(char *,uint);
    int size();
protected:
    int readBlock(char *,int);
    ifstream& in;
};


int SmallPort::size() {                                    //read 10 char from the serialPort one time
    return 10;
}

int SmallPort::readBlock(char *c,int size) {                //read a char form file
    in.get(*c);
}

int SmallPort::readLine(char *data, uint maxlen) {
    int bytesAvail=(int)size();
    char* pCur=data;

    /*if nothing waiting, return 0 length*/
    if (bytesAvail<1) {
        return 0;
    }

    /*read a byte at a time for MIN(bytesAvail, maxlen) iterations, or until a newline*/
    while (pCur<(data+bytesAvail) && --maxlen) {
        readBlock(pCur, 1);
        if (*pCur++ == '/n') {
            break;
        }
    }
    *pCur++='/0';

    /*return size of data read*/
    return (pCur-data);
}
//############################################################################################
//################################## vitrual serialPort#######################################
//############################################################################################
//############################################################################################


















//############################################################################################
//#####################################PortDataParser#########################################
//############################################################################################
//############################################################################################
class PortDataParser {
public:
    void start();
private:
    void parse();
    int __ggaLength;
    int __rmcLength;
    char __buffer[1000];
    char __ggaBuffer[1000];
    char __rmcBuffer[1000];
};




//###################################################################################
//ä¾startParseNMEADataå
//###################################################################################
void PortDataParser::parse(void) {
    _NMEA_DATA data;

    if (__ggaLength==-1 || __rmcLength==-1) {
        return;
    }

    //**************************************************************
    //ä»$GPGGAç¬ get  the satellite number (between 7-8 comma)¸ª
    //**************************************************************
    {
        char *ptr;
        ptr = __ggaBuffer;
        for (int i=0; i<7; i++) {
            if ((ptr = strchr(ptr+1,','))==NULL) return;
        }
        char* ptrNext=strchr(ptr+1,',');
        if (ptrNext == NULL)return;
        if ( ptrNext-ptr>0) {
            data.SVnum = (U8)cstringToInt(ptr+1, ptrNext-ptr);
        } else {
            data.SVnum = 0;
        }

        ptr=ptrNext+1;

        if ((ptrNext = strchr(ptr,','))==NULL) return;

        ptr=ptrNext+1;

        if ((ptrNext = strchr(ptr,','))==NULL) return;

        if ((ptrNext-ptr)>0) {
            data.Altitude = (S16)negcstringToDouble(ptr,ptrNext-ptr);
        }

    }
    //**************************************************************
    //**************************************************************



    //**************************************************************
    //ä»$GPRMCä
    //**************************************************************
    char *ptr;
    char *ptrNext;
    ptr = __rmcBuffer;
    cout << "/n rmcbuffer->" << ptr;
    if ((ptr = strchr(ptr,',')) == NULL) return;

    ptr++;

    ptrNext=strchr(ptr,',');
    if ((ptrNext-ptr)==9) {
        data.Hour = (U8)cstringToInt(ptr,2);
        data.Min = (U8)cstringToInt(ptr+2,2);
        data.Sec = (U8)cstringToInt(ptr+4,2);
    }


    //第¯GPSæ
    ptr = ptrNext+1;
    if ((ptrNext = strchr(ptr,','))==NULL) return;
    if (*ptr=='A') data.GPSfix=1;
    else data.GPSfix = 0;

    //ç¬longitudeï¼ ddmm.mmmmï¼
    ptr = ptrNext+1;
    if ((ptrNext = strchr(ptr,','))==NULL) return;
    if ((ptrNext-ptr)>0) {
        double d = cstringToDouble(ptr,ptrNext-ptr);
        data.Longitude = (S32)((d-40*((int)d/100))*1000);
    }


    //ç¬(æN or S)
    ptr = ptrNext+1;
    if ((ptrNext = strchr(ptr,','))==NULL) return;
    if (*ptr=='S') data.Longitude = 0 - data.Longitude;


    //ç¬( latitude  ddmm.mmmm)
    ptr = ptrNext+1;
    if ((ptrNext = strchr(ptr,','))==NULL) return;
    if ((ptrNext-ptr)>0) {
        double d = cstringToDouble(ptr,ptrNext-ptr);
        data.Latitude = (S32)((d-40*((int)d/100))*1000);
    }

    //· (E or W)
    ptr = ptrNext+1;
    if ((ptrNext = strchr(ptr,','))==NULL) return;
    if (*ptr=='W') data.Latitude = 0 - data.Latitude;

    //ç(spd,knots )
    ptr = ptrNext+1;
    if ((ptrNext = strchr(ptr,','))==NULL) return;
    if ((ptrNext-ptr)>0) {
        data.Speed = (int)(cstringToDouble(ptr,ptrNext-ptr)*18.42);
    }

    //ç(cog,degrees);
    ptr = ptrNext+1;
    if ((ptrNext = strchr(ptr,','))==NULL) return;
    if ((ptrNext-ptr)>0) {
        data.Azimuth = (int)(cstringToDouble(ptr,ptrNext-ptr)*10);
    }

    //ç¬( ddmmyy);
    ptr = ptrNext+1;
    if ((ptrNext = strchr(ptr,','))==NULL) return;
    if ((ptrNext-ptr)==6) {
        data.Day = (U8)cstringToInt(ptr,2);
        data.Mon= (U8)cstringToInt(ptr+2,2);
        data.Year = (U16)cstringToInt(ptr+4,2);
    }
    //**************************************************************
    //**************************************************************


//---------------------------------------------------------------------------------------------------------------------------------------
    DEBUGINFO(data);
//---------------------------------------------------------------------------------------------------------------------------------------

    __ggaLength = -1;
    __rmcLength = -1;
}

void PortDataParser::start() {
    ifstream in("./data");
    SmallPort testPort(in);

    int time = 0;
    while (time++<=10) {

        cout << "/n/n/n/n/n/n/n  start load ! /n";

        //############################################################################
        //1      load  some chars  from  port  to  __buffer until to  a line
        //############################################################################
        int address=0;
        bool NotMoveToBuffer = true;
        while (NotMoveToBuffer) {
            //int i = __serialPort.readLine(&__buffer[address],MAXLEN_SERIALPORT - address);
            int i = testPort.readLine(&__buffer[address],1000 - address);
            if (i>1) {
                address += i - 1;
            }
            if (i==0 || address > 1 && __buffer[address-1]!='/n') {
                //if (address >= MAXLEN_SERIALPORT)  address = 0;
                millisleep(100);
            } else    {
                NotMoveToBuffer = false;
            }
            cout << "buffer-> " << __buffer << endl << '/n';
        }

        cout << "-----------------------------------------------------------------------------------/n";
        cout << "move " << address << " bytes into buffer!" << "/n";
        cout << "-----------------------------------------------------------------------------------/n";

        //############################################################################
        // 2        start checksum
        //############################################################################
        //æfind the char'$'符ç
        int dollerAddress=-1;
        for (int i=0; i<address-1; i++) {
            if (__buffer[i] == '$' || __buffer[i]=='/n') {
                if (__buffer[i]=='$') {
                    dollerAddress = i;
                }
                break;
            }
        }

        //cout << "find '$' in " << dollerAddress << endl;
        //cout << "__buffer[address-1]" << (int)__buffer[address-1];
        //cout << "__buffer[address-2]" << (int)__buffer[address-2] << "/n";

        if (dollerAddress==-1 || __buffer[address-2]!='/r'
                ||  !__gpsCheckSum((unsigned char *)&__buffer[dollerAddress],address-dollerAddress-2)) {
            cout << "-------------------------------------------------------------------------------------------------/n";
            cout << "The data in buffer is wrong!";
            cout << "-------------------------------------------------------------------------------------------------/n";
            continue;
        }

        cout << "-----------------------------------------------------------------------------------------------------/n";
        cout << "The data in buffer is valid!";
        cout << "-----------------------------------------------------------------------------------------------------/n";

        //############################################################################
        //  3 move useful data to other buffers!
        //############################################################################
        bool parseNMEAData = false;
        if (strncmp(&__buffer[dollerAddress],"$GPGGA",6)==0) {
            __ggaLength = address-dollerAddress;
            strncpy(__ggaBuffer,&__buffer[dollerAddress],__ggaLength);
            __ggaBuffer[__ggaLength]='/0';
        } else if (strncmp(&__buffer[dollerAddress],"$GPRMC",6)==0) {
            __rmcLength =  address-dollerAddress;
            strncpy(__rmcBuffer,&__buffer[dollerAddress],__rmcLength);
            __rmcBuffer[__rmcLength]='/0';
            parseNMEAData = true;
        } else {
            continue;
        }

        //#############################################################################
        // 4 start parse!
        //#############################################################################

        if (parseNMEAData) {
            parse();
        }
    }
}



int main() {
    PortDataParser parse;
    parse.start();
    return 0;
}



这是NMEA协议的数据
$GPGSV,3,1,11,02,52,114,49,26,60,206,48,42,46,143,41,04,13,123,45*7D
$GPGSV,3,2,11,29,77,199,47,07,29,298,,06,38,283,18,08,21,073,*7C
$GPGSV,3,3,11,27,11,047,,24,42,320,27,10,56,023,*48
$GPGLL,3201.85399,N,11849.58941,E,055602.00,A,A*67
$GPZDA,055602.00,25,03,2007,00,00*63
$GPRMC,055603.00,A,3201.85411,N,11849.58933,E,0.003,,250307,,,A*7D
$GPVTG,,T,,M,0.003,N,0.005,K,A*25
$GPGGA,055603.00,3201.85411,N,11849.58933,E,1,05,3.02,49.9,M,5.3,M,,*57
$GPGSA,A,3,02,26,04,29,06,,,,,,,,3.59,3.02,1.93*08
$GPGSV,3,1,11,02,52,114,49,26,60,206,48,42,46,143,40,04,13,124,44*7A
$GPGSV,3,2,11,29,77,199,47,07,29,298,,06,38,283,16,08,21,073,*72
$GPGSV,3,3,11,27,11,047,,24,42,320,26,10,56,023,*49
$GPGLL,3201.85411,N,11849.58933,E,055603.00,A,A*64
$GPZDA,055603.00,25,03,2007,00,00*62
$GPRMC,055604.00,A,3201.85424,N,11849.58925,E,0.024,143.86,250307,,,A*68
$GPVTG,143.86,T,,M,0.024,N,0.044,K,A*33
$GPGGA,055604.00,3201.85424,N,11849.58925,E,1,05,3.03,49.7,M,5.3,M,,*5E
$GPGSA,A,3,02,26,04,29,06,,,,,,,,3.59,3.03,1.93*09
$GPGSV,3,1,11,02,52,114,49,26,60,206,48,42,46,143,41,04,13,124,44*7B
$GPGSV,3,2,11,29,77,199,47,07,29,298,,06,38,283,14,08,21,073,*70
$GPGSV,3,3,11,27,11,047,,24,42,320,27,10,56,023,*48
$GPGLL,3201.85424,N,11849.58925,E,055604.00,A,A*62
$GPZDA,055604.00,25,03,2007,00,00*65
$GPRMC,055605.00,A,3201.85438,N,11849.58918,E,0.009,,250307,,,A*73
$GPVTG,,T,,M,0.009,N,0.016,K,A*2D
$GPGGA,055605.00,3201.85438,N,11849.58918,E,1,05,3.03,49.5,M,5.3,M,,*5E


程序运行后的结果
#######################################################################
receive a gps message!
Year: 7
Month: 3
Day: 25
Hour: 5
Minute: 56
Sec: 4
Sate: 46
Latitude:7129589
Longitude:1921854
Speed:0
Azimuth1438
GPSFix: fix
Altitude: 49
#######################################################################

这篇关于刚学C写的东西,纪念下:)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/604939

相关文章

【新东西】链接合集

1、RxJava。 基础介绍:http://www.jianshu.com/p/5e93c9101dc5 详细介绍:http://gank.io/post/560e15be2dca930e00da1083 方法介绍:https://zhuanlan.zhihu.com/p/21926591 2、Retrofit。网络请求框架,外包代码里用的这个。 简单介绍:http://blog.csd

发现个有趣的东西:Tweetable Mathematical Art(用三个140字符以内的函数生成一个1024尺寸的图片)

发现 我是在看《构建之法》这本书时,看到作者提到这个: 好厉害!用三段140字符以内的代码生成一张1024×1024的图片_IT新闻_博客园 这是2014年一个人在 Code Golf Stack Exchange (a question and answer site for programming puzzle enthusiasts and code golfers) 发起的编程挑战:

纪念一下第二个assignment 100分

感悟就是:坚持,才能从good到great。精益求精就是要不断打磨产品。 Princeton的课就是好,一个作业可以牵扯到很多算法。复习了shuffle算法和Resevoir Sampling算法,还有linkedin,array implement deque,iterator的用法,确实不错的课程,经典就是经典!刷题不在乎刷题数目多少,而在于刷背后知识点的深度和广度。加油!我觉得我刷完A

纪念一下自己的Coursera Princeton Algorithm的课程第一个assignment

今天终于完成了第一个Union-Find的assignment,之前觉得特别的难,可是最后自己也搞定了。而且是100%满分。 自己后来plot了一下自己的分数,也许这就是学习曲线吧。刚开始不会,到后来中期显著提高,但是要到100%,那就要经历更多的波折,甚至是下降都有可能。最后才能达到100%满分。 我觉得最有用的还是下面这段源代码: /*************************

六西格玛是什么东西

我看到这个名词是我在查minitab的相关用法的时候看到的。 这个理论是摩托罗拉的某人提出的,用于衡量制造业的制造水平: 一下为MBA智库的相关信息:   6個西格瑪=3.4失誤/百萬機會―意味著卓越的管理,強大的競爭力和忠誠的客戶   5個西格瑪=230失誤/百萬機會-優秀的管理、很強的競爭力和比較忠誠的客戶   4個西格瑪=6,210失誤/百萬機會-意味著較好的

app逆向1-实战里常见东西

幕布链接:app逆向1-实战里常见东西 - 幕布

挖一挖C#中那些我们不常用的东西之系列(2)——IsXXX 系列方法

不知道有人做没做过对日外包,如果做过的话,那么对vb.net应该非常熟悉了,当年我刚毕业的时候也做过四个月的外包,那种日子简直 不是人过的,就连大楼下面买珠宝的阿姨都说,这些孩子,只看过他们上班,就没见过他们下班,不过有一点好,有个QA的小姑娘天天下午6 点教我们倭瓜语,现在还在勾搭中。。。     好了,现在我们看看需求。   一: 如何判断“a”是不是数字类型。

秋冬春夏,纪念在CSDN的第365天

目录 时光 收获 工作 生活 憧憬 时光 再次收到创作纪念日的消息时,已在CSDN创作和度过了一年的时光。创作,成了自己的第二工作空间,成为了日常的一种习惯。 每当看到第1篇文章的提醒消息,都会想起当时创作的初衷和情景。是一种宣泄也好,是一种证明也好,时光,是沉淀情绪最好的良药。 收获 一年了,我身后的竹子都已经长成一片竹林了,看着它们茁壮的成长,也彷佛看到了自

(待更)将windows11配置成生产力高的电脑:当计算机新生的你拿到新电脑时该配置哪些东西(python、mysql、git)

常见开发软件下载 接口工具:apifox 文本工具:obsidian 云盘:百度云盘 浏览器:Microsoft Edge、google chrome 其他:腾讯会议、腾讯桌面整理 显示文件后缀 http://t.csdnimg.cn/FBypl Python相关 配置pyenv http://t.csdnimg.cn/nBXvY 替换pip源 https://segmentfau

简单的mail发送邮件里面的更多东西-postfix-exim MTA试验以及linux下使用mail发送邮件的简单实现

一、简单的mail发送邮件里面的更多东西-postfix-exim MTA试验      publish:September 27, 2018 -Thursday mail发送邮件应该是一个常用的东西,但是从简单的东西切入,也许你会有更多的收获。今天再看了看mail发邮件的东西,真的一个很小的知识点但要弄透不下功夫真的是不行的。先了解下面两个东西: 邮件用户代理(MUA,Mail User A