| Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
#useRS232
05.11.2010, 09:42
|
|
|
Вид на жительство
Регистрация: 29.04.2007
Адрес: Иркутск
Сообщений: 311
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 12 сообщении(ях)
|
#useRS232
приёмка и отправка символов работала пока был маленький код.
Потои я добавил проверки, расчёты, загрузки из ЕЕПРОМ и всё сломалось.
То есть программа зависает на n=getc();
Перед этой функцией я зажигаю светодиодик. Поэтому и понял, что на ней. Ведь эха не получаю.
Оказалось, что если от начала функции МАЙН до первого вызова getc() проходит милллисекунд (30), то всё и виснет.
Для теста делаю просто:
void main()
{
InicializacMC();
ledik=0;
delay_ms(100);
ledik=1;
n=getc();
putc(n+1);
......
Если 100мсек закоментировать, то всё норм.
|
|
|
|
05.11.2010, 09:59
|
|
|
Гражданин KAZUS.RUN
Регистрация: 08.07.2006
Сообщений: 883
Сказал спасибо: 119
Сказали Спасибо 1,108 раз(а) в 175 сообщении(ях)
|
Re: #useRS232
Может глюк компилятора?
Попробуйте так:
|
Код:
|
static volatile unsigned char test_flag = 0;
void main()
{
InicializacMC();
ledik=0;
if (test_flag)
delay_ms(100);
ledik=1;
n=getc();
putc(n+1);
} |
Виснет? И попробуйте изменить потом значение test_flag на 1.
Также обратите внимание на прерывания, возможно за 30 милисекунд они успевают попортить что-нибудь
__________________
.

В мире всего два типа людей: те у кого был ZX Spectrum, и те у кого его не было.
|
|
|
|
05.11.2010, 10:06
|
|
|
Вид на жительство
Регистрация: 29.04.2007
Адрес: Иркутск
Сообщений: 311
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 12 сообщении(ях)
|
Re: #useRS232
я уже пробовал.
Если при подаче питания кнопка удерживается, то задержку включить, иначе пропустить.
Так вот: при задержке контроллер виснет.
Глобальное прерывание я не разрешал.
|
|
|
|
05.11.2010, 18:01
|
|
|
Супер-модератор
Регистрация: 13.03.2004
Адрес: Minsk
Сообщений: 2,394
Сказал спасибо: 2,016
Сказали Спасибо 1,356 раз(а) в 591 сообщении(ях)
|
Re: #useRS232
Приходит на ум включенный WDT
Хотя неясно, что за МК, что за компилятор... Да и рабочий цикл выглядит странно (нету его, цикла этого).
__________________
[ жизнь приятна и красива, если выпить литр пива ]
|
|
|
|
09.11.2010, 12:24
|
|
|
Вид на жительство
Регистрация: 29.04.2007
Адрес: Иркутск
Сообщений: 311
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 12 сообщении(ях)
|
Re: #useRS232
#include ‹16F628A.h›
#use delay(clock=4000000)
#fuses INTRC_IO, NOMCLR, PUT, NOLVP, NOWDT, NOPROTECT, NOBROWNOUT, NOCPD
#use rs232(baud=9600, parity=N, xmit=PIN_B2, rcv=PIN_B1)
#byte PORTB =6
#bit diBUTTON =PORTB.0
#bit diRx =PORTB.1
#bit diTx =PORTB.2
#bit doTxEn =PORTB.3
#bit doLED =PORTB.4
///////////////////////////////////////////////////
void SendAnswer(int n)
{
int i;
doLED=1;
delay_ms(1); // ждём пока РС переключиться на приём
doTxEn=1;
for(i=4; i›0; --i)
putc(n);
delay_ms(5); // время передачи четырёх байт
doLED=0;
doTxEn=0;
}
///////////////////////////////////////////////////////
void main (void)
{
const int unit=1;
int key, command, value, crc8;
setup_comparator(NC_NC_NC_NC);
SET_TRIS_A(0);
OUTPUT_A(0);
SET_TRIS_B(0b00000111);
doTxEn=0;
setup_oscillator(OSC_4MHZ);
doLED=0;
//i=getc(); проблема всё равно не разрешилась
if(!diBUTTON)
delay_ms (3000);
doLED=1;
while(getc()!=255);
do
{
key = getc ();
if (key == 255) continue;
command = getc ();
value = getc ();
crc8 = getc ();
if( (key ^ command ^ value) != crc8 ) continue;
if(key==unit) SendAnswer (++key);
}while(1);
}
Последний раз редактировалось yellow87; 09.11.2010 в 12:29.
|
|
|
|
09.11.2010, 13:07
|
|
|
Вид на жительство
Регистрация: 29.04.2007
Адрес: Иркутск
Сообщений: 311
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 12 сообщении(ях)
|
Re: #useRS232
компилятор PIC-CCS
среда МПЛАБ
|
|
|
|
10.11.2010, 16:49
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 06.02.2007
Сообщений: 1,340
Сказал спасибо: 3
Сказали Спасибо 107 раз(а) в 66 сообщении(ях)
|
Re: #useRS232
я ни ухом, ни рылом ху из ццс, но при приеме символа Вам нужно обработать 2 ошибки
1 пропуск стопового бита
2 переполнение буфера
#define serial_error() OERR
#define nostop() FERR
#define serial_fix() {CREN = 0; CREN = 1;}
if (RCIF && RCIE)
{
if(serial_error()) serial_fix(); // передергиваем обмен
if (nostop()) RCREG;// здесь просто читаем в аккумулятор
возможно, ццс это делает автоматом - пусть спецы поправят...
|
|
|
|
14.11.2010, 20:56
|
|
|
Вид на жительство
Регистрация: 29.04.2007
Адрес: Иркутск
Сообщений: 311
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 12 сообщении(ях)
|
Re: #useRS232
Я только книгу Шпака читал.
Там про проверки этих ошибок - ни слова.
А где спецы?
Или никто ЦЦС не использует?
А чем все пользуются тогда?
|
|
|
|
15.11.2010, 07:24
|
|
|
Вид на жительство
Регистрация: 29.04.2007
Адрес: Иркутск
Сообщений: 311
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 12 сообщении(ях)
|
Re: #useRS232
Да и не переходить же на другой компилятор в последний момент.
Если я всё же удачно вхожу в основной цикл, то принимающий контроллер иногда всё таки зависает. И потом помогает только сброс. Может точно ошибки эти проверять в цикле? Какие команды только там я не знаю.
Ну биты регистра RCSTA именно так и называется FERR, OERR.
Но я не соображу куда, приведённый urry код вставить.
Как я понимаю функция getc() блокирующая, в ней и происходит зависание.
Если ниже неё поместить эти проверки, то до них дело всё равно не дойдёт.
Или я не прав. Просветите кто-нибудь
Последний раз редактировалось yellow87; 15.11.2010 в 07:50.
|
|
|
|
15.11.2010, 09:30
|
|
|
Вид на жительство
Регистрация: 29.04.2007
Адрес: Иркутск
Сообщений: 311
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 12 сообщении(ях)
|
Re: #useRS232
Дизассемблировал сишный код, увидел реализацию функции приёма.
Она оказалась очень проста, никаких проверок на ошибки:
[HTML]key = getc();
BTFSS 0XC, 0X5 // ждём пока принимаемый байт
GOTO $-1 // не появится в буфере приёмника
MOVF 0X1A, W // регистр данных приёмника в аккум.
MOVWF 0X2E // и в регистр переменной переносим[/HTML]
Но если произошло переполнение приёмника, приёмник принимать не будет,
вот видимо и зависает, в ожидании приёма байта.
То есть функцию приёма нужно переписать?
[HTML]int mygetc()
{
if(OERR)
{
CREN=0;
CREN=1;
}
if(FERR)
{
FERR=0;
RCIF=1;
}
return(getc());
}[/HTML]
Так ли?
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 08:01.
|
|