Заголовок сообщения: Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Ср ноя 04, 2015 22:14:38
Родился
Зарегистрирован: Пн май 05, 2014 11:59:11 Сообщений: 15
Рейтинг сообщения:0
COKPOWEHEU писал(а):
Зачем cli и sei в прерывании? Почему не использовали кольцевой буфер? Точно средняя частота возникновения прерывания INT0 меньше скорости передачи по UART? Если больше то никакие ухищрения не помогут. Точно для логического анализатора не нужна привязка к времени?
ширина импульса за который нужно успеть считать данные с порта 0,33 мкс, до следующего импульса еще примерно 0,7 мкс кварц на 16мГц я не смог найти данные о том через сколько изменения логического уровня на пинах контроллера переходят в регистр PINn
мне кажется, что в регистр PINn либо не успевают заноситься изменения, либо контроллер не успевает с него считывать, потому что когда я дергаю ножку прерывания вручную по UART передаются точные данные, а когда подключаю к шине устройства данные идут с большими ошибками
привязка по времени пока не нужна, возможно добавлю на будущее, если вообще заработает нормально
Они там зачем-то написаны, хотя по смыслу именно в тех местах бесполезны. Вот и интересно. По идее контроллер должен успевать, но не UART. Если ширина импульса 0.33 мкс и пауза между ними 0.7 мкс, период колебаний 1.03 мкс что соответствует частоте 971 кГц, по 10 бит на посылку UART получается требуется скорость обмена не менее 9.7 мегабит в секунду. Даже если такое позволяет контроллер (хотя не позволяет, его частота должна быть более 77 МГц), стабильность будет на нуле. На счет того, что данные не соответствуют ожиданиям - я не знаю, какая там схема, вдруг не все напряжения успевают установиться. Прерывание прервано быть не может, если этого специально не разрешить, но здесь этого не делается. sei сразу перед reti не успеет отработать.
Любезный, во-первых - я с Вами на брудершафт не пил, да и не выпью никогда, а потому - оставьте этот тон для соседей по двору. А во-вторых, вводить в заблуждение - это скорее ляпнуть что-то категоричное, из серии:
DronVolk писал(а):
Прерывание не может быть прервано ...
, не давая никаких пояснений, как будто это истина на все случаи жизни.
А во-вторых, вводить в заблуждение - это скорее ляпнуть что-то категоричное, из серии:
DronVolk писал(а):
Прерывание не может быть прервано ...
, не давая никаких пояснений, как будто это истина на все случаи жизни.
Здесь DroncVolk имел ввиду, что после первой команды sei(); , когда обработчик начал работу, он и так запрещаете все прерывания, и кманда cli(); ничего не может запретить.
Народ помогите, какой функцией и как можно вывести информацию на LCD с выводов микроконтроллера. к примеру на N-ый вывод микроконтроллера подаю 1 или 0 , а на LCD отображается надпись к пимеру да или нет.
допустим на вывод 23 микроконтроллера atmega8 я подаю питание соответственно на нем будет 1-ца мне нужно чтоб эту 1 мог отобразить LCD в виде надписи OK.
LCD - это технология изготовления дисплея, не более. Неплохо знать хотя бы модель. И неплохо бы по модели сначала поискать ответ самому, скорее всего кому-то из всего мира уже пришлось на него что-то выводить.
С такой постановкой задачи вероятность найти ответ минимальна. Вам нужно отдельное устройство с ножкой, за которую можно дергать, и интерфейсом дисплея, которое будет туда выводить если кто-то дернул? Что за дисплей, не HD44780 часом? Что хочется, готовое устройство или разобраться в теме?
Заголовок сообщения: Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Сб ноя 07, 2015 21:53:11
Родился
Зарегистрирован: Пн май 05, 2014 11:59:11 Сообщений: 15
Рейтинг сообщения:0
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 -отправил данные с буфера на комп опять получил ерунду((((
А если с буферизацией - 1 байт нормально приходит? Может скорости не хватает даже на буфер? Если частота возникновения прерывания 971 кГц, на обработку остается всего 16 тактов (на тактовой частоте 16 МГц), из которых 10-11 тактов уйдет на внутренние процессы обработчика прерываний и еще сколько-то на программное сохранение регистров вроде SREG. За 0.33 мкс вылетаете на первых 6 тактах, то есть еще до выполнения вашего кода. Можно попробовать использовать кольцевой буфер, а прерывания обрабатывать программно, а еще лучше перейти на ассемблер и реализовать это там. И не забывайте считать такты :-D
Заголовок сообщения: Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Вс ноя 08, 2015 08:15:00
Родился
Зарегистрирован: Пн май 05, 2014 11:59:11 Сообщений: 15
Рейтинг сообщения:0
COKPOWEHEU писал(а):
А если с буферизацией - 1 байт нормально приходит? Может скорости не хватает даже на буфер? Если частота возникновения прерывания 971 кГц, на обработку остается всего 16 тактов (на тактовой частоте 16 МГц), из которых 10-11 тактов уйдет на внутренние процессы обработчика прерываний и еще сколько-то на программное сохранение регистров вроде SREG. За 0.33 мкс вылетаете на первых 6 тактах, то есть еще до выполнения вашего кода. Можно попробовать использовать кольцевой буфер, а прерывания обрабатывать программно, а еще лучше перейти на ассемблер и реализовать это там. И не забывайте считать такты :-D
Сколько всего времени длится пакет? Может можно использовать программную обработку прерываний, причем на ассемблере оно проще - точно известно какие регистры и где используются.
Заголовок сообщения: Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлено: Сб ноя 14, 2015 20:40:32
Родился
Зарегистрирован: Пн май 05, 2014 11:59:11 Сообщений: 15
Рейтинг сообщения:0
Пробовал ставить кристалл на 20Мгц и сразу во внешнем прерывании кидать в данные с PORTA в UDR1, количество правильный данных заметно возросло, прерывание настроил на спадающий фронт Что вы имеете ввиду под программным прерыванием? просто считывать данные с порта в главном цикле программы не используя аппаратных прерываний? Прилагаю картинку с лог. анализатора черный канал подключен к линии RD, остальные каналы на шине данных, в месте обведенном овалом появиться импульс с линии WR и данные на шине изменяться, я пока к WR не подключался, это будет следующим шагом, когда все заработает
Что-то в таком роде. Наверняка не соберется (я не знаю что за камень, какая скорость 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); } }
Сейчас этот форум просматривают: Anatoly32, Majestic-12 [Bot], Simon.S и гости: 10
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения