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

Язык СИ для микроконтроллеров


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

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

И, соответственно, трассировку для конкретных ног только нужно будет менять.

Ага, для ног питания и общего. Точнее, для всех цепей питания и общего.

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

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

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

Ага, для ног питания и общего. Точнее, для всех цепей питания и общего.

Да, да если цифровая и аналоговая части разделены не правильно при разводке, то смысла нет искать отдельные ноги.

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

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

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

  • 5 месяцев спустя...

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

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

Помогите, пожалуйста: не работает получение ответа от датчика DS18B20.

Пишу так:

 void ds_init() 
 {  //функция инициализации датчика ds18, т.е. сброса и получения сигнала присутствия
 
  pin_dir = 0; //вывод на выход

  pin_ds = 0;
  Delay_us(550);
  pin_dir = 1; //настройка на вход
  
  while (PORTA.B0 == 0) continue;
  while (PORTA.B0 == 1) continue; // датчик ждёт 15-60 мкс
  while (PORTA.B0 == 0) continue; // ждём, пока датчик держит линию на земле (60-240 мкс)

  
  
 }

Если вместо этих 3-х while просто вставляю ожидание 550 мкс, пока там датчик отвечает, то всё работает. (pin_ds это PORTA.B0,   pin_dir это TRISA.B0)

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

А если датчика нет, у вас всё подвиснет в ваших while. Как минимум нужен таймаут.
В своё время отказался от анализа импульса присутствия. Контроль ведётся только по CRC (дополнительно вёлся контроль на замыкание линии на ноль, при выходе выходного каскада из строя).
Если импульса присутствия нет, вы что будете делать? Отправите ещё один импульс сброса, через какой промежуток времени? А если несколько датчиков на линии, как вы определите какой ответил, а какой нет?
Мне кажется лучше произвести полноценный опрос датчика. Не ответил, ставим признак ошибки, 8 ошибок (например), датчик в обрыве.

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

Импульс присутствия имеет смысл при работе в режиме ожидания, например при работе с DS1990A.
После подаче питания на DS1990A, "таблеткой" будет сформирован импульс присутствия, что запустит процедуру чтения данных из DS1990A.

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

1 час назад, technik-1017 сказал:

таймаут

Вы имеете ввиду таймером подсчитывать длительность нуля, который формируется датчиком? Мне всё-таки хотелось бы понять, почему у меня в Протеусе не работает с while? Вроде ведь всё должно получаться: настроили вывод на вход, и сравниваем, ноль или единица. Пока там 1(датчик ждет 15-60 мкс), программа будет выполняться во 2-ом цикле while. Затем там появляется 0, и управление переходит к 3-ему оператору while.

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

12 минуты назад, Aleksandr1111 сказал:

почему у меня в Протеусе не работает с while?.....

Пока там 1(датчик ждет 15-60 мкс), программа будет выполняться во 2-ом цикле while. Затем там появляется 0, и управление переходит к 3-ему оператору while.

потомушта первый 0 принадлежит МК и вы его сформировали , потомушта датчик может сформировать ответ 0 сразу и 1 вы не увидете/пропустите , потомушта второй 0 датчик не передает.

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

16 минут назад, Aleksandr1111 сказал:

почему у меня в Протеусе не работает

Подключите в протеусе осциллограф и посмотрите что происходит на линии

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

  • 9 месяцев спустя...

Доброго времени суток.

Использую XC8 v1.3

Есть задача общаться программно по 1wire в PIC. Для этого выделено 3 вывода (RB0, RB1, RB2). На каждом весит свой датчик. Для работы с каждым выводом будут использоваться одинаковые функции (например:

void wire_vivod_byte(char data, char kanal)

). Как можно в теле функции обратиться к RB0, RB1 или RB2 в зависимости от переменной kanal. Через if (kanal==0)..., или swith (kanal)..., я реализовать могу, а вот хочется что бы переменная kanal выступала в роли смещения.

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

можно номер канала передать в массив, как индекс, а на выходе получить маску канала
что то вроде этого

const unsigned char mask[] = {0x01,0x02,0x04};

и использование
PORTB = 0xFF & mask[kanal];
Ссылка на комментарий
Поделиться на другие сайты

То есть устанавливать не бит а записывать порт. Тогда:

//при записи единицы
PORTB|=mask[kanal];
//при записи нуля
PORTB&=~mask[kanal];

При таком подходе маска не нужна, необходимо канал задавать правильно (1,2,4).

//при записи единицы
PORTB|=kanal;
//при записи нуля
PORTB&=~kanal;

Вроде бы просто, а не догнал. 

Спасибо.

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

  • 1 месяц спустя...

Опять затупил. Помогите разобраться. Объявлены массивы:

unsigned char  dekady[4][10],dekadyBCD[4][10];

Начальный адрес первого 0х110, второго 0х190.

Есть функция 

void inc_chass(unsigned char *chas_dec,unsigned char *chas_bcd){
    if (++(*chas_dec)==24)
        *chas_dec=0;
    *chas_bcd=bin_to_bcd(*chas_dec);
    *(chas_bcd+1)=*chas_bcd&0x0f;
    *chas_bcd=(*chas_bcd>>4)&0x0f;
}

Ее прототип:

void inc_chass(char *chas_dec,char *chas_bcd);

Вызов функции:

inc_chass(dekady,dekadyBCD[1][0]);         //увеличить час

Но в функцию передаются не те данные, которые хочу, т.е. не адрес начала массива "dekady" (0х110) и не адрес "dekadyBCD[1][0]" (0х19А), а вот что:5cc59d3060340_.jpg.63109e408054050928ff1f8170928d55.jpg

Где не прав, подскажите. Может это длина адреса виновата, которая в char не помещается?

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

Дак Вы в функцию принимаете указатель на char, а передаёте туда значение.
Компилятор не материл Вас ? :wacko:

PS: Для справки. Адрес начала массива - есть само имя массива. Без всяких там индексов и т.д...

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

Да так и есть - предупреждение "illegal conversion between pointer types". Однако переписав вызов функции:

inc_chass(&(dekady[1][0]),&(dekadyBCD[1][0]));         //увеличить час

приводит не совсем к нужному результату:  chas_dec=0x0F1A, должен быть 0х11А, chas_bcd=0х19А, что есть правильно.

48 минут назад, Alex сказал:

Адрес начала массива - есть само имя массива. Без всяких там индексов и т.д...

Я знаю, однако, в дальнейшем, необходимо будет передавать указатель  на разные области массива.

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

47 минут назад, Bugrim сказал:

необходимо будет передавать указатель  на разные области массива.

Тогда взятие адреса "&" обязано сработать.

48 минут назад, Bugrim сказал:

chas_dec=0x0F1A, должен быть 0х11А, chas_bcd=0х19А, что есть правильно

Ничего не понятно. Можете перевести ? :wacko:

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

Объявлены массивы:

unsigned char  dekady[4][10],dekadyBCD[4][10];

Начальный адрес первого 0х110, второго 0х190.

Функция

void inc_chass(char *chas_dec,char *chas_bcd);

Тогда вызов функции

inc_chass(&dekady[1][0],&dekadyBCD[1][0]);

должен передать указателю chas_dec значение 0х11А, а указателю   chas_bcd значение 0х19А. Однако при прогоне в протеусе указателю chas_dec присваивается значение 0x0F1A, почему мне не понятно. Указателю chas_bcd присваивается правильное значение 0х19А.

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

Не раз накалываюсь. Присваивается не правильное значение, однако программа отрабатывает правильно. Вероятней всего для данного камня это не имеет значения. Использую PIC16F886, компилятор XC8, v1.33.

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

В 28.04.2019 в 18:10, Bugrim сказал:

Однако при прогоне в протеусе указателю chas_dec присваивается значение 0x0F1A, почему мне не понятно.

потомушта для пыков,   адреса регистров ОЗУ 0х1A, 0x9A, 0x11A, 0x19A это одно и тоже значение , адрес берется маской 0x7F, старшие разряды берутся битами переключения банков, так что шо там в значении адреса 0хF1A or 0x11A абсолютно монопенисуально.

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

  • 2 месяца спустя...

Всем привет. начинаю изучать Си. 

При опросе PINа в AVR, на то, нажата ли кнопка if((PIND&(1<<PD0)) == 0) все выполняется, то есть при имитации нажатия (отлаживал в avr Studio7) проходит в тело функции (истина)

А при if((PIND&(1<<PD0)) == 1) и не нажатой кнопке (условие лог 1) в тело функции не входит(в истину). Как работает последний if?

В железе не проверял. Пытаюсь разобраться с ифом. Заранее благодарю.

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

Иф работает, как должен. У вас ведь там не PD0, а PD1 или что-то иное?

Ну и вообще-то надо показывать конкретный кусок кода с проблемой. Потому как не входить в ИФ может и по причине бесполезности входа...

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

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

5 hours ago, ARV said:

Ну и вообще-то надо показывать конкретный кусок кода с проблемой. Потому как не входить в ИФ может и по причине бесполезности входа...

#include <avr/io.h>
char x = 0;
char temp = 0;
int main(void)
{
    DDRD = 0;
    PORTD = 0xFF;
     while (1) 
    {
        for (char i = 0; i<8; i++)
        {
            if ((PIND&(1<<x))==1)
            {
                temp++;
            }
            else
            {
                x++;    
            }
        }
        x = 0;
     }
}

Хотел опрашивать все 8 пинов. на наличии лог1. так не работает. Если написать PD0 работает (был не внимателен) 

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

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

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

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

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

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

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

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

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

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

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

  • Сообщения

    • Если не добавлять: при чтении регистра UDR сбрасывается флаг прерывания RXC. После приёма  "\r" и установки флага FLAG_END_RX обработчик больше не читает UDR. Но затем приходит "\n" от плеера, снова устанавливается флаг RXC, и программа зависает в бесконечном прерывании.
    • Сказал - сделал! Благодарю! И остальным, у кого Ц4353 может сломаться, данная табличка будет очень полезна!
    • Автору. Никаких тут 250...200 ватт у этой китайской бздюшки нет в помине. Тем паче на таком подобии радиатора Катушки даже на выходе нет-плохо  
    • Повторюсь - НЕТ, так как у вас там крутилки, что приведет к искажениям при работе в мостовой схеме. Если бы вы "могли" то вам нужно было разорвать выход с темброблока и вход усилителей и впаять (можно навесом) вот такую схему:
    • Все верно, вы почти все что нужно сделали.  Только не нужно было добавлять это b=UDR; Сразу после старта сбросить флаг flags = 0; А в основном цикле ждать установки флага FLAG_END_RX. И если он установлен, проверять на совпадение строки в буфере (rx_buf) с вашей строкой (AT+QM \ r \ n .....   .....  AT+MP \ r \ n) При совпадении вызывать выполнение нужного алгоритма.
    • У меня до саба ещё дело не дошло, только сейчас думаю купить амп на полкиловатта, но так можно, при условии, что на входе будет моно, и будет срез частот
    • Про флаг Т: если он не используется в основной программе, а у меня он постоянно в деле. для меня меня отложенная обработка прерывания обычное дело, нужно лишь правильно расставить приоритеты частей программы. И обычное дело: выставляешь частоту задающего генератора побольше, делишь его до получения частоты 1000 Гц каким либо таймером, загоняешь в прерывание с флагом. затем закольцовываешь основную программу с проверкой флага прерывания от таймера 1000Гц. загоняешь программу в Sleep. Получаешь кольцо обработки с образцовым интервалом в 1 мс. После любого прерывания проверяешь флаг от таймера, если он, то сбрасываешь флаг и начинаешь перебирать подпрограммы обработки индикаторов, клавиатуры, и тд. и тп, подпрограммы обработки флагов и др. После окончания обработки всех подпрограмм возвращаешься к Sleep. И так по кольцу. Если происходит прерывание не от таймера, программа выходит из Sleep, проверяется флаг от таймера, если не он (а это не он) обратно к Sleep. В большенстве программ использую этот алгоритм.   GPIOR1 и GPIOR2 в 88 условно можно использовать как флаги, но их адреса больше 0х1Е, на них не распространяются команды cbi, sbi, sbic, sbis, и их сначала нужно загрузить в общий регистр, промодифицировать, и заново сохранить. Эта последовательность длинная, и модифицирует SREG, что сводит на нет работу по сравнению с  классическим GPIOR.
  • Похожий контент

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