roboforum.ru

Технический форум по робототехнике.


PIC 16F877A, случайное значение в порту

Программирование микроконтроллеров AVR, PIC, ARM.
Разработка и изготовление печатных плат для модулей.

PIC 16F877A, случайное значение в порту

Сообщение 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;
};
//__________________________________________________________________________________________________________________________
//--------------------------------------------------------------------------------------------------------------------------



С чем это может быть связано?
Dusk
 
Сообщения: 8
Зарегистрирован: 25 май 2011, 16:31

Re: PIC 16F877A, случайное значение в порту

Сообщение dccharacter » 25 май 2011, 22:33

Сделайте без "кода для ПС". Запустите терминал, переключитесь в 16-тиричный режим, и посмотрите, что прилетает на терминал.

Также, повесьте на какаую-нить ногу на ПИКе светодиод и включайте/выключайте его раз в секунду, чтобы убедиться, что МК работает реально на 4МГц

Добавлено спустя 5 минут 11 секунд:
глупый вопрос - а какое значение получаете на компе? не 0x32 случаем?
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: PIC 16F877A, случайное значение в порту

Сообщение 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, то вопроса бы не возникло, я ж его и посылаю :)
Dusk
 
Сообщения: 8
Зарегистрирован: 25 май 2011, 16:31

Re: PIC 16F877A, случайное значение в порту

Сообщение dccharacter » 26 май 2011, 14:37

RealTerm
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: PIC 16F877A, случайное значение в порту

Сообщение Dusk » 26 май 2011, 15:42

Микроконтроллеры не только в роботах есть.
Dusk
 
Сообщения: 8
Зарегистрирован: 25 май 2011, 16:31

Re: PIC 16F877A, случайное значение в порту

Сообщение dccharacter » 26 май 2011, 15:47

это нонсенс

если серьезно - при чем тут роботы? У вас в самописную прогу сыпется какой-то мусор. Я предлагаю устранить прокладку из непонятного кода и посмотреть что там реально летит в терминал. Вы в ответ мне о каких-то своих квази-гениальных наблюдениях рассказываете.
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: PIC 16F877A, случайное значение в порту

Сообщение Dusk » 26 май 2011, 15:58

Терминал это что?
Dusk
 
Сообщения: 8
Зарегистрирован: 25 май 2011, 16:31

Re: PIC 16F877A, случайное значение в порту

Сообщение dccharacter » 26 май 2011, 16:12

Программа, которая покажет, что валится в порт
PuTTy (не умеет байты показывать, только аски)
RealTerm (который я советую)
еще стопицот разных программ
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: PIC 16F877A, случайное значение в порту

Сообщение Dusk » 26 май 2011, 16:29

HyperTerminal стандартный, виндовый, то же самое выдает. Один и тот же байт, но при каждом старте новый. Запустил терминалку - один байт постоянно. Закрыл и запусти заново, другой байт постоянно.
Dusk
 
Сообщения: 8
Зарегистрирован: 25 май 2011, 16:31

Re: PIC 16F877A, случайное значение в порту

Сообщение dccharacter » 26 май 2011, 16:43

С какой ноги(ТХ) МК снимаете сигнал? Почему в приведенном коде какие-то манипуляции с портом B, когда ТХ - это RC6?

Добавлено спустя 1 минуту 16 секунд:
Сделайте BRGH = 1 и SPBRG = 12

Добавлено спустя 1 минуту 9 секунд:
В настройках ком-порта сделайте 19200 8n1
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: PIC 16F877A, случайное значение в порту

Сообщение 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 раз.
Dusk
 
Сообщения: 8
Зарегистрирован: 25 май 2011, 16:31

Re: PIC 16F877A, случайное значение в порту

Сообщение dccharacter » 26 май 2011, 16:56

На этой плате такт выбирается конфигурацией джамперов - проверить, что нужный кварц выбран

Добавлено спустя 1 минуту 33 секунды:
Плюс в прошивке надо включить внешний кварц - в конфигурационном слове HS

Добавлено спустя 2 минуты 7 секунд:
Дальше, МПЛАБ ИЦД используется как ин-сёкит дебаггер и висит на (та-дам!) ногах RC6/RC7

Чтобы получить кайф, надо дебаггер отключить, подключить кабель к 9-ти пиновому выходу и на ком-порт компа, сконфигурировать ЮСАРТ....

Добавлено спустя 2 минуты 11 секунд:
А, вру-вру. Сам перепутал, это RB6/RB7
Но это дебаггер - это не RS232-USB переходник!

Добавлено спустя 54 секунды:
или у тебя и то и то подключено... не пойму. Ну попробуй раз в секунду помигать светиком.
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: PIC 16F877A, случайное значение в порту

Сообщение Dusk » 27 май 2011, 11:27

Поставил HS - ситуация стала следующей. Первая передача проходит нормально, до того, как я закрою порт или окно терминалки. После открытия окна терминалки заново (другими словами порта) туда либо ничего не приходит, либо приходит мусор. Надо остановить микроконтроллер, закрыть терминалку и повторить сначала. Другими словами, микроконтроллер не может быть постоянно включен, его надо каждый раз перезагружать, если я собираюсь считывать с порта неважно чем, терминалкой или руками. Это неподходит, он должен все время работать.

Подключено так: на плате есть спец. разъем для коробочки ICD 2, куда она и подключена. Дальше ICD 2 подключена к USB PC. Через неё IDE общается с микроконтроллером.
Другой разъем на плате - это COM порт, он напрямую подключен к PC, через него терминалка общается с микроконтроллером, ну или я руками.
Теперь нужна идея, как сделать так, чтобы начинать/заканчивать работу с микроконтроллером не перезагружая его.
Dusk
 
Сообщения: 8
Зарегистрирован: 25 май 2011, 16:31

Re: PIC 16F877A, случайное значение в порту

Сообщение dccharacter » 27 май 2011, 11:39

Надо понять, почему он перегружается. У ПИКов есть регистр-флаг, который поднимается, если сбоит тактовый генератор. Выведи этот флаг на какую-нить ногу и повесь туда светодиод - это поможет тебе узнать, остаемся ли мы на том же тактовом генераторе.

Потом, сделай какой-нибудь флаг ресета. Типа, в начале программы зажечь светодиод. Этот светодиод можно погасить нажатием кнопки. Запускаешь все, светодиод горит. Убеждаешься, что все работает, гасишь его кнопкой. Запускаешь терминал, ловишь "правильные" байты в него. Закрываешь терминал. Если светодиод загорелся - произошел ресет. Дальше будешь копать - из-за чего.
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: PIC 16F877A, случайное значение в порту

Сообщение Dusk » 27 май 2011, 11:59

Так нет, перезагружаю я его вручную, в дебаггере. Потому что только после перезагрузки микроконтроллера в PC с него начинают поступать правильные байты. Если микроконтроллер не перезагружать, то PC начинает ловить неправильные байты после закрытия/открытия терминалки(порта).
Dusk
 
Сообщения: 8
Зарегистрирован: 25 май 2011, 16:31

След.

Вернуться в Микроконтроллеры

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3