Перейти к содержанию
    

mr_smit

Участник
  • Постов

    68
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные mr_smit


  1. Т.е. при выдаче в USART добавлять номер, а при получении номера обратно, просто считать файлы? И дойдя до нужного номера открывать? Это скорее всего будет очень долго.

  2. 32 minutes ago, jcxz said:

    хоть имя, хоть порядковый номер, хоть знак зодиака присвоенный файлу.

    Вот именно что присвоенный. Присваивать его в МК не хотелось бы. К тому же не понятно что делать с русскими именами в названиях. Сейчас включена поддержка длинных имен в FatFS и Unicode.  Но перед отправкой в USART всё равно приходится делать перекодировку из cp866 в win1251 чтобы правильно отобразить русский текст. Отсылать обратно русское имя и перекодировать его в МК опять же не удобно. Какой нибудь индекс файла в файловой системе решил бы все эти проблемы.

     

    В процессе поиска информации наткнулся где то на arduino форум и заметил что там они используют file.dirIndex(). Описания подробного так и не нашел. Вот и подумалось мне что это как то реализуемо.

    23 minutes ago, MrBearManul said:

    Вы уж сразу все подробности напишите. Чтобы мы тут в угадайку не играли.

    Так я ничего и не скрываю. Есть STM32 подключенный к ПК через преобразователь USART-USB на FT232. В свою очередь к STM32 ещё подключена SD карточка. Задача прочитать содержимое файла на SD карте, но его перед этим надо как то выбрать. Вот и вопрос как более правильно организовать этот выбор.

  3. Со стороны ПК будет самописная программа. Т.е. после получения списка файлов, надо как то обратно сообщить МК какой файл нас интересует.

     

    Да, можно отправить целиком название файла, но хотелось бы как то укоротить это до одного номера.

  4. Я наверное не правильно выразился. Терминальная программа это для примера. Меня интересует ЧТО отправить, а не КАК. Это вопрос больше по части кода для микроконтроллера. Как организовать такое взаимодействие.

    Можно в МК сделать присвоение:

    1  -  ПАПКА1

    2  -  Data1.txt

    3  -  SuperData.txt

    4  -  BigDataSuperMegaLog.txt

    5  -  Данные.txt

     

    Тогда после того как я отправлю список, в ответ достаточно будет отправить, например, 2, чтобы со стороны микроконтроллера обработать это и определить что пользователь выбрал Data1.txt. Ну а если файлов штук 150 ? Где этот список хранить. Да ещё и с длинными именами.

     

    Поэтому я и спрашиваю есть ли какие то "маркеры", чтобы отправлять по USART этот маркер перед названием файла. И не создавать большие массивы для присвоения номера.  Т.е. выдать в USART что то типа:

     

    15  -  ПАПКА1

    324  -  Data1.txt

    48  -  SuperData.txt

    194  -  BigDataSuperMegaLog.txt

    31  -  Данные.txt

     

    И выбор 194 будет означать BigDataSuperMegaLog.txt. Вроде какие то индексы есть у файлов, но не могу найти информацию на этот счет.

  5. Здравствуйте. Появилась следующая задача: к STM32F103C8T6 подключена SD карта по SPI. Библиотека FatFS. Микроконтроллер читает содержимое карты и выдает список файлов в USART. На ПК в терминальной программе я наблюдаю этот список. Но не могу понять как получить обратную связь от ПК, а именно как указать МК по USART что я выбрал какой либо файл?

    Пусть, например, на SD карте у меня 4 файла и одна папка. Я наблюдаю их в окне терминальной программы:

    ПАПКА1

    Data1.txt

    SuperData.txt

    BigDataSuperMegaLog.txt

    Данные.txt

    Как дать понять МК что я выбрал файл "Данные.txt" ? Чтобы он его прочитал и также выдал содержимое в USART. Или что я выбрал ПАПКА1 и МК прочитал содержимое этой папки и так же выдал в USART список файлов в ней. Пересылать названия скорее всего не очень правильная идея. Организовать буфер в МК и присвоить каждому файлу свой номер - не хватит ОЗУ. Может есть в FatFS какие то индексы у файлов?

     

    Читаю список так:

    Spoiler
    
    	FRESULT result;
    	FATFS FATFS_Obj;
    
    	DIR dir;
    	FILINFO fileInfo;
    	char *fn;
    
    	result = f_mount(&FATFS_Obj, "0:", 1);      // смонтировать диск
    	if (result != FR_OK)
    	  {
    		printf("SD Card error %d\r\n", result);
    	  }
    	else {
    	result = f_opendir(&dir, "/");  
    	if (result == FR_OK)
    	  {
    	    while (((result = f_readdir(&dir, &fileInfo)) == FR_OK) && fileInfo.fname[0])
    		  {
    			fn = fileInfo.fname;
    
    			if (fileInfo.fattrib & AM_DIR)
    			  {
    				USART_print(">");
    			  }
    			else
    			  {
    				USART_print("<");
    			  }
    
    			if (strlen(fn))
    			  {
    				Print_files(fn);
    			  }
    			else
    			  {
    				Print_files(fileInfo.fname);
    			  }
    		  }
    		}
    
    	f_closedir(&dir);

     

     

  6. Вам ведь только прием нужен?

    Нет. Нужна и передача.

     

    Припаялся к ножкам Tx и Rx микросхемы HA12241FP внутри магнитолы. На выходе прекрасный сигнал 0-5 В.

     

    post-51457-1436777706_thumb.jpg

     

    post-51457-1436778075_thumb.jpg

     

    Пока вижу 2 варианта:

     

    1. Выпаять трансивер из чейнджера. Чейнджер в мусор.

    2. Найти аналог HA12241FP. Уж за 12 лет должны были что то подобное придумать. Хотя кто знает.

  7. post-51457-1436765827_thumb.jpg

     

    В магнитоле для этого используется микросхема HA12241FP. Даташита на неё не нашел, нашел только на HA12240FP. Разница только в одной цифре, но смысл думаю тот же:

     

    post-51457-1436765922_thumb.png

     

    datasheet_HA12240FP.pdf

     

    Это драйвер шины с токовым выходом! Какой современный аналог взять? Не могу найти.

     

    P.S. В 2003 году такой CD эмулятор собирали, но там использовали схему на компараторе для чтения данных. Я её тоже навесным монтажом собрал, подключил и вот:

     

    post-51457-1436766585_thumb.jpg

     

    Но хочется принимать и передавать через одну микросхему. Подскажите какую взять?

  8. Ради спортивного интереса решил сделать эмулятор CD чейнджера для своей старенькой магнитолы Pioneer 88. Посмотрел обмен на шине. Там похоже CAN шина:

     

    post-51457-1436457620_thumb.jpg

     

    Амплитуда сигнала 100 мВ. Как этот сигнал привести к уровню 0-5 или 0-3.3 вольта?

     

    Т.е. вот тут амплитуда 1 вольт:

    post-51457-1436457401_thumb.png

    А у меня 100 мВ.

     

    Пробовал трансивер TJA1050, но он на выходе дает TTL сигнал амплитудой 200 мВ. Естественно ни логический анализатор ни контроллер не воспринимает этот уровень. Как получить 0-5 В ?

  9. И всё равно я не могу передать изображение :( Взял png изображение размером 2179 байт. Открыл через HEX редактор. Создал массив байт:

    const char Img [2179] =
    {
    0x89,0x50,0x4E,0x47,0x0D...
    ...
    };

    И пробую передать по запросу в браузер. В состоянии http_state[sn]==HTTP_IDLE формирую заголовок:

    if(strcmp(url,"/test.png")==0)
                  {
                    strcpy((char*)buf,http_200);
                    strcat((char*)buf, http_server);
                    strcat((char*)buf,"Connection: close\r\n");
                    strcat((char*)buf,"Content-Length: ");
                    itoa(sizeof(Img),str);
                    strcat((char*)buf,str);
                    strcat((char*)buf,"\r\n");
                    strcat((char*)buf,"Content-Type: image/png\r\n");
                    strcat((char*)buf, http_header_end);
                    header_sz=strlen((char*)buf);
                    http_state[sn]=HTTP_SENDING;
                  }

    В состоянии http_state[sn]==HTTP_SENDING отправляю изображение по частям:

    if(http_state[sn]==HTTP_SENDING)
             {
                 ret = send(sn,buf,header_sz);   // заголовок
                 ret = send(sn,&Img[0],2048);    // первые 2048 байт изображения
                 ret = send(sn,&Img[2048],130);  // остаток
                 HTTP_reset(sn);
                 disconnect(sn);
             }

    В итоге при обращении по адресу 192.168.1.25/test.png браузер показывает изображение, но только эти первые 2048 байт. Последние байты не отображаются. Т.е. не передаются.

    post-51457-1431877831_thumb.png

    Я не понимаю почему так. Хоть убейте. Почему при вызове функции send второй раз она ничего не передает??

  10. mr_smit стесняюсь спросить, неужели не видно задержки тут ? vTaskDelayUntil(&xLastWakeTime, 300);

    Вы уже столько кода привели что в каждую строчку не вникнешь. Я говорил про саму идею реализации. Где возможны грабли. Если вы это всё уже учли, то это хорошо. Надо дальше искать.

     

    P.S. Тем не менее не понимаю почему бы не подключить бортовик к зажиганию и не морочить дальше голову.

  11. что значит не выходит? То есть символы идут а прерывания нет? Или символы тоже не идут?

    Поддержу. Это бы желательно проверить.

     

    но если эбу выключить и включить(типо обрыв), после 5ти таймаутов о не получении код начинается сначала и уже в прерывание уарт не входит после 5бод слоу инита, тут делаю ресет nvic reset и линк поднимается

     

    Типо обрыв это нифига не выкл/вкл. После включения ЭБУ как минимум 300 мс "запускается". Об этом даже в протоколе говорится. Нельзя раньше 300 мс после включения ничего слать. Поэтому, возможно, вы просто не выжидаете эти 300 мс и делаете сброс, а пока инициализация STM-ки закончится, тут уже и ЭБУ просыпается. Сколько ваши "5 таймаутов" длятся?

     

    Включайте свою поделку одновременно с зажиганием. Я, в своё время, просто от замка зажигания запитал бортовик и всё. Включили зажигание - подключились, показали параметры. Выключили зажигание - бортовик потух. Один хрен ЭБУ выходит на связь только при включенном зажигании. К чему весь этот велосипед с "делаю ресет".

  12. Да, подзабыл.

    RXNE - This bit is set by hardware when the content of the RDR shift register has been transferred to

    the USART_DR register. An interrupt is generated if RXNEIE=1 in the USART_CR1 register.

    It is cleared by a read to the USART_DR register.

     

    добавил NVIC_SystemReset(); в случае обрыва и оно как бы работает, почемуто уарт нормально запускается только после ресета(

    Судя по всему то что работает это чистая случайность. Никаких обрывов быть не должно. Не знаю как там у японцев, но я когда бортовик себе под BOSCH делал - никаких обрывов не было. Связь очень стабильная. Мне кажется вы что то перемудрили с USARTом оттого и глючит.

     

    Ну вот элементарно:

    Usart_Send_symbol(0x70, KLINE_UART);

    вставлять это в прерывании, мягко говоря, не правильно. Ни на AVR ни на STM32.

     

    А это что?

    void UART4_IRQHandler()
    {
    
    ...
    
    if(USART_GetITStatus(UART4, USART_SR_ORE) == SET)
    {
        USART_ReceiveData(UART4);
      }
    }

     

    Я бы так сделал:

    #define Connect      1
    #define ReadData     2
    
    int mode;
    
    #define BUFFER_SIZE 200
    unsigned char buffer[BUFFER_SIZE];                       // приемный буфер
    
    volatile unsigned char   counter;    // счетчик принятых байт
    
    // прерывание USART
    if если байт успешно приняли
       {
       buffer[counter] = data;   // положили его в буфер
       if (++counter == BUFFER_SIZE) {
         counter = 0;
         }
       }
    
    void main(void)
    { 
      ...
      while (1) 
      {
      switch (mode)               // смотрим в каком режиме находимся
       {                               
        case Connect:            // если только что включились => подключаемся к ЭБУ
        //
        // если всё хорошо
        //
        mode = ReadData;     // переходим в режим чтения информации
    
        case ReadData:
        //
        //  отправляем -> читаем
        //
      }
    }
    }

    В прерывании USART надо только положить байт в буфер и больше ничего.

     

    P.S. А вообще можно и обычный Init сделать и не заморачиваться с этим fast 5 baud. Единственное старые мозги могут его не поддерживать. Ну ооочень старые. И тогда всё сведется к тому что надо будет дрыгнуть ногой и потом отослать строчку вида 81 10 f1 81 03 на нормальной скорости 10400 и потом на ней же работать. Только адрес ЭБУ подобрать (0-255). На каком откликнется с тем и работать. Я вот с Relault Logan такой финт хочу сделать, только всё руки не доходят.

  13. В обработчике прерывания от USART надо сбрасывать флаг прерывания:

    void UART4_IRQHandler()
    {
        uint8_t data;
    //    portBASE_TYPE xStatus;
    
        if((UART4->SR & USART_SR_RXNE))
        {
    
          UART4->SR&=~USART_SR_RXNE; // сбрасываем флаг прерывания
    
          data = UART4->DR;
    
    ......

     

    Опечатка: не USART4->SR..., а UART4->SR... в вашем случае. Поправил.

  14. Передатчик передаёт

    500+500+24

    Приёмник МОЖЕТ принять

    24+100+100+300+400+50+50

     

    почувствуйте разницу...

    Выходит надо учитывать переменную ret. Это число реально переданных байт. И в зависимости от неё двигать указатель в буфере отправки buf при посылке следующей части. Но вопрос о прикреплении заголовка к каждой части посылки остается открытым.

     

  15. Кстати, его код пробовали разобрать для понимания? То есть, его последовательность действий:

    Чтение файла, обработка, передача... и т.п.?

    Так я его исходник и правлю. Функция Send, как я понимаю, сама следит за передающим буфером:

    int32_t send(uint8_t sn, uint8_t * buf, uint16_t len)
    {
      uint8_t tmp=0;
      uint16_t freesize=0;
    
      CHECK_SOCKNUM();
      CHECK_SOCKMODE(Sn_MR_TCP);
      CHECK_SOCKDATA();
      tmp = getSn_SR(sn);
      if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS;
      if( sock_is_sending & (1<<sn) )
      {
      tmp = getSn_IR(sn);
      if(tmp & Sn_IR_SENDOK)
      {
    	 setSn_IR(sn, Sn_IR_SENDOK);
    	 #if _WZICHIP_ == 5200
    		if(getSn_TX_RD(sn) != sock_next_rd[sn])
    		{
    		   setSn_CR(sn,Sn_CR_SEND);
    		   while(getSn_CR(sn));
    		   return SOCKERR_BUSY;
    		}
    	 #endif
    	 sock_is_sending &= ~(1<<sn);		 
      }
      else if(tmp & Sn_IR_TIMEOUT)
      {
    	 close(sn);
    	 return SOCKERR_TIMEOUT;
      }
      else return SOCK_BUSY;
      }
      freesize = getSn_TxMAX(sn);
      if (len > freesize) len = freesize; // check size not to exceed MAX size.
      while(1)
      {
      freesize = getSn_TX_FSR(sn);
      tmp = getSn_SR(sn);
      if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
      {
    	 close(sn);
    	 return SOCKERR_SOCKSTATUS;
      }
      if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
      if(len <= freesize) break;
      }
      wiz_send_data(sn, buf, len);
      #if _WIZCHIP_ == 5200
      sock_next_rd[sn] = getSn_TX_RD(sn) + len;
      #endif
      setSn_CR(sn,Sn_CR_SEND);
      /* wait to process the command... */
      while(getSn_CR(sn));
      sock_is_sending |= (1 << sn);
      return len;
    }

     

    А отправляет он так:

    if(fs[sn].fsize != sentsize[sn])
                    {
    
                      f_read(&fs[sn], &buf[header_sz], DATA_BUF_SIZE-header_sz, &blocklen);
    
                       ret = send(sn,buf,blocklen+header_sz);
    
                       if(ret < 0)
                       {
                        f_close(&fs[sn]);
                        close(sn);
                        return ret;
                       }
    
                      sentsize[sn] += ret; // Don't care SOCKERR_BUSY, because it is zero.
                     }

    Читает с карты 2048 байт минус размер HTTP заголовка (DATA_BUF_SIZE-header_sz). А отправляет по факту каждый раз 2048 байт (blocklen+header_sz) кроме последней итерации.

     

    Сейчас только заметил blocklen+header_sz. Может надо HTTP заголовок отправлять с каждым куском данных??? Я то сейчас отправляю заголовок, а потом просто куски картинки. А у него в буфере каждый раз оказывается заголовок + новая порция считанных данных &buf[header_sz]. Правильно?

  16. Сделал так:

    ret = send(sn,buf,size);  // отправляем заголовок
    
    ret = send(sn,(char*)Img1,sizeof(Img1)); // картинка по частям
    ret = send(sn,(char*)Img2,sizeof(Img2)); //
    ret = send(sn,(char*)Img3,sizeof(Img3)); //
    
    disconnect(sn);

    в итоге загружается только первая треть картинки или даже меньше:

    post-51457-1431523497.jpg

  17. int32_t send(uint8_t sn, uint8_t * buf, uint16_t len)

     

    Я пока никак не пойму можно ли большой массив передать порциями по 2 КБ. В смысле поддерживает само железо такой финт или нет. Но судя по всему поддерживает, ведь человек из вышеприведенной статьи как то загружает сайт с SD карточки.

  18. В общем работают оба способа. Если при запросе картинки отдать сначала заголовок, а потом сырые данные картинки, то она отображается.

    ret = send(sn,buf,size);
    ret = send(sn,(char*)Img, sizeof(Img));

     

    Так же можно вставить картинку в кодировке base64 непосредственно в html код страницы.

    const char site[] =
            "<html>"
            "<head>"
            "<title>Умный дом</title>"
            "<meta http-equiv='content-type' content='text/html; charset=windows-1251'>"
            "</head>"
        "<body>"
            "<br><br><br><center><b>Тестовая страница W5500</b></center><br>"
            "<center><img src='data:image/png;base64,"
    
            "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A"
            "/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB98FCg4BIKAKV80AAAAZdEVYdENv"
            "bW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAKElEQVQI102LQQ4AMAjCqP//cz0Y3bg0lEAS"
            "NZtSgddnP1WDU/xnoAGOzg8GbihEeAAAAABJRU5ErkJggg=="
                    "'></center>"
        "</body>"
        "</html>";

     

    В этом случае при запросе страницы она открывается корректно с картинкой. Но когда я взял картинку размером 5 КБ, то страница не открывается. Постоянно висит ожидание.

     

    Размер передающего буфера 2 КБ. Т.е. надо разбить данные на блоки. Вот это место:

    ...
    sentsize[sn]=0;
    ...
    
    if(http_state[sn]==HTTP_SENDING)
                   {
                     while (sentsize[sn] < size)
                     {
                     ret = send(sn,buf+sentsize[sn],size-sentsize[sn]);
    
                          if(ret < 0)
                          {
                          close(sn);
                          return ret;
                          }
    
                     sentsize[sn] += ret;   // Don't care SOCKERR_BUSY, because it is zero.
                     }
                     HTTP_reset(sn);
                     disconnect(sn);
                  }

     

    ret длина реально отправленных данных. Опять же не уловлю в чем проблема.

  19. конечно же затрёт. И ещё пять копеек. Картинку Вы точно в бинарном виде собрались передавать, а не в base64?

    В бинарном. Я посмотрел, браузер получает картинки в чистом виде. Для этого указывается тип (image/png, image/jpg и т.д.) и количество байт.

     

    Хотя черт его знает:

    post-51457-1431422109_thumb.png

     

    Надо попробовать в base64 конвертнуть и strcat-ом приклеить.

  20. strcat((char*)buf, http_header_end); // Заголовок... и всё, что до него.
    size=strlen((char*)buf); // Текущий размер строк в буфере
    memcpy((char*)buf,Img[0]*, sizeof(Img)); // Копируем картинку в буфер.
    size += sizeof(Img); // Увеличиваем на размер картинки.

     

    А в таком случае разве memcpy не затрет buf? И в buf будет только сама картинка без заголовков?

     

    Может отправить сначала заголовок, а затем картинку?

    ret = send(sn,buf, strlen(buf));
    ret = send(sn, Img, sizeof(Img));

  21. Но функция копирования строки останавливается на символе 0x00 - нуль-терминатор.

    Вам нужен бинарный буфер вместо строкового.

    И попробуйте сделать через memcpy:

    Точно. Похоже на правду. Спасибо! Проверить, к сожалению, смогу только вечером.

×
×
  • Создать...