Технический форум по робототехнике.
Dusk » 25 май 2011, 16:45
Появилась проблема, которая заключается в следующем: при отправке байта через com порт с микроконтроллера, он доходит до компа со случайным значением. Т.е. мы ждем-ждем - нет байта, отправили - он пришел, но значение его не то, что отправляли.
Вот код для pic:
- Код: Выделить всё • Развернуть
#include <pic.h>
void transmit(unsigned char byte) {
while(!TXIF) continue;
TXREG= byte;
}
void main(void) {
SPBRG= 2; //4MHz, 19200
BRGH= 0; //4MHz, 19200
SYNC= 0;
SPEN= 1;
TXIE= 0;
TX9= 0;
TXEN= 1;
GIE= 0;
PEIE= 0;
TRISB= 0;
PORTB= 0;
RCREG= 0;
while (1) {
transmit(50);
};
}
Это для PC:
- Код: Выделить всё • Развернуть
//______________________________________________________tcom_port___________________________________________________________
//--------------------------------------------------------------------------------------------------------------------------
class tcom_port {
HANDLE hcom_;
COMMTIMEOUTS commTimeOuts_;
DCB portDcb_;
static const char* pdefault_name;
char* pname;
public:
tcom_port();
bool open();
void close();
bool set_baud_rate(const int nrate);
bool write(const char* pbuffer, int length);
bool read (const char* pbuffer, int length, int* pnread);
~tcom_port();
};
const char* tcom_port::pdefault_name= "COM1";
//_____________________________________
tcom_port::tcom_port(): hcom_(NULL), pname((char*)pdefault_name) {
commTimeOuts_.ReadIntervalTimeout= 1;
commTimeOuts_.ReadTotalTimeoutMultiplier= 1;
commTimeOuts_.ReadTotalTimeoutConstant= 1;
commTimeOuts_.WriteTotalTimeoutMultiplier= 1;
commTimeOuts_.WriteTotalTimeoutConstant= 1;
memset(&portDcb_, 0, sizeof(portDcb_)); portDcb_.DCBlength=sizeof(portDcb_);
};
//_____________________________________
bool tcom_port::open() {
hcom_ = CreateFileA(pname, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);
if ( hcom_==INVALID_HANDLE_VALUE ) return false;
if ( !SetCommTimeouts(hcom_, &commTimeOuts_) ) return false;
if ( !GetCommState(hcom_, &portDcb_) ) return false;
return true;
};
//_____________________________________
void tcom_port::close() {
if (hcom_) { CloseHandle(hcom_); hcom_= NULL; };
};
//_____________________________________
bool tcom_port::set_baud_rate(const int nrate) {
if ( !GetCommState(hcom_, &portDcb_) ) return false;
portDcb_.BaudRate= nrate;
if ( !SetCommState(hcom_, &portDcb_) ) return false;
return true;
};
//_____________________________________
bool tcom_port::write(const char* pbuffer, int length) {
DWORD dwWritten= 0;
if ( !WriteFile(hcom_, (void*)pbuffer, length, &dwWritten, NULL) ) return false;
return dwWritten==length;
};
//_____________________________________
bool tcom_port::read (const char* pbuffer, int length, int* pnread) {
if ( !ReadFile(hcom_, (void*)pbuffer, length, (DWORD*)pnread, NULL) ) return false;
return true;
};
//_____________________________________
tcom_port::~tcom_port() {
if (hcom_) CloseHandle(hcom_);
};
//__________________________________________________________________________________________________________________________
//--------------------------------------------------------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, INT ) {
char value1= 8;
char read_value= 100;
int nread= 0;
tcom_port com_port;
com_port.open();
com_port.set_baud_rate(19200);
while (true ) {
while ( nread==0 ) com_port.read(&read_value, 1, &nread);;
};
return 0;
};
//__________________________________________________________________________________________________________________________
//--------------------------------------------------------------------------------------------------------------------------
С чем это может быть связано?
dccharacter » 25 май 2011, 22:33
Сделайте без "кода для ПС". Запустите терминал, переключитесь в 16-тиричный режим, и посмотрите, что прилетает на терминал.
Также, повесьте на какаую-нить ногу на ПИКе светодиод и включайте/выключайте его раз в секунду, чтобы убедиться, что МК работает реально на 4МГц
Добавлено спустя 5 минут 11 секунд:
глупый вопрос - а какое значение получаете на компе? не 0x32 случаем?
Dusk » 26 май 2011, 09:21
У меня плата PICDEM 2 PLUS DEMO BOARD, на ней контроллер, на генераторе написано "TWT 4.000/5V MHZ", плата подключена к PC через MPLAB ICD2, через USB, COM порт напрямую в PC. Там есть светодиоды на плате, для порта B,я ими мигал, там все четко, что посылаешь, то и отображается. По времени не пробовал ровно через секунду, сейчас попробую. Тестирую через MPLAB IDE, вы какой терминал имели в виду? Мне что дали, то я и использую.
А приходит на PC например 66, 101, 22... После каждого открытия порта - новое значение. Пока порт открыт - одно и тоже, но левое. Если б я получал 0x32, то вопроса бы не возникло, я ж его и посылаю

dccharacter » 26 май 2011, 14:37
RealTerm
Dusk » 26 май 2011, 15:42
Микроконтроллеры не только в роботах есть.
dccharacter » 26 май 2011, 15:47
это нонсенс
если серьезно - при чем тут роботы? У вас в самописную прогу сыпется какой-то мусор. Я предлагаю устранить прокладку из непонятного кода и посмотреть что там реально летит в терминал. Вы в ответ мне о каких-то своих квази-гениальных наблюдениях рассказываете.
Dusk » 26 май 2011, 15:58
Терминал это что?
dccharacter » 26 май 2011, 16:12
Программа, которая покажет, что валится в порт
PuTTy (не умеет байты показывать, только аски)
RealTerm (который я советую)
еще стопицот разных программ
Dusk » 26 май 2011, 16:29
HyperTerminal стандартный, виндовый, то же самое выдает. Один и тот же байт, но при каждом старте новый. Запустил терминалку - один байт постоянно. Закрыл и запусти заново, другой байт постоянно.
dccharacter » 26 май 2011, 16:43
С какой ноги(ТХ) МК снимаете сигнал? Почему в приведенном коде какие-то манипуляции с портом B, когда ТХ - это RC6?
Добавлено спустя 1 минуту 16 секунд:
Сделайте BRGH = 1 и SPBRG = 12
Добавлено спустя 1 минуту 9 секунд:
В настройках ком-порта сделайте 19200 8n1
Dusk » 26 май 2011, 16:46
RC6/RC7 вообще говоря плата то сама стандартная, она в коробке с Microchip MPLab ICD 2 шла.
Порт B можно убрать, от этого ничего не зависит.
В настройках порта:
bits per second: 19200
Data bits: 8
Parity: none
Stop bits: 1
Flow control: hardware
Последний раз редактировалось
Dusk 26 май 2011, 16:51, всего редактировалось 1 раз.
dccharacter » 26 май 2011, 16:56
На этой плате такт выбирается конфигурацией джамперов - проверить, что нужный кварц выбран
Добавлено спустя 1 минуту 33 секунды:
Плюс в прошивке надо включить внешний кварц - в конфигурационном слове HS
Добавлено спустя 2 минуты 7 секунд:
Дальше, МПЛАБ ИЦД используется как ин-сёкит дебаггер и висит на (та-дам!) ногах RC6/RC7
Чтобы получить кайф, надо дебаггер отключить, подключить кабель к 9-ти пиновому выходу и на ком-порт компа, сконфигурировать ЮСАРТ....
Добавлено спустя 2 минуты 11 секунд:
А, вру-вру. Сам перепутал, это RB6/RB7
Но это дебаггер - это не RS232-USB переходник!
Добавлено спустя 54 секунды:
или у тебя и то и то подключено... не пойму. Ну попробуй раз в секунду помигать светиком.
Dusk » 27 май 2011, 11:27
Поставил HS - ситуация стала следующей. Первая передача проходит нормально, до того, как я закрою порт или окно терминалки. После открытия окна терминалки заново (другими словами порта) туда либо ничего не приходит, либо приходит мусор. Надо остановить микроконтроллер, закрыть терминалку и повторить сначала. Другими словами, микроконтроллер не может быть постоянно включен, его надо каждый раз перезагружать, если я собираюсь считывать с порта неважно чем, терминалкой или руками. Это неподходит, он должен все время работать.
Подключено так: на плате есть спец. разъем для коробочки ICD 2, куда она и подключена. Дальше ICD 2 подключена к USB PC. Через неё IDE общается с микроконтроллером.
Другой разъем на плате - это COM порт, он напрямую подключен к PC, через него терминалка общается с микроконтроллером, ну или я руками.
Теперь нужна идея, как сделать так, чтобы начинать/заканчивать работу с микроконтроллером не перезагружая его.
dccharacter » 27 май 2011, 11:39
Надо понять, почему он перегружается. У ПИКов есть регистр-флаг, который поднимается, если сбоит тактовый генератор. Выведи этот флаг на какую-нить ногу и повесь туда светодиод - это поможет тебе узнать, остаемся ли мы на том же тактовом генераторе.
Потом, сделай какой-нибудь флаг ресета. Типа, в начале программы зажечь светодиод. Этот светодиод можно погасить нажатием кнопки. Запускаешь все, светодиод горит. Убеждаешься, что все работает, гасишь его кнопкой. Запускаешь терминал, ловишь "правильные" байты в него. Закрываешь терминал. Если светодиод загорелся - произошел ресет. Дальше будешь копать - из-за чего.
Dusk » 27 май 2011, 11:59
Так нет, перезагружаю я его вручную, в дебаггере. Потому что только после перезагрузки микроконтроллера в PC с него начинают поступать правильные байты. Если микроконтроллер не перезагружать, то PC начинает ловить неправильные байты после закрытия/открытия терминалки(порта).