HF_Cat писал(а):Не нашёл как оформить функцию, которая бы вмещала обе части программы по индикации на "дисплей". Подскажите как или скажите где почитать. СПС
Не нужно стараться делать универсальные функции- нужно, чтобы функция выполняла одну конкретную задачу, но так хорошо, чтобы к ней никаких претензий не было.
HF_Cat писал(а):Пишу прогу на Си в AVR Studio 4 - динамическую индикацию на 7сегм-ных индикаторах. Нужно оформить вывод данных на этот дисплей как отдельную функцию. Часть программы по выводу на дисплей выполняется в прерывании по OVF_T0, а часть - вне прерывания. Не нашёл как оформить функцию, которая бы вмещала обе части программы по индикации на "дисплей". Подскажите как или скажите где почитать. СПС
По прерыванию выводить на экран некий массив, а в функции просто заполнять этот массив.
Приветствую, господа. Изучал очередную учебную программку для Attiny13A, и появился очередной глупый вопрос. Программа считывает значения с трех входов АЦП и выдает на три выхода сигнал ШИМ, скважность которого зависит от значений с АЦП. Код: Спойлер
//Эта функция вызывается для включения светодиодов в //определенный период работы ШИМ. void abc(unsigned char a,unsigned char b,unsigned char c,unsigned char status) {
//Эта функция считывает значение на выбранном канале АЦП unsigned char read_adc(unsigned char channel) {
unsigned char k; unsigned int adcvalue=0; ADMUX = ADMUX&(0b11111100); //Сброс битов выбора канала ADMUX |= channel;
//Игнорируется первое чтение после смены канала ADCSRA |= 1<<ADSC; while(ADCSRA&(1<<ADSC));//Ждем adcvalue=ADCH; adcvalue=0;//Игнорирование for(k=0;k<=7;k++) { ADCSRA |= 1<<ADSC; while(ADCSRA&(1<<ADSC));//Ждем adcvalue += ADCH; } return (adcvalue>>3); //Деление на 8
}
В функции обработки прерывания используется переменная unsigned char e. Но нигде в программе я не увидел установки начального значения этой переменной. Сразу идет проверка, равна ли переменная 255 и тд. по программе. А что в нее записано в первый момент времени непонятно. Это нормально или очередное издевательство авторов программы над стандартом?
baron_P писал(а):В функции обработки прерывания используется переменная unsigned char e. Но нигде в программе я не увидел установки начального значения этой переменной.
Это глобальная переменная, а глобальные переменные (если им не присваивается другое значение) автоматически при старте обнуляются.
Кстати то же самое происходит и с неглобальными переменными объявленными как static.
статик и есть глобальная переменная, только с ограниченной областью видимости. Ее, кстати, инициировать бы вручную при создании. Я бы задумался над отсутствием критической секции в проге - прерывание может наступить в любой момент, когда значение с ацп еще не готово. Что-то такое дописать
предотвратит ситуацию, когда прерывание наступает между присвоением, например, rwn[0] и rwn[1] измеренных значений, т.е. в функции прерывания используется часть массива с устаревшими значениями, считанными с АЦП в прошлом цикле. А сама функция считывания значений на входе АЦП (read_adc()) может быть прервана в любой момент, но на работу программы это влияния оказыать не должно. Правильно?
да, в данной ситуации это некритично - прочитается всего лишь старое значение - но представим ситуацию, если вы будете усреднять значение ацп - скажем, сумму 4 значений, чтобы потом ее разделить на 4 - и по прерыванию наверх уйдет сумма, а не результат деления. То же касается инкремента, декремента и т.д. Такие варианты нужно предусматривать заранее, чтобы не было потом неприятных сюрпризов.
В этой программе такой кусок кода не нужен, но, вообще, помнить о не вовремя выскочившем прерывании стоит всегда - так можно переформулировать. Вопросы кончились, пойду следующий девайс паять/программить
доброго времени суток поскажите как из этого кода сделать функцию,которая возвращает строку 'txxxxxxe' символ 't' можно было заменить на любой другой, строка переменная получается путем преобразования числа в строку
в flash памяти avr я не говорю что этод код оптимален и является эталоном явно нет но он работает если есть мысль по оптимизации всегда рад совету тем более я не очень силен в программировании можно сказать'молодо зелено' просто этод код должен выполнятся 8 раз вот поэтому и хочу преобразовать его в функцию
DDRC = 0xFF; // Configure PORTC as output PORTC = 0xAA; // Initial PORTC value
oldstate = 0;
do { if (Button(&PINB, 0, 1, 1)) { // Detect logical one oldstate = 1; // Update flag } if (oldstate && Button(&PINB, 0, 1, 0)) { // Detect one-to-zero transition PORTC = ~PORTC; // Invert PORTC oldstate = 0; // Update flag } } while(1); // Endless loop }
Судя по строке DDB0_bit = 0; // Set PB0 pin as input на порт PB0 можно посадить кнопку, и она работает, а если мне нужно на PB1? DDB1_bit = 0; не работает..