久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5095|回復: 4
打印 上一主題 下一主題
收起左側

CAN Bootloader協議介紹與C++源碼

[復制鏈接]
跳轉到指定樓層
樓主
CAN Bootloader命令列表
命令名稱    命令值(Hex)    說明
GET_ADDR(1)    000    向主機請求本機地址
ERASE(2)    XX1    擦除應用程序
WRITE(3)    XX2    將程序寫入Flash
READ(4)    XX3    將程序從Flash中讀出
GO(5)    XX4    執行應用程序
SET_WRITE_ADDR    XX5    設置寫數據起始地址
WRITE_CONTINUOUS    XX6    連續寫數據,寫數據地址自動遞增
SET_READ_ADDR    XX7    設置讀數據起始地址
READ_CONTINUOUS    XX8    連續讀數據,讀數據起始地址遞增
GET_VERSION    XX9    獲取Bootloader固件版本
ADDR_OK    XXC    請求地址可用
ADDR_ERROR    XXD    請求地址不可用
CMD_OK    XXE    命令執行成功
CMD_ERROR    XXF    命令執行失敗
1、本機地址為7bit,所以在CAN總線上最多只能連接128個節點,本命令由從機發出,主機會給從機分配一個臨時地址并回復CMD_OK,如果主機地址使用完畢則回復CMD_ERROR,從機可以根據接收到的主機反饋判斷本機地址設置是否成功;
2、擦除應用程序命令會帶擦除起始地址和擦除結束地址;
3、寫數據命令帶4字節寫數據地址參數和4字節的數據;
4、讀數據命令會攜帶4字節地址,從機返回4字節數據;
5、執行應用程序;

命令詳解
GET_ADDR:
該命令由從機發送給主機,主機接收到該命令后會分配一個地址給從機,如果主機無法分配地址則發送ADDR_ERROR回復從機,此時從機應進入無法獲取地址的錯誤處理程序中。主機和從機在發送命令的時候必須攜帶8字節物理地址,也就是說DLC為8。從機如果正確獲取到地址后可以設置過濾器為只接收和自己地址匹配的數據,這樣可以減少CPU的負擔。
ERASE:
擦除應用程序儲存地址區域的數據,該命令由主機發送給從機,命令攜帶8字節數據,前4字節數據為擦出起始地址,后4字節為擦出結束地址,從機接收到該命令后可回復CMD_OK或CMD_ERROR給主機。
WRITE:
將一個字(4Byte)的數據寫入指定的Flash地址,該命令由主機發送給從機,命令攜帶8字節數據,前4字節為數據寫入地址,后4字節為準備寫入的數據。
READ:
從指定的Flash地址讀取4字節的數據,該命令由主機發送給從機或者從機發送給主機,主機發送給從機的時候攜帶4字節地址參數,從機發送給主機的時候攜帶4字節的數據。
GO:
執行應用程序,該命令由主機發送給從機,命令攜帶4字節的地址參數,從機接收到該命令后從指定的地址開始執行程序。
SET_WRITE_ADDR:
設置連續寫數據的起始地址,該命令由主機發送給從機,命令攜帶4字節的地址參數。
WRITE_CONTINUOUS:
連續寫數據到Flash中,該命令由主機發送給從機,從機根據SET_WRITE_ADDR命令設置的起始地址將程序數據寫入Flash中,該命令攜帶最多8字節的程序數據。
SET_READ_ADDR:
設置連續讀數據起始地址,該命令由主機發送給從機,命令攜帶4字節的地址參數。
READ_CONTINUOUS:
連續讀數據,該命令由主機發送給從機或者由從機發送給主機,由主機發送給從機時DLC為0,從機接收到這個命令后將該命令攜帶最多8字節數據返回給主機。
GET_VERSION:
獲取Bootloader固件版本號,版本號由兩字節組成,第一字節為主版本號,第二字節為從版本號。
ADDR_OK:
返回合法的從機地址。
ADDR_ERROR:
不能正常分配從機地址。
CMD_OK:
命令支持成功。
CMD_ERROR:
命令執行失敗。

單片機源程序如下:
  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"

  3. typedef  struct {
  4.   unsigned char   SJW;
  5.   unsigned char   BS1;
  6.   unsigned char   BS2;
  7.   unsigned short  PreScale;
  8. } tCAN_BaudRate;

  9. #define GET_ADDR                        0x0        //向主機請求本機地址,XX為本機地址,一共7bit
  10. #define ERASE                                0x1        //擦除應用程序
  11. #define WRITE                                0x2        //將程序寫入Flash
  12. #define READ                                0x3        //將程序從Flash中讀出
  13. #define GO                                        0x4        //執行應用程序
  14. #define SET_WRITE_ADDR                0x5        //設置寫數據起始地址
  15. #define WRITE_CONTINUOUS        0x6        //連續寫數據,寫數據地址自動遞增
  16. #define SET_READ_ADDR                0x7        //設置讀數據起始地址
  17. #define READ_CONTINUOUS                0x8        //連續讀數據,讀數據起始地址遞增
  18. #define GET_VERSION                        0x9        //獲取Bootloader固件版本
  19. #define        ONLINE_CHECK                0xA        //檢測CAN節點是否在線
  20. #define ADDR_OK                                0xC        //請求地址可用
  21. #define ADDR_ERROR                        0xD        //請求地址不可用
  22. #define CMD_OK                                0xE        //命令執行成功
  23. #define CMD_ERROR                        0xF        //命令執行失敗

  24. MainWindow::MainWindow(QWidget *parent) :
  25.     QMainWindow(parent),
  26.     ui(new Ui::MainWindow)
  27. {
  28.     int ret;
  29.     ui->setupUi(this);
  30.     for(int i=0;i<128;i++){
  31.         can_addr.local_addr[i]=0;
  32.     }
  33.     nodeTableInit();
  34.     ret = VCI_ScanDevice(1);
  35.     if(ret<=0){
  36.         QMessageBox::warning(this,"Warning","No device Connected!");
  37.         return;
  38.     }
  39.     ret = VCI_OpenDevice(VCI_USBCAN2,ui->deviceIndexComboBox->currentIndex(),0);
  40.     if(ret!=STATUS_OK){
  41.         QMessageBox::warning(this,"Warning","Open device Error!");
  42.         return;
  43.     }
  44.     if(canInit()){
  45.         ret = VCI_StartCAN(VCI_USBCAN2,
  46.                            ui->deviceIndexComboBox->currentIndex(),
  47.                            ui->channelIndexComboBox->currentIndex());
  48.         if(ret!=STATUS_OK){
  49.             QMessageBox::warning(this,"Warning","Start CAN Error!");
  50.             return;
  51.         }
  52.     }
  53.     scanNodeTimerID = startTimer(100);
  54. }

  55. MainWindow::~MainWindow()
  56. {
  57.     VCI_ResetCAN(VCI_USBCAN2,
  58.                  ui->deviceIndexComboBox->currentIndex(),
  59.                  ui->channelIndexComboBox->currentIndex());
  60.     VCI_CloseDevice(VCI_USBCAN2,ui->deviceIndexComboBox->currentIndex());
  61.     delete ui;
  62. }

  63. void MainWindow::nodeTableInit(void)
  64. {
  65.     QStringList strList;
  66.     strList << "Addr" << "MAC(Hex)" << "Version";
  67.     model = new QStandardItemModel;
  68.     model->setColumnCount(strList.count());
  69.     model->setRowCount(127);
  70.     model->setHorizontalHeaderLabels(strList);
  71.     ui->nodeListTableView->setModel(model);
  72.     ui->nodeListTableView->setColumnWidth(0, 50);
  73.     ui->nodeListTableView->setColumnWidth(1, 160);
  74.     ui->nodeListTableView->setColumnWidth(2, 60);
  75.     ui->nodeListTableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
  76.     ui->nodeListTableView->setSelectionBehavior(QAbstractItemView::SelectRows); //整行選中的方式
  77.     ui->nodeListTableView->verticalHeader()->setDefaultSectionSize(20);
  78.     ui->nodeListTableView->verticalHeader()->hide();
  79.     for(int r=0;r<model->rowCount();r++){
  80.         for(int c = 0; c < model->columnCount(); c++)
  81.         {
  82.             QStandardItem *item = new QStandardItem("");
  83.             model->setItem(r,c,item);
  84.         }
  85.     }
  86. }
  87. int MainWindow::CAN_GetBaudRateNum(unsigned int BaudRate)
  88. {
  89.     switch(BaudRate){
  90.         case 1000000 :return 0;
  91.         case 900000 :return 1;
  92.         case 800000 :return 2;
  93.         case 666000 :return 3;
  94.         case 600000 :return 4;
  95.         case 500000 :return 5;
  96.         case 400000 :return 6;
  97.         case 300000 :return 7;
  98.         case 250000 :return 8;
  99.         case 225000:return 9;
  100.         case 200000 :return 10;
  101.         case 160000:return 11;
  102.         case 150000 :return 12;
  103.         case 144000:return 13;
  104.         case 125000 :return 14;
  105.         case 120000:return 15;
  106.         case 100000 :return 16;
  107.         case 90000 :return 17;
  108.         case 80000 :return 18;
  109.         case 75000:return 19;
  110.         case 60000 :return 20;
  111.         case 50000 :return 21;
  112.         case 40000 :return 22;
  113.         case 30000 :return 23;
  114.         case 20000 :return 24;
  115.         default:return 0;
  116.     }
  117. }
  118. bool MainWindow::canInit(void)
  119. {
  120.     int ret;
  121.     tCAN_BaudRate  CAN_BaudRateInitTab[]= {      // CLK=36MHz
  122.        1,5,3,4,     // 1M
  123.        1,4,3,5,     // 900K
  124.        1,5,3,5,     // 800K
  125.        1,5,3,6,     // 666K
  126.        1,6,3,6,     // 600K
  127.        1,5,2,9,     // 500K
  128.        1,7,2,9,     // 400K
  129.        1,16,3,6,    // 300K
  130.        1,4,3,18,    // 250K
  131.        1,6,3,16,        // 225K
  132.        1,8,3,15,    // 200K
  133.        1,4,4,25,        // 160K
  134.        1,5,4,24,    // 150K
  135.        1,5,4,25,        // 144K
  136.        1,13,4,16,   // 125K
  137.        1,10,4,20,        // 120K
  138.        1,9,5,24,    // 100K
  139.        1,10,5,25,   // 90K
  140.        1,12,5,25,   // 80K
  141.        1,9,6,30,        // 75K
  142.        1,7,7,40,    // 60K
  143.        1,8,7,45,    // 50K
  144.        1,9,8,50,    // 40K
  145.        1,6,3,120,   // 30K
  146.        1,3,2,300,   // 20K
  147.     };
  148.     VCI_INIT_CONFIG_EX CAN_InitConfig;
  149.     QString str = ui->baudRateComboBox->currentText();
  150.     str.resize(str.length()-4);
  151.     int baud = str.toInt(NULL,10)*1000;
  152.     CAN_InitConfig.CAN_BRP = CAN_BaudRateInitTab[CAN_GetBaudRateNum(baud)].PreScale;
  153.     CAN_InitConfig.CAN_SJW = CAN_BaudRateInitTab[CAN_GetBaudRateNum(baud)].SJW;
  154.     CAN_InitConfig.CAN_BS1 = CAN_BaudRateInitTab[CAN_GetBaudRateNum(baud)].BS1;
  155.     CAN_InitConfig.CAN_BS2 = CAN_BaudRateInitTab[CAN_GetBaudRateNum(baud)].BS2;
  156.     CAN_InitConfig.CAN_ABOM = 1;
  157.     CAN_InitConfig.CAN_Mode = 0;
  158.     CAN_InitConfig.CAN_NART = 0;
  159.     CAN_InitConfig.CAN_RELAY = 0;
  160.     CAN_InitConfig.CAN_RFLM = 0;
  161.     CAN_InitConfig.CAN_TXFP = 1;
  162.     ret = VCI_InitCANEx(VCI_USBCAN2,
  163.                         ui->deviceIndexComboBox->currentIndex(),
  164.                         ui->channelIndexComboBox->currentIndex(),
  165.                         &CAN_InitConfig);
  166.     if(ret!=STATUS_OK){
  167.         QMessageBox::warning(this,"Warning","Initialize device Error!");
  168.         return false;
  169.     }
  170.     VCI_FILTER_CONFIG CAN_Filter;
  171.     CAN_Filter.Enable = 1;
  172.     CAN_Filter.ExtFrame = 0;
  173.     CAN_Filter.FilterIndex = 0;
  174.     CAN_Filter.FilterMode = 0;
  175.     CAN_Filter.ID_IDE = 0;
  176.     CAN_Filter.ID_RTR = 0;
  177.     CAN_Filter.ID_Std_Ext = 0;
  178.     CAN_Filter.MASK_IDE = 0;
  179.     CAN_Filter.MASK_RTR = 0;
  180.     CAN_Filter.MASK_Std_Ext = 0;
  181.     ret = VCI_SetFilter(VCI_USBCAN2,
  182.                         ui->deviceIndexComboBox->currentIndex(),
  183.                         ui->channelIndexComboBox->currentIndex(),
  184.                         &CAN_Filter);
  185.     if(ret!=STATUS_OK){
  186.         QMessageBox::warning(this,"Warning","Set filter Error!");
  187.         return false;
  188.     }
  189.     return true;
  190. }

  191. void MainWindow::logMessage(QString str)
  192. {
  193.     ui->logTextEdit->moveCursor(QTextCursor::End);
  194.     ui->logTextEdit->append(str);
  195. }
  196. bool MainWindow::setStartAddr(unsigned char can_node_addr,unsigned int startAddr)
  197. {
  198.     VCI_CAN_OBJ CAN_SendData;
  199.     VCI_CAN_OBJ CAN_ReadData;
  200.     int ret,retry;
  201.     CAN_SendData.Data[0] = startAddr>>24;
  202.     CAN_SendData.Data[1] = startAddr>>16;
  203.     CAN_SendData.Data[2] = startAddr>>8;
  204.     CAN_SendData.Data[3] = startAddr>>0;
  205.     CAN_SendData.DataLen = 4;
  206.     CAN_SendData.ID = (can_node_addr<<4)|SET_WRITE_ADDR;
  207.     CAN_SendData.ExternFlag = 0;
  208.     CAN_SendData.RemoteFlag = 0;
  209.     CAN_SendData.SendType = 0;
  210.     ret = VCI_Transmit(VCI_USBCAN2,
  211.                        ui->deviceIndexComboBox->currentIndex(),
  212.                        ui->channelIndexComboBox->currentIndex(),
  213.                        &CAN_SendData,
  214.                        1);
  215.     if(ret!=1){
  216.         logMessage("Set start address error!");
  217.         QMessageBox::warning(this,"Warning","Set start address error!");
  218.         return false;
  219.     }
  220.     retry = 0;
  221.     while(1){
  222.         Sleep(10);
  223.         ret = VCI_Receive(VCI_USBCAN2,
  224.                           ui->deviceIndexComboBox->currentIndex(),
  225.                           ui->channelIndexComboBox->currentIndex(),
  226.                           &CAN_ReadData,
  227.                           1);
  228.         if((ret==1)&&(can_node_addr==(CAN_ReadData.ID>>4))&&((CAN_ReadData.ID&0xF)==CMD_OK)){
  229.             break;
  230.         }else{
  231.             Sleep(10);
  232.             retry++;
  233.             if(retry>5){
  234.                 logMessage("Set start address error!");
  235.                 QMessageBox::warning(this,"Warning","Set start address error!");
  236.                 return false;
  237.             }
  238.             QCoreApplication::processEvents(QEventLoop::AllEvents);
  239.         }
  240.     }
  241.     logMessage("Set start success!");
  242.     return true;
  243. }

  244. bool MainWindow::eraseSectors(unsigned char can_node_addr,unsigned int startAddr,unsigned int EndAddr)
  245. {
  246.     VCI_CAN_OBJ CAN_SendData;
  247.     VCI_CAN_OBJ CAN_ReadData;
  248.     int ret,retry;
  249.     if(startAddr>EndAddr){
  250.         QMessageBox::warning(this,"Warning","Address error!");
  251.         return false;
  252.     }else{
  253.         CAN_SendData.Data[0] = startAddr>>24;
  254.         CAN_SendData.Data[1] = startAddr>>16;
  255.         CAN_SendData.Data[2] = startAddr>>8;
  256.         CAN_SendData.Data[3] = startAddr>>0;
  257.         CAN_SendData.Data[4] = EndAddr>>24;
  258.         CAN_SendData.Data[5] = EndAddr>>16;
  259.         CAN_SendData.Data[6] = EndAddr>>8;
  260.         CAN_SendData.Data[7] = EndAddr>>0;
  261.         CAN_SendData.DataLen = 8;
  262.         CAN_SendData.ID = (can_node_addr<<4)|ERASE;
  263.         CAN_SendData.ExternFlag = 0;
  264.         CAN_SendData.RemoteFlag = 0;
  265.         CAN_SendData.SendType = 0;
  266.         ret = VCI_Transmit(VCI_USBCAN2,
  267.                            ui->deviceIndexComboBox->currentIndex(),
  268.                            ui->channelIndexComboBox->currentIndex(),
  269.                            &CAN_SendData,
  270.                            1);
  271.         if(ret!=1){
  272.             logMessage("Erase sectors error!");
  273.             QMessageBox::warning(this,"Warning","Send Data Error!");
  274.             return false;
  275.         }
  276.         logMessage("Start erase sectors,please wait...");
  277.         retry = 0;
  278.         while(1){
  279.             Sleep(10);
  280.             ret = VCI_Receive(VCI_USBCAN2,
  281.                               ui->deviceIndexComboBox->currentIndex(),
  282.                               ui->channelIndexComboBox->currentIndex(),
  283.                               &CAN_ReadData,
  284.                               1);
  285.             if((ret==1)&&(can_node_addr==(CAN_ReadData.ID>>4))&&((CAN_ReadData.ID&0xF)==CMD_OK)){
  286.                 break;
  287.             }else{
  288.                 Sleep(10);
  289.                 retry++;
  290.                 if(retry>200){
  291.                     logMessage("Erase sectors error!");
  292.                     QMessageBox::warning(this,"Warning","Erase sector error!");
  293.                     return false;
  294.                 }
  295.                 QCoreApplication::processEvents(QEventLoop::AllEvents);
  296.             }
  297.         }
  298.         logMessage("Erase sector success!");
  299.         return true;
  300.     }
  301. }

  302. void MainWindow::on_updatePushButton_clicked()
  303. {
  304.     int ret,retry;
  305.     QString str;
  306.     uint32_t startAddr = ui->startAddrLineEdit->text().toInt(NULL,16);
  307.     VCI_CAN_OBJ CAN_SendData;
  308.     VCI_CAN_OBJ CAN_ReadData;
  309.     QFile firmwareFile(ui->fileLineEdit->text());
  310.     if(model->item(ui->nodeListTableView->currentIndex().row(),0)->text().isEmpty()){
  311.         QMessageBox::warning(this,"Warning","Please select online can node!");
  312.         return;
  313.     }
  314.     uint8_t can_node_addr = ui->nodeListTableView->currentIndex().row()+1;
  315.     if (firmwareFile.open(QFile::ReadOnly)){
  316.         killTimer(scanNodeTimerID);
  317.         //擦出程序扇區
  318.         if(!eraseSectors(can_node_addr,startAddr,startAddr+firmwareFile.size())){
  319.             scanNodeTimerID = startTimer(100);
  320.             return;
  321.         }
  322.         //設置程序起始地址
  323.         if(!setStartAddr(can_node_addr,startAddr)){
  324.             scanNodeTimerID = startTimer(50);
  325.             return;
  326.         }
  327.         logMessage("Start write firmware data...");
  328.         str.sprintf("CAN node address:%d",can_node_addr);
  329.         logMessage(str);
  330.         str.sprintf("Firmware start address(Hex):%08X",startAddr);
  331.         logMessage(str);
  332.         str.sprintf("Firmware size:%d Byte",firmwareFile.size());
  333.         logMessage(str);
  334.         str.sprintf("Current Progress:%3d%%",0);
  335.         logMessage(str);
  336.         for(int i=0;i<firmwareFile.size();i+=8){
  337.             firmwareFile.read((char*)(&CAN_SendData.Data[0]),8);
  338.             CAN_SendData.DataLen = 8;
  339.             CAN_SendData.ExternFlag = 0;
  340.             CAN_SendData.RemoteFlag = 0;
  341.             CAN_SendData.SendType = 0;
  342.             CAN_SendData.ID = (can_node_addr<<4)|WRITE_CONTINUOUS;
  343.             ret = VCI_Transmit(VCI_USBCAN2,
  344.                                ui->deviceIndexComboBox->currentIndex(),
  345.                                ui->channelIndexComboBox->currentIndex(),
  346.                                &CAN_SendData,
  347.                                1);
  348.             if(ret!=1){
  349.                 logMessage("Write firmware data error!");
  350.                 QMessageBox::warning(this,"Warning","Send Data Error!");
  351.                 scanNodeTimerID = startTimer(100);
  352.                 return;
  353.             }
  354.             //設置更新進度
  355.             QTextCursor cursor = ui->logTextEdit->textCursor();
  356.             cursor.deletePreviousChar();
  357.             cursor.deletePreviousChar();
  358.             cursor.deletePreviousChar();
  359.             cursor.deletePreviousChar();
  360.             str.sprintf("%3d%%",i*100/firmwareFile.size());
  361.             ui->logTextEdit->insertPlainText(str);
  362.             retry = 0;
  363.             while(1){
  364.                 ret = VCI_Receive(VCI_USBCAN2,
  365.                                   ui->deviceIndexComboBox->currentIndex(),
  366.                                   ui->channelIndexComboBox->currentIndex(),
  367.                                   &CAN_ReadData,
  368.                                   1);
  369.                 if((ret==1)&&(can_node_addr==(CAN_ReadData.ID>>4))&&((CAN_ReadData.ID&0xF)==CMD_OK)){
  370.                     break;
  371.                 }else{
  372.                     Sleep(10);
  373.                     retry++;
  374.                     if(retry>10){
  375.                         logMessage("Write firmware data error!");
  376.                         QMessageBox::warning(this,"Warning","Get ACK error!");
  377.                         scanNodeTimerID = startTimer(100);
  378.                         return;
  379.                     }
  380.                 }
  381.             }
  382.             QCoreApplication::processEvents(QEventLoop::AllEvents);
  383.         }
  384.         //設置更新進度
  385.         QTextCursor cursor = ui->logTextEdit->textCursor();
  386.         cursor.deletePreviousChar();
  387.         cursor.deletePreviousChar();
  388.         cursor.deletePreviousChar();
  389.         cursor.deletePreviousChar();
  390.         str.sprintf("%3d%%",100);
  391.         ui->logTextEdit->insertPlainText(str);
  392.         logMessage("Write firmware data success!");
  393.         QMessageBox::information(this,"Information","Update firmware success!");
  394.         scanNodeTimerID = startTimer(100);
  395.         firmwareFile.close();
  396.     }else{
  397.         QMessageBox::warning(this,"Warning","Open file error!");
  398.     }
  399. }

  400. void MainWindow::timerEvent(QTimerEvent * event)
  401. {
  402.     if(event->timerId() == scanNodeTimerID){
  403.         onlineCheck();
  404.     }

  405. }

  406. void MainWindow::onlineCheck(void)
  407. {
  408.     VCI_CAN_OBJ CAN_ReadData[200];
  409.     VCI_CAN_OBJ CAN_SendData;
  410.     int ret,i,k;
  411.     QString mac_str;
  412.     QString str;
  413.     ret = VCI_Receive(VCI_USBCAN2,
  414.                       ui->deviceIndexComboBox->currentIndex(),
  415.                       ui->channelIndexComboBox->currentIndex(),
  416.                       &CAN_ReadData[0],
  417.                       200);
  418.     for(k=0;k<ret;k++){
  419.         if((CAN_ReadData[k].ID&0xF)==GET_ADDR){
  420.             mac_str.sprintf("%02X%02X%02X%02X%02X%02X%02X%02X",
  421.                             CAN_ReadData[k].Data[0],CAN_ReadData[k].Data[1],
  422.                             CAN_ReadData[k].Data[2],CAN_ReadData[k].Data[3],
  423.                             CAN_ReadData[k].Data[4],CAN_ReadData[k].Data[5],
  424.                             CAN_ReadData[k].Data[6],CAN_ReadData[k].Data[7]);
  425.             for(i=1;i<128;i++){
  426.                 if(can_addr.local_addr[i]==0){
  427.                     can_addr.local_addr[i] = i;
  428.                     for(int j=0;j<8;j++){
  429.                         can_addr.mac_addr[i][j] = CAN_ReadData[k].Data[j];
  430.                         CAN_SendData.Data[j] = CAN_ReadData[k].Data[j];
  431.                     }
  432.                     CAN_SendData.DataLen = 8;
  433.                     CAN_SendData.ExternFlag = 0;
  434.                     CAN_SendData.RemoteFlag = 0;
  435.                     CAN_SendData.SendType = 0;
  436.                     CAN_SendData.ID = (i<<4)|ADDR_OK;//設置從機地址
  437.                     break;
  438.                 }else if(mac_str==model->item(i-1,1)->text()){
  439.                     for(int j=0;j<8;j++){
  440.                         CAN_SendData.Data[j] = CAN_ReadData[k].Data[j];
  441.                     }
  442.                     CAN_SendData.DataLen = 8;
  443.                     CAN_SendData.ExternFlag = 0;
  444.                     CAN_SendData.RemoteFlag = 0;
  445.                     CAN_SendData.SendType = 0;
  446.                     CAN_SendData.ID = (i<<4)|ADDR_OK;//設置從機地址
  447.                     break;
  448.                 }else{
  449.                     continue;
  450.                 }
  451.             }
  452.             if(i==128){
  453.                 CAN_SendData.DataLen = 0;
  454.                 CAN_SendData.ExternFlag = 0;
  455.                 CAN_SendData.RemoteFlag = 0;
  456.                 CAN_SendData.SendType = 0;
  457.                 CAN_SendData.ID = ADDR_ERROR;
  458.             }
  459.             ret = VCI_Transmit(VCI_USBCAN2,
  460.                                ui->deviceIndexComboBox->currentIndex(),
  461.                                ui->channelIndexComboBox->currentIndex(),
  462.                                &CAN_SendData,
  463.                                1);
  464.             if(ret!=1){
  465.                 QMessageBox::warning(this,"Warning","Send Data Error!");
  466.                 killTimer(scanNodeTimerID);
  467.             }else{
  468.                 //將正確獲取到設備地址的節點在界面列表里面顯示出來
  469.                 if((CAN_SendData.ID&0xF)!=ADDR_ERROR){
  470.                     str.sprintf("%d",i);
  471.                     model->item(i-1,0)->setText(str);
  472.                     model->item(i-1,1)->setText(mac_str);
  473.                 }
  474.             }
  475.         }
  476.     }
  477.     QCoreApplication::processEvents(QEventLoop::AllEvents);
  478.     //檢測在線狀態
  479.     for(i=0;i<model->rowCount();i++){
  480.         uint32_t local_addr,retry=0;
  481.         if(!model->item(i,0)->text().isEmpty()){
  482.             //清除之前接收的數據
  483.             VCI_ClearBuffer(VCI_USBCAN2,
  484.                             ui->deviceIndexComboBox->currentIndex(),
  485.                             ui->channelIndexComboBox->currentIndex());
  486.             local_addr = model->item(i,0)->text().toInt(NULL,0);
  487.             //發送在線檢測命令
  488.             CAN_SendData.DataLen = 0;
  489.             CAN_SendData.ExternFlag = 0;
  490.             CAN_SendData.RemoteFlag = 0;
  491.             CAN_SendData.SendType = 0;
  492.             CAN_SendData.ID = (local_addr<<4)|ONLINE_CHECK;
  493.             ret = VCI_Transmit(VCI_USBCAN2,
  494.                                ui->deviceIndexComboBox->currentIndex(),
  495.                                ui->channelIndexComboBox->currentIndex(),
  496.                                &CAN_SendData,
  497.                                1);
  498.             if(ret!=1){
  499.                 QMessageBox::warning(this,"Warning","Send Data Error!");
  500.             }
  501.             retry = 0;
  502.             while(1){
  503.                 ret = VCI_Receive(VCI_USBCAN2,
  504.                                   ui->deviceIndexComboBox->currentIndex(),
  505.                                   ui->channelIndexComboBox->currentIndex(),
  506.                                   &CAN_ReadData[0],
  507.                                   1);
  508.                 if((ret==1)&&(local_addr==(CAN_ReadData[0].ID>>4))&&((CAN_ReadData[0].ID&0xF)==CMD_OK)){
  509.                     mac_str.sprintf("%02X%02X%02X%02X%02X%02X%02X%02X",
  510.                                     CAN_ReadData[0].Data[0],CAN_ReadData[0].Data[1],
  511.                                     CAN_ReadData[0].Data[2],CAN_ReadData[0].Data[3],
  512.                                     CAN_ReadData[0].Data[4],CAN_ReadData[0].Data[5],
  513.                                     CAN_ReadData[0].Data[6],CAN_ReadData[0].Data[7]);
  514.                     model->item(i,1)->setText(mac_str);
  515.                     break;
  516.                 }else{
  517.                     if(retry<10){
  518.                         Sleep(10);
  519.                         retry++;
  520.                     }else{
  521.                         for(int c=0;c<model->columnCount();c++){
  522.                             model->item(i,c)->setText("");
  523.                         }
  524.                         can_addr.local_addr[i+1]=0;
  525.                         break;
  526.                     }
  527.                 }
  528.             }
  529.         }
  530.     }
  531.     QCoreApplication::processEvents(QEventLoop::AllEvents);
  532.     //獲取版本信息
  533.     for(i=0;i<model->rowCount();i++){
  534.         uint32_t local_addr,retry=0;
  535.         if(!model->item(i,0)->text().isEmpty()){
  536.             //清除之前接收的數據
  537.             VCI_ClearBuffer(VCI_USBCAN2,
  538.                             ui->deviceIndexComboBox->currentIndex(),
  539.                             ui->channelIndexComboBox->currentIndex());
  540.             local_addr = model->item(i,0)->text().toInt(NULL,0);
  541.             //發送在線檢測命令
  542.             CAN_SendData.DataLen = 0;
  543.             CAN_SendData.ExternFlag = 0;
  544.             CAN_SendData.RemoteFlag = 0;
  545.             CAN_SendData.SendType = 0;
  546.             CAN_SendData.ID = (local_addr<<4)|GET_VERSION;
  547.             ret = VCI_Transmit(VCI_USBCAN2,
  548.                                ui->deviceIndexComboBox->currentIndex(),
  549.                                ui->channelIndexComboBox->currentIndex(),
  550.                                &CAN_SendData,
  551.                                1);
  552.             if(ret!=1){
  553.                 QMessageBox::warning(this,"Warning","Send Data Error!");
  554.             }
  555.             retry = 0;
  556.             while(1){
  557.                 ret = VCI_Receive(VCI_USBCAN2,
  558.                                   ui->deviceIndexComboBox->currentIndex(),
  559.                                   ui->channelIndexComboBox->currentIndex(),
  560.                                   &CAN_ReadData[0],
  561.                                   1);
  562.                 if((ret==1)&&(local_addr==(CAN_ReadData[0].ID>>4))&&((CAN_ReadData[0].ID&0xF)==GET_VERSION)){
  563.                     str.sprintf("V%d.%d",CAN_ReadData[0].Data[0],CAN_ReadData[0].Data[1]);
  564.                     model->item(local_addr-1,2)->setText(str);
  565.                     break;
  566.                 }else{
  567.                     if(retry<10){
  568.                         Sleep(10);
  569.                         retry++;
  570.                     }else{
  571.                         break;
  572.                     }
  573.                 }
  574.             }
  575.         }
  576.     }
  577. }

  578. void MainWindow::on_openFilePushButton_clicked()
  579. {
  580.     QString fileName;
  581.     fileName=QFileDialog::getOpenFileName(this,
  582.                                           tr("Open files"),
  583.                                           "",
  584. ……………………

  585. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼


所有資料51hei提供下載:
CAN Bootloader.rar (440.04 KB, 下載次數: 68)


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏4 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:624979 發表于 2019-10-16 13:03 | 只看該作者
很實用!
回復

使用道具 舉報

板凳
ID:505032 發表于 2019-11-12 20:12 | 只看該作者
我下載了以后,解壓不了,顯示‘文件格式未知或者數據已經損壞’

請發一份我QQ郵箱:號871854638
謝!

回復

使用道具 舉報

地板
ID:650811 發表于 2019-12-4 16:09 | 只看該作者
正在學習CAN總線,學習一下
回復

使用道具 舉報

5#
ID:700459 發表于 2020-3-19 19:42 | 只看該作者
thank you
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久草热8精品视频在线观看 午夜伦4480yy私人影院 | 日韩精品一区二区在线 | 日韩免费视频一区二区 | 欧美日韩国产一区二区 | 午夜影院 | 日韩1区 | 国产成人网 | 在线国产一区二区三区 | a网站在线观看 | 69亚洲精品 | 久久久久国产精品一区二区 | 精品国产亚洲一区二区三区大结局 | 中文字幕精品一区二区三区精品 | 欧美精品在线免费 | 欧美国产日韩在线观看成人 | 91久久精品国产91久久性色tv | 日韩不卡在线 | 久草.com | 亚洲成人一区二区三区 | 天天操夜夜拍 | 91久久精品一区二区二区 | 金莲网| 国产精品视频一二三区 | 亚洲精品在线免费 | 夜夜爽99久久国产综合精品女不卡 | 久久久久久久网 | 午夜视频一区 | 日韩精品一区二区三区在线观看 | 欧美一级视频免费看 | 国产精品久久久久久吹潮日韩动画 | 九色国产 | 中文字幕av免费 | 久久国产精品一区二区三区 | 国产精品久久久久久久久图文区 | 国产欧美精品 | 国产欧美一区二区三区日本久久久 | 日本电影韩国电影免费观看 | 99热这里| 久久国产精品视频 | 国产精品区二区三区日本 | 毛片免费在线观看 |