Мелкие вопросы по МК и ПЛИС.

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Встал на лапы
Сообщения: 118
Зарегистрирован: Ср фев 05, 2014 18:54:39

Сообщение jazz393 »

Добрый день(точнее утро). Немного глупый вопрос - зачем существует прерывание по передаче?Ну к примеру в usart или в i2c или can...Я вот не понимаю, с прерыванием по приём - всё понятно, а вот передача....мы же итак отправляем посылку из тела main в нужное нам время, зачем тогда оно существует? какие задачи на практике решает?

У меня вот сейчас весьма сложный проект более 20к строк, там активно юзается can и usart, и вот с usart-ом начинаются какие-то гонки если канал загружать...Я вот боюсь что связано как раз с моим не грамотным подходом в силу юности и неопытности =(
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

2sanyo.95:
Кнопку вы считали и даже переменную нарастили. И ее же считываете процедурой ShowTime. Ясен пень результата работы кнопки не увидите. Вам нужно позаботиться о том, чтобы содержимое hour попало в RTC, т.е. записать его туда.
2jazz393:
Прерывание - всё, канал свободен, можно пихать следующее.
Docendo discimus
Контактная информация:
Реклама
Встал на лапы
Сообщения: 118
Зарегистрирован: Ср фев 05, 2014 18:54:39

Сообщение jazz393 »

pyzhman писал(а):2sanyo.95:
Кнопку вы считали и даже переменную нарастили. И ее же считываете процедурой ShowTime. Ясен пень результата работы кнопки не увидите. Вам нужно позаботиться о том, чтобы содержимое hour попало в RTC, т.е. записать его туда.
2jazz393:
Прерывание - всё, канал свободен, можно пихать следующее.
не понимаю...итак же данные в канал идут последовательно, или что вы имеете ввиду...
Друг Кота
Аватара пользователя
Сообщения: 4779
Зарегистрирован: Сб апр 02, 2011 12:40:46
Откуда: Минск

Сообщение Леонид Иванович »

jazz393 писал(а):зачем существует прерывание по передаче?
Чаще всего передавать приходится не 1 байт, а целый пакет. Делать передачу с программным опросом флага готовности неэффективно. Поэтому обычно сначала заполняют буфер, а затем по прерываниям идет его передача. Нужно отметить, что часто существуют два разных флага готовности передатчика: буфер передатчика пуст и передача байта завершена. По первому можно загружать следующий байт для передачи, а по второму можно, скажем, переключать направление трансиверов RS-485.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Chettuser

Сообщение Chettuser »

Прерывания по событиям вообще существуют для разгрузки вычислительного ядра от монотонной работы. Используется при использовании модулей периферии, например аппаратный модуль SPI.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Сообщение Engineer_Keen »

jazz393 писал(а):Добрый день(точнее утро). Немного глупый вопрос - зачем существует прерывание по передаче?Ну к примеру в usart или в i2c или can...Я вот не понимаю, с прерыванием по приём - всё понятно, а вот передача....мы же итак отправляем посылку из тела main в нужное нам время, зачем тогда оно существует?
Во время передачи, если не использовать прерывания по передаче или опустошению буфера, контроллер будет простаивать ожидая этот флаг в тупом цикле. На скорости 9600 при тактовой 16М это между прочим 1600 тактов на бит.
Если использовать прерывания, то во время передачи символа контроллер будет делать другие полезные вещи.
А если вам надо килобайт данных переслать на скорости 9600? Вы будете 10 секунд ждать и ничего не делать?
PS:пока писал, уже ответили :)))
Видимо ваши 20к строк надо как-то оптимизировать. У меня в самом сложном проекте всего около 1500 строк (а в ассемблере каждая строка это отдельная инструкция, не считая директив компилятора), при этом UART используются 95% времени, SPI 50% и контроллер приспокойно успевает просчитать практически в реальном времени 3 сотни хитрых функций. Без прерываний хрен бы он что успел...
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
Реклама
Встал на лапы
Сообщения: 118
Зарегистрирован: Ср фев 05, 2014 18:54:39

Сообщение jazz393 »

всем спасибо, сейчас буду пытаться настроить прерывание и оптимизировать всё
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

pyzhman писал(а):Вам нужно позаботиться о том, чтобы содержимое hour попало в RTC, т.е. записать его туда.
О, теперь уже что-то проясняеться. То есть после чтения кнопки и инкремента переменной hour, мне как то нужно записать её в RTC? И как мне это сделать. Спасибо.
Встал на лапы
Сообщения: 118
Зарегистрирован: Ср фев 05, 2014 18:54:39

Сообщение jazz393 »

блин я всёравно не понимаю...ну есть эти 2 флага...
1) генерирует прерывание когда буфер передатчика пуст
т.е. допустим в программе у меня передача сделана так, тюею я в строке while ((UCSR1A & DATA_REGISTER_EMPTY)==0); жду когда флаг освободится...

Код: Выделить всё

void uasrt_tx_1(char *data){
	unsigned char z=0;
	z=0;
	do
		{
		while ((UCSR1A & (1<<UDRE))==0);
			UDR1 = data[z++];
		}while(data[z-1]!=0x03);
	}
Не понимаю следующего - как его использовать...если буфер передатчика всёвремя свободен, и мне надо скажем отправить какую-то строку char *str , то как это всё организовывается...? Мне что нужно будет разрешить прерывание, оно (если свободен буфер) вызывается, и записывает в буфер UDR1 = data[z]; затем прерывание возвращается и продолжается выполнять main, когда
флаг UDRE опять сработает, то снова вызывается прерывание и пишется UDR1 = data[z]; , а когда я дохожу до data[z]==0x03 (это признак конца сообщения) то я запрещаю это прерывание и обнуляю z =0; который должен быть глобальным счетчиком...

я правильно понимаю пункт 1?
или же я сначала всё должен записать в UDR1 т.е. UDR1 = data[z++]; в цикле пока data[z]!=0x03, и только затем уже давать добро на отправку?

2)Прерывание по завершению передачи - всёравно не представляю для чего оно на практике ....
и вызывается оно после каждого байта, или после того, как весь UDR1 завершит передачу?

я переводил сейчас даташит но всёравно лучше объясните, а то оттуда картина не очень понятна
Друг Кота
Аватара пользователя
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Сообщение Engineer_Keen »

jazz393 писал(а):блин я всёравно не понимаю...ну есть эти 2 флага...
1)Не понимаю следующего - как его использовать...если буфер передатчика всёвремя свободен, и мне надо скажем отправить какую-то строку char *str , то как это всё организовывается...? Мне что нужно будет разрешить прерывание, оно (если свободен буфер) вызывается, и записывает в буфер UDR1 = data[z]; затем прерывание возврощается и продолжается выполнять main, когда
флаг UDRE опять сработает, то снова вызывается прерывание и пишется UDR1 = data[z]; , а когда я дохожу до data[z]==0x03 (это признак конца сообщения) то я запрещаю это прерывание и обнуляю z -= который должен быть глобальным счетчиком...
я правильно понимаю пункт 1?
Вроде верно
jazz393 писал(а): или же я сначала всё должен записать в UDR1 т.е. UDR1 = data[z++]; в цикле пока dztz[z]!=0x03, и только затем уже давать добро на отправку?
Если вы так сделаете, то контроллер быстро перезапишет в UDR1 всю строку посимвольно, а т.к. UDR1 это всего лишь 8 битный регистр, то в нем просто останется последний символ, при этом запись первого запустит процесс передачи (первый байт попадет в сдвиговый регистр). После передачи первого байта, в регистр запишется последний байт и отправится на передачу, т.е. передадутся 1 и последний символы, а вся середина потеряется, вот что примерно получится...
Как работает UART подробно описано в даташите на контроллер.
jazz393 писал(а): 2)Прерывание по завершению передачи - всёравно не представляю для чего оно на практике ....
и вызывается оно после каждого байта, или после того, как весь UDR1 завершит передачу?
Никакого "всего UDR1" нету, есть 8 битный буферный регистр UDR1 (точнее 2, на вход и выход), так что прерывание вызовется после передачи байта. Контроллер ничего не знает о строках и массивах, он 8 битный, так что вся работа по реализации алгоритмов отправки/приема/обработки массивов данных лежит на разработчике.
Разница в том, что прерывание по пустому буферу, если его включить, будет срабатывать постоянно, если в буфере будет пусто, а прерывание по окончанию передачи срабатывает один раз (до следующей передачи). И срабатывают они в разное время. По пустому буферу прерывание начинает срабатывать как только из UDR байт перемещается в выходной сдвиговый регистр, а по окончанию передачи срабатывает как только из выходного регистра уходят последний байт со стоп битами.
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
Встал на лапы
Сообщения: 118
Зарегистрирован: Ср фев 05, 2014 18:54:39

Сообщение jazz393 »

Да спасибо, впринципе я уже примерно понял как делать - кольцевой буфер на отправку, и в прерывании считывать из него если счетчики записанной инфы и переданной инфы не совпадают
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18793
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

иначе говоря:

Код: Выделить всё

буфер;
флаг_окончания_передачи=0;

обработчик_прерываний_по_передаче_символа{
   если буфер не пуст{
      извечь из буфера очередной символ и поместить его в UDR;
   } иначе {
      флаг_окончания_передачи=1;
   }
}

передача_строки(строка){
   ждать пока флаг_окончания_передачи =0;
   флаг_окончания_передачи=0;
   буфер=строка;
   извлечь из буфера первый символ и поместить его в UDR;
}

главная_функция{
   ...
   разрешить прерывания по передаче символа;
   ...
   передача_строки("Туды её в качель!"); 
   ...
}
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Встал на лапы
Сообщения: 118
Зарегистрирован: Ср фев 05, 2014 18:54:39

Сообщение jazz393 »

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

Код: Выделить всё

void transmit_Usart_INT_1(unsigned char *data)
	{
	unsigned char i=0;
	if(flag_tx_rdy_1)
		return;
	do
		{
		flag_tx_rdy_1=1;
		buf_tx_usart_1[tail_tx_usart_1++]=data[i++];
		if(tail_tx_usart_1==48)
			tail_tx_usart_1=0;
		}while(data[i-1] != 0x03);

	if(head_tx_usart_1 != tail_tx_usart_1)
		{
		UDR1=data[head_tx_usart_1++];
		flag_tx_rdy_1=1;
		}
	UCSR1B |= (1<<UDRIE1));			// разрешаем прерывание
	}
обр прерываний

Код: Выделить всё

interrupt [USART1_TXC] void usart1_tx_isr(void)
    {
    #asm("cli")
    UDR1='k';
    // UDR1=buf_tx_usart_1[head_tx_usart_1];
    flag_tx_rdy_1=0;
    if (++head_tx_usart_1 == 48)
        head_tx_usart_1=0;
    #asm("sei")
    if(head_tx_usart_1 == tail_tx_usart_1)
        UCSR1B &= ~(1<<UDRIE1);
    return;
    }
Друг Кота
Аватара пользователя
Сообщения: 20126
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

jazz393 писал(а):

Код: Выделить всё

    #asm("cli")
    #asm("sei")
Лишнее. Поправьте если не прав.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Встал на лапы
Сообщения: 118
Зарегистрирован: Ср фев 05, 2014 18:54:39

Сообщение jazz393 »

Gudd-Head писал(а):
jazz393 писал(а):

Код: Выделить всё

    #asm("cli")
    #asm("sei")
Лишнее. Поправьте если не прав.
да там что с ними что без них, просто ещё куча таймеров, это на всякий
Друг Кота
Аватара пользователя
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Сообщение Engineer_Keen »

jazz393 писал(а):да там что с ними что без них, просто ещё куча таймеров, это на всякий
Глобальные прерывания отключаются автоматически при переходе на обработчик прерывания, и автоматически же восстанавливаются при выходе из него. Сказать что будет, если разрешить прерывание внутри самого обработчика прерывания? А если в этот момент взведется как раз флаг ЭТОГО прерывания? Так что для начала cli-sei таки уберите оттудова...
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
akl
Друг Кота
Сообщения: 4475
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Engineer_Keen писал(а):... автоматически же восстанавливаются при выходе из него.
Уточню. Только при выходе по RETI.
Встал на лапы
Сообщения: 118
Зарегистрирован: Ср фев 05, 2014 18:54:39

Сообщение jazz393 »

Engineer_Keen писал(а):
jazz393 писал(а):да там что с ними что без них, просто ещё куча таймеров, это на всякий
Глобальные прерывания отключаются автоматически при переходе на обработчик прерывания, и автоматически же восстанавливаются при выходе из него. Сказать что будет, если разрешить прерывание внутри самого обработчика прерывания? А если в этот момент взведется как раз флаг ЭТОГО прерывания? Так что для начала cli-sei таки уберите оттудова...
убрал, результат тот же самый=(
Друг Кота
Аватара пользователя
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Сообщение Engineer_Keen »

akl писал(а):Уточню. Только при выходе по RETI.
Думаю любителям ЯВУ этого знать не нужно не обязательно :))) (шутка)
jazz393, очевидно что дело было не только в cli-sei, но sei явно мог породить еще большие глюки...
Конкретно в чем косяк не скажу, т.к. Си не воспринимаю на 100%, у меня все проще...
Спойлер

Код: Выделить всё

[...]
;отправка
	LDIW	XH,CMD ;ставим указатель (X) на строку
	LD	R16,X+ ;читаем первый символ
	OUT	UDR,R16 ;отправляем в UART
	OUTI	UCSRB,(1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN) ;включаем прерывание
	STW	CMD_PTR,XH
[...]
;прерывание по передаче
UART_TX:
	PUSHS3	R16,XH,XL ;сохраняем регистры
	LDW	XH,CMD_PTR ;читаем указатель
	LD	R16,X+ ;читаем строку
	OUT	UDR,R16 ;отправляем в UART
	STW	CMD_PTR,XH ;сохраняем указатель
	CJNE	R16,0x03,TX_EX ;проверяем что не конец строки
	OUTI	UCSRB,(1<<RXCIE)|(0<<TXCIE)|(1<<RXEN)|(1<<TXEN) ;отключаем прерывание
TX_EX:	POPS3	R16,XH,XL ;восстанавливаем регистры
	RETI ;выходим из прерывания
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
Встал на лапы
Сообщения: 118
Зарегистрирован: Ср фев 05, 2014 18:54:39

Сообщение jazz393 »

оу кстати разобрался - cvavr генерировал обработчик для др прерывания)
Ответить

Вернуться в «Разные вопросы по МК»