Оказалось довольно хитро, но распознал так. Оказалось, передевалась структура файла xmlGudd-Head писал(а):Та не, суть-то вроде как раз расшифровать принятую на комп абракадабру.Chettuser писал(а):если только не программа, то логический анализатор умеет.
Мелкие вопросы по МК и ПЛИС.
- Roman Venom
- Сверлит текстолит когтями
- Сообщения: 1135
- Зарегистрирован: Сб июл 11, 2009 18:42:21
- Откуда: Украина, г.Николаев
Re: Мелкие вопросы по МК и ПЛИС.
Успех - императив!
- Реклама
- sphincs
- Нашел транзистор. Понюхал.
- Сообщения: 174
- Зарегистрирован: Вт сен 11, 2012 09:13:52
- Откуда: Брест, Беларусь
- Контактная информация:
Re: Мелкие вопросы по МК и ПЛИС.
подскажите как работает цикл while (условие); без тела цикла? просто бесконечно проверяет условие, пока оно не станет ложно? при работе с АЦП косяк какой-то. эта часть кода выполняется до while((ADCSRA & 0x10)==0); и зацикливается, строка ADCSRA|=0x10; уже не идет (да я как-то не сильно понимаю зачем она нужна. зачем вручную выставлять флаг прерывания, если она вроде как должна выполниться только тогда, когда флаг автоматически будет выставлен самим АЦП). я так понимаю, что при симуляции в протеусе почему-то не выставляется флаг прерывания ADIF, хотя в примере, с которого это было списано, все нормально (не считая небольших косяков в других местах, не влияющих на выполнение именно этой части кода) и результат выводился на дисплей, сам проверял. вот источник http://radioaktiv.ru/publ/lessons/digit ... tmetr.html подскажите, кто чем может, а то работа простаивает 
Код: Выделить всё
unsigned char ADC_result()
{
ADMUX=adc_input | (ADMUX & 0b01110000); //выставляем канал
delay_us(30); //задержка для стабилизации
ADCSRA |= 0x40; // запускаем преобразование
while((ADCSRA & 0x10)==0); //Ждём флаг окончания измерения
ADCSRA|=0x10;
return ADCH;//Возвращаем старший байт
}Re: Мелкие вопросы по МК и ПЛИС.
Да, именно так.sphincs писал(а):подскажите как работает цикл while (условие); без тела цикла? просто бесконечно проверяет условие, пока оно не станет ложно?
После while (условие) должен идти оператор. Оператор может быть одиночным, например,
Код: Выделить всё
while (условие) i++;Код: Выделить всё
while (условие) { i++; printf("%d",i);}Код: Выделить всё
while (условие) ;Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
- sphincs
- Нашел транзистор. Понюхал.
- Сообщения: 174
- Зарегистрирован: Вт сен 11, 2012 09:13:52
- Откуда: Брест, Беларусь
- Контактная информация:
Re: Мелкие вопросы по МК и ПЛИС.
Kavka, благодарю. теперь остался самый сложный вопрос: почему не выставляется флаг прерывания
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Мелкие вопросы по МК и ПЛИС.
Так нихуя ничего не запуститсяsphincs писал(а):ADCSRA |= 0x40; // запускаем преобразование
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- Реклама
- sphincs
- Нашел транзистор. Понюхал.
- Сообщения: 174
- Зарегистрирован: Вт сен 11, 2012 09:13:52
- Откуда: Брест, Беларусь
- Контактная информация:
Re: Мелкие вопросы по МК и ПЛИС.
у меня уже не получается догадываться)Gudd-Head писал(а):не запуститсяsphincs писал(а):ADCSRA |= 0x40; // запускаем преобразованиеНадеюсь, сами догадаетесь почему.
значение ADCSRA 10001111
значение 0х40 01000000 т.е. нужно выставить ADSC в 1 (запуск)
--------------------------------------------
побитовое ИЛИ |= 11001111
получаем тот же ADCSRA но уже с выставленным битом начала преобразования. где ошибка? если дело в каких-то тонкостях си (типа нельзя шестнадцатеричное число сравнить с двоичным), то так и скажите, потому что си я учу вот как раз на этом примере используя знания паскаля/делфи и гугл
UPD. а дело случаем не в однократном режиме работы АЦП?
UPD1. именно в нем
Последний раз редактировалось sphincs Пт мар 07, 2014 12:03:56, всего редактировалось 1 раз.
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Мелкие вопросы по МК и ПЛИС.
Блин, точно. У вас побитовое ИЛИ, а не присвоениеsphincs писал(а):побитовое ИЛИ |= 11001111
Попробуйте присвоением:
Код: Выделить всё
ADCSRA = 0xCF; // запускаем преобразованиеА дело как раз-таки в цикле While, не знаток СИ.
Не должно быть в этом.sphincs писал(а):а дело случаем не в однократном режиме работы АЦП?
Если вы внимательно почитаете ДШ, то поймёте что флаг прерывания сбрасывается либо при обработке соотв. прерывания (если оно разрешено), либо программно записью "1" в соотв. бит.sphincs писал(а):строка ADCSRA|=0x10; уже не идет (да я как-то не сильно понимаю зачем она нужна. зачем вручную выставлять флаг прерывания, если она вроде как должна выполниться только тогда, когда флаг автоматически будет выставлен самим АЦП).
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- sphincs
- Нашел транзистор. Понюхал.
- Сообщения: 174
- Зарегистрирован: Вт сен 11, 2012 09:13:52
- Откуда: Брест, Беларусь
- Контактная информация:
Re: Мелкие вопросы по МК и ПЛИС.
не знаю почему, но убрав цикл while все заработало
Re: Мелкие вопросы по МК и ПЛИС.
Если файл прошивки HEX весит 20кб, значит и мк должен иметь RAM на 20кб?? Просто у меня ATmega88PA с 1кб и грузиться и работает?
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Мелкие вопросы по МК и ПЛИС.
Нет, в ХЕКСе много всякой другой инфы.
Пример: прошивка код весит 1,9 кбайт, прошивка (хекс) — 5,2 кбайт.
Да и прошивка грузится не в RAM, а во FLASH.
Пример: прошивка код весит 1,9 кбайт, прошивка (хекс) — 5,2 кбайт.
Да и прошивка грузится не в RAM, а во FLASH.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- DJ_Kiridza
- Мучитель микросхем
- Сообщения: 458
- Зарегистрирован: Пн дек 13, 2010 13:01:59
- Откуда: Украина
- Контактная информация:
Re: Мелкие вопросы по МК и ПЛИС.
Гран-мерси!!!!oleg110592 писал(а):ATmega8535чтобы было два кварца
ATmega16/32
ATmega164PA/324PA/644PA/1284P
А про Атмегу16 - я сам баран, не внимательно читал даташит, когда первый раз знакомился с этой Мегой. Мне тогда таймер2 не нужен был, я инфу о нем поверхностно прочитал... спасибо что носом ткнули!!!!
мысли мысли штош вы вйотесь
над мойейу головойу
вы там мосга нинайдете
нед там мосга! йа тупойе (БОР)
над мойейу головойу
вы там мосга нинайдете
нед там мосга! йа тупойе (БОР)
Re: Мелкие вопросы по МК и ПЛИС.
RAM = Random Access Memory - это оперативная память и никакого отношения к размеру помещаемого в МК кода не имеет, потому что код заливается в ROM ( Read Only Memory ), то бишь флешь-память. Ее-то у 88-й Меги 8кб. Поскольку в HEX-файле ( INTEL-формат) каждый байт кода представлен двумя символьными байтами + служебная информация ( : , адрес, длина, КС,ВК,ПС ), то длина HEX-файла приблизительно в 3 раза превышает размер содержащегося в нем кода, так что 20кб кекса нормально влезает в 8 кб флеши.service47 писал(а):Если файл прошивки HEX весит 20кб, значит и мк должен иметь RAM на 20кб?? Просто у меня ATmega88PA с 1кб и грузиться и работает?
- Mem
- Поставщик валерьянки для Кота
- Сообщения: 1915
- Зарегистрирован: Вт апр 17, 2012 14:20:59
- Откуда: Новокузнецк
Re: Мелкие вопросы по МК и ПЛИС.
Не могу слить флеш с 6225, китай мобайл. Флштоол выдаёт: brom error: s_undefined_error (1001). Поиск ничего путного не выдаёт. Может сталкивался кто?
Главный инженер проекта - человек, который как никто другой знает, что приближаться к спроектированной им хрени близко не стоит.
- baron_P
- Нашел транзистор. Понюхал.
- Сообщения: 183
- Зарегистрирован: Вт сен 14, 2010 23:07:10
- Откуда: Ростов
Re: Мелкие вопросы по МК и ПЛИС.
Здравствуйте.
Есть такая (использую в качестве учебной) страшненькая программа:
Контроллер ATTiny 13A. Программа реализует программный ШИМ на трех вывода PB0, PB1, PB2. Задание для ШИМ берется из заранее сформированных массивов, в зависимости от напряжения на входе АЦП PB4. На PB3 висит кнопка, которая переводит это дело в спящий режим.
Программа работает, но есть один неясный момент. В обработчике прерывания по переполнению Таймера 0 сначала идет команда перевода выводов ШИМ в состояние входов:
Код:
Потом идет вызов функции, которая меняет значения на выводах ШИМ:
Код:
А потом идет команда перевода выводов ШИМ в состояние выходов:
Код:
Должно же быть наоборот: сперва делаем выводы выходами, потом меняем их состояние, потом делаем их входами. Правда, зачем нужен последний шаг (используемый в этой программе часто) тоже не понимаю. Пусть бы и оставались выводы в состоянии выходов, что в этом плохого. В общем, непонятно, как оно работает и зачем оно сделано так.
Есть такая (использую в качестве учебной) страшненькая программа:
Спойлер
Код: Выделить всё
#include<avr/io.h>
#include<avr/interrupt.h>
#define F_CPU 1200000UL
#include<util/delay.h>
#include<avr/pgmspace.h>
#include<avr/sleep.h>
//Prototypes
//This function is called to switch on the LED at the
//Required stage of PWM cycle
void abc(unsigned char a,unsigned char b,unsigned char c,unsigned char status);
//This function is used to initialise the new PWM cycle
void xyz(void);
volatile unsigned char e;
volatile unsigned char pwm[3]={0,8,8};
volatile unsigned char i=0;
volatile unsigned char k=0;
//PWM scale 0 - On 8 OFF
const unsigned char Blue[15] PROGMEM = {0,8,8,0,0,8,0,6,2,3,6,1,4,5,7};
const unsigned char Red[15] PROGMEM = {8,0,8,2,8,2,0,5,5,5,6,6,6,7,7};
const unsigned char Green[15] PROGMEM = {8,8,0,8,0,0,0,2,0,6,4,2,7,0,2};
volatile unsigned int counter =0;
int main(void)
{
DDRB &= ~((1<<3)|(1<<4)); //Switches and ADC
PORTB |= (1<<3); //Switches
PCMSK = 1<<PCINT3;//Configure PB3 as interrupt
//ADC init
ADMUX = 0b00100010; //ADC2,ADLAR,VCc
ADCSRA = 0b10000010; //prescaled by 4
//neglect first reading
ADCSRA |= 1<<ADSC;
while(ADCSRA&(1<<ADSC));//Wait
i = ADCH;
//Timer Initialisation
TCCR0A = 0x00;
TCCR0B = 0x02;//Prescaling
TIMSK0 = 1<<TOIE0;//Overflow Interrupt Enabled
sei();//Global Interrupts Enabled
while(1)
{
i=0;
ADCSRA |= 1<<ADSC;
while(ADCSRA&(1<<ADSC));//Wait
i = ADCH;
i = i>>4;//Divide by 16
if(i!=15)
{
pwm[0] = pgm_read_byte(&Blue[i]);
pwm[1] = pgm_read_byte(&Red[i]);
pwm[2] = pgm_read_byte(&Green[i]);
counter = 0;
k = 0;
}
_delay_ms(2);//Just a small delay
if(!(PINB&(1<<3)))
{
_delay_ms(30);
while(!(PINB&(1<<3))); //wait
_delay_ms(30);
TIMSK0 &= ~(1<<TOIE0);//Clear timer interrupt
DDRB &=~(1<<0|1<<1|1<<2);
GIFR |= 1<<PCIF;//Clear pending interrupt
GIMSK |= 1<<PCIE;//Pin change interrupt enable
MCUCR |= (1<<SE|1<<SM1);//Power down mode setting
sleep_cpu(); //CPU halted till interrupt
}
}
}
ISR(TIM0_OVF_vect)
{
DDRB &=~(1<<0|1<<1|1<<2);
if(e==8)
{
e=0;
xyz();
}
abc(pwm[0],pwm[1],pwm[2],e);
DDRB |=(1<<0|1<<1|1<<2);
e++;
if(i==15)//Run mode
{
counter++;
if(counter == 390)//500ms
{
counter = 0;
if(k==14)
k=0;
else k++;
pwm[0] = pgm_read_byte(&Blue[k]);
pwm[1] = pgm_read_byte(&Red[k]);
pwm[2] = pgm_read_byte(&Green[k]);
}
}
}
void xyz(void)
{
PORTB |= (1<<0)|(1<<1)|(1<<2);
}
void abc(unsigned char a,unsigned char b,unsigned char c,unsigned char status)
{
if((status==a))
{
PORTB&= ~(1<<0);
}
if((status==b))
{
PORTB&= ~(1<<1);
}
if((status==c))
{
PORTB&= ~(1<<2);
}
}
ISR(PCINT0_vect)
{
_delay_ms(30);
while(!(PINB&(1<<3))); //wait
_delay_ms(30);
MCUCR = 0x00; //sleep disable
GIMSK &= ~(1<<PCIE);//Pin change interrupt disable
TIMSK0 = 1<<TOIE0;//Overflow Interrupt Enabled
}Программа работает, но есть один неясный момент. В обработчике прерывания по переполнению Таймера 0 сначала идет команда перевода выводов ШИМ в состояние входов:
Код:
Код: Выделить всё
DDRB &=~(1<<0|1<<1|1<<2);Код:
Код: Выделить всё
abc(pwm[0],pwm[1],pwm[2],e);Код:
Код: Выделить всё
DDRB |=(1<<0|1<<1|1<<2);We do what we must because we can (c) GLaDOS
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Мелкие вопросы по МК и ПЛИС.
Действительно страшненькая. Без комментов в коде никто разбираться не будет.baron_P писал(а):Есть такая страшненькая программа
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- baron_P
- Нашел транзистор. Понюхал.
- Сообщения: 183
- Зарегистрирован: Вт сен 14, 2010 23:07:10
- Откуда: Ростов
Re: Мелкие вопросы по МК и ПЛИС.
Всю программу я привел на всякий случай. Не думал, что та часть, к которой относится мой вопрос, нуждается в комментариях. Но вот они ниже:
Вопрос: почему при таком порядке объявления фукнционала портов (обявляем как входа, меняем значение на них, объявляем как выхода), программа работает?
UPD:
Упростил программу до предела:
Смотрел дебаггером в AVRStudio 4.19 - программа моргает выходами. При этом на PINB все время висят нули. Если убрать строку с DDRB &=~(1<<0|1<<1|1<<2), то моргают также и PINB. Это баг или так и должно быть? Я ожидал другой логики работы от команды назначения выводов входами. Когда вывод вход, он не должен меняться от записи в PORTB. Или должен?
Спойлер
Код: Выделить всё
//вектор прерывания по перполнению Т0
ISR(TIM0_OVF_vect)
{
//перевод PB0, PB1, PB2 в состояние входов
DDRB &=~(1<<0|1<<1|1<<2);
//если e равно 8, обнуляем е и вызываем функцию
//которая выставляет PB0, PB1, PB2 в 1
if(e==8)
{
e=0;
xyz();
}
//вызываем фукцию, которая выставляет 0 на
//выводах PB0, PB1, PB2, в зависимости от
//значения е
abc(pwm[0],pwm[1],pwm[2],e);
//перевод PB0, PB1, PB2 в состояние выходов
DDRB |=(1<<0|1<<1|1<<2);
//инкремент е
e++;
//дальше идет дополнительный режим работы,
//когда значения на PB2, PB1, PB0 меняются
//в цикле, он к вопросу не относится
if(i==15)//Run mode
{
counter++;
if(counter == 390)//500ms
{
counter = 0;
if(k==14)
k=0;
else k++;
pwm[0] = pgm_read_byte(&Blue[k]);
pwm[1] = pgm_read_byte(&Red[k]);
pwm[2] = pgm_read_byte(&Green[k]);
}
}
}UPD:
Упростил программу до предела:
Спойлер
Код: Выделить всё
#include<avr/io.h>
#define F_CPU 1200000UL
int main(void)
{
while(1)
{
//объявляем PB0, PB1, PB2 входами
DDRB &=~(1<<0|1<<1|1<<2);
//на PB0, PB1, PB2 выставляем 0
PORTB &= ~(0b00000111);
//на PB0, PB1, PB2 выставляем 1
PORTB |= 0b00000111;
//объявляем PB0, PB1, PB2 выходами
DDRB |=(1<<0|1<<1|1<<2);
}
}We do what we must because we can (c) GLaDOS
- urry
- Сверлит текстолит когтями
- Сообщения: 1262
- Зарегистрирован: Пн дек 08, 2008 10:58:48
- Откуда: Винница
- Контактная информация:
Re: Мелкие вопросы по МК и ПЛИС.
Код: Выделить всё
Когда вывод вход, он не должен меняться от записи в PORTB.-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: Мелкие вопросы по МК и ПЛИС.
А посмотри внимательно структурную схему выходного порта в даташите на контроллер, многие вопросы сразу отпадают.
Делается это чтобы манипуляции не влияли на выход, за то время как программа будет решать 1 или 0 должен быть на выходе ШИМа в данном такте на выводе контроллера будет удерживаться уровень по инерции. Хотя, по хорошему эту операцию достаточно буферизировать - менять внутреннюю переменную, а потом её за один раз выводить в порт. И не нужны будут всякие подобные шаманства.
Делается это чтобы манипуляции не влияли на выход, за то время как программа будет решать 1 или 0 должен быть на выходе ШИМа в данном такте на выводе контроллера будет удерживаться уровень по инерции. Хотя, по хорошему эту операцию достаточно буферизировать - менять внутреннюю переменную, а потом её за один раз выводить в порт. И не нужны будут всякие подобные шаманства.
- baron_P
- Нашел транзистор. Понюхал.
- Сообщения: 183
- Зарегистрирован: Вт сен 14, 2010 23:07:10
- Откуда: Ростов
Re: Мелкие вопросы по МК и ПЛИС.
Спасибо.
О логике работы я судил по этой картинке:
Когда выводы порта B объявлены как входы, в PORTB можно записать 1, что включит подтягивающие резисторы. Если к выводам ничего не подцеплено, на PINB должны появиться 1. Если записать при этом в PORTB 0, то выводы будут висеть в воздухе и непонятно, что будет в PINB. Если к порту В подцепить катоды светодиодов, подав на аноды питание, то в первом случае светодиоды гореть не будут. И во втором тоже, т.к. тока нет.
Когда выводы порта В объявлены как выходы, в PORTВ можно записать 1, и в PINB появится 1. Если записать 0, то и в PINB появится 0. Если к порту В подцепить катоды светодиодов, подав на аноды питание, то в первом случае светодиоды гореть не будут. А во втором должны загореться, т.к. будут посажены на землю.
По моему так должно работать.
А тут же получается что-то другое. При обявленнии выводов входами всегда в PINB висят нули, и при записи в PORTB нулей загораются светодиоды. Я не пойму, почему так.
Объявляем выводы входами, записываем в PORTB сначала какие-то промежуточные значения, потом то, что должно быть выведено на него. Объявляем выводы выходами и на них тут же появляется уже находящиеся в PORTB значения. Между двумя объявлениями фактические значения на выводах не меняются, потому и PINB не меняется. Вроде дошло. Еще раз спасибо.
О логике работы я судил по этой картинке:
Спойлер
Когда выводы порта В объявлены как выходы, в PORTВ можно записать 1, и в PINB появится 1. Если записать 0, то и в PINB появится 0. Если к порту В подцепить катоды светодиодов, подав на аноды питание, то в первом случае светодиоды гореть не будут. А во втором должны загореться, т.к. будут посажены на землю.
По моему так должно работать.
А тут же получается что-то другое. При обявленнии выводов входами всегда в PINB висят нули, и при записи в PORTB нулей загораются светодиоды. Я не пойму, почему так.
Это фраза объясняет структуру программы в виде: объявили порт выходом, записали нужное значение, объявили входом, чтоб чего лишнего не записалось. Я правильно понял? Нет, не правильноДелается это чтобы манипуляции не влияли на выход, за то время как программа будет решать 1 или 0 должен быть на выходе ШИМа в данном такте на выводе контроллера будет удерживаться уровень по инерции. Хотя, по хорошему эту операцию достаточно буферизировать - менять внутреннюю переменную, а потом её за один раз выводить в порт. И не нужны будут всякие подобные шаманства.
We do what we must because we can (c) GLaDOS
- Mem
- Поставщик валерьянки для Кота
- Сообщения: 1915
- Зарегистрирован: Вт апр 17, 2012 14:20:59
- Откуда: Новокузнецк
Re: Мелкие вопросы по МК и ПЛИС.
Как исправить эти фьюзы?

Понятно что Mega 16 теперь от внешнего кварца, но какого? Пробовал разные, не определяется. Сигнатура 0х000000, в остальном пишет что готово к работе. Один раз завелась от 8 МГц, я затер флеш и еепром, после этого опять перестало работать.
Понятно что Mega 16 теперь от внешнего кварца, но какого? Пробовал разные, не определяется. Сигнатура 0х000000, в остальном пишет что готово к работе. Один раз завелась от 8 МГц, я затер флеш и еепром, после этого опять перестало работать.
- Вложения
-
- Безымянный.png
- (60.72 КБ) 808 скачиваний
Главный инженер проекта - человек, который как никто другой знает, что приближаться к спроектированной им хрени близко не стоит.


