Перейти к содержанию

Вопросы от начинающих по МК


Рекомендуемые сообщения

подключать можно любые файлы, которые способны корректно обрабатываться компилятором. Вместо директивы будет подставлен текст того файла, а уж дальше - смотря что в нем написано

Изменено пользователем mail_robot

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

Ссылка на комментарий
Поделиться на другие сайты

  • Ответов 8,9т
  • Создана
  • Последний ответ

Топ авторов темы

Смотри на подключение файла как будто ты его содержимое вставляешь в место подключения. Именно так оно работает. Думаю компилятор языка С не поймет такого прикола когда ему подсунут текст программы на ассемблере.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

В 15.02.2018 в 13:12, altec сказал:

что SPI не запрещен, в чем может быть причина неудачи в прошивке? На Reset должна быть 1?

есть пдф-ка на 16-ю мегу: DOC000059759.pdf

Там в разделе:

Memory Programming

Serial Downloading

SPI Serial Programming Algorithm

все расписано (страница 274) по пунктам и по ногам про программирование по SPI!

Можно сделать все! Но чем больше можно, тем больше нельзя!

Ссылка на комментарий
Поделиться на другие сайты

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

По ЮСБ/com порту (плата Ардуино) отправляю значения АЦП на комп. В качестве терминала использую среду Ардуино. Значения читаются  в формате типа "0123", что хорошо, но как только втыкаю шнур ЮСБ, Винда "обнаруживает" новое устройство "Микрософт BollPoint трекбол для посл. порта" и мышка (как PC/2 так и ЮСБ) перестает работать(( . Устройство реально появляется в диспетчере устройств в разделе "Мыши".   Код выполняется в цикле.... прерывание сделаю потом.  Код загружается по ISP. Загрузчик стерт.

char B1;
	ADCSRA|=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); 
	ADMUX =0xC2;
	_delay_us(500);
	ADCSRA|=(1<<ADSC);   //Начать преобразование до 1024
	while ((ADCSRA & 0x10)==0);
	voltage=ADCW;
	
	if (voltage<1000)
	{
		v=voltage;  // буфер
		
		i=voltage/1000;//1
		voltage=voltage-i*1000;
		while ( !( UCSR0A & (1 << UDRE0)) );
		UDR0= 0x30+i;
		
		i=voltage/100;//2
		voltage=voltage-i*100;
		while ( !( UCSR0A & (1 << UDRE0)) );
		UDR0= 0x30+i;
		
		i=voltage/10;//3
		voltage=voltage-i*10;
		while ( !( UCSR0A & (1 << UDRE0)) );
		UDR0= 0x30+i;
		
		i=voltage/1;//4
		voltage=voltage-i*1;
		while ( !( UCSR0A & (1 << UDRE0)) );
		UDR0= 0x30+i;
		
		while ( !( UCSR0A & (1 << UDRE0)) );
		UDR0='\n'; //новая строка
	}

 

 

 

Изменено пользователем dim3740
Ссылка на комментарий
Поделиться на другие сайты

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. 

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

52 минуты назад, dim3740 сказал:

новое устройство "Микрософт BollPoint трекбол для посл. порта" и мышка (как PC/2 так и ЮСБ) перестает работать((

Такое происходит если устройство при подключении к COM-порту постоянно отправляет какие-либо данные без запроса (например, мышь отправляет своё положение при движении). Для отключения посмотри здесь программку COMDisable

https://support.microsoft.com/ru-ru/help/819036/overview-of-the-comdisable-tool

правда есть ограничение, не все операционные системы поддерживает.

Ссылка на комментарий
Поделиться на другие сайты

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

@technik-1017 спасибо, правда, программку по ссылке не запустилась... Нашел выход путем добавления буквенного префикса в старший (5) разряд посылаемых данных, который потом можно отфильтровать. 

Ссылка на комментарий
Поделиться на другие сайты

Бодрый день.

Решил недавно немного поиграться  с STM8

нашел буржуйское видео для начинающих и повторил код оттуда для мигания светодиодом посредством таймера, слегка адаптировав его для китайского модуля stm8s103f3, скомпилил его и залил в плату.

вобщем все заработало.

однако мне, как не очень большому знатоку С остались не ясны некоторые моменты кода...

сам код

#include "iostm8s103f3.h"
#include  "stdint.h"

#define PIN 5

volatile uint8_t timer4 = 0;

#pragma vector = TIM4_OVR_UIF_vector
__interrupt void TIM4_UPD_OVF_IRQHandler(){
  if(timer4 % 32 == 0){ //Замедляем Timer4 еще больше, чтобы видить мигание светодиода
    PB_ODR ^= (1<<PIN); //переключаем Pin B5
    timer4 = 0;
  }
  timer4++;
  TIM4_SR &=~(1<<0); //Очищаем флаг обновления прерывания
}

void initGPIO(){
  PB_DDR |= (1<<PIN); //Установить пин 5 как выход
  PB_CR1 |= (1<<PIN); //Установить пин 5 как пушпул
  PB_ODR |= (1<<PIN); //Установить пин 5 высокий (1)
}

void initTimer4(){
  CLK_PCKENR1 |= (1<<4); //Разрешить тактирование переферии для Timer4
  TIM4_PSCR = 0x0F; //Делитель частоты, делим на макс
  TIM4_IER = 1; // Разрешить обновление прерывания
  TIM4_CR1 |= 1; // Разрешаем таймер
  asm ("rim"); //Разрешаем глобальные прерывания
}


int main( void )
{
  initGPIO();
  initTimer4();
  while (1){
  }  
}

так вот, хотелось бы спросить более опытных камрадов, что именно делает и значит такая конструкция в условии проверки:

 if(timer4 % 32 == 0){

а так же не понятно, зачем двумя строками ниже переменная  timer4 сбрасывается на ноль, ведь эта секция кода выполняется только если  timer4 и так равна 0  или я не прав?

так же, прошу пояснить как работает след конструкция

 TIM4_SR &=~(1<<0);

понятно что & и ~ это логическое "и" и инвертирование... но как и в какой последовательности оно выполняется при таком написании?

Ссылка на комментарий
Поделиться на другие сайты

1 hour ago, Selfrock said:

if(timer4 % 32 == 0){

% - это остаток от деления. Как только остаток становится равен нулю условие выполнено. Понятно что нулем он станет только если таймер достигнет значения 32 или будет кратным ему. Честно говоря не самое лучшее решение.

1 hour ago, Selfrock said:

TIM4_SR &=~(1<<0);

здесь автор просто захотел простым способом получить бинарную единицу в голом байте, вот и задвинул ее в нулевой бит. А потом произвел логическую операцию проверки состояния бита с тем же номером в регистре TIM4_SR

Бинарные операции выполняются всегда в порядке, описанном стандартом языка С. Можно почитать раздел операторы. Будет полезно

Изменено пользователем mail_robot

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

Ссылка на комментарий
Поделиться на другие сайты

10 часов назад, mail_robot сказал:

Честно говоря не самое лучшее решение.

бредовое решение , лечение гланд через опу...

достаточно просто проверять 5бит

if(timer4 & (1<<5))

 

Ссылка на комментарий
Поделиться на другие сайты

6 часов назад, IMXO сказал:

достаточно просто проверять 5бит

if(timer4 & (1<<5))

нет, это не эквивалентное выражение для

(timer4 % 32 == 0) 

оно 32-раза будет верно , потом 32-раза не верно, а надо 1 к 31 разам!

Вот эквивалентное:

(timer4 & (32 - 1) == 0) 

Можно сделать все! Но чем больше можно, тем больше нельзя!

Ссылка на комментарий
Поделиться на другие сайты

Сейчас пишу первую программку и в ней тоже использовал деление по модулю, приблизительно вот так:

Скрытый текст

void timer(void){
    i++;
    if (mode == 1){
        if ((i % 8) == 0)    GPIOF->ODR ^= GPIO_PIN_0; // Инвертируем состояние ножки
        if (i == 16) i = 0;
    }
    else if (mode == 2){
        if ((i % 8) == 0)    GPIOF->ODR ^= GPIO_PIN_0;
        if (i == 32) i = 0;
    }
}

Смысл в том, чтобы в зависимости от выбранного режима, светодиод моргнул 1 или 2 раза (реально режимов около 10). Насколько данный код неправилен?

Ссылка на комментарий
Поделиться на другие сайты

Только что, Гость Гость сказал:

Насколько данный код неправилен?

Работающий код по определению правильный. Оптимальный или нет - это может быть вопросом. Красивый или нет - тоже можно думать.

Для Если режимов у вас много, и все определяются константами, логичнее использовать не многоэтажный if-else-if-else..., а switch.

Ну и логически: если в зависимости от режима надо мигнуть определенное кол-во раз, то все эти странные действия не нужны: режим определяет значение счетчика, затем при срабатывании таймера счетчик уменьшается и делается "миг", если счетчик нулевой - не делается...

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

59 минут назад, ruhi сказал:

оно 32-раза будет верно , потом 32-раза не верно, а надо 1 к 31 разам!

Вот эквивалентное:

(timer4 & (32 - 1) == 0) 

О! Поздно увидел Ваше сообщение. Пробовал как @IMXO написал 32 проверять, но каждые 32 верно, потом неверно. А вот проверка на все 11111. В моем случае 8 проверять на 7 (111)

Ссылка на комментарий
Поделиться на другие сайты

5 минут назад, ARV сказал:

Ну и логически: если в зависимости от режима надо мигнуть определенное кол-во раз, то все эти странные действия не нужны: режим определяет значение счетчика, затем при срабатывании таймера счетчик уменьшается и делается "миг", если счетчик нулевой - не делается...

А если данный таймер общий и предназначен не только для выбора режимов? Т.е. есть таймер на 30мс, который работает постоянно и обслуживает сразу несколько действий, в том числе и обработку нажатий кнопки с сигнализацией режима. Чтобы моргнуть светодиодом с нужной частотой, я и отсчитываю 8 тактов таймера (по 30 мс) и меняю состояние. Подсветка режима нужна, чтобы было видно, какой режим был выбран (по кол-ву миганий светодиода).

Ссылка на комментарий
Поделиться на другие сайты

Только что, Гость Гость сказал:

А если данный таймер общий

Я не знаю, что вы там затеяли, но включать-выключать пин в КАЖДОЙ ветке if или switch - это как-то не красиво. Где-то в коде вы готовите значение счетчика миганий, где-то отсчитываете нужные интервалы для периодичности мигания, а затем - мигаете по счетчику. С моей точки зрения это более логично и понятно.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

  • 2 недели спустя...

     Здравствуйте. Подскажите как с одной ножки порта например (РС2 выход)  передать  значение на одну ножку другого порта (PD0) при определенном условии, к примеру если на PB0 появится короткий импульс. Импульс на РВ0 на много короче чем на РС2, но передние фронты совпадают.

P.S. Вроде стало получаться программировать, а тут, с (КАК-БЫ) ерундой закопался.

Пишу в Atmel 6.2

Изменено пользователем RA3DTI
Ссылка на комментарий
Поделиться на другие сайты

@RA3DTI лучше нарисуй , потому как

3 часа назад, RA3DTI сказал:

Импульс на РВ0 на много короче чем на РС2, но передние фронты совпадают.

результат этого будет только один: (PD0)=1

Ссылка на комментарий
Поделиться на другие сайты

1 час назад, IMXO сказал:

@RA3DTI лучше нарисуй , потому как

результат этого будет только один: (PD0)=1

Но в принципе если PD0 будет 1 на протяжении всего времени прихода коротких импульсов тоже годится.

Вообще, интересно самому разобраться, но информация которую нашел либо совсем примитивная  либо совсем заоблачная

(со временем надеюсь и с ней разобраться)

atmel.png

Изменено пользователем RA3DTI
Ссылка на комментарий
Поделиться на другие сайты

Тебе кажется что передние фронты совпадают. Закладываться на одновременность фронтов не стоит, ибо это самый махровый RACE CONDITION. где-то у входа гистерезис больше где-то меньше и под защелку один фронт попадает а другой уже нет. Надо заложить в условие если фронт на втором входе НЕ ПОЗДНЕЕ первого на NN наносекунд(микро-, мили- ?) тогда делать то-то. Иначе тут дела не будет, начнёт обязательно схема выпендриваться то работаю то не работаю.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

11 час назад, Alexeyslav сказал:

......кажется что передние фронты совпадают. Закладываться на одновременность фронтов не стоит...... фронт на втором входе ... ПОЗДНЕЕ первого на NN наносекунд..........

   С фронтами в схеме (программе) все в порядке. Импульс приходит всегда с небольшой задержкой,  ну просто по алгоритму работы схемы (программы).

   На каком-нибудь  ПЛК могу без проблем считать значение с выхода Q1(bit0) и записать его на выход  Q3(bit2) при условии, что на входе ”ai1” появится импульс или придумать любое другое условие какое только придет в голову. В Atmel studio пока так не получается.

Изменено пользователем RA3DTI
Ссылка на комментарий
Поделиться на другие сайты

Потому что дял AVR надо выстроить последовательный алгоритм того что вы хотите. "скопировать импульс" - нет такого понятия. Может имеется в виду подклчить вход к выходу? На ПЛИС это возможно, для АВР вам надо будет постоянно смотреть вход и в соотвесттвии с ним устанавливать выход постоянно прокручивая этот алгоритм с максимальной скоростью, не забывая смотреть за импульсом по второму входу. Это накладывает серьёзные ограничения на длительности входных импульсов - они должны быть не менее двух итераций алгоритма.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Получилось. Из-за ..!..-ских нюансов синтаксиса этой Atmel закопался действительно с ерундой. Где-то надо ставить  " !"  ,  а где-то "~" , чтобы сказать что здесь 0.

Спасибо тем кто хотел помочь. Вот этот фрагмент.

 

     if ((PINB&(1<<0)) &&(PINC&(1<<2))){PORTD |=(1<<0);}

     if ((PINB&(1<<0)) &&!(PINC&(1<<2))) {PORTD |=(1<<0);}         

          if (!(PINB&(1<<0)) &&!(PINC&(1<<2))) {PORTD &=~(1<<0);}       

     }

Screenshot_15.png

Ссылка на комментарий
Поделиться на другие сайты

10 часов назад, RA3DTI сказал:

Спасибо тем кто хотел помочь. Вот этот фрагмент.

 

     if ((PINB&(1<<0)) &&(PINC&(1<<2))){PORTD |=(1<<0);}

     if ((PINB&(1<<0)) &&!(PINC&(1<<2))) {PORTD |=(1<<0);}         

          if (!(PINB&(1<<0)) &&!(PINC&(1<<2))) {PORTD &=~(1<<0);}       

     }

сдается мне это не правильно. условие выполняется при любом значении пинС

надо фиксировать фронт импульса пинВ и спад импульса пинС

я бы сделал так
 

temp_PIN=0;
if(PINB&(1<<0)) temp_PIN |=(1<<0);
if(PINC&(1<<2)) temp_PIN |=(1<<1);
if(!(tempOld_PIN&(1<<0))
     &&(temp_PIN&(1<<0))
     &&(temp_PIN&(1<<1))) PORTD |=(1<<0);
if(!(temp_PIN&(1<<1))
     &&(tempOld_PIN&(1<<1)) PORTD &= ~(1<<0);
tempOld_PIN=temp_PIN;

 

Ссылка на комментарий
Поделиться на другие сайты

33 минуты назад, Alexeyslav сказал:

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

В самом начале, когда заинтересовался АВР-ками об этом задумывался. Сейчас когда стало понемногу получаться это напрягает. Серьезно временными параметрами не занимался, но предвидя это , тактирующий генератор и ГУН (связка timer & ADC) создал аппаратно, не залезая в основное тело программы. Остался только таймер 0.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...