Страница 490 из 628

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

Добавлено: Чт мар 06, 2014 19:12:53
Roman Venom
Gudd-Head писал(а):
Chettuser писал(а):если только не программа, то логический анализатор умеет.
Та не, суть-то вроде как раз расшифровать принятую на комп абракадабру.
Оказалось довольно хитро, но распознал так. Оказалось, передевалась структура файла xml :idea:

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

Добавлено: Пт мар 07, 2014 10:42:58
sphincs
подскажите как работает цикл 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: Мелкие вопросы по МК и ПЛИС.

Добавлено: Пт мар 07, 2014 11:07:56
Kavka
sphincs писал(а):подскажите как работает цикл while (условие); без тела цикла? просто бесконечно проверяет условие, пока оно не станет ложно?
Да, именно так.
После while (условие) должен идти оператор. Оператор может быть одиночным, например,

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

while (условие) i++;
составным

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

while (условие) { i++; printf("%d",i);}
или пустым

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

while (условие) ;

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

Добавлено: Пт мар 07, 2014 11:10:10
sphincs
Kavka, благодарю. теперь остался самый сложный вопрос: почему не выставляется флаг прерывания

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

Добавлено: Пт мар 07, 2014 11:25:24
Gudd-Head
sphincs писал(а):ADCSRA |= 0x40; // запускаем преобразование
Так нихуя ничего не запустится :) Надеюсь, сами догадаетесь почему.

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

Добавлено: Пт мар 07, 2014 11:35:29
sphincs
Gudd-Head писал(а):
sphincs писал(а):ADCSRA |= 0x40; // запускаем преобразование
не запустится :) Надеюсь, сами догадаетесь почему.
у меня уже не получается догадываться)

значение ADCSRA 10001111
значение 0х40 01000000 т.е. нужно выставить ADSC в 1 (запуск)
--------------------------------------------
побитовое ИЛИ |= 11001111

получаем тот же ADCSRA но уже с выставленным битом начала преобразования. где ошибка? если дело в каких-то тонкостях си (типа нельзя шестнадцатеричное число сравнить с двоичным), то так и скажите, потому что си я учу вот как раз на этом примере используя знания паскаля/делфи и гугл :) при пошаговом выполнении в авр студио этот бит выставляется, но ровно до перехода на следующую строку кода, после обнуляется. к такому меня жизнь не готовила)))

UPD. а дело случаем не в однократном режиме работы АЦП? :)

UPD1. именно в нем :) убрал while и все заработало. Gudd-Head, спасибо! :)

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

Добавлено: Пт мар 07, 2014 12:03:48
Gudd-Head
sphincs писал(а):побитовое ИЛИ |= 11001111
Блин, точно. У вас побитовое ИЛИ, а не присвоение :facepalm: проглядел. (Конечно, с учётом, что АЦП включен — в куске кода это не показано)
Попробуйте присвоением:

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

  ADCSRA = 0xCF;   // запускаем преобразование
, хотя, думаю, дело не в этом.
А дело как раз-таки в цикле While, не знаток СИ.
sphincs писал(а):а дело случаем не в однократном режиме работы АЦП?
Не должно быть в этом.
sphincs писал(а):строка ADCSRA|=0x10; уже не идет (да я как-то не сильно понимаю зачем она нужна. зачем вручную выставлять флаг прерывания, если она вроде как должна выполниться только тогда, когда флаг автоматически будет выставлен самим АЦП).
Если вы внимательно почитаете ДШ, то поймёте что флаг прерывания сбрасывается либо при обработке соотв. прерывания (если оно разрешено), либо программно записью "1" в соотв. бит.

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

Добавлено: Пт мар 07, 2014 12:06:45
sphincs
не знаю почему, но убрав цикл while все заработало

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

Добавлено: Пт мар 07, 2014 14:38:11
service47
Если файл прошивки HEX весит 20кб, значит и мк должен иметь RAM на 20кб?? Просто у меня ATmega88PA с 1кб и грузиться и работает?

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

Добавлено: Пт мар 07, 2014 14:49:54
Gudd-Head
Нет, в ХЕКСе много всякой другой инфы.
Пример: прошивка код весит 1,9 кбайт, прошивка (хекс) — 5,2 кбайт.

Да и прошивка грузится не в RAM, а во FLASH.

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

Добавлено: Сб мар 08, 2014 00:31:02
DJ_Kiridza
oleg110592 писал(а):
чтобы было два кварца
ATmega8535
ATmega16/32
ATmega164PA/324PA/644PA/1284P
Гран-мерси!!!! :)
А про Атмегу16 - я сам баран, не внимательно читал даташит, когда первый раз знакомился с этой Мегой. Мне тогда таймер2 не нужен был, я инфу о нем поверхностно прочитал... спасибо что носом ткнули!!!!

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

Добавлено: Сб мар 08, 2014 12:26:28
Jack_A
service47 писал(а):Если файл прошивки HEX весит 20кб, значит и мк должен иметь RAM на 20кб?? Просто у меня ATmega88PA с 1кб и грузиться и работает?
RAM = Random Access Memory - это оперативная память и никакого отношения к размеру помещаемого в МК кода не имеет, потому что код заливается в ROM ( Read Only Memory ), то бишь флешь-память. Ее-то у 88-й Меги 8кб. Поскольку в HEX-файле ( INTEL-формат) каждый байт кода представлен двумя символьными байтами + служебная информация ( : , адрес, длина, КС,ВК,ПС ), то длина HEX-файла приблизительно в 3 раза превышает размер содержащегося в нем кода, так что 20кб кекса нормально влезает в 8 кб флеши.

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

Добавлено: Вт мар 11, 2014 17:41:37
Mem
Не могу слить флеш с 6225, китай мобайл. Флштоол выдаёт: brom error: s_undefined_error (1001). Поиск ничего путного не выдаёт. Может сталкивался кто?

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

Добавлено: Чт мар 13, 2014 10:36:00
baron_P
Здравствуйте.
Есть такая (использую в качестве учебной) страшненькая программа:
Спойлер

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

#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
         
         

}
Контроллер ATTiny 13A. Программа реализует программный ШИМ на трех вывода PB0, PB1, PB2. Задание для ШИМ берется из заранее сформированных массивов, в зависимости от напряжения на входе АЦП PB4. На PB3 висит кнопка, которая переводит это дело в спящий режим.
Программа работает, но есть один неясный момент. В обработчике прерывания по переполнению Таймера 0 сначала идет команда перевода выводов ШИМ в состояние входов:

Код:

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

DDRB &=~(1<<0|1<<1|1<<2);
Потом идет вызов функции, которая меняет значения на выводах ШИМ:

Код:

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

abc(pwm[0],pwm[1],pwm[2],e);
А потом идет команда перевода выводов ШИМ в состояние выходов:

Код:

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

DDRB |=(1<<0|1<<1|1<<2);
Должно же быть наоборот: сперва делаем выводы выходами, потом меняем их состояние, потом делаем их входами. Правда, зачем нужен последний шаг (используемый в этой программе часто) тоже не понимаю. Пусть бы и оставались выводы в состоянии выходов, что в этом плохого. В общем, непонятно, как оно работает и зачем оно сделано так.

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

Добавлено: Чт мар 13, 2014 11:17:37
Gudd-Head
baron_P писал(а):Есть такая страшненькая программа
Действительно страшненькая. Без комментов в коде никто разбираться не будет.

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

Добавлено: Чт мар 13, 2014 12:42:22
baron_P
Всю программу я привел на всякий случай. Не думал, что та часть, к которой относится мой вопрос, нуждается в комментариях. Но вот они ниже:
Спойлер

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

//вектор прерывания по перполнению Т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);

  }
}
Смотрел дебаггером в AVRStudio 4.19 - программа моргает выходами. При этом на PINB все время висят нули. Если убрать строку с DDRB &=~(1<<0|1<<1|1<<2), то моргают также и PINB. Это баг или так и должно быть? Я ожидал другой логики работы от команды назначения выводов входами. Когда вывод вход, он не должен меняться от записи в PORTB. Или должен?

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

Добавлено: Чт мар 13, 2014 17:39:51
urry

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

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

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

Добавлено: Чт мар 13, 2014 18:05:43
Alexeyslav
А посмотри внимательно структурную схему выходного порта в даташите на контроллер, многие вопросы сразу отпадают.
Делается это чтобы манипуляции не влияли на выход, за то время как программа будет решать 1 или 0 должен быть на выходе ШИМа в данном такте на выводе контроллера будет удерживаться уровень по инерции. Хотя, по хорошему эту операцию достаточно буферизировать - менять внутреннюю переменную, а потом её за один раз выводить в порт. И не нужны будут всякие подобные шаманства.

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

Добавлено: Пт мар 14, 2014 12:31:24
baron_P
Спасибо.
О логике работы я судил по этой картинке:
СпойлерИзображение
Когда выводы порта B объявлены как входы, в PORTB можно записать 1, что включит подтягивающие резисторы. Если к выводам ничего не подцеплено, на PINB должны появиться 1. Если записать при этом в PORTB 0, то выводы будут висеть в воздухе и непонятно, что будет в PINB. Если к порту В подцепить катоды светодиодов, подав на аноды питание, то в первом случае светодиоды гореть не будут. И во втором тоже, т.к. тока нет.
Когда выводы порта В объявлены как выходы, в PORTВ можно записать 1, и в PINB появится 1. Если записать 0, то и в PINB появится 0. Если к порту В подцепить катоды светодиодов, подав на аноды питание, то в первом случае светодиоды гореть не будут. А во втором должны загореться, т.к. будут посажены на землю.
По моему так должно работать.
А тут же получается что-то другое. При обявленнии выводов входами всегда в PINB висят нули, и при записи в PORTB нулей загораются светодиоды. Я не пойму, почему так.
Делается это чтобы манипуляции не влияли на выход, за то время как программа будет решать 1 или 0 должен быть на выходе ШИМа в данном такте на выводе контроллера будет удерживаться уровень по инерции. Хотя, по хорошему эту операцию достаточно буферизировать - менять внутреннюю переменную, а потом её за один раз выводить в порт. И не нужны будут всякие подобные шаманства.
Это фраза объясняет структуру программы в виде: объявили порт выходом, записали нужное значение, объявили входом, чтоб чего лишнего не записалось. Я правильно понял? Нет, не правильно :idea: Объявляем выводы входами, записываем в PORTB сначала какие-то промежуточные значения, потом то, что должно быть выведено на него. Объявляем выводы выходами и на них тут же появляется уже находящиеся в PORTB значения. Между двумя объявлениями фактические значения на выводах не меняются, потому и PINB не меняется. Вроде дошло. Еще раз спасибо.

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

Добавлено: Сб мар 15, 2014 19:05:17
Mem
Как исправить эти фьюзы?

Изображение

Понятно что Mega 16 теперь от внешнего кварца, но какого? Пробовал разные, не определяется. Сигнатура 0х000000, в остальном пишет что готово к работе. Один раз завелась от 8 МГц, я затер флеш и еепром, после этого опять перестало работать.