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

Не Работают Прерывания Uart


l-e-o-n-a-r-d-o

Рекомендуемые сообщения

Пишу в кодевижине. Тини2313

Есть небольшая програмка, которая в мейне с помощью getchar() работает отлично. Что именно делает: если принят первый байт 253, тогда остальных 7 записывает в буффер.

вот она

while (1) // безконечный цикл

{

if( getchar() == 253 ) // ждем того момента пока не словим "старт"

{

for( i=0; i<7; i++ ) // если приняли ютарт, считываем еще 7 байт принятых

{

rx_buffer = getchar(); // и помещаем их в буффер

}

frame(); // вызываем вункцию анализатора принятой посылки

}

}

вот это работает замечательно. Теперь это же нужно засунуть в прерывания. Да проблема в том, что сколько я не пытался, прерывания вообще отказываются работать, точней такое впечатление что первое сработало, и на этом все закончилось. (обработку прерываний формирует генератор кодевижина). Даже текст привводить не буду, потому что ниче не работало. (даже один байт не принимает!) Вчера я еще 2 часа воевал с протеусом в котором вообще ничего не работало. :angry:

вот например такое:

// USART Receiver interrupt service routine

interrupt [uSART_RXC] void usart_rx_isr(void)

{

char status,data;

data=UDR;

putchar('3');

}

тоже не работает :(

Дайте мне пожалуйста РАБОЧИЙ пример работы с прерываниями в кодевижине от юарта. Или может скажите где тут какие то подводные камни? фьюзы? ....

чем шире кругозор, тем тупее угол обозрения

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

// USART initialization

// Communication Parameters: 8 Data, 1 Stop, No Parity

// USART Receiver: On

// USART Transmitter: On

// USART Mode: Asynchronous

// USART Baud Rate: 115200

UCSRA=0x00;

UCSRB=0xD8;

UCSRC=0x06;

UBRRH=0x00;

UBRRL=0x01;

// USART Receiver interrupt service routine

interrupt [uSART_RXC] void usart_rx_isr(void)

{

char status,data,i=0;

bit rec=0;

status=UCSRA;

data=UDR;

if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)

{

if (rec==1) { rx_buffer=data; i++;}

if (i == 8) { i=0; rec=0; frame_received=1; frame();}

if (data == 253) {rec=1;}

};

}

даже и 1 байт не хочет принимать, не говоря уже о этом.

чем шире кругозор, тем тупее угол обозрения

Ссылка на комментарий
Поделиться на другие сайты

Особенности хранения литиевых аккумуляторов и батареек

Потеря емкости аккумулятора напрямую зависит от условий хранения и эксплуатации. При неправильном хранении даже самый лучший литиевый источник тока с превосходными характеристиками может не оправдать ожиданий. Технология, основанная на рекомендациях таких известных производителей литиевых источников тока, как компании FANSO и EVE Energy, поможет организовать правильный процесс хранения батареек и аккумуляторов. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Лучше комментарий к коду.

Как не раз указывалось, в прерывании лучше не задерживаться и уж тем более не организовывать проверки, циклы, счетчики.

Вот мои замечания.

Начнем с того, что прерывание наступает КАЖДЫЙ РАЗ, когда в приемнике появляются принятые данные (байт). В твоем коде, l-e-o-n-a-r-d-o, все переменные будут сбрасываться при приеме каждого байта, что не позволит выполнится ни одному условию.

Например:

// USART Receiver interrupt service routine

interrupt [uSART_RXC] void usart_rx_isr(void)

{

char status,data,i=0;   обнулил данные, счетчик и статус

bit rec=0;                  обнулил флаг записи (я прав?)

status=UCSRA;

data=UDR;

if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)

{

if (rec==1) { rx_buffer=data; i++;} даже если попал сюда, не выполнится, т.к. rec=0 всегда (см. выше)

if (i == 8) { i=0; rec=0; frame_received=1; frame();} это тоже не выполнится, i=0 сам обнуляешь при входе в прерывание каждый раз (см. выше) 

if (data == 253) {rec=1;} выполнится в начале, но при следующем байте опять обнулится, сам это делаешь (см. выше)

Прием осуществляется по-байтно и каждый принятый байт будет вызывать прерывание, которое вначале все твои признаки обнулит, а потом ничего не сделает, т.к. обнуленные счетчики и флаги не проходят ни по одному условию. Вот примерно так. Может я чего и не допонял, пусть парни поправят, если что не так.

Зайди в прерывание, прочитай буфер в регистр (если нет ошибок - проверка это уже по желанию), далее можешь его сохранить в ОЗУ (для гарантии) и выходи из прерывания. Все остальное - сделаешь в мейне.

Изменено пользователем Геннадий
Ссылка на комментарий
Поделиться на другие сайты

мда, действительно, я об этом не подумал.. :wacko: Попробую исправить, сделав переменные глобальными, отпишусь о результате.

еще немного другой вопрос, в протеусе у когото хотя бы такое:

interrupt [uSART_RXC] void usart_rx_isr(void)

{

char status,data,i=0;

data=UDR;

putchar(data);

}

работает??? потому что сколько я не воевал с протеусом, он даже не хочет по приему моргнуть диодом..не то что отправить это назад.

чем шире кругозор, тем тупее угол обозрения

Ссылка на комментарий
Поделиться на другие сайты

мда.. чудо свершилось! во первых, сами прерывания (1 байт) заработали!

interrupt [uSART_RXC] void usart_rx_isr(void)

{

char status,data;

data=UDR;

putchar('3');

}

вот такое заработало уже. А дальше- подкорректировал обработку прерываний для приема пакета 8 байт, и теперь все заработало как надо, так же как было в мейне (см. 1 пост) тоесть то что надо!!!! :rolleyes:

Огромное спасибо Геннадий, я б про это еще не скоро подумал бы!!! который день ломал голову над этим, а оно было под носом! как всегда вобщем)

остался только вопрос протеуса. У когото работают прерывания юарта в протеусе?? (свои я проверял на железе)

чем шире кругозор, тем тупее угол обозрения

Ссылка на комментарий
Поделиться на другие сайты

  • 12 лет спустя...

Здравствуйте, у меня похожая проблема, не срабатывает прерывание по приему, помогите разобраться пожалуйста

void UART_Init(unsigned int speed)//Инициализация модуля USART 8bit, 2 stop bit
{
    cli();
    UBRR0H = (speed & 0x0F00) >> 8;
    UBRR0L = (speed & 0x00FF);
    UCSR0B |= ((1 << TXEN0) | (1 << RXEN0) /*| (1 << TXCIE0)*/ | (1 << RXCIE0));
    /* Set frame format: 8data,  2stop bit  */
    UCSR0C = (1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00);
    sei();
}

ISR(USART_RX_vect) //Прерывания после приема
{     
   PORTB ^= (1<<5);    
}
int main(void)
{   
    UART_Init(103); //9600
    DDRB |= (1<<5);
}

P.s: было выяснено, что прерывания работает как бесканечный цикл, чего не должно быть, но оно есть.

Изменено пользователем Kostyanskiy
Ссылка на комментарий
Поделиться на другие сайты

@Kostyanskiy Чтобы прерывание загасить, в обработчике прерывания надо прочитать принятый байт. Типа, вот так

char data = UDR

 

Изменено пользователем Yurkin2015
Ссылка на комментарий
Поделиться на другие сайты

@Yurkin2015 благодарю, но я так и не понял с чем это связано, это по меньшей мере не логично, ведь прерывание это не цикл, где  можно почитать? В даташите я не помню чтобы это было описано. 

И тут еще один такой момент есть, я читаю строку по ЮАРТ и походу не могу считать буфер в который я её записываю,  идея такая:

При получении строки считывать регистр на приянятые данные, если там есть знак переноса строки, то у нас уже конец строки и в основном цикле парсим данные и понимаем какое условие выполнять, так проблема в том, что условие strcmp или strstr не читают данные с буфера приема, что порекомендуете сделать?

Вот код прерывания

ISR(USART_RX_vect) //Прерывания после приема
{   
    if ((UCSR0A & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN)) == 0)
    {
       while (UDR0 != 0x0D) 
       {
          sReceivedChar[rx_count++] = UDR0;       
          PORTB ^= (1<<5);
          if((UDR0 == 0x0D) && (FlagRecievData == 0)) FlagRecievData = 1;
       }            
    }
}

Вот код парсира, если убрать эту строку (strcmp(sReceivedChar, "1") == 0), то соответственно все заработает по приходу рандомного символа в порт

int main(void)
{   
    UART_Init(103); //9600
    DDRB |= (1<<5);

    while (1) 
    {
        if((strcmp(sReceivedChar, "1") == 0) && (FlagRecievData == 1))
        {
           UART_Transmit("OK");
           UART_Transmit((const char*)sReceivedChar);
           FlagRecievData = 0;
        }
    }
}

 

Ссылка на комментарий
Поделиться на другие сайты

@Kostyanskiy Надо переделать обработчик прерывания:

ISR(USART_RX_vect) //Прерывания после приема
{   
    if ((UCSR0A & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN)) == 0)
    {
       if (UDR0 != 0x0D) 
       {
          sReceivedChar[rx_count] = UDR0;
          if (rx_count < sizeof(sReceivedChar)-1)
            rx_count++;
          PORTB ^= (1<<5);
       }            
       else
       {
            sReceivedChar[rx_count] = 0;
            rx_count = 0;
            FlagRecievData = 1;
       }
    }
}

 

Ссылка на комментарий
Поделиться на другие сайты

@Yurkin2015  

8 минут назад, Yurkin2015 сказал:
sReceivedChar[rx_count] = 0;

Немного не понял для чего это, мы типа стираем 0x0D из sReceivedChar?

Это к сожалению тоже не работает:unsure:

Ссылка на комментарий
Поделиться на другие сайты

@Kostyanskiy Мы не стираем 0x0D, а записываем 0 в конец строки. Если функция srtcmp() будет сравнивать строки от начала до конца, как она узнает где конец в строке sReceivedChar? До какого места сравнивать? Признаком конца как раз и является 0.

Кстати, для упрощения выкиньте strcmp() и для начала сравните только первый принятый символ:

if((sReceivedChar[0] == '1')&&(FlagRecievData == 1))
{
	UART_Transmit("OK"); 
	UART_Transmit((const char*)sReceivedChar);
	FlagRecievData = 0;
}

 

Изменено пользователем Yurkin2015
Ссылка на комментарий
Поделиться на другие сайты

@Yurkin2015 А вот это уже реально не понятно, откуда \r в начале строки, и почему 9-ка пропала в конце?:huh: 

image.png.6be9cdb6dc691735be6a6a7300faa1f4.png

P.s Недозаписался символ в конце при проверке условия UDR0 != 0x0D, исправил так, 

if (UDR0 != 0x0D)
       {
           sReceivedChar[rx_count++] = UDR0;
           if (rx_count > sizeof(sReceivedChar)) rx_count = 0;        
       }
       else
       {
           sReceivedChar[rx_count] = UDR0;
           sReceivedChar[rx_count + 1] = 0;
           rx_count = 0;
           FlagRecievData = 1;
       }          

Но что делать с  \r в начале, и как он там появляется, не понятно.

Изменено пользователем Kostyanskiy
Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • @Александр2, это у тебя в голове что-то с чем-то вступает в противоречие.  Я знаю, что ты ярый поклонник Ланзара. Поэтому пояснение для тебя того, почему симметричная на бумаге/на экране монитора схема, и спаянная на реальной плате с реальными комплектующими в отличии от неё за редким исключением вместо 0 на выходе зачастую имеет сдвиг напряжения величиной в +/- километр, думается мне излишняя трата времени.    
    • Верно подмечено. Вот их-то, КТ602ВМ и BD139 в ТО-126 в 1969-ом как раз-таки и не было. Не только у J. L. Hood-а, их вообще ещё не существовало. К тому же КТ602БМ  в корпусе КТ-27-2 (как и BD139 в TO-126) и КТ602А в корпусе КТЮ-3-9 - это совсем не близнецы-братья. Технология изготовления совершенно разная, а она при работе транзисторов динамическом режиме, как в случае с JLH-69, играет далеко не последнюю роль. Просто юноша в силу своего быстрого и раннего развития об этом ничего не знает. 
    • Садится разбираться в алгоритме работы и на микроконтроллере делать замену.  Попробуйте прогреть микросхему на зажигалке, когда-то читал о таком способе восстановления процессора от телевизора. Шансов мало, но вам нечего терять, а потом в панельку.
    • Я хочу попробовать разные способы победить эти шумы. Для начала собрать фильтр для блока питания. Корпус с блютуз антенной я пробовал убрать, ничего не изменилось, если фильтр для блока питания тоже не поможет, значит дело в самом усилителе. В Aiyima A3001, который выдает шум гораздо тише, на выходе стоят электролитические конденсаторы и фильтры, можно попробовать сделать также и на Aiyima A09, может таким образом удастся снизить шумы. Если нет, то буду искать еще варианты. Кроме шумов еще надо разобраться с щелчками в колонки при включении и выключении Brzhifi. Aiyima A09 выдает щелчок только при выключении сетевого фильтра, и слабый. А вот Brzhifi щелкает так, что аж диффузоры в колонках двигаются. Схема питания у них отличается, Brzhifi остается в режиме ожидания и питание не отключается, я хочу переделать его так, чтобы оно отключалось, как на Aiyima A09. Может там что сдохло. а может он так спроектирован. Либо что то делать с контроллером питания, либо найти в схеме где можно врезать выключатель и впихнуть его.
    • @CrazyDog34RU Понять, что изначально были неправы, и питание в вашей проблеме не виновато, например?
    • Неожиданный вопрос... При измерениях в любой точке вот этой части схемы "масса" осциллографа вот тут: При измерениях вот в этой части схемы - вот тут: У этой части схемы - вот в этой точке: Подключать "массу" к одной части схемы, а смотреть точки в другой - нельзя. Все эти три "общие" точки - совершенно разные точки. Между ними может быть вполне ощутимое напряжение. Вот тут это хорошо видно:
×
×
  • Создать...