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

mr_smit

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

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

  • Посещение

Весь контент mr_smit


  1. Ладно, думаю действительно проще будет передавать названия целиком и не заморачиваться. Всем спасибо )
  2. Т.е. при выдаче в USART добавлять номер, а при получении номера обратно, просто считать файлы? И дойдя до нужного номера открывать? Это скорее всего будет очень долго.
  3. Вот именно что присвоенный. Присваивать его в МК не хотелось бы. К тому же не понятно что делать с русскими именами в названиях. Сейчас включена поддержка длинных имен в FatFS и Unicode. Но перед отправкой в USART всё равно приходится делать перекодировку из cp866 в win1251 чтобы правильно отобразить русский текст. Отсылать обратно русское имя и перекодировать его в МК опять же не удобно. Какой нибудь индекс файла в файловой системе решил бы все эти проблемы. В процессе поиска информации наткнулся где то на arduino форум и заметил что там они используют file.dirIndex(). Описания подробного так и не нашел. Вот и подумалось мне что это как то реализуемо. Так я ничего и не скрываю. Есть STM32 подключенный к ПК через преобразователь USART-USB на FT232. В свою очередь к STM32 ещё подключена SD карточка. Задача прочитать содержимое файла на SD карте, но его перед этим надо как то выбрать. Вот и вопрос как более правильно организовать этот выбор.
  4. Со стороны ПК будет самописная программа. Т.е. после получения списка файлов, надо как то обратно сообщить МК какой файл нас интересует. Да, можно отправить целиком название файла, но хотелось бы как то укоротить это до одного номера.
  5. Я наверное не правильно выразился. Терминальная программа это для примера. Меня интересует ЧТО отправить, а не КАК. Это вопрос больше по части кода для микроконтроллера. Как организовать такое взаимодействие. Можно в МК сделать присвоение: 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. Вроде какие то индексы есть у файлов, но не могу найти информацию на этот счет.
  6. Здравствуйте. Появилась следующая задача: к STM32F103C8T6 подключена SD карта по SPI. Библиотека FatFS. Микроконтроллер читает содержимое карты и выдает список файлов в USART. На ПК в терминальной программе я наблюдаю этот список. Но не могу понять как получить обратную связь от ПК, а именно как указать МК по USART что я выбрал какой либо файл? Пусть, например, на SD карте у меня 4 файла и одна папка. Я наблюдаю их в окне терминальной программы: ПАПКА1 Data1.txt SuperData.txt BigDataSuperMegaLog.txt Данные.txt Как дать понять МК что я выбрал файл "Данные.txt" ? Чтобы он его прочитал и также выдал содержимое в USART. Или что я выбрал ПАПКА1 и МК прочитал содержимое этой папки и так же выдал в USART список файлов в ней. Пересылать названия скорее всего не очень правильная идея. Организовать буфер в МК и присвоить каждому файлу свой номер - не хватит ОЗУ. Может есть в FatFS какие то индексы у файлов? Читаю список так:
  7. Фраза из даташита: "Valid Output With as Little as 50 mV Input Voltage Difference". Только боюсь уровни у неё не те.
  8. Нет. Нужна и передача. Припаялся к ножкам Tx и Rx микросхемы HA12241FP внутри магнитолы. На выходе прекрасный сигнал 0-5 В. Пока вижу 2 варианта: 1. Выпаять трансивер из чейнджера. Чейнджер в мусор. 2. Найти аналог HA12241FP. Уж за 12 лет должны были что то подобное придумать. Хотя кто знает.
  9. В магнитоле для этого используется микросхема HA12241FP. Даташита на неё не нашел, нашел только на HA12240FP. Разница только в одной цифре, но смысл думаю тот же: datasheet_HA12240FP.pdf Это драйвер шины с токовым выходом! Какой современный аналог взять? Не могу найти. P.S. В 2003 году такой CD эмулятор собирали, но там использовали схему на компараторе для чтения данных. Я её тоже навесным монтажом собрал, подключил и вот: Но хочется принимать и передавать через одну микросхему. Подскажите какую взять?
  10. Ради спортивного интереса решил сделать эмулятор CD чейнджера для своей старенькой магнитолы Pioneer 88. Посмотрел обмен на шине. Там похоже CAN шина: Амплитуда сигнала 100 мВ. Как этот сигнал привести к уровню 0-5 или 0-3.3 вольта? Т.е. вот тут амплитуда 1 вольт: А у меня 100 мВ. Пробовал трансивер TJA1050, но он на выходе дает TTL сигнал амплитудой 200 мВ. Естественно ни логический анализатор ни контроллер не воспринимает этот уровень. Как получить 0-5 В ?
  11. И всё равно я не могу передать изображение :( Взял 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 байт. Последние байты не отображаются. Т.е. не передаются. Я не понимаю почему так. Хоть убейте. Почему при вызове функции send второй раз она ничего не передает??
  12. stm32 uart kline 5baud slow init

    Вы уже столько кода привели что в каждую строчку не вникнешь. Я говорил про саму идею реализации. Где возможны грабли. Если вы это всё уже учли, то это хорошо. Надо дальше искать. P.S. Тем не менее не понимаю почему бы не подключить бортовик к зажиганию и не морочить дальше голову.
  13. stm32 uart kline 5baud slow init

    Поддержу. Это бы желательно проверить. Типо обрыв это нифига не выкл/вкл. После включения ЭБУ как минимум 300 мс "запускается". Об этом даже в протоколе говорится. Нельзя раньше 300 мс после включения ничего слать. Поэтому, возможно, вы просто не выжидаете эти 300 мс и делаете сброс, а пока инициализация STM-ки закончится, тут уже и ЭБУ просыпается. Сколько ваши "5 таймаутов" длятся? Включайте свою поделку одновременно с зажиганием. Я, в своё время, просто от замка зажигания запитал бортовик и всё. Включили зажигание - подключились, показали параметры. Выключили зажигание - бортовик потух. Один хрен ЭБУ выходит на связь только при включенном зажигании. К чему весь этот велосипед с "делаю ресет".
  14. stm32 uart kline 5baud slow init

    Да, подзабыл. Судя по всему то что работает это чистая случайность. Никаких обрывов быть не должно. Не знаю как там у японцев, но я когда бортовик себе под 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 такой финт хочу сделать, только всё руки не доходят.
  15. stm32 uart kline 5baud slow init

    В обработчике прерывания от 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... в вашем случае. Поправил.
  16. Выходит надо учитывать переменную ret. Это число реально переданных байт. И в зависимости от неё двигать указатель в буфере отправки buf при посылке следующей части. Но вопрос о прикреплении заголовка к каждой части посылки остается открытым.
  17. Так я его исходник и правлю. Функция 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]. Правильно?
  18. Сделал так: 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); в итоге загружается только первая треть картинки или даже меньше:
  19. int32_t send(uint8_t sn, uint8_t * buf, uint16_t len) Я пока никак не пойму можно ли большой массив передать порциями по 2 КБ. В смысле поддерживает само железо такой финт или нет. Но судя по всему поддерживает, ведь человек из вышеприведенной статьи как то загружает сайт с SD карточки.
  20. Речь о версии 2.0.2. Тоже столкнулся с этой проблемой. Где галочки ставить что я подключаю библиотеки USART, SPI и т.д.
  21. В общем работают оба способа. Если при запросе картинки отдать сначала заголовок, а потом сырые данные картинки, то она отображается. 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 длина реально отправленных данных. Опять же не уловлю в чем проблема.
  22. В бинарном. Я посмотрел, браузер получает картинки в чистом виде. Для этого указывается тип (image/png, image/jpg и т.д.) и количество байт. Хотя черт его знает: Надо попробовать в base64 конвертнуть и strcat-ом приклеить.
  23. 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));
  24. Точно. Похоже на правду. Спасибо! Проверить, к сожалению, смогу только вечером.
×
×
  • Создать...