色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于STM32F107與RT-Thread的數(shù)據(jù)采集器方案設(shè)計(jì)與解析

RTThread物聯(lián)網(wǎng)操作系統(tǒng) ? 來源:未知 ? 作者:佚名 ? 2017-11-26 09:30 ? 次閱讀
作者孫冬梅:南京工業(yè)大學(xué)自動(dòng)化與電氣工程學(xué)院博士、副教授

設(shè)計(jì)了基于STM32F107設(shè)計(jì)的數(shù)據(jù)采集器,實(shí)現(xiàn)多種數(shù)據(jù)(串口、CAN口)采集處理后通過 GPRS模塊 無線上傳。重點(diǎn)編寫了CAN設(shè)備驅(qū)動(dòng); 使用設(shè)備方式實(shí)現(xiàn)GPRS模塊串口數(shù)據(jù)的上傳下載;最后提出了使用線程過程中出現(xiàn)的一些問題。

一、 功能分析

系統(tǒng)功能如圖1 所示,不算太復(fù)雜。由于下級(jí)傳感器模塊的上報(bào)的數(shù)據(jù)內(nèi)容很多,導(dǎo)致編寫處理程序內(nèi)容較多。

二、CAN驅(qū)動(dòng)編寫

為了模塊化地處理傳感器的主動(dòng)上報(bào)數(shù)據(jù),CAN設(shè)備不再用以前的中斷處理,而是采用了RTT的設(shè)備框架,重新編寫了device的驅(qū)動(dòng)。研究RTT里的CAN總線收發(fā)設(shè)備:

發(fā)現(xiàn)只有框架,沒有內(nèi)容。就仿著串口寫一個(gè)candevice。研究組件使用 中的串口驅(qū)動(dòng):

這是一個(gè)讀代碼的過程,弄清楚框架后,編寫類似于linux中的驅(qū)動(dòng)編寫。

以上程序全部寫好后,就可以使用設(shè)備通用操作函數(shù)來操作CAN。在主程序中首先要初始化設(shè)備,再注冊設(shè)備。

三、設(shè)備方式實(shí)現(xiàn)串口數(shù)據(jù)處理

GPRS模塊使用實(shí)際上是串口數(shù)據(jù)的收到處理。首先創(chuàng)建gprswatch進(jìn)程,用來監(jiān)控串口接收數(shù)據(jù)。

void gprswatch(void){
  rt_thread_t thread;
  thread = rt_thread_find("gprswatch");
  if( thread != RT_NULL)
    rt_thread_delete(thread);
  /* 創(chuàng)建gprswatch線程*/
  thread = rt_thread_create("gprswatch",
  gprswatch_entry, RT_NULL,
  0x1000, 0x12, 200);
  
  /* 創(chuàng)建成功則啟動(dòng)線程*/
  if( thread != RT_NULL)
  {
    rt_thread_startup(thread);
    //rt_thread_delay(RT_TICK_PER_SECOND/2);
  } }

監(jiān)視GPRS串口線程中,當(dāng)收到串口數(shù)據(jù)后,接收并分析,置位網(wǎng)絡(luò)狀態(tài)。

/* 監(jiān)視GPRS串口線程入口*/void gprswatch_entry(void* parameter){
  rt_err_t result = RT_EOK;
  rt_uint32_t event;
  unsigned char gprs_rx_buffer[GPRS_RX_LEN]={0x00};
          
  while(1)
  {
      result = rt_event_recv(&rev_event, 
         REV_MASK, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, 
         RT_WAITING_FOREVER, &event);
      if (result == RT_EOK)
      {
        if (event & REV_DATA)
        {
          rt_memset(gprs_rx_buffer,0x00,sizeof(gprs_rx_buffer));
          rt_thread_delay(RT_TICK_PER_SECOND/10);
          rt_device_read(gprs_device, 0, gprs_rx_buffer, GPRS_RX_LEN);
          rt_kprintf(gprs_rx_buffer);
        
        /*監(jiān)視GPRS模塊接收數(shù)據(jù)*/
          if(rt_strstr((char const*)gprs_rx_buffer,"MYURCCLOSE: 0"))//網(wǎng)絡(luò)斷
          {
            net_status = CONNECT_ERROR;
            rt_kprintf("
網(wǎng)絡(luò)斷。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
 ");
          }
          else if(rt_strstr((char const*)gprs_rx_buffer,"Call Ready"))//模塊重啟
          {
            net_status = CONNECT_NULL;
            rt_kprintf("
模塊重啟。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
 ");
          }
          else if(rt_strstr((char const*)gprs_rx_buffer,"+CPIN: NOT READY"))//卡被拔出
          {
            net_status = CONNECT_ERROR;
            rt_kprintf("
卡被拔出。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
 ");
          }
          else if(rt_strstr((char const*)gprs_rx_buffer,"$MYURCACT: 0,0"))//網(wǎng)絡(luò)斷開
          {
            net_status = CONNECT_DISCONNECT;
            rt_kprintf("
網(wǎng)絡(luò)斷開。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
 ");
          }
          else if(rt_strstr((char const*)gprs_rx_buffer,"MYURCREAD: 0"))//有網(wǎng)絡(luò)數(shù)據(jù)
          {
            net_status = CONNECT_GPRSDATAIN;
          }
          else if(rt_strstr((char const*)gprs_rx_buffer,"+CMTI:"))//有短信來
          {
            net_status = CONNECT_MSGDATAIN;
          }
          else 
          { 
          }
        }
        if (event & REV_STOPWATCH)
        {
          return;
        }
      }
    }}

在程序其它地方完成對(duì)應(yīng)GPRS模塊的監(jiān)控和操作。對(duì)GPRS模塊讀和寫操作也編寫了一個(gè)設(shè)備操作函數(shù),主要是利用前面編寫的gprswatch線程操作:

/*GPRS模塊發(fā)送和接收*/rt_bool_t gprs_send_data_package(unsigned char *cmd,char *ack,rt_uint32_t waittime, rt_uint8_t retrytime, rt_uint32_t len){
  rt_bool_t res = RT_FALSE; 
  rt_err_t result = RT_EOK;
  rt_uint32_t event;
  unsigned char gprs_rx_buffer[GPRS_RX_LEN]={0x00};
  rt_thread_t thread;
  
  thread = rt_thread_find("gprswatch");
  if( thread != RT_NULL)
  {
    rt_thread_delete(thread);
  }   
  
  do 
  {
    rt_device_write(gprs_device, 0, cmd, len);   
    result = rt_event_recv(&rev_event, 
       REV_MASK, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, 
       waittime*RT_TICK_PER_SECOND, &event);
    if (result == RT_EOK)
    {
      if (event & REV_DATA)
      {
        rt_memset(gprs_rx_buffer,0x00,sizeof(gprs_rx_buffer));
        rt_thread_delay(RT_TICK_PER_SECOND/2);
        rt_device_read(gprs_device, 0, gprs_rx_buffer, GPRS_RX_LEN);
        rt_kprintf(gprs_rx_buffer);
        
        if(rt_strstr(cmd,MSG_IMSI))//如果是讀IMSI 解析出IMSI數(shù)據(jù)
        {
          unsigned char *addr;
          addr = rt_strstr((char const*)gprs_rx_buffer,"AT+CIMI")+10;
          if(addr!=NULL)
            {
               strncpy(&imsi[0],addr,15);
               rt_kprintf("
IMSI = :%s
" ,imsi);              
            }
        }
        
        if(rt_strstr(cmd,MSG_IMEI))//如果是讀IMEI 解析出IMEI數(shù)據(jù)
        {
          unsigned char *addr;
          addr = rt_strstr((char const*)gprs_rx_buffer,""")+1;
          if(addr!=NULL)
            {
               strncpy(&imei[0],addr,15);
               rt_kprintf("
IMEI = :%s
" ,imei);              
            }
        }
        
        if(rt_strstr(cmd,CSQ_CMD))//如果是讀CSQ 解析出dbm數(shù)據(jù)
        {
          unsigned char csq[5] = {0x00};
          unsigned char *addr;
          rt_int16_t dbm;
          addr = rt_strstr((char const*)gprs_rx_buffer,",") - 3;
          rt_strncpy(csq, addr,3);
          if(addr!=NULL)
            {
               dbm =  2* atoi(csq) - 109;
               dbm_data[0] = dbm;  
               dbm_data[1] = dbm>>8;
               rt_kprintf("
 DBM = %d
" ,dbm);              
               rt_kprintf("
 RSSI = %02x%02x
" ,dbm_data[0],dbm_data[1]);              
            }
        }

        if((rt_strstr(gprs_rx_buffer,ack))||(rt_strstr(gprs_rx_buffer,"OK")))
        {
          res = RT_TRUE;
          if(rt_strstr(cmd,MG323_READ_CMD))//如果是讀數(shù)據(jù)命令,將數(shù)據(jù)拷出
          {
            rt_memcpy(gprs_rx_data, gprs_rx_buffer, GPRS_RX_LEN);
          }
        }
        else
          res = RT_FALSE;
      }
      if(rt_strstr((char const*)gprs_rx_buffer,"MYURCREAD: 0"))//有網(wǎng)絡(luò)數(shù)據(jù)
      {
        net_status = CONNECT_GPRSDATAIN;
        rt_kprintf("
收到網(wǎng)絡(luò)數(shù)據(jù)!
");
      }
    }
    retrytime--;
  }while((!res)&&(retrytime>=1));
 gprswatch();
  return res;} 

至此,基本實(shí)現(xiàn)了GPRS模塊的設(shè)備操作。

四、調(diào)試過程中的經(jīng)驗(yàn)

1.進(jìn)程初始化及分配內(nèi)存

在RTT工程中,int rt_application_init(void) 函數(shù)給出了一個(gè)最基本的使用方法,動(dòng)態(tài)創(chuàng)建線程rt_thread_create,動(dòng)態(tài)分配內(nèi)存。在程序編寫的過程,由于內(nèi)存太小,不得不心劃分分配的內(nèi)存。手冊建議在程序運(yùn)行過程中使用命令查看線程的占用內(nèi)存,再按經(jīng)驗(yàn)分內(nèi)存,這樣操作,還是地調(diào)試過程中出現(xiàn)很多次錯(cuò)誤。后來再翻看手冊,仿造例子修改程序?yàn)殪o態(tài)分配內(nèi)存的線程創(chuàng)建,rt_thread_init,上面的錯(cuò)誤就不再出現(xiàn)了。

2.使用finsh

在調(diào)試過程中大量使用了finsh, 極大地方便了調(diào)試。

引用用戶手冊的說明:編寫了一個(gè)函數(shù),如果不在程序中運(yùn)行,便可以將此函數(shù)引出到finsh中。

在串口控制臺(tái)中操作,就可以很方便地實(shí)現(xiàn)GPRS相關(guān)函數(shù)的調(diào)試,而并需要在主程序中運(yùn)行以上函數(shù)。

3.RTT例程的格式

編寫了基于RTT的 STM32F107平臺(tái)的例程,發(fā)布在github上:https://github.com/sundm75/STM32F107Board-rttproject每個(gè)example下的 applications中,都有一個(gè)對(duì)應(yīng)的 test**** 文件。該文件中,全部使用的finsh 在串口控制中操作。

- End -


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10910

    瀏覽量

    356615
  • 數(shù)據(jù)采集器

    關(guān)注

    1

    文章

    141

    瀏覽量

    14951
  • rt_thread
    +關(guān)注

    關(guān)注

    2

    文章

    13

    瀏覽量

    14660

原文標(biāo)題:基于STM32F107與RT-Thread設(shè)計(jì)的數(shù)據(jù)采集器

文章出處:【微信號(hào):RTThread,微信公眾號(hào):RTThread物聯(lián)網(wǎng)操作系統(tǒng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    RT-thread源碼移植到STM32F10x和STM32F4xx

    RT-thread源碼移植到STM32F10x和STM32F4xx: 一、源碼下載 點(diǎn)擊入門->下載 ? 在歷史版本里邊隨便選取一個(gè) ? 會(huì)進(jìn)入百度云盤的下載地址,里邊有全部版本的源碼。這里下載
    的頭像 發(fā)表于 11-15 09:38 ?2635次閱讀
    <b class='flag-5'>RT-thread</b>源碼移植到<b class='flag-5'>STM32F</b>10x和<b class='flag-5'>STM32F</b>4xx

    STM32平臺(tái)RT-Thread最小系統(tǒng)移植搭建 - STM32F107VCT6 精選資料分享

    前言因?yàn)槭诸^有大量的開發(fā)板,最近熟悉了RT-Thread,所以想都移植搭建RT-Thread,為以后進(jìn)一步學(xué)習(xí)應(yīng)用打下基礎(chǔ)。大概有STM32F103幾個(gè)系列,STM32F107
    發(fā)表于 08-05 08:05

    怎樣去設(shè)計(jì)一種基于STM32F107RT-Thread設(shè)計(jì)的數(shù)據(jù)采集器

    作者孫冬梅:南京工業(yè)大學(xué)自動(dòng)化與電氣工程學(xué)院博士、副教授,資深RT-Thread開發(fā)者歡迎給RT-Thread投稿,獲贈(zèng)RT-Thread T恤一件。征稿 | 你寫不寫,福利就在這里~~...
    發(fā)表于 08-06 06:51

    怎樣去設(shè)計(jì)一種基于STM32F107數(shù)據(jù)采集器

    基于STM32F107設(shè)計(jì)的數(shù)據(jù)采集器有哪些功能呢?怎樣去設(shè)計(jì)一種基于STM32F107數(shù)據(jù)采集器呢?
    發(fā)表于 11-09 08:06

    STM32F767移植rt-thread nano時(shí)Finsh無法讀取輸入怎么辦

    提供的是 STM32F107 版本的代碼:char rt_hw_console_getchar(void){int ch = -1;if (__HAL_UART_GET_FLAG
    發(fā)表于 11-02 14:08

    基于STM32F107的UDP服務(wù)程序

    基于STM32F107的UDP服務(wù)程序
    發(fā)表于 03-26 15:44 ?151次下載

    STM32F107的時(shí)鐘設(shè)置

    STM32F107的時(shí)鐘設(shè)置,有用的107 時(shí)鐘配置
    發(fā)表于 10-12 16:05 ?14次下載

    RT-Thread STM32 配置指南

    105,STM32F107 則叫做 CL 系列,所以當(dāng)您使用 RT-Thread 時(shí),請(qǐng)先確定您使用的芯片型號(hào),在軟件的配置上主要是兩 個(gè)地方(在工程的選項(xiàng)中): 在上圖中選擇左邊的芯片型號(hào),例如 STM32F103ZE,
    發(fā)表于 09-12 15:13 ?24次下載
    <b class='flag-5'>RT-Thread</b> <b class='flag-5'>STM32</b> 配置指南

    基于STM32F4和RT-Thread通用BootLoader使用經(jīng)驗(yàn)

    基于STM32F4、RT-Thread通用BootLoader使用經(jīng)驗(yàn)
    的頭像 發(fā)表于 02-27 17:23 ?6331次閱讀
    基于<b class='flag-5'>STM32F</b>4和<b class='flag-5'>RT-Thread</b>通用BootLoader使用經(jīng)驗(yàn)

    RT-Thread系統(tǒng)移植到STM32f103

    RT-Thread系統(tǒng)移植到STM32f103
    發(fā)表于 12-09 12:51 ?26次下載
    <b class='flag-5'>RT-Thread</b>系統(tǒng)移植到<b class='flag-5'>STM32f</b>103

    RT-Thread STM32 配置系統(tǒng)時(shí)鐘(使用外部晶振)

    RT-Thread STM32 配置系統(tǒng)時(shí)鐘開發(fā)環(huán)境芯片:STM32F103RCT6RT-Thread Studio: V1.0.6(現(xiàn)在已經(jīng)更新到1.1.3,由于本人使用RTT開發(fā)已經(jīng)有一段時(shí)間了
    發(fā)表于 12-14 18:45 ?14次下載
    <b class='flag-5'>RT-Thread</b> <b class='flag-5'>STM32</b> 配置系統(tǒng)時(shí)鐘(使用外部晶振)

    RT-Thread libmodbus RS485 RTU主機(jī)調(diào)試 - STM32F107VCT6

    的管理,雖然軟件包移植的沒有那么細(xì)。移植MCU 為 STM32F107VCT6,RS485 UART4, modbus采用RS485 RTU,MSH shell UART5。 先移植好RT-Thread最小系統(tǒng) 使用STM32C
    發(fā)表于 12-28 19:46 ?15次下載
    <b class='flag-5'>RT-Thread</b> libmodbus RS485 RTU主機(jī)調(diào)試 - <b class='flag-5'>STM32F107</b>VCT6

    RT-Thread文檔_Keil 模擬 STM32F103 上手指南

    RT-Thread文檔_Keil 模擬 STM32F103 上手指南
    發(fā)表于 02-22 18:22 ?4次下載
    <b class='flag-5'>RT-Thread</b>文檔_Keil 模擬<b class='flag-5'>器</b> <b class='flag-5'>STM32F</b>103 上手指南

    RT-Thread文檔_RT-Thread 潘多拉 STM32L475 上手指南

    RT-Thread文檔_RT-Thread 潘多拉 STM32L475 上手指南
    發(fā)表于 02-22 18:23 ?9次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> 潘多拉 <b class='flag-5'>STM32</b>L475 上手指南

    rt-thread studio新建stm32f407工程

    rt-thread studio新建stm32f407工程,使用的版本是:2.2.6,stm32f4的支持包版本為0.2.2。先不用0.2.3,因?yàn)槭褂?.2.3建立的模板編譯會(huì)報(bào)錯(cuò)。
    的頭像 發(fā)表于 10-12 17:42 ?1377次閱讀
    主站蜘蛛池模板: 午夜dj免费中文字幕| 26uuu老色哥| 亚洲 欧美 国产 视频二区| 无码任你躁久久久久久久| 亚洲AV蜜桃永久无码精品无码网 | 97SE亚洲国产综合在线| jlzzzjizzzjlzzz亚洲| 国产成人免费观看在线视频| 國產日韓亞洲精品AV| 久久精品AV无码亚洲色欲| 久久精品熟女亚洲AV国产| 年轻的老师5理伦片| 熟女久久久久久久久久久| 亚洲国产日韩欧美在线a乱码| 影音先锋xfplay影院av| qvod在线观看| 国产午夜一级淫片| 美国一级大黄一片免费的网站| 日本欧美久久久久免费播放网| 亚洲AV成人无码网天堂| 做暧暧免费30秒体验| 俄罗斯XBXBXB兽交| 久草精品在线| 日本A级作爱片金瓶双艳| 亚洲国产中文字幕在线视频| 97精品伊人久久大香线蕉app| 国产不卡一卡2卡三卡4卡网站| 极品色αv影院| 日本wwwxx爽69护士| 中文成人在线| 国产亚洲精品97在线视频一| 日本边添边摸边做边爱边| 在线播放av欧美无码碰| 国产麻豆精品久久一二三| 欧美精品AV无码一区二区| 一边吃奶一边添P好爽故事| 国产高清精品自在久久| 欧美精品一卡二卡| 在线视频中文字幕| 果冻传媒在线观看网站| 手机移动oa|