реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Непонятка с USART в Tiny2313, В протеусе работает, в контроллере нет
vsk
сообщение Feb 26 2008, 07:38
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 11-01-08
Пользователь №: 33 988



Подскажите что может быть, в протеусе работает, в контроллере нет, вернее на вывод в комп все пашет, кварц стоит на 4 Мгц, а вот от команд с ПК, типа цифры от 1 до 8, не работает.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/iotn2313.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>

#define BAUD (4000000/16/9600 - 1)
#define USART_RXC_vect USART_RX_vect


void sleep(void);
volatile unsigned char rxbuff;
volatile unsigned int rx_int = 1;

SIGNAL(SIG_USART0_RECV)

{

if (bit_is_clear(UCSRA, FE))
{
rxbuff=UDR;
rx_int=1;
}

}

void sleep(void)
{
int i;
for (i=0; i<=10; i++)
_delay_loop_2(30000);
}

void RestartPin(int PinNumber)
{
sleep();
switch (PinNumber)
{
case 1:
PORTB=PORTB | (1<<PB0);
sleep();
PORTB=PORTB & (0<<PB0);
sendString(" TC1 Ok\0");
break;
case 2:
PORTB=PORTB | (1<<PB1);
sleep();
PORTB=PORTB & (0<<PB1);
sendString(" TC2 Ok\0");
break;
case 3:
PORTB=PORTB | (1<<PB2);
sleep();
PORTB=PORTB & (0<<PB2);
sendString(" TC3 Ok\0");
break;
case 4:
PORTB=PORTB | (1<<PB3);
sleep();
PORTB=PORTB & (0<<PB3);
sendString(" TC4 Ok\0");
break;
case 5:
PORTB=PORTB | (1<<PB4);
sleep();
PORTB=PORTB & (0<<PB4);
sendString(" TC5 Ok\0");
break;
case 6:
PORTB=PORTB | (1<<PB5);
sleep();
PORTB=PORTB & (0<<PB5);
sendString(" TC6 Ok\0");
break;
case 7:
PORTB=PORTB | (1<<PB6);
sleep();
PORTB=PORTB & (0<<PB6);
sendString(" TC7 Ok\0");
break;
case 8:
PORTB=PORTB | (1<<PB7);
sleep();
PORTB=PORTB & (0<<PB7);
sendString(" TC8 Ok\0");
break;
}
}

int main(void)
{
// DDRA = 0x00; //1 - out, 0 - in
DDRB = 0xFF;

USARTInit();

sei();

sleep();
sendString("Welcome to Remote Reset\0");

for (;;)
{
if (rx_int==1)
{
if (rxbuff == '1') RestartPin(1);
if (rxbuff == '2') RestartPin(2);
if (rxbuff == '3') RestartPin(3);
if (rxbuff == '4') RestartPin(4);
if (rxbuff == '5') RestartPin(5);
if (rxbuff == '6') RestartPin(6);
if (rxbuff == '7') RestartPin(7);
if (rxbuff == '8') RestartPin(8);
rx_int = 0;
}
}
return 0;
}



void USARTInit()
{

UBRRL = BAUD;
UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(0<<UDRIE);
//UCSRC = (1<<UCSZ1)|(1<<UCSZ0);
}

void sendChar(unsigned char data)
{
while (!(UCSRA &(1<<UDRE))) ;
UDR = data;
}

void sendString(unsigned char s[])
{
int i=0;
while (i<64)
{
if (s[i]=='\0') break;
sendChar(s[i++]);
}
}
Go to the top of the page
 
+Quote Post
vsk
сообщение Feb 26 2008, 11:03
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 11-01-08
Пользователь №: 33 988



Подскажите в какую сторону хоть копать то, fuse - биты выставлены правильно....
Go to the top of the page
 
+Quote Post
URANst
сообщение Feb 26 2008, 11:17
Сообщение #3


Частый гость
**

Группа: Новичок
Сообщений: 83
Регистрация: 2-02-06
Пользователь №: 13 912



Код
switch (PinNumber)
{

Как я понял ключ сдесь - это принятый байт, который вы генерите нажатием клавиши, так вот клавиши 1, 2 ... - цифры , не возвращают значения 0x01,0x02 ...
Поключите в протеусе виртуальный терминал , нажмите на клавишу и посмотрите какой код она возвращает и тогда все поймете .

Код
PORTB=PORTB | (1<<PB0);
замените на PORTB|=(1<<PB0);
Код
PORTB=PORTB & (0<<PB0);
замените на PORTB&=~(1<<PB0);

Код
#define USART_RXC_vect USART_RX_vect
- зачем вот эта строка ?

Сообщение отредактировал URANst - Feb 26 2008, 11:26
Go to the top of the page
 
+Quote Post
vsk
сообщение Feb 26 2008, 11:38
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 11-01-08
Пользователь №: 33 988



Как я понял в терминале, в виде HEX'a протеуса цифре 1 - соответствует код 31.
Но после замены в коже на этот код, результат, что даже протуес не симулирует, а в первоначальном варианте все работает, а вот в железе ни в какую.....
Исправленный код для теста:
for (;;)
{
if (rx_int==1)
{
//RestartPin(8);
if (rxbuff == 31) RestartPin(1);
.........
rx_int = 0;
}
Go to the top of the page
 
+Quote Post
=GM=
сообщение Feb 26 2008, 12:27
Сообщение #5


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(vsk @ Feb 26 2008, 07:38) *
Подскажите что может быть, в протеусе работает, в контроллере нет, вернее на вывод в комп все пашет, кварц стоит на 4 Мгц, а вот от команд с ПК, типа цифры от 1 до 8, не работает

Если правильно понял, вы совсем ничего не принимаете от писюка, верно?

1) Проверьте тот ли адрес стоит для перехода к программе обработки прерывания на приём.

2) Убедитесь, что инструкция if(bit_is_clear(UCSRA, FE)) правильно работает или лучше уберите её временно.

3) Ну и rx_int должен быть равен нулю до входа в цикл for(;;).


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
URANst
сообщение Feb 26 2008, 12:47
Сообщение #6


Частый гость
**

Группа: Новичок
Сообщений: 83
Регистрация: 2-02-06
Пользователь №: 13 912



Вот побыстрому набросал тоже что и вы, все работает !!
там файл пртеуса, .с, hex.
При нажатии клавиши "1" загорается светодиод на PB0 и через 1 сек гаснет, контроллер назад отправляет код клавиши.

Сообщение отредактировал URANst - Feb 26 2008, 12:50
Прикрепленные файлы
Прикрепленный файл  1.rar ( 26.7 килобайт ) Кол-во скачиваний: 27
 
Go to the top of the page
 
+Quote Post
vsk
сообщение Feb 26 2008, 12:58
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 11-01-08
Пользователь №: 33 988



Да, в протеусе все работает, а в живом железе, никак....
В прерывание попадает, и если символ сразу отсылать обратно, все ок, может в сравнении что не так?....


---- Убедитесь, что инструкция if(bit_is_clear(UCSRA, FE)) правильно работает или лучше уберите её временно.
Это пробовал по разному.

---- Ну и rx_int должен быть равен нулю до входа в цикл for(;;).
С этим да, не досмотрел, в 0 надо выставить.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Feb 26 2008, 13:46
Сообщение #8


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(vsk @ Feb 26 2008, 12:58) *
В прерывание попадает, и если символ сразу отсылать обратно, все ок, может в сравнении что не так?...

Ага, значит у вас приём сам по себе идёт, что ж вы нас дезинформируете(:-)?

1) Попробуйте вместо void RestartPin(int PinNumber) поставить void RestartPin(char PinNumber). Кстати, странно, что у вас нет описания прототипа функции RestartPin.

2) Поставьте в операторе switch вариант по default: <что-то сделать>.

3) Если уж ничего не помогает, попробуйте временно вместо switch поставить вывод некой строки, типа "превед медвед".


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 26 2008, 14:00
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(vsk @ Feb 26 2008, 14:58) *
---- Ну и rx_int должен быть равен нулю до входа в цикл for(;;).
С этим да, не досмотрел, в 0 надо выставить.
Достаточно его не инициализировать при объявлении. Неинициализированные глобальные переменные обнуляются перед вызовом main(). Зачем вы его объявили как int? Достаточно char - код будет короче.

Судя по исходному коду, вы используете WinAVR. Какую версию? В последних надо вместо SIGNAL() использовать ISR(). SIGNAL() при входе в обработчик разрешает прерывания, а поскольку вы не вычитали UDR, то снова вызывается прерывание и вы снова заходите в обработчик. И так пока стек не закончится.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
=GM=
сообщение Feb 26 2008, 14:09
Сообщение #10


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(Сергей Борщ @ Feb 26 2008, 14:00) *
SIGNAL() при входе в обработчик разрешает прерывания, а поскольку вы не вычитали UDR, то снова вызывается прерывание и вы снова заходите в обработчик. И так пока стек не закончится

А если rxbuff=UDR; поставить первым?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
vsk
сообщение Feb 26 2008, 14:19
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 11-01-08
Пользователь №: 33 988



Странно, код подкрутил, но теперь в терминале буквы теряются.....
и на switch defaut не переходит..... Вот умеченный код:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/iotn2313.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include "commutator.h"

#define BAUD (4000000/16/9600 - 1)

void sleep(void);
volatile unsigned char rxbuff;
volatile unsigned int rx_int = 0;

SIGNAL(SIG_USART0_RECV)
{
// if (bit_is_clear(UCSRA, FE))
// while ( !(UCSRA & (1<<RXC)) );
//{
rxbuff=UDR;//c;
rx_int=1;
//}
}

void sleep(void)
{
int i;
for (i=0; i<=10; i++)
_delay_loop_2(30000);
}

void RestartPin(unsigned char PinNumber)
{
sleep();
switch (PinNumber)
{
case 0x31:
PORTB=PORTB | (1<<PB0);
sleep();
PORTB=PORTB & (0<<PB0);
sendString(" TC1 Ok\0");
break;
case 0x32:
PORTB=PORTB | (1<<PB1);
sleep();
PORTB=PORTB & (0<<PB1);
sendString(" TC2 Ok\0");
break;
case 0x33:
PORTB=PORTB | (1<<PB2);
sleep();
PORTB=PORTB & (0<<PB2);
sendString(" TC3 Ok\0");
break;
case 0x34:
PORTB=PORTB | (1<<PB3);
sleep();
PORTB=PORTB & (0<<PB3);
sendString(" TC4 Ok\0");
break;
case 0x35:
PORTB=PORTB | (1<<PB4);
sleep();
PORTB=PORTB & (0<<PB4);
sendString(" TC5 Ok\0");
break;
case 0x36:
PORTB=PORTB | (1<<PB5);
sleep();
PORTB=PORTB & (0<<PB5);
sendString(" TC6 Ok\0");
break;
case 0x37:
PORTB=PORTB | (1<<PB6);
sleep();
PORTB=PORTB & (0<<PB6);
sendString(" TC7 Ok\0");
break;
case 0x38:
PORTB=PORTB | (1<<PB7);
sleep();
PORTB=PORTB & (0<<PB7);
sendString(" TC8 Ok\0");
break;
default:
sendString(" Error Code\0");
break;
}
}

int main(void)
{
//1 - out, 0 - in
USARTInit();
DDRB = 0xFF;

sei();

sleep();
sendString("Welcome to Remote Reset\0");

for (;;)
{
if (rx_int==1)
{
RestartPin(rxbuff);
rx_int = 0;
}
}
return 0;
}



void USARTInit()
{

UBRRL = BAUD;
UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
//UCSRC = (1<<UCSZ1)|(1<<UCSZ0);
}

void sendChar(unsigned char data)
{
while (!(UCSRA &(1<<UDRE))) ;
UDR = data;
}

void sendString(unsigned char s[])
{
int i=0;
while (i<64)
{
if (s[i]=='\0') break;
sendChar(s[i++]);
}
}
Go to the top of the page
 
+Quote Post
URANst
сообщение Feb 26 2008, 14:36
Сообщение #12


Частый гость
**

Группа: Новичок
Сообщений: 83
Регистрация: 2-02-06
Пользователь №: 13 912



При таких настройках UARTa будут ошибки передачи, смотри в даташит на описание UART (самый конец), возможно из-за этого в протеусе работало а в железке нет, хотя нигде не должно правильно работать.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 26 2008, 15:41
Сообщение #13


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(=GM= @ Feb 26 2008, 16:09) *
А если rxbuff=UDR; поставить первым?
А толку? К моменту исполнения первой команды С - функции-обработчика прерывания уже будут разрешены.

P.S. Ой... Сам залез в документацию и обнаружил, что SIGNAL() и ISR() в последних версиях - одно и то же, но пользование SIGNAL() не рекомендуется - она будет исключена в следующих версиях. Что-то в память запало из предыдущих версий. Автору - проверьте, как объявлен SIGNAL() в заголовочном файле - attribute((interrupt)) или attribute((signal)). Если interrupt - обязательно замените в своей программе SIGNAL() на ISR().


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
=GM=
сообщение Feb 26 2008, 16:00
Сообщение #14


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(vsk @ Feb 26 2008, 14:19) *
Странно, код подкрутил, но теперь в терминале буквы теряются..

Попробуйте прямое эхо организовать, типа такого
Код
SIGNAL(SIG_USART0_RECV)
{
  rxbuff=UDR;
  UDR = rxbuff;   //эхо
  rx_int=1;
}

Будут символы теряться?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
vsk
сообщение Feb 27 2008, 05:47
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 11-01-08
Пользователь №: 33 988



Цитата(=GM= @ Feb 26 2008, 19:00) *
Попробуйте прямое эхо организовать, типа такого
Код
SIGNAL(SIG_USART0_RECV)
{
  rxbuff=UDR;
  UDR = rxbuff;   //эхо
  rx_int=1;
}

Будут символы теряться?

После reset'a выдается слово с потерянными символами, при нажатии клавиш в терминале,
с предложенным кодом эха символы не возвращаются. Вместо Signal пробовал ставить
ISR, результат аналогичен, а в заголовочном файле код:
#ifdef __cplusplus
#define ISR(vector) \
extern "C" void vector(void) __attribute__ ((signal)); \
void vector (void)
#else
#define ISR(vector) \
void vector (void) __attribute__ ((signal)); \
void vector (void)
#endif

/** \def SIGNAL(signame)
\ingroup avr_interrupts

\code#include <avr/interrupt.h>\endcode

Introduces an interrupt handler function that runs with global interrupts
initially disabled.

This is the same as the ISR macro.
\note Do not use anymore in new code, it will be deprecated
in a future release.
*/

#ifdef __cplusplus
#define SIGNAL(signame) \
extern "C" void signame(void) __attribute__ ((signal)); \
void signame (void)
#else
#define SIGNAL(signame) \
void signame (void) __attribute__ ((signal)); \
void signame (void)
#endif

При SIGNAL(SIG_USART0_RECV)
{
// if (bit_is_clear(UCSRA, FE))
// while ( !(UCSRA & (1<<RXC)) );
//{
rxbuff=UDR;
UDR = rxbuff; //эхо
rx_int=1;
//}
} в терминале появляется текст и сразу за ним бегут символы с мусором без остановки, при нажатии кнопок, все замирает, и символов нет.
При ISR - аналогично.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 06:52
Рейтинг@Mail.ru


Страница сгенерированна за 0.01495 секунд с 7
ELECTRONIX ©2004-2016