国产久操视频-国产久草视频-国产久热精品-国产久热香蕉在线观看-青青青青娱乐-青青青青在线成人视99

  • 方案介紹
    • 一,項(xiàng)目名稱
    • 二,項(xiàng)目概述
    • 三,硬件部分
    • 四,系統(tǒng)框架
    • 五,軟件部分
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

基于樹莓派5的簡易汽車儀表盤

05/29 09:40
233
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

一,項(xiàng)目名稱

基于樹莓派5的簡易汽車儀表盤

二,項(xiàng)目概述

** **本項(xiàng)目主要應(yīng)用于車載娛樂方面,因此,本項(xiàng)目致力于設(shè)計(jì)一款創(chuàng)新的車載中控面板,集成了多種先進(jìn)技術(shù),包括OBD(車載診斷系統(tǒng))、衛(wèi)星定位陀螺儀和后視影像系統(tǒng)。這款中控面板不僅能夠?qū)崟r(shí)監(jiān)測車輛的運(yùn)行狀態(tài)和故障信息,還能提供精準(zhǔn)的定位服務(wù),確保駕駛者在行駛過程。

三,硬件部分

主控:

  • 樹莓派5

image20250302224741230.png

  • 先楫HPM5361

image20250302224827063.png
傳感器:

-**GPS模塊-ATGM332D-5N-11-0 **

-mpu6050

-oled

-蜂鳴器

-sht30溫濕度傳感器

-usb攝像頭

實(shí)物圖如下:

image20250302225356816.png
詳細(xì)原理圖如下:

-電源部分

采用矽力杰的SY8089A1AAC高效1.5MHz 2A同步降壓調(diào)節(jié)器。

image20250302225624673.png
充電部分

采用wsp4056,輸出電壓 4.2V 輸入電壓 4.0-8.0V 最大充電電流 1000ma

image20250302225912055.png

蜂鳴器部分

image20250302230013219.png

mpu6050

image20250302230031490.png

GNSS

image20250302230043985.png

CAN

采用NXP的TJA1050T,can收發(fā)器

image20250302230056667.png

OLED

image20250302230228304.png

溫濕度計(jì)

image20250302230305520.png

四,系統(tǒng)框架

五,軟件部分

OBD協(xié)議解析

void CAN_RxBytes(void)
{
	unsigned char data[8];
	uint16_t pid  = 0;
	uint8_t data1 = 0;
	uint8_t data2 = 0;
	int16_t value;
	bool status;
	/*-------------------------------------mxz add------------------------------------*/

	send_pid(PID,7);
	status=CAN_ReceiveBytes(CAN,8,data,8);	// frameSize from 1 to 8
	pid  = data[2];
	data1 = data[3];
	data2 = data[4];
	if (status)
	{
		switch (pid)
		{
			case PID_RPM://轉(zhuǎn)速
				value = (data2 | data1 << 8) / 4;
				g_odb_message.rpm = value * g_parm_config.RPM_config / 100;
//				LTPrintf("PID_RPM %d n",value);
				break;
			case PID_SPEED://車速
				value = data1 ;
//				LTPrintf("PID_SPEED :%dn",value);
				if(g_parm_config.Speed_Src == 0)//速度來自GPS
				{
					g_odb_message.speed = gpsx.SOGK * g_parm_config.speed_config / 100;
				}else
				{
					g_odb_message.speed = value * g_parm_config.speed_config / 100;
				}
				break;
			case PID_DISTANCE: // km//表示總行駛里程
				value = (data2 | data1 << 8) ;
				g_odb_message.Distance = value;
//				LTPrintf("PID_DISTANCE :%dn",value);
				break;
			case PID_CONTROL_MODULE_VOLTAGE: // 表示控制模塊的電壓,通常用于監(jiān)控電源狀態(tài)。 v
				value = (data2 | data1 << 8) / 1000;
				g_odb_message.Control_Module_Voltage = value;
//				LTPrintf("PID_CONTROL_MODULE_VOLTAGE :%dn",value);
				break;
			case PID_ENGINE_FUEL_RATE: // L/h	 //表示單位時(shí)間內(nèi)的燃油消耗量(通常以升每小時(shí)或加侖每小時(shí)為單位)。
				value = (data2 | data1 << 8) / 20;
				g_odb_message.engine_fuel_rate = value;
//				LTPrintf("PID_ENGINE_FUEL_RATE :%dn",value);
				break;
			case PID_EVAP_SYS_VAPOR_PRESSURE: // kPa 表示蒸發(fā)系統(tǒng)內(nèi)的氣壓,通常用于監(jiān)測油箱的密封性。
				value = (data2 | data1 << 8) / 4;
				g_odb_message.map = value * g_parm_config.MAP_config / 100;
//				LTPrintf("PID_EVAP_SYS_VAPOR_PRESSURE :%dn",value);
				break;
			case PID_COOLANT_TEMP: // 水溫
				value =  data1 - 40;
				g_odb_message.coolant_temp = value;
//				LTPrintf("PID_COOLANT_TEMP :%dn",value);
				break;
#if 0
			case PID_FUEL_PRESSURE: // kPa
				value = data1 * 3;
				break;
			case PID_COOLANT_TEMP:
			case PID_INTAKE_TEMP:
			case PID_AMBIENT_TEMP:
			case PID_ENGINE_OIL_TEMP:
				value = data1 - 40;
				break;
			case PID_THROTTLE:
			case PID_COMMANDED_EGR:
			case PID_COMMANDED_EVAPORATIVE_PURGE:
			case PID_FUEL_LEVEL:
			case PID_RELATIVE_THROTTLE_POS:
			case PID_ABSOLUTE_THROTTLE_POS_B:
			case PID_ABSOLUTE_THROTTLE_POS_C:
			case PID_ACC_PEDAL_POS_D:
			case PID_ACC_PEDAL_POS_E:
			case PID_ACC_PEDAL_POS_F:
			case PID_COMMANDED_THROTTLE_ACTUATOR:
			case PID_ENGINE_LOAD:
			case PID_ABSOLUTE_ENGINE_LOAD:
			case PID_ETHANOL_FUEL:
			case PID_HYBRID_BATTERY_PERCENTAGE:
				value = data1 * 100 / 255;
				break;
			case PID_MAF_FLOW: // grams/sec
				value = (data2 | data1 << 8) / 100;
				break;
			case PID_TIMING_ADVANCE:
				value = (data1 / 2) - 64;
				break;
			case PID_DISTANCE_WITH_MIL: // km
			case PID_TIME_WITH_MIL: // minute
			case PID_TIME_SINCE_CODES_CLEARED: // minute
			case PID_RUNTIME: // second
			case PID_FUEL_RAIL_PRESSURE: // kPa
			case PID_ENGINE_REF_TORQUE: // Nm
				value = (data2 | data1 << 8);
				break;
			case PID_CONTROL_MODULE_VOLTAGE: // V
				value = (data2 | data1 << 8) / 1000;
				break;
			case PID_ENGINE_FUEL_RATE: // L/h
				value = (data2 | data1 << 8) / 20;
				break;
			case PID_ENGINE_TORQUE_DEMANDED: // %
			case PID_ENGINE_TORQUE_PERCENTAGE: // %
				value = data1 - 125;
				break;
			case PID_SHORT_TERM_FUEL_TRIM_1:
			case PID_LONG_TERM_FUEL_TRIM_1:
			case PID_SHORT_TERM_FUEL_TRIM_2:
			case PID_LONG_TERM_FUEL_TRIM_2:
			case PID_EGR_ERROR:
				value = (data1 * 100 / 128) - 100;
				break;
			case PID_FUEL_INJECTION_TIMING:
				value = ((data2 | data1 << 8) / 128) - 210;
				break;
			case PID_CATALYST_TEMP_B1S1:
			case PID_CATALYST_TEMP_B2S1:
			case PID_CATALYST_TEMP_B1S2:
			case PID_CATALYST_TEMP_B2S2:
				value = ((data2 | data1 << 8) / 10) - 40;
				break;
			case PID_AIR_FUEL_EQUIV_RATIO: // 0~200
				value = (data2 | data1 << 8) * 2 / 65536;
				break;
#endif
			default:
				break;
		}
	}
}

GNSS數(shù)據(jù)解析

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-03-02     Administrator       the first version
 */
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
/*******************************************************************************************/
#include "gps.h"
#include <string.h>


nmea_msg gpsx;
/**
 * @brief       NMEA_Comma_pos 從buf里面得到第n個(gè)逗號所在的位置
 * @argument    數(shù)組
 * @argument    地n個(gè)','
 * @return      逗號的位置
 */
#if 1
 u8 NMEA_Comma_Pos(u8 *buf,u8 n)
 {
     u8 *ptr = buf;
     while(n)
     {
         //遇到'*'或者非法字符,則不存在第cx個(gè)逗號
         if(*ptr == '*' || *ptr < ' '|| *ptr > 'z')return 0xFF;
         if(*ptr == ',')n--;
         ptr++;
     }
     return ptr-buf;
 }
 /**
  * @brief  NMEA_Pow    m^n次方
  */
 u32 NMEA_Pow(u8 m,u8 n)
 {
     u32 result =1;
     while(n--)result *= m;
     return result;
 }
 /**
  * @brief      字符串轉(zhuǎn)數(shù)字
  */
 int NMEA_Str2Num(u8 *buf,u8*dx)
 {
     u8 *p = buf;
     u32 ires=0,fres=0;
     u8 ilen = 0,flen =0,i;
     u8 mask=0;
     int res;
     /*********得到個(gè)位十位***************/
     while(1)
     {
         if(*p == '-')
         {
             mask |= 0x02;
             p++;
         }
         if(*p == ',' || *p == '*')break;
         if(*p == '.')
         {
             mask |= 0x01;
             p++;
         }
         else if((*p >'9') || (*p < '0'))
         {
             ilen=0;
             flen=0;
             break;
         }
         if(mask & 0x01)flen++;//小數(shù)
         else ilen++;//整數(shù)
         p++;
     }
     if(mask&0x02)buf++;
     for(i = 0;i<ilen;i++)
     {
         ires += NMEA_Pow(10,ilen-1-i)*(buf[i]-'0');
         //LTPrintf("buf[%d]:%d ,ires:%dn",i,(buf[i]-'0'),ires);
     }
     if(flen>5)flen = 5;
     *dx = flen;
     for(i=0;i<flen;i++)
     {
         fres += NMEA_Pow(10,flen-1-i)*(buf[ilen+1+i]-'0');
     }
     //LTPrintf("ilen:%d flen%d ires:%d fres:%dn",ilen,flen,ires,fres);
     res = ires*NMEA_Pow(10,flen)+fres;
     if(mask&0x02)res = -res;
     return res;
 }
/**
 * @brief       分析GPGSV信息信息
 * @argument    nmea信息結(jié)構(gòu)體
 * @argument    buf接收數(shù)據(jù)的緩存區(qū)地址
 * @return      無?
 * @note        GSV表示可視的GNSS衛(wèi)星。本語句包含可視的衛(wèi)星數(shù)、衛(wèi)星標(biāo)識號、仰角、方位角和信噪比。每次傳送,
 *              一個(gè)GSV語句只能包含最多4顆衛(wèi)星的數(shù)據(jù),
 *              因此可能需要多個(gè)語句才能獲得完整的信息。由于GSV包含的衛(wèi)星不用于定位解決方案,所以GSV語句指示的衛(wèi)星可能比GGA多。
 * @note        “GN”標(biāo)識符不可用于該語句。如果可以多個(gè)衛(wèi)星系統(tǒng)可視,則設(shè)備輸出多條GSV語句,用不同的發(fā)送設(shè)備標(biāo)識符表示相應(yīng)的衛(wèi)星。
 **/
void NMEA_GPGSV_Analysis(nmea_msg *gpsx,u8 *buf)
{
    u8 *p,*p1,dx;
    u8 len,i,j,slx = 0;
    u8 posx;
    p = buf;
    p1 = (u8*)strstr((const char*)p,"$GPGSV");
    len = p1[7] - '0';                                  //得到GPGSV的條數(shù)語句總數(shù)。范圍:1~9。
    posx=NMEA_Comma_Pos(p1,3);                          //得到可見衛(wèi)星總數(shù)
    if(len!=0xFF)gpsx->svnum = NMEA_Str2Num(p1+posx,&dx);
    for(i=0;i<len;i++)
    {
        p1 = (u8*)strstr((const char*)p,"$GPGSV");
        for(j=0;j<4;j++)
        {
            posx=NMEA_Comma_Pos(p1,4+j*4);
            if(posx!=0xFF)gpsx->slmsg[slx].num = NMEA_Str2Num(p1+posx,&dx);//得到衛(wèi)星編號
            else    break;
            posx=NMEA_Comma_Pos(p1,5+j*4);
            if(posx!=0xFF)gpsx->slmsg[slx].eledeg= NMEA_Str2Num(p1+posx,&dx);//得到衛(wèi)星仰角
            else    break;
            posx=NMEA_Comma_Pos(p1,6+j*4);
            if(posx!=0xFF)gpsx->slmsg[slx].azideg = NMEA_Str2Num(p1+posx,&dx);//得到衛(wèi)星方位角
            else    break;
            posx=NMEA_Comma_Pos(p1,7+j*4);
            if(posx!=0xFF)gpsx->slmsg[slx].sn = NMEA_Str2Num(p1+posx,&dx);//得到衛(wèi)星信噪比
            else    break;
            slx++;
        }
    }
}
/**
 * @brief       分析GPGGA信息
 * @argument    nmea信息結(jié)構(gòu)體
 * @argument    buf接收數(shù)據(jù)的緩存區(qū)地址
 * @return      無?
 * @note        GGA提供全球定位系統(tǒng)定位數(shù)據(jù)。本語句包含GNSS接收機(jī)提供的時(shí)間、位置和定位相關(guān)數(shù)據(jù)
 *  1.QZSS和GPS星系配置下<TalkerID>均為GP;有關(guān)衛(wèi)星標(biāo)識符的詳情,請參考表16:GNSS標(biāo)識符。
 *  2. NMEA 0183協(xié)議指示GGA消息為GPS系統(tǒng)特有;但當(dāng)接收器配置為多星系時(shí),GGA消息的內(nèi)容將從多星系解決方案中生成。
 *  3. 1) NMEA 0183協(xié)議定義的使用中衛(wèi)星數(shù)量范圍為00~12,然而,在多星系解決方案中,使用的衛(wèi)星數(shù)量可能超過12顆。
 **/
void NMEA_GPGGA_Analysis(nmea_msg *gpsx,u8 *buf)
{
    u8 *p1,dx;
    u8 posx;
    p1 = (u8*)strstr((const char*)buf,"$GNGGA");
    posx = NMEA_Comma_Pos(p1,1);//得到日期
    if(posx != 0xFF)
    {
        int temp = NMEA_Str2Num(p1+posx,&dx);
        gpsx->utc.sec = (temp / 1000) % 10;
        gpsx->utc.min = (temp / 100000) %100;
        gpsx->utc.hour = temp / 10000000;
    }

    posx = NMEA_Comma_Pos(p1,2);NMEA_Str2Num;
    if(posx!=0xFF)
    {
        int temp = NMEA_Str2Num(p1+posx,&dx);
        //LTPrintf("temp:%d dx:%dn",temp,dx);
        gpsx->latitude = temp / NMEA_Pow(10,dx+2);//得到°
        float rs = temp%NMEA_Pow(10,dx+2);            //得到'
        gpsx->latitude=gpsx->latitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//轉(zhuǎn)換為°
    }
    posx = NMEA_Comma_Pos(p1,3);//南緯還是北緯
    if(posx!=0xFF)gpsx->nshemi = *(p1+posx);
    posx = NMEA_Comma_Pos(p1,4);//得到經(jīng)度
    if(posx!=0xFF)
    {
        int temp = NMEA_Str2Num(p1+posx,&dx);
        gpsx->longitude = temp / NMEA_Pow(10,dx+2);
        float rs = temp%NMEA_Pow(10,dx+2);
        gpsx->longitude = gpsx->longitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;
    }
    posx = NMEA_Comma_Pos(p1,5);//東經(jīng)還是**
    if(posx!=0xFF)gpsx->ewhemi = *(p1+posx);

    posx = NMEA_Comma_Pos(p1,6);                //GPS狀態(tài):0,未定位;1,非差分定位;2,差分定位;6,正在估算.
    if(posx!=0XFF)gpsx->gpssta = NMEA_Str2Num(p1+posx,&dx);
    posx = NMEA_Comma_Pos(p1,7);                //使用的衛(wèi)星數(shù)。
    if(posx!=0xFF)gpsx->posslnum = NMEA_Str2Num(p1+posx,&dx);
    posx = NMEA_Comma_Pos(p1,9);                //得到海拔高度
    if(posx != 0xFF)gpsx->altitude = NMEA_Str2Num(p1+posx,&dx);
}
/**
 * @brief       分析GPGSA信息
 * @argument    nmea信息結(jié)構(gòu)體
 * @argument    buf接收數(shù)據(jù)的緩存區(qū)地址
 * @return      無?
 * @note        GSA表示GNSS精度因子(DOP)與有效衛(wèi)星。本語句包含GNSS接收機(jī)工作模式,GGA或GNS
語句報(bào)告的導(dǎo)航解算中用到的衛(wèi)星以及精度因子的值。
 **/
void NMEA_GPGSA_Analysis(nmea_msg *gpsx,u8 *buf)
{
    u8 *p1,dx;
    u8 posx,i;
    //LTPrintf("===============NMEA_GPGSA_Analysis=======================rn");
    p1 = (u8*)strstr((const char*)buf,"$GNGSA");
    //LTPrintf("p1:%p   buf:%prn",p1,buf);
    posx = NMEA_Comma_Pos(p1,2);    //得到定位類型
    //LTPrintf("posx:%drn",posx);
    if(posx!=0xFF)gpsx->fixmode = NMEA_Str2Num(p1+posx,&dx);
    for(i=0;i<12;i++)//得到定位衛(wèi)星編號
    {
        posx = NMEA_Comma_Pos(p1,3+i);
        if(posx!=0xFF)gpsx->possl[i] = NMEA_Str2Num(p1+posx,&dx);
        else break;
    }
    posx = NMEA_Comma_Pos(p1,15);//位置精度因子
    if(posx != 0xFF)gpsx->pdop = NMEA_Str2Num(p1+posx,&dx);
    posx = NMEA_Comma_Pos(p1,16);//水平精度因子
    if(posx != 0xFF)gpsx->hdop = NMEA_Str2Num(p1+posx,&dx);
    posx = NMEA_Comma_Pos(p1,17);//垂直精度因子
    if(posx != 0xFF)gpsx->vdop = NMEA_Str2Num(p1+posx,&dx);
}
/**
 * @brief       分析GPRMC信息
 * @argument    nmea信息結(jié)構(gòu)體
 * @argument    buf接收數(shù)據(jù)的緩存區(qū)地址
 * @return      無?
 * @note        RMC表示推薦的最少專用GNSS數(shù)據(jù)。本語句包含GNSS接收機(jī)提供的時(shí)間、日期、位置、航跡向
和速度數(shù)據(jù)。
 **/
void NMEA_GPRMC_Analysis(nmea_msg *gpsx,u8 *buf)
{
    u8 *p1,dx,posx;
    u32 temp;
    float rs;
    p1 = (u8 *)strstr((const char*)buf,"GNRMC");//"$GPRMC",經(jīng)常有&和GPRMC分開的情況,故只判斷GPRMC.
    //LTPrintf("buf:%p  p1:%pn",buf,p1);
    //LTPrintf("buf:%s  p1:%sn",buf,p1);
    posx = NMEA_Comma_Pos(p1,1);//獲取時(shí)間,不要ms
    //LTPrintf("posx:%d ",posx);
    if(posx!=0xFF)
    {
        temp = NMEA_Str2Num(p1+posx,&dx) / NMEA_Pow(10,dx);
        //LTPrintf("temp:%d dx:%dn",temp,dx);
        gpsx->utc.hour = temp/10000;
        gpsx->utc.min = (temp /100) %100;
        gpsx->utc.sec = temp % 100;
    }
    posx = NMEA_Comma_Pos(p1,3);NMEA_Str2Num;
    if(posx!=0xFF)
    {
        temp = NMEA_Str2Num(p1+posx,&dx);
        //LTPrintf("temp:%d dx:%dn",temp,dx);
        gpsx->latitude = temp / NMEA_Pow(10,dx+2);//得到°
        rs = temp%NMEA_Pow(10,dx+2);            //得到'
        gpsx->latitude=gpsx->latitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//轉(zhuǎn)換為°
    }
    posx = NMEA_Comma_Pos(p1,4);//南緯還是北緯
    if(posx!=0xFF)gpsx->nshemi = *(p1+posx);
    posx = NMEA_Comma_Pos(p1,5);//得到經(jīng)度
    if(posx!=0xFF)
    {
        temp = NMEA_Str2Num(p1+posx,&dx);
        gpsx->longitude = temp / NMEA_Pow(10,dx+2);
        rs = temp%NMEA_Pow(10,dx+2);
        gpsx->longitude = gpsx->longitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;
    }
    posx = NMEA_Comma_Pos(p1,6);//東經(jīng)還是**
    if(posx!=0xFF)gpsx->ewhemi = *(p1+posx);
    posx = NMEA_Comma_Pos(p1,9);//得到日期
    if(posx != 0xFF)
    {
        temp = NMEA_Str2Num(p1+posx,&dx);
        gpsx->utc.date = temp / 10000;
        gpsx->utc.month = (temp / 100) %100;
        gpsx->utc.year = 2000 + temp % 100;
    }
}
/**
 * @brief       分析GPVTG信息
 * @argument    nmea信息結(jié)構(gòu)體
 * @argument    buf接收數(shù)據(jù)的緩存區(qū)地址
 * @return      無?
 * @note        VTG語句包含相對于地面的實(shí)際航向和速度
 **/
void NMEA_GPVTG_Analysis(nmea_msg *gpsx,u8 *buf)
{
    u8 *p1,dx,posx;
    p1 = (u8*)strstr((const char*)buf,"$GNVTG");
    posx = NMEA_Comma_Pos(p1,1);//<COGT 對地航向(真北)
    if(posx!=0xFF)gpsx->cogt = NMEA_Str2Num(p1+posx,&dx) / NMEA_Pow(10,dx);
    posx = NMEA_Comma_Pos(p1,5);//對地速度 節(jié)
    if(posx!=0xFF)
    {
        gpsx->SOGN = NMEA_Str2Num(p1+posx,&dx) / NMEA_Pow(10,dx);

    }
    posx = NMEA_Comma_Pos(p1,7);//對地速度 km/h
    gpsx->SOGK = NMEA_Str2Num(p1+posx,&dx) / NMEA_Pow(10,dx);
}
/**
 * @brief       提取NMEA-0183信息
 * @argument    nmea信息結(jié)構(gòu)體
 * @argument    buf接收數(shù)據(jù)的緩存區(qū)地址
 * @return      無?
 * @note
 **/

void GPS_Analysis(nmea_msg *gpsx,u8 *buf)
{
    NMEA_GPGSV_Analysis(gpsx,buf);  //GPGSV解析
    NMEA_GPGGA_Analysis(gpsx,buf);  //GPGGA解析
    NMEA_GPGSA_Analysis(gpsx,buf);  //GPGSA解析
    NMEA_GPRMC_Analysis(gpsx,buf);  //GPRMC解析
    NMEA_GPVTG_Analysis(gpsx,buf);  //GPVTG解析
}
/**
 * @brief       GPS校驗(yàn)和計(jì)算
 * @argument
 * @argument
 * @return      無?
 * @note
 **/
void GPS_CheckSum(u8*buf,u8*checksum)
{
    *checksum = 0;
    u8 *ptr = buf;
    const char *start = strchr(ptr,'$');
    const char *end   = strchr(ptr,'*');
    if(start == NULL || end == NULL || (start >= end))return;
    for(ptr = (u8 *)(start + 1);ptr < (u8 *)end;ptr++)
    {
        *checksum ^= *ptr;
    }
}
/*-----------------------------------------PCAS_---------------------------*/
/**
 * @brief       配置NMEA串口波特率
 * @argument
 * @argument
 * @return      無?
 * @note
 **/
//void PCAS01(u8 *buf,u8 baud)
//{
//  u8 *ptr = "$PCAS01,1*";
//  u8 len = strlen(ptr);
//  memncpy(ptr,buf,len-1);
//
//}
#endif


/****************************************************************************************/
#define SAMPLE_UART_NAME                 "uart2" /* 串口設(shè)備名稱 */

struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;  /* 初始化配置參數(shù) */

/* 用于接收消息的信號量 */
static struct rt_semaphore rx_sem;
static rt_device_t serial;


u16 RXD_index;
u8 RX_BUF[800];

//接收數(shù)據(jù)回調(diào)函數(shù)
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
    /* 串口接收到數(shù)據(jù)后產(chǎn)生中斷,調(diào)用此回調(diào)函數(shù),然后發(fā)送接收信號量 */
    if (size > 0)
   {
        rt_sem_release(&rx_sem);
   }
    return RT_EOK;
}

static void serial_thread_entry(void *parameter)
{
    char ch;

    while (1)
    {
        rt_sem_take(&rx_sem, RT_WAITING_FOREVER); // 等待信號量

        // 循環(huán)讀取可用數(shù)據(jù)
        while (rt_device_read(serial, 0, &ch, 1) == 1)
        {
            // 存儲接收到的數(shù)據(jù)
            if (RXD_index < (sizeof(RX_BUF) - 1)) // 確保不會超出緩沖區(qū)大小
            {
                RX_BUF[RXD_index++] = ch;
            }
            else
            {
               GPS_Analysis(&gpsx, RX_BUF);
               RX_BUF[RXD_index++] = '';
               for(int i = 0;i<RXD_index;i++)
                   rt_kprintf("%c",RX_BUF[i]);
//               rt_kprintf("%s",RX_BUF);
               rt_kprintf("n-----------------------------------------------n");
               rt_kprintf("GPS Analysis Result:n");
               rt_kprintf("Year: %dn", gpsx.utc.date);
               rt_kprintf("Month: %dn", gpsx.utc.month);
               rt_kprintf("Date: %dn", gpsx.utc.date);
               rt_kprintf("hour: %dn", gpsx.utc.hour);
               rt_kprintf("min: %dn", gpsx.utc.min);
               rt_kprintf("sec: %dn", gpsx.utc.sec);
//               rt_kprintf("Longitude: %.6fn", (float)gpsx.longitude / 100000.0);
//               rt_kprintf("Latitude: %.6fn", (float)gpsx.latitude / 100000.0);
               printf("Longitude: %.6fn", (float)gpsx.longitude / 100000.0);
               printf("Latitude: %.6fn", (float)gpsx.latitude / 100000.0);
               RXD_index = 0; // 處理完后重置索引

            }
        }

    }
}
/**
  * @brief  thread_serial
  * @param  None
  * @retval ret
  */
int GPS_serial(void)
{
    rt_err_t ret = RT_EOK;
    char uart_name[RT_NAME_MAX];
    char str[] = "hello RT-Thread!rn";

    rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);

    /* 查找系統(tǒng)中的串口設(shè)備 */
    serial = rt_device_find(uart_name);
    if (!serial)
    {
        rt_kprintf("find %s failed!n", uart_name);
        return RT_ERROR;
    }
    /* 修改串口配置參數(shù) */
    config.baud_rate = BAUD_RATE_9600;        //修改波特率為 115200
    config.data_bits = DATA_BITS_8;           //數(shù)據(jù)位 8
    config.stop_bits = STOP_BITS_1;           //停止位 1
    config.parity    = PARITY_NONE;           //無奇偶校驗(yàn)位

    /* 控制串口設(shè)備。通過控制接口傳入命令控制字,與控制參數(shù) */
    rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);

    /* 初始化信號量 */
    rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
    /* 以中斷接收及輪詢發(fā)送模式打開串口設(shè)備 */
    rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
    /* 設(shè)置接收回調(diào)函數(shù) */
    rt_device_set_rx_indicate(serial, uart_input);
    /* 發(fā)送字符串 */
    rt_device_write(serial, 0, str, (sizeof(str) - 1));

    /* 創(chuàng)建 serial 線程 */
    rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);
    /* 創(chuàng)建成功則啟動線程 */
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        ret = RT_ERROR;
    }

    return ret;
}

/* 導(dǎo)出到 msh 命令列表中 */
//MSH_CMD_EXPORT(GPS_serial,GPS uart device sample);
// 導(dǎo)出函數(shù)自動運(yùn)行,在系統(tǒng)初始化時(shí)調(diào)用usr_led_run函數(shù)
INIT_APP_EXPORT(GPS_serial);
image20250302232908498.png
image20250302234725099.png
儀表盤界面重繪:

2B453E0D8F964F169B66A8FC6BD8472E.png

 

 

 

DigiKey得捷

DigiKey得捷

DigiKey 總部位于美國明尼蘇達(dá)州錫夫里弗福爾斯市,是一家獲得原廠授權(quán)的全球性、全類目電子元器件和自動化產(chǎn)品分銷商。我們通過分銷來自 2,300 多家優(yōu)質(zhì)品牌制造商的 1,020 多萬種元器件獲得了強(qiáng)大的技術(shù)優(yōu)勢。DigiKey 還為工程師、設(shè)計(jì)師、開發(fā)者和采購專業(yè)人員提供豐富的數(shù)字解決方案、無障礙互動和工具支持,以幫助他們提升工作效率。在中國,客戶可以通過電子郵件、電話和客服獲得全方位技術(shù)支持。如需了解更多信息和獲取 DigiKey 廣泛的產(chǎn)品,請?jiān)L問 www.digikey.cn 并關(guān)注我們的微信、微博、騰訊視頻和 BiliBili 賬號。

DigiKey 總部位于美國明尼蘇達(dá)州錫夫里弗福爾斯市,是一家獲得原廠授權(quán)的全球性、全類目電子元器件和自動化產(chǎn)品分銷商。我們通過分銷來自 2,300 多家優(yōu)質(zhì)品牌制造商的 1,020 多萬種元器件獲得了強(qiáng)大的技術(shù)優(yōu)勢。DigiKey 還為工程師、設(shè)計(jì)師、開發(fā)者和采購專業(yè)人員提供豐富的數(shù)字解決方案、無障礙互動和工具支持,以幫助他們提升工作效率。在中國,客戶可以通過電子郵件、電話和客服獲得全方位技術(shù)支持。如需了解更多信息和獲取 DigiKey 廣泛的產(chǎn)品,請?jiān)L問 www.digikey.cn 并關(guān)注我們的微信、微博、騰訊視頻和 BiliBili 賬號。收起

查看更多

相關(guān)推薦

西宁市| 青阳县| 民丰县| 巴里| 聂荣县| 三明市| 含山县| 宁津县| 海林市| 桂阳县| 宁陵县| 崇明县| 名山县| 东宁县| 屏南县| 万山特区| 化隆| 博爱县| 湖口县| 垦利县| 栖霞市| 津市市| 加查县| 陆良县| 正阳县| 安徽省| 安多县| 平安县| 安图县| 金沙县| 天等县| 田林县| 三亚市| 汤原县| 深州市| 永新县| 射洪县| 开鲁县| 池州市| 宁海县| 敦化市|