在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于STM32F107與RT-Thread的數據采集器方案設計與解析

RTThread物聯網操作系統 ? 來源:未知 ? 作者:佚名 ? 2017-11-26 09:30 ? 次閱讀
作者孫冬梅:南京工業大學自動化與電氣工程學院博士、副教授

設計了基于STM32F107設計的數據采集器,實現多種數據(串口、CAN口)采集處理后通過 GPRS模塊 無線上傳。重點編寫了CAN設備驅動; 使用設備方式實現GPRS模塊串口數據的上傳下載;最后提出了使用線程過程中出現的一些問題。

一、 功能分析

系統功能如圖1 所示,不算太復雜。由于下級傳感器模塊的上報的數據內容很多,導致編寫處理程序內容較多。

二、CAN驅動編寫

為了模塊化地處理傳感器的主動上報數據,CAN設備不再用以前的中斷處理,而是采用了RTT的設備框架,重新編寫了device的驅動。研究RTT里的CAN總線收發設備:

發現只有框架,沒有內容。就仿著串口寫一個candevice。研究組件使用 中的串口驅動:

這是一個讀代碼的過程,弄清楚框架后,編寫類似于linux中的驅動編寫。

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

三、設備方式實現串口數據處理

GPRS模塊使用實際上是串口數據的收到處理。首先創建gprswatch進程,用來監控串口接收數據。

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

監視GPRS串口線程中,當收到串口數據后,接收并分析,置位網絡狀態。

/* 監視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);
        
        /*監視GPRS模塊接收數據*/
          if(rt_strstr((char const*)gprs_rx_buffer,"MYURCCLOSE: 0"))//網絡斷
          {
            net_status = CONNECT_ERROR;
            rt_kprintf("
網絡斷。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
 ");
          }
          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"))//網絡斷開
          {
            net_status = CONNECT_DISCONNECT;
            rt_kprintf("
網絡斷開。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
 ");
          }
          else if(rt_strstr((char const*)gprs_rx_buffer,"MYURCREAD: 0"))//有網絡數據
          {
            net_status = CONNECT_GPRSDATAIN;
          }
          else if(rt_strstr((char const*)gprs_rx_buffer,"+CMTI:"))//有短信來
          {
            net_status = CONNECT_MSGDATAIN;
          }
          else 
          { 
          }
        }
        if (event & REV_STOPWATCH)
        {
          return;
        }
      }
    }}

在程序其它地方完成對應GPRS模塊的監控和操作。對GPRS模塊讀和寫操作也編寫了一個設備操作函數,主要是利用前面編寫的gprswatch線程操作:

/*GPRS模塊發送和接收*/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數據
        {
          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數據
        {
          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數據
        {
          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))//如果是讀數據命令,將數據拷出
          {
            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"))//有網絡數據
      {
        net_status = CONNECT_GPRSDATAIN;
        rt_kprintf("
收到網絡數據!
");
      }
    }
    retrytime--;
  }while((!res)&&(retrytime>=1));
 gprswatch();
  return res;} 

至此,基本實現了GPRS模塊的設備操作。

四、調試過程中的經驗

1.進程初始化及分配內存

在RTT工程中,int rt_application_init(void) 函數給出了一個最基本的使用方法,動態創建線程rt_thread_create,動態分配內存。在程序編寫的過程,由于內存太小,不得不心劃分分配的內存。手冊建議在程序運行過程中使用命令查看線程的占用內存,再按經驗分內存,這樣操作,還是地調試過程中出現很多次錯誤。后來再翻看手冊,仿造例子修改程序為靜態分配內存的線程創建,rt_thread_init,上面的錯誤就不再出現了。

2.使用finsh

在調試過程中大量使用了finsh, 極大地方便了調試。

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

在串口控制臺中操作,就可以很方便地實現GPRS相關函數的調試,而并需要在主程序中運行以上函數。

3.RTT例程的格式

編寫了基于RTT的 STM32F107平臺的例程,發布在github上:https://github.com/sundm75/STM32F107Board-rttproject每個example下的 applications中,都有一個對應的 test**** 文件。該文件中,全部使用的finsh 在串口控制中操作。

- End -


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • STM32
    +關注

    關注

    2270

    文章

    10915

    瀏覽量

    356754
  • 數據采集器
    +關注

    關注

    1

    文章

    141

    瀏覽量

    14955
  • rt_thread
    +關注

    關注

    2

    文章

    13

    瀏覽量

    14661

原文標題:基于STM32F107與RT-Thread設計的數據采集器

文章出處:【微信號:RTThread,微信公眾號:RTThread物聯網操作系統】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    RT-thread源碼移植到STM32F10x和STM32F4xx

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

    STM32平臺RT-Thread最小系統移植搭建 - STM32F107VCT6 精選資料分享

    前言因為手頭有大量的開發板,最近熟悉了RT-Thread,所以想都移植搭建RT-Thread,為以后進一步學習應用打下基礎。大概有STM32F103幾個系列,STM32F107
    發表于 08-05 08:05

    怎樣去設計一種基于STM32F107RT-Thread設計的數據采集器

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

    怎樣去設計一種基于STM32F107數據采集器

    基于STM32F107設計的數據采集器有哪些功能呢?怎樣去設計一種基于STM32F107數據采集器呢?
    發表于 11-09 08:06

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

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

    基于STM32F107的UDP服務程序

    基于STM32F107的UDP服務程序
    發表于 03-26 15:44 ?151次下載

    STM32F107的時鐘設置

    STM32F107的時鐘設置,有用的107 時鐘配置
    發表于 10-12 16:05 ?14次下載

    RT-Thread STM32 配置指南

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

    基于STM32F4和RT-Thread通用BootLoader使用經驗

    基于STM32F4、RT-Thread通用BootLoader使用經驗
    的頭像 發表于 02-27 17:23 ?6342次閱讀
    基于<b class='flag-5'>STM32F</b>4和<b class='flag-5'>RT-Thread</b>通用BootLoader使用經驗

    RT-Thread系統移植到STM32f103

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

    RT-Thread STM32 配置系統時鐘(使用外部晶振)

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

    RT-Thread libmodbus RS485 RTU主機調試 - STM32F107VCT6

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

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

    RT-Thread文檔_Keil 模擬 STM32F103 上手指南
    發表于 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 上手指南
    發表于 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,因為使用0.2.3建立的模板編譯會報錯。
    的頭像 發表于 10-12 17:42 ?1386次閱讀
    主站蜘蛛池模板: 曰韩毛片| 亚洲国产片| se94se欧美| 日日噜噜爽爽狠狠视频| 国产精品久久久久乳精品爆| 2021韩国理论片ok电影天堂| 欧美色88| 四虎影院的网址| 中国特黄毛片| 欧美精品一区二区三区在线播放| 国产亚洲精品久久午夜| 五月天婷婷在线免费观看| 河南毛片| 免费人成在线| 手机看片a永久免费看大片| 色丁香影院| 黄色视屏免费看| 精品日韩| 毛片毛片免费看| 全黄毛片| 尤物啪啪| 色在线视频观看| 色亚洲视频| 欧美就是色| 欧美视频色| 韩国三级理论在线看中文字幕| 亚洲一区二区三区在线网站| japanese日本护士xx亚洲| 奇米7777第四色| 日韩一级片免费观看| 天天av天天翘天天综合网| 亚洲444kkk| 国产精品网站在线进入| 成人激情综合网| 性欧美高清极品猛交| 五月天色丁香| 国产精品一区在线播放| 色婷婷婷丁香亚洲综合不卡| 四虎影院免费观看| 婷婷六月丁| 四虎精品久久|