admin

Видеокурс По Avr-Микроконтроллерам Для Начинающих

2344 posts in this topic

Alex    589
42 минуты назад, MaxVest сказал:

Посмотрел код  - обнуление есть во время объявления переменной. Просто когда чистил коменты, видимо и эту строку захватил.


unsigned int everage_val = 0;


 

Если это обнуление в глобальной области, то толку от него - как молока от козла. Обнулять её нужно перед началом суммирования в неё данных.
 

Share this post


Link to post
Share on other sites
MaxVest    2

Спасибо, сейчас сделаю!

Вроде как на своём месте, не глобально, а в функции readADC, блин...

float readADC()
	{	
		
		//объявляем переменную для хранения среднего значения
		float everage_val= 0;
		
	/*  выбираем лапку ADC0, потому что термодатчик схемно подсоединен к этому входу. 
	 *	Для этого нужно записать в младший нимбл 0000, но записываем в младший нимбл 1111
	 *	и затем инвертируем их, получая 0000.
	 */											
		ADMUX &=~((1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (1<<MUX0));
		_delay_ms(2);	
		
		
		// Высчитываем среднюю арефметическое значение для уменьшения погрешности		 
			
		for (int i=0; i<2000; i++)			// организуем цикл количества опросов(20), используя бит окончания преобразования для этого
			{
				ADCSRA |= (1<<ADSC);		// запуск преобразования (записываем значение 1 в бит ADSC регистра ADSCRA)
				while ((ADCSRA &(1<<ADSC)));// ожидание окончания преобразования (В условии - сравнение бита ADSC с его маской в 1 с помощью оператора &
											// после окончания преобразования  в бит ADSC -
											// регистра ADCSRA аппаратно запишется 0 и цикл завершится,
											// поскольку в условии  используется оператор побитного логического сравнения "И".
				everage_val += ADC;			// складываем все значения измерения(20 раз) в нашу переменную
				_delay_us(10);
			}
			// возвращенное значение делим на 20(столько раз измеряли)получаем среднее значение измерения
			return everage_val/2000;
							
	}

дальше в цикле ...

Share this post


Link to post
Share on other sites
MaxVest    2

Замена мк не помогла, попробую спаять обвязку,  мк в кроватку, экран через разъем

Share this post


Link to post
Share on other sites

Старт складской программы по Wi-Fi/ Bluetooth-чипам от Espressif

На склад КОМПЭЛ поступили чипы, модули и отладочные платы от компании Espressif Systems на базе ESP8266 и ESP32. Стоимость всех изделий данной линейки – в 2-3 раза ниже ближайших аналогов, чипы занимают минимальное место на плате, энергоэффективны и универсальны в применении

Подробнее...

Grig96    73

Вторый видеоурок - 29:30-30:10, автор говорит что 

PORTB = 0b00001000

"подаст логическую 1 на 8 лапку которой нет"? Помойму автор что то заговорился, вначале там правильно обьяснял а потом чет запутался...

Share this post


Link to post
Share on other sites
Viktor26    309

Ну вы же знаете где будет лог 1 при такой записи, поэтому не стоит обострять внимание на оговорку, всякое бывает, что ж поделать))))

Share this post


Link to post
Share on other sites

Вебинар Литиевые ХИТы FANSO или что нужно знать инженеру о батарейках»

20 июня компания Компэл приглашает всех желающих принять участие в вебинаре, посвященном литиевым батарейкам FANSO. На вебинаре будет рассказано о параметрах батареек, их зависимости от режима работы и эксплуатации. Будет дана информация о том, на какие параметры следует обращать внимание, выбирая литиевый ХИТ, и как избежать некоторых проблем.

Подробнее...

URRS    0

Всем привет. Нуждаюсь в вашей подсказке. Задумал собрать датчик направления ветра (анемометр). Необходимо отобразить на дисплее LCD Nokia3310 инфу поступающую на 4 регистра (в моём случае РС0 – РС3), т.е. 4 бита. Например: 1011 – ветер северный, при входе на регистры 1010 – ветер южный и т.д. Четырёх разрядов вполне хватит на 16 направлений (0000 – 1111). Реализую на МК Atmega8 в ПО Atmel Studio 6.1. Легко получается с одним регистром (см. рис 2), а как считать в один момент времени 4 бита и сделать вывод не могу сообразить? В чём СИНУС? Пользовался фишкой «проверка некоторого разряда переменной на наличие лог.1» (If{} else {}). Предположил записать 15 значений (0001 – 1111) If{}, в противном случае при 0000 (на регистрах) else{}. Подскажите пример и направление, где «КОПНУТЬ»? Заранее благодарен.

Север.jpg

Си.jpg

Share this post


Link to post
Share on other sites
COKPOWEHEU    273

В PC0-PC3 у вас хранится 4-битный код направления ветра, от 0 до 15. Используйте его в качестве индекса массива, хранящего строки.

Share this post


Link to post
Share on other sites
URRS    0
13 часа назад, COKPOWEHEU сказал:

В PC0-PC3 у вас хранится 4-битный код направления ветра, от 0 до 15. Используйте его в качестве индекса массива, хранящего строки.

@COKPOWEHEU  приветствую! Идея замечательная, If{},else{} можно исключить и воспользоваться выводом строки из переменной (LCD_print (x,y,FONT_1X, (unsigned char*) переменная). Почитав, что такое :umnik2:массив, пришел к такому результату (см рисунок). Индексы массива записал в двоичной (правда чую надо 8 битами записывать (иль в шестнадцатеричной системе, что проще)), а значение текстом. Правильно иль нет:unknw:(всё на интуиции)? Возник вопрос, как связать регистры с индексом:shok:. С программированием дело никогда не имел, хотя с двоичными и шестнадцатеричными сист. работаю постоянно на работе.Чую там всё не так, кроме строчки 37,38.

строка из переменной 1.jpg

Share this post


Link to post
Share on other sites
COKPOWEHEU    273

Это делается не так

PROGMEM const char str_N[] = "N"; //современная версия gcc требует, чтобы значения, объявленные PROGMEM обязательно были const
PROGMEM const char str_NNW[] = "NNW"; //строки в Си задаются в двойных кавычках, а не одинарных
PROGMEM const char str_NW[] = "NW"; //особенность Си - каждую строку надо объявлять отдельно
PROGMEM const char str_NWW[] = "NWW";
...
PROGMEM const char *dir_arr[] = {str_N, str_NNW, str_NW, str_NWW, ...}; //массив, в котором хранятся _адреса_ всех строк
...
//процедура отображения на дисплей текстового значения направления
//аргумент - индекс направления (0 - 15)
//прим. Вот текстовое описание выполняемого действия, входных и выходных параметров перед каждой функцией стоит делать даже для себя
void ShowDir(unsigned char dir){
  char *index; //адрес нужной строки
  dir = dir & 0b00001111; //"защита от дурака" на случай если передадут число, выходящее за допустимые пределы
//if( dir > 15 )lcd_str_P(PSTR("E: ShowDir")); //другой вариант защиты - отображение ошибки на дисплее
  memcpy_P(&index, &dir_arr[ dir ], sizeof(char*) ); //тут не совсем уверен в синтаксисе
//копирование адреса нужной строки в переменную index
  lcd_str_P( index ); //отображение строки (из flash!) на дисплей. Мне привычнее свои процедуры
}
...
ShowDir( PINC & 0b00001111 );

Но выучить язык все-таки стоит

Share this post


Link to post
Share on other sites
URRS    0

Предупреждения на строчки PROGMEM const char str_W[] = "W"; выскакивают (Warning    '__progmem__' attribute ignored [-Wattributes] ). Библиотеку поставил #include <avr/pgmspace.h>, а он ругается:umnik2:

Share this post


Link to post
Share on other sites
Guest Ruslan   
Guest Ruslan
  1. Всем привет!!! У меня возникла проблема с отображением дисплея на Proteus 8... Он просто светится белым... Вот снимок кода и протеуса. Помогите пожалуйста....Безы    мянный.png

Безымянн  ый.png

 

 

Share this post


Link to post
Share on other sites
Viktor26    309

Почитайте первую страницу этой ветки ещё раз(если конечно вы до этого Ее читали ). 100500 раз говорили и в начале написано, МОДЕЛЬ ДИСПЛЕЯ РАБОТАЕТ ТОЛЬКО В ПРОТЕУС 7.

Share this post


Link to post
Share on other sites
URRS    0

@COKPOWEHEU, приветствую! Не выходит задумка. сжал код до 2 бит на прием (4 комбинации). "dir_arr" не признает (variable 'dir_arr' must be const in order to be put into read-only section by means of '__attribute__((progmem))')...

//Atmega8
#define F_CPU 8000000 //частота 8МГц
#include <avr/pgmspace.h> //Библиотека PROGMEM
#include <avr/io.h>
#include "n5110.h" //Библиотека LCD Nokia3310
#include <util/delay.h> //Библиотека задержки

PROGMEM const char string_N[] = "N"; //массив
PROGMEM const char string_NNW[] = "NNW"; //
PROGMEM const char string_NW[] = "NW"; //
PROGMEM const char string_NWW[] = "NWW";//ключевого слова const декларирует размещение данных в памяти программ (flash)
PROGMEM const char *dir_arr[] = {string_N, string_NNW, string_NW, string_NWW}; //массив, в котором хранятся _адреса_ всех строк

//процедура отображения на дисплей текстового значения направления
//аргумент - индекс направления (0 - 15)
void ShowDir(unsigned char dir){
    char *index; //адрес нужной строки
    //dir = dir & 0b00000011; //"защита от дурака"
    //if( dir > 15 )lcd_str_P(PSTR("E: ShowDir")); //другой вариант защиты - отображение ошибки на дисплее
    memcpy_P(&index, &dir_arr[ dir ], sizeof(char*) ); //Обращение к страке
    //копирование адреса нужной строки в переменную index
    lcd_str_P( index ); //отображение строки (из flash!) на дисплей
    Lcd_print(1,1, FONT_1X, index); // Вывод строки из переменной
    Lcd_update();// Копирование буфера в ОЗУ дисплея
}

ShowDir (PINC & 0b00000011 );

не могу сообразить, как программа поймет при какой комбинации регистров (РС0, РС1) выдать ту или иную строчку??? Жаль в интернете мало примеров с PROGMEM. Чую чего то не хватает.

Share this post


Link to post
Share on other sites
COKPOWEHEU    273

Именно массив строк - хитрая система. Именно в таком виде я ее не использовал, вот и дезинформировал вас. Гугль выдает вот эти ссылки на первой же странице: раз; два.
 

const char string_0[] PROGMEM = "String 0";
const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";

const char* const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5};

Или, тоже самое, записанное по-другому

PROGMEM const char str1[] = "STR1";
PROGMEM const char str2[] = "STR2";

PROGMEM const char* const arr[] = {str1, str2};

 

Share this post


Link to post
Share on other sites
URRS    0

@dm37 , приветствую! Читал. все вроде просто, а в переменную никак не могу заставить работать. Точнее правильно ли я формирую.

Думал так:

const char string_0[] PROGMEM = "String 0";   // "String 0" и т.д. - это содержимое строк; если необходимо меняйте его
const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";
 
 
// Теперь создаем таблицу с отсылками к этим строкам:
const char* const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5};
 
char buffer[30];

Дальше надо работать с переменной и выводить на дисплей

???(тут стопор) //Все пишут по разному

//Обращение к такой строке идет через специальные команды strcpy_P, memcpy_P, pgm_read_byte и т.д.

Lcd_print(x,y, FONT_1X, переменная???)// вывод на дисплей nokia3310

Вот тут работает на Ура... Но смысла сжатия входной логич. 1 нету. 

//Atmega8
//Анемометр, направление ветра
#define F_CPU 8000000 //частота 8МГц
#include <avr/io.h>
#include "n5110.h" //Библиотека LCD Nokia3310
#include <util/delay.h>
#include <avr/delay.h>

void presets(){
    DDRC = 0x0f; //Порт С настроен на вход
    PORTC = 0x00; //Обнуление порта С
    Lcd_init(); //инициализация дисплея LCD Nokia3310
    Lcd_clear(); //Очистка буфера дисплея
      
}

int main(void){
    presets();
    while(1)
    {
        
        if (PINC &(1<<0))  //Регистр РС0
        {
    Lcd_prints(0,0, FONT_1X, (unsigned char*)PSTR("ВЕТЕР:"));
    Lcd_prints (0,1, FONT_1X, (unsigned char*)PSTR("Север"));
    Lcd_update(); //Копирование буфера в ОЗУ системы
    _delay_ms(1000);
        } 
        else
        {
    Lcd_clear(); //Очистка буфера дисплея
    Lcd_prints(0,0, FONT_1X, (unsigned char*)PSTR("ВЕТЕР:"));    
    Lcd_update(); //Копирование буфера в ОЗУ системы
        }
        if (PINC &(1<<1))  //Регистр РС1
        {
            Lcd_prints(0,0, FONT_1X, (unsigned char*)PSTR("ВЕТЕР:"));
            Lcd_prints (0,1, FONT_1X, (unsigned char*)PSTR("Восток"));
            Lcd_update(); //Копирование буфера в ОЗУ системы
            _delay_ms(1000);
        }
        else
        {
            Lcd_clear(); //Очистка буфера дисплея
            Lcd_prints(0,0, FONT_1X, (unsigned char*)PSTR("ВЕТЕР:"));
            Lcd_update(); //Копирование буфера в ОЗУ системы
        }

Share this post


Link to post
Share on other sites
URRS    0

Технически анемометр готов. По началу хотел собрать на герконах, да к это банально. Подумав решил сжать в двоичную систему для увеличения количества направлений. 4 фотодиода, 2 ист света и круглая пластинка с прорезями между ними (свет пройдя через вращаемую ветром пластинку попадет на фотодиод нужного бита и сформирует сигнал). Проще, легче и магнит не нужен. А с кодом засада вышла:unknw:. Как программе сказать вот 4 бита (0,1,2,3), сравни с табличными значениями и выдай текст. Как то так... 

Edited by URRS

Share this post


Link to post
Share on other sites
dm37    54

@URRS выложите, пожалуйста, весь проект

включая файл для протеуса

 

попробуйте так (проверить к сожалению пока не могу)

const unsigned char string_0[] PROGMEM = "String 0";   // "String 0" и т.д. - это содержимое строк; если необходимо меняйте его
const unsigned char string_1[] PROGMEM = "String 1";
const unsigned char string_2[] PROGMEM = "String 2";
const unsigned char string_3[] PROGMEM = "String 3";
const unsigned char* const string_table[] PROGMEM = {string_0, string_1, string_2, string_3};

...
  
Lcd_prints (0,1, FONT_1X, string_table[dir & 0b00000011]);	// 2 бита (4 состояния)

 

Edited by dm37

Share this post


Link to post
Share on other sites
COKPOWEHEU    273

Так не сработает. В флеше хранятся и строки и их адреса, то есть нужно считать сначала адрес нужной строки из флеша в ОЗУ, а потом передать его в процедуру отображения строки. В принципе, именно это и было сделано в моем примере, странно что его не использовали.

void ShowDir(unsigned char dir){
  char *index;
  dir = dir & 0b00001111;
  memcpy_P(&index, &dir_arr[ dir ], sizeof(char*) ); //можно использовать pgm_read_word, но размер указателя в общем случае не равен 2 байтам, так что такой способ безопаснее
  lcd_str_P( index );
}

 

Share this post


Link to post
Share on other sites
URRS    0

Всем добрый вечер! Прикрепил код в Си и схему для протеуса (AS 6.1, Proteus 7).Вывод переменной на LCD (Lcd_print(x,y, FONT_1X, (unsigned char*)some_char);)

@COKPOWEHEU , тестил всякие варианты, dir_arr никак не хочет воспринимать :unknw:.

Анемометр.rar

 

Edited by URRS
Ошибка при вводе текста

Share this post


Link to post
Share on other sites
URRS    0
8 минут назад, dm37 сказал:

@URRS а где у вас функция main() в проекте?

Прошляпил. Не совсем понимаю, что вписывать в

void setup{???основные установки?}

далее

int main{setup()while(1){???цикл или циклы выполнения кода?}}.

В общем вопросов море, а книга одна:umnik2: "1000 и одна микроконтроллерная схема". Пока техн часть...

Share this post


Link to post
Share on other sites
dm37    54
45 минут назад, URRS сказал:

Не совсем понимаю, что вписывать в

void setup{???основные установки?}

это

DDRC = 0x0f; //регистры С 0,1,2,3 на вход
PORTC = 0x00; //обнуление портов
Lcd_init(); //инициализация дисплея NOKIA3310

 

Share this post


Link to post
Share on other sites

Your content will need to be approved by a moderator

Guest
You are commenting as a guest. If you have an account, please sign in.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoticons maximum are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Similar Content

    • By small girl
      Привет, ребят! Кто возьмется написать на С протокол взаимодействия для сети микроконтроллеров. База: STM32 с bluetooth модулем HC-06,- slave. ПК - master?

      За вознаграждение
    • By LegionKC
      Добрый день.
      Экспериментирую с платой TP4056 и MK ATmega8, конкретнее - пытаюсь собрать простенькое зарядное устройство с выводом параметров при зарядке/разрядке на АЦП МК. Для измерения тока нашел ACS712. Думаю, что получится выводить ток при зарядке (т.е. когда идет питание на TP4056 и нагрузка отключена) и при разрядке (питание выключено, нагрузка подключена). Нагрузка - резистор. Возникла проблема с измерением напряжения на АКБ. Вернее, проблема с отсутствием идей как это сделать. Может какую-нибудь схему делителя напряжения нужно сделать? Прошу помочь советом. Схему из пэинта прилагаю.
      Спасибо.
       

    • By Геннадий Быков
      Уважаемые электронщики и им сочувствующие!
      Хочу на даче собрать макет морского маяка в человеческий рост. Но для этого необходима схема управляющая светодиодами. Основное, схема должна иметь независимое питание(Солнечная панель) и быть слаботочной (5-9 вольт). Как вижу я. Маяк ориентировочно высотой 1,50-1,80 м. В маяке, с низу до верха 6 окошек (по одному 5мм светодиоду). И на верху сам маяк из 8-ми 0,5 ваттных светодиодов установленных по кругу. С наступлением темноты, включаются диоды на "1 этаже" и раз в 5-10 минут происходит действие. Диоды поэтажно (снизу вверх) начинают загораться (как будто кто-то поднимается вверх по ступеням) и после загорания самого верхнего окна, через пару секунд, включается маяк. Поочередно по кругу (эффект метеора), со скоростью 2-3 сек на круг, делает оборотов 10 и выключается. Потом в обратной последовательности гасятся окошки (светодиоды) сверху в низ и остаются два нижних, периодически и независимо включающиеся и выключающиеся (эффект присутствия). И вновь через 5-10 минут вышеописанное действие. Буду очень признателен любым советам, ссылкам, помощью. Немного умею паять, немного знаю Ардуино. Готов в разумных пределах спонсировать, разработку и сборку.
    • By Vladislav7
      Добрый день.
       
      Необходимо разработать схему для изготовления печатной платы с установленным микроконтроллером (подобрать подходящий), также подобрать все электронные компоненты и написать программу.
      Цель следующая:
      Необходимо с помощью одного контроллера управлять двумя цепями состоящими из 15 светодиодов (мощность одного = 0,1 Вт) каждая, диоды одноцветные.
      При включении одной кнопки начинает мигать одна цепь. При включении второй - вторая. Возможность одновременного включения кнопок.
      Необходим датчик индикации на кнопке, который будет мигать в такт светодиодной цепи. Принцип кнопки как у аварийной сигнализации.
       
      Спасибо.