Нескольно простых вопросов о программировании AVR на Си.

Обсуждаем контроллеры компании Atmel.
Joni999
Родился
Сообщения: 15
Зарегистрирован: Пн май 05, 2014 11:59:11

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Joni999 »

COKPOWEHEU писал(а):Зачем cli и sei в прерывании?
Почему не использовали кольцевой буфер?
Точно средняя частота возникновения прерывания INT0 меньше скорости передачи по UART? Если больше то никакие ухищрения не помогут.
Точно для логического анализатора не нужна привязка к времени?
ширина импульса за который нужно успеть считать данные с порта 0,33 мкс, до следующего импульса еще примерно 0,7 мкс
кварц на 16мГц
я не смог найти данные о том через сколько изменения логического уровня на пинах контроллера переходят в регистр PINn

мне кажется, что в регистр PINn либо не успевают заноситься изменения, либо контроллер не успевает с него считывать, потому что когда я дергаю ножку прерывания вручную по UART передаются точные данные, а когда подключаю к шине устройства данные идут с большими ошибками

привязка по времени пока не нужна, возможно добавлю на будущее, если вообще заработает нормально
Реклама
Аватара пользователя
DronVolk
Встал на лапы
Сообщения: 109
Зарегистрирован: Чт сен 03, 2015 15:52:10
Откуда: Сибирский федеральный округ

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение DronVolk »

COKPOWEHEU писал(а):Зачем cli и sei в прерывании?
Это наверное был не вопрос... ))))

Прерывание не может быть прервано ....))))
Реклама
Pnjom-Penb
Мучитель микросхем
Сообщения: 469
Зарегистрирован: Вс авг 30, 2015 03:52:59

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Pnjom-Penb »

DronVolk писал(а):Прерывание не может быть прервано ...
Может.
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение COKPOWEHEU »

Они там зачем-то написаны, хотя по смыслу именно в тех местах бесполезны. Вот и интересно.
По идее контроллер должен успевать, но не UART. Если ширина импульса 0.33 мкс и пауза между ними 0.7 мкс, период колебаний 1.03 мкс что соответствует частоте 971 кГц, по 10 бит на посылку UART получается требуется скорость обмена не менее 9.7 мегабит в секунду. Даже если такое позволяет контроллер (хотя не позволяет, его частота должна быть более 77 МГц), стабильность будет на нуле.
На счет того, что данные не соответствуют ожиданиям - я не знаю, какая там схема, вдруг не все напряжения успевают установиться.
Прерывание прервано быть не может, если этого специально не разрешить, но здесь этого не делается. sei сразу перед reti не успеет отработать.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
DronVolk
Встал на лапы
Сообщения: 109
Зарегистрирован: Чт сен 03, 2015 15:52:10
Откуда: Сибирский федеральный округ

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение DronVolk »

Pnjom-Penb писал(а):Может.
описывай уже полностью, а то введешь человека в заблуждение.

Если не разрешить прерывание в прерывании то не может быть и прерван обработчик.
Реклама
Pnjom-Penb
Мучитель микросхем
Сообщения: 469
Зарегистрирован: Вс авг 30, 2015 03:52:59

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Pnjom-Penb »

DronVolk писал(а):введешь человека в заблуждение
Любезный, во-первых - я с Вами на брудершафт не пил, да и не выпью никогда, а потому - оставьте этот тон для соседей по двору.
А во-вторых, вводить в заблуждение - это скорее ляпнуть что-то категоричное, из серии:
DronVolk писал(а):Прерывание не может быть прервано ...
, не давая никаких пояснений, как будто это истина на все случаи жизни.
Реклама
gavrasio
Нашел транзистор. Понюхал.
Сообщения: 162
Зарегистрирован: Пн июн 01, 2015 15:23:01

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение gavrasio »

Pnjom-Penb писал(а):
DronVolk писал(а):Прерывание не может быть прервано ...
Может.
Есть такое общее понятие - вложенные прерывания( прерываия внутри прерываний). Это про общее утверждение. Тонкости, если понадобятся, можно выложить.
gavrasio
Нашел транзистор. Понюхал.
Сообщения: 162
Зарегистрирован: Пн июн 01, 2015 15:23:01

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение gavrasio »

DronVolk писал(а):
Если не разрешить прерывание в прерывании то не может быть и прерван обработчик.
Ну, конечно Вы правы в этом утверждении. Просто, оно тяжеловато для быстрого понимания.
gavrasio
Нашел транзистор. Понюхал.
Сообщения: 162
Зарегистрирован: Пн июн 01, 2015 15:23:01

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение gavrasio »

Pnjom-Penb писал(а):
DronVolk писал(а):введешь человека в заблуждение
А во-вторых, вводить в заблуждение - это скорее ляпнуть что-то категоричное, из серии:
DronVolk писал(а):Прерывание не может быть прервано ...
, не давая никаких пояснений, как будто это истина на все случаи жизни.

Здесь DroncVolk имел ввиду, что после первой команды sei(); , когда обработчик начал работу, он и так запрещаете все прерывания, и кманда cli(); ничего не может запретить.
LEONID59R
Родился
Сообщения: 7
Зарегистрирован: Вт авг 27, 2013 13:19:29

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение LEONID59R »

Народ помогите, какой функцией и как можно вывести информацию на LCD с выводов микроконтроллера. к примеру на N-ый вывод микроконтроллера подаю 1 или 0 , а на LCD отображается надпись к пимеру да или нет.
Аватара пользователя
hybroid
Друг Кота
Сообщения: 8007
Зарегистрирован: Вс ноя 14, 2010 19:24:26
Откуда: Лукалэнд

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение hybroid »

Соответствующей функцией.
Для более подробного ответа нужен более подробный вопрос.
LEONID59R
Родился
Сообщения: 7
Зарегистрирован: Вт авг 27, 2013 13:19:29

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение LEONID59R »

допустим на вывод 23 микроконтроллера atmega8 я подаю питание соответственно на нем будет 1-ца мне нужно чтоб эту 1 мог отобразить LCD в виде надписи OK.
Аватара пользователя
hybroid
Друг Кота
Сообщения: 8007
Зарегистрирован: Вс ноя 14, 2010 19:24:26
Откуда: Лукалэнд

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение hybroid »

LCD - это технология изготовления дисплея, не более. Неплохо знать хотя бы модель.
И неплохо бы по модели сначала поискать ответ самому, скорее всего кому-то из всего мира уже пришлось на него что-то выводить.
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение COKPOWEHEU »

С такой постановкой задачи вероятность найти ответ минимальна.
Вам нужно отдельное устройство с ножкой, за которую можно дергать, и интерфейсом дисплея, которое будет туда выводить если кто-то дернул?
Что за дисплей, не HD44780 часом?
Что хочется, готовое устройство или разобраться в теме?
Joni999
Родился
Сообщения: 15
Зарегистрирован: Пн май 05, 2014 11:59:11

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Joni999 »

COKPOWEHEU писал(а):Они там зачем-то написаны, хотя по смыслу именно в тех местах бесполезны. Вот и интересно.
По идее контроллер должен успевать, но не UART. Если ширина импульса 0.33 мкс и пауза между ними 0.7 мкс, период колебаний 1.03 мкс что соответствует частоте 971 кГц, по 10 бит на посылку UART получается требуется скорость обмена не менее 9.7 мегабит в секунду. Даже если такое позволяет контроллер (хотя не позволяет, его частота должна быть более 77 МГц), стабильность будет на нуле.
На счет того, что данные не соответствуют ожиданиям - я не знаю, какая там схема, вдруг не все напряжения успевают установиться.
Прерывание прервано быть не может, если этого специально не разрешить, но здесь этого не делается. sei сразу перед reti не успеет отработать.
схема довольно простая, все напрямую без резисторов и конденсаторов,
то, что я подключаюсь к устройству и оно продолжает стабильно работать говорит о том, что какие то серьезные помехи я не вношу
посылки идут не постоянно, а пачками, на это я и рассчитываю судя по тому, что у FT245 два буфера 384 и 128 байт, мне на буфер байт 700 будет за глаза
провел эксперимент:
-включил только прерывание INT0 по нарастающему фронту
-записал данные с PINA в буфер на 255 байт
-отключил прерывание по INT0
-включил прерывание по UDRE1
-отправил данные с буфера на комп
опять получил ерунду((((

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

#define UART_UDRTE_EN	(UCSR1B |= _BV(UDRIE1))
#define UART_UDRTE_DES	(UCSR1B &= ~_BV(UDRIE1))
#define EXT_INT0_EN		(EIMSK |= _BV(INT0))
#define EXT_INT0_DES	(EIMSK &= ~_BV(INT0))
#define DATA			PINA

unsigned char countData = 0;
unsigned char dataBuffer[255];
unsigned char dataBuff;
unsigned char countSendBuffer = 0;

ISR(INT0_vect){
	if(countData < 255){
		dataBuffer[countData] = DATA;
		countData ++;
	} else {
		EXT_INT0_DES;
		UART_UDRTE_EN;
	}
}

ISR(USART1_UDRE_vect){
	UDR1 = dataBuffer[countSendBuffer];
	countSendBuffer ++;
	if(countSendBuffer == countData){
		UART_UDRTE_DES;
	}
}
если не через буфер, а напрямую в UDR1 кидать, то вначале пару байт правильные приходят
Вложения
11.gif
(34.44 КБ) 353 скачивания
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение COKPOWEHEU »

А если с буферизацией - 1 байт нормально приходит?
Может скорости не хватает даже на буфер? Если частота возникновения прерывания 971 кГц, на обработку остается всего 16 тактов (на тактовой частоте 16 МГц), из которых 10-11 тактов уйдет на внутренние процессы обработчика прерываний и еще сколько-то на программное сохранение регистров вроде SREG. За 0.33 мкс вылетаете на первых 6 тактах, то есть еще до выполнения вашего кода.
Можно попробовать использовать кольцевой буфер, а прерывания обрабатывать программно, а еще лучше перейти на ассемблер и реализовать это там. И не забывайте считать такты :-D
Joni999
Родился
Сообщения: 15
Зарегистрирован: Пн май 05, 2014 11:59:11

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Joni999 »

COKPOWEHEU писал(а):А если с буферизацией - 1 байт нормально приходит?
Может скорости не хватает даже на буфер? Если частота возникновения прерывания 971 кГц, на обработку остается всего 16 тактов (на тактовой частоте 16 МГц), из которых 10-11 тактов уйдет на внутренние процессы обработчика прерываний и еще сколько-то на программное сохранение регистров вроде SREG. За 0.33 мкс вылетаете на первых 6 тактах, то есть еще до выполнения вашего кода.
Можно попробовать использовать кольцевой буфер, а прерывания обрабатывать программно, а еще лучше перейти на ассемблер и реализовать это там. И не забывайте считать такты :-D
посмотрел как код преобразовался в ассемблер

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

ISR(INT0_vect){
  b6:	1f 92       	push	r1
  b8:	0f 92       	push	r0
  ba:	0f b6       	in	r0, 0x3f	; 63
  bc:	0f 92       	push	r0
  be:	11 24       	eor	r1, r1
  c0:	0b b6       	in	r0, 0x3b	; 59
  c2:	0f 92       	push	r0
  c4:	8f 93       	push	r24
  c6:	9f 93       	push	r25
  c8:	ef 93       	push	r30
  ca:	ff 93       	push	r31
	if(countData < 255){
  cc:	80 91 01 01 	lds	r24, 0x0101
  d0:	8f 3f       	cpi	r24, 0xFF	; 255
  d2:	a1 f0       	breq	.+40     	; 0xfc <__vector_1+0x46>
		dataBuffer[countData] = DATA;
  d4:	90 b1       	in	r25, 0x00	; 0
  d6:	e8 2f       	mov	r30, r24
  d8:	f0 e0       	ldi	r31, 0x00	; 0
  da:	ee 5f       	subi	r30, 0xFE	; 254
  dc:	fe 4f       	sbci	r31, 0xFE	; 254
  de:	90 83       	st	Z, r25
		countData ++;
  e0:	8f 5f       	subi	r24, 0xFF	; 255
  e2:	80 93 01 01 	sts	0x0101, r24
	} else {
		EXT_INT0_DES;
		UART_UDRTE_EN;
	}
}
в 16 тактов явно не влезаю(((
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение COKPOWEHEU »

Сколько всего времени длится пакет? Может можно использовать программную обработку прерываний, причем на ассемблере оно проще - точно известно какие регистры и где используются.
Joni999
Родился
Сообщения: 15
Зарегистрирован: Пн май 05, 2014 11:59:11

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Joni999 »

Пробовал ставить кристалл на 20Мгц и сразу во внешнем прерывании кидать в данные с PORTA в UDR1, количество правильный данных заметно возросло, прерывание настроил на спадающий фронт
Что вы имеете ввиду под программным прерыванием? просто считывать данные с порта в главном цикле программы не используя аппаратных прерываний?
Прилагаю картинку с лог. анализатора
черный канал подключен к линии RD, остальные каналы на шине данных, в месте обведенном овалом появиться импульс с линии WR и данные на шине изменяться, я пока к WR не подключался, это будет следующим шагом, когда все заработает
Вложения
Новый точечный рисунок (2).jpg
(73.21 КБ) 336 скачиваний
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение COKPOWEHEU »

Что-то в таком роде. Наверняка не соберется (я не знаю что за камень, какая скорость UART'a и какой максимальный промежуток между принимаемыми байтами), но, надеюсь, суть ясна.

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

volatile char buffer[256]; //лучше бы переписать на ассемблере и выравнять, чтобы младший байт адреса был равен 0, например, 0x0100
volatile char size=0; //лучше бы переписать на ассемблере и выделить для этого одну из регистровых пар, а не область ОЗУ
int main(){
 //настроить Timer0_comp (для определенности, но можно и любой другой) на период чуть больше времени передачи по UART
 //настроить порты, UART и прочее
 //прерывания UART запрещены, прерывание таймера разрешено
 //таймер остановлен (CS = 0)
 while(1){
  if( /*условие срабатывания INT0 */){
   buffer[size++] = PINA;  //записываем данные в буфер
   TCNT0 = 0; //сбрасываем таймер, чтобы отсрочить прерывание
   TCCR0B |= (1<<CS00); //запускаем таймер
  }
 }
}
ISR(TIMER0_COMP){ //прерывание должно возникнуть если данные долгое время не принимались
  if(start > 0){ //если буфер не пуст - запускаем передачу
    UCSRB |= (1<<UDRIE);
    UDR = buffer[0];
  }
  TCCR0B &=~ (0b111 << CS00); //останавливаем таймер
  TCNT0 = 0;
  TIMSK &=~(1<<OCIE0);
}
ISR(UDR_vect){
  static char start=1; //тоже лучше бы выделить регистровую пару
  if( start < size ){ //в буфере еще остались данные
    UDR = buffer[ start++ ]; //значит передаем их
  }else{ //буфер пуст
    start = 0; size = 0; //очищаем буфер для следующих данных
    UCSRB &=~ (1<<UDRIE); //запрещаем прерывание UART
    TCCR0B |= (1<<CS00); //запускаем таймер
    TIMSK |= (1<<OCIE0);
  }
}
Ответить

Вернуться в «AVR»