Ви не увійшли.
Плохое решение. Оператор Switch будет выполнять все Case пока не найдет нужное. Эффективней что-то типа как Азаров предложил функцией. Еще лучше структуру с адресами массивов с портов с готовыми значениями что б оттранслировалось в команду с относительной адресацией. Тогда в две команды уложится.
Я согласен, что это не самое лучшее решение, у меня есть готовая отлаженная программа её просто нужно перенести на новый контроллер. Вы почему то думаете что я умею читать мысли:
const struct
{
__IO uint8_t * port;
uint8_t bitmask;
}
pin[] = {{&PORTA, 0xXX}, ...};
Я не понял задумку...
В русском языке есть слово пожалуйста а в украинском будь ласка.
const struct { __IO uint8_t * port; uint8_t bitmask; } pin[] = {{&PORTA, 0xXX}, ...};
Что-то вроде этого. Смотрите в заголовочных файлах точный тип порта.
__IO Что это такое?
Решил проблему так, вместо битовой операции был применен оператор switch. Конечно это не самое оригинальное решение но все же.
void port_on(uint8_t potr)
{
switch(potr)
{
case 1: out1_on; break;
case 2: out2_on; break;
case 3: out3_on; break;
case 4: out4_on; break;
case 5: out5_on; break;
case 6: out6_on; break;
case 7: out7_on; break;
case 8: out8_on; break;
case 9: out9_on; break;
case 10: out10_on; break;
case 11: out11_on; break;
case 12: out12_on; break;
case 13: out13_on; break;
case 14: out14_on; break;
case 15: out15_on; break;
case 16: out16_on; break;
case 17: out17_on; break;
case 18: out18_on; break;
case 19: out19_on; break;
case 20: out20_on; break;
}
}
void port_off(uint8_t potr)
{
switch(potr)
{
case 1: out1_off; break;
case 2: out2_off; break;
case 3: out3_off; break;
case 4: out4_off; break;
case 5: out5_off; break;
case 6: out6_off; break;
case 7: out7_off; break;
case 8: out8_off; break;
case 9: out9_off; break;
case 10: out10_off; break;
case 11: out11_off; break;
case 12: out12_off; break;
case 13: out13_off; break;
case 14: out14_off; break;
case 15: out15_off; break;
case 16: out16_off; break;
case 17: out17_off; break;
case 18: out18_off; break;
case 19: out19_off; break;
case 20: out20_off; break;
}
}
char letter[] = {'q','A','A','A','A','A','A','A','A','G','C','C','C','C','C','C','C','C','G','G','D'};
uint8_t pin[] = {9,0,1,2,3,4,5,6,7,2,7,6,5,4,3,2,1,0,0,1,7};
#define out_on(x) port ## letter[x] &= ~(1u << pin[x]);
#define out_off(x) port ## letter[x] |= (1u << pin[x]);
Но как я понял компилятор объединяет 'portletter' как две строки а не как значение массива
goodspeedmen пише:Здесь у вас используется массив и структура? В который нужно поместить номер порта а в структуру его название?
Массив структур. Указатель на порт, и маску бита порта. Я думаю вы сами сможете описать массив констант. Чем вас не устраивает digitalWrite(..) из Ардуино?
Потому что это не ардуино. Напишите пример плиз.
Если вам нужно адресовать порты по переменной то одними макросами вы это не сделаете, нужно что-то вроде этого:
void out_on(uint8_t n) { *pin[n].port &= pin[n].bitmask; }
Здесь у вас используется массив и структура? В который нужно поместить номер порта а в структуру его название?
У меня это пришло из программы управление сдвиговым регистром, при помощи 32 битной переменной я мог управлять 4 микросхемами.
Передовая в функцию которая вызывалась по таймеру номер бита и "номер операции" я мог управлять "портами". Но тут все по другому. Неужели нет ни чего такого что бы с моими портами вывода можно было работать также. Или подскажите как передавать и хранить эти макроопределения в массиве
uint32_t out_shift = 0;
uint8_t Bufer_set_res[32];
#define Out_on(x) out_shift |=(1UL << x)
#define Out_off(x) out_shift &=~ (1UL << x)
void on_off(uint8_t bit_n, uint8_t set_res)
{
if(set_res == 0)
out_shift &= ~(1UL << Bufer_bit[Count_t1]); // сброс.
else if(set_res == 1)
out_shift |= (1UL << Bufer_bit[Count_t1]); // установка бита.
else ifset_res == 2)
out_shift ^= (1UL << Bufer_bit[Count_t1]); // инверсия бита.
}
#define out1_on PORTA &=~(1UL<<0);
#define out2_on PORTA &=~(1UL<<1);
#define out3_on PORTA &=~(1UL<<2);
#define out4_on PORTA &=~(1UL<<4);
#define out5_on PORTA &=~(1UL<<3);
#define out6_on PORTA &=~(1UL<<5);
#define out7_on PORTA &=~(1UL<<6);
#define out8_on PORTA &=~(1UL<<7);
#define out9_on PORTG &=~(1UL<<2);
#define out10_on PORTC &=~(1UL<<7);
#define out11_on PORTC &=~(1UL<<6);
#define out12_on PORTC &=~(1UL<<5);
#define out13_on PORTC &=~(1UL<<4);
#define out14_on PORTC &=~(1UL<<3);
#define out15_on PORTC &=~(1UL<<2);
#define out16_on PORTC &=~(1UL<<1);
#define out17_on PORTC &=~(1UL<<0);
#define out18_on PORTG &=~(1UL<<0);
#define out19_on PORTG &=~(1UL<<1);
#define out20_on PORTD &=~(1UL<<7);
Всем привет, помогите "запихнуть" эти макроопределения в массив, структуру или смесь что бы можно было работать как с массивом. Спасибо. Я написал макроопределение таким образом:
#define out_on(x) PORTC &=~(1UL << port_out[x]);
но порты то разные.
Привет, есть устройство, мотор с энкодером и LCD. Экран обслуживается по прерыванию таймера счетчика 1 примерно каждые 0.3 секунды.
Я решил проверить точность подсчета импульсов энкодера, параллельно к энкодеру я подключил счетчик на семисегментных индикаторах и выяснялось, что показания разные, я начал копать и понял, что при заходе в прерывание аппаратно сбрасывается 7 бит SREG (запрет глобальных прерываний). То есть когда заходит в прерывания по таймеру счетчику перестают обслуживаться прерывание INT0, отсюда и ошибка подсчета. Вопрос в том можно (уместно) разрешать глобальные прерывания из прерывания таймера счетчика 1?
ISR(TIMER1_COMPA_vect)
{
sei();
}
Или лучше будет написать код обслуживания LCD как подпрограмму и заходить в нею по счетчику на переменной, что честно сказать меня смущает, не хочется нагружать лишней "работой" цикл опроса энкодера.
Ищи короткое замыкание или переполюсовку если плата новая, камень если умирает то он не греется, чему там греться? Если юзал её то есть большая вероятность что спалил таки...
символы из таблицы ASCII
Интересует опыт людей в этом вопросе.
Олег, и как ты еще на власть не пожаловался? ) или еще транш не пришел по этой теме?
прекращай считать чужие деньги в бизнесе, Украина свободная страна - займись сам этим вопросом, начиная от клонирования ( очень свободная ) до ввоза и продажи по той цене, по котрой считаеш нужным.
https://imrad.com.ua/ru/atmega328-au
ROFLОлег какой был твой рейт на обучение молодежи в "школе"?
Я думаю, что человек считает не чужие деньги а свои!!! А если вы воспринимаете свободу ка вседозволенность то мне жаль ваш вас...
bool trig = 0;
uint8_t command = 0; //Int to store app command state.
uint8_t T_command = 0;
void setup()
{
Serial.begin(9600);
DDRD = 0b11111100; // i/o D.
PORTD = 0b11111100; // port D.
DDRB = 0b11111111; // i/o B.
PORTB = 0b11111111; // port B.
}
void loop()
{
if(Serial.available() > 0)
{
command = Serial.read();
if(command == T_command)
{
trig = 0;
}
else
{
trig = 1;
}
if(trig == 1)
{
T_command = command;
Serial.println(command);
trig = 0;
}
}
}
Парни нацарапал программку что-бы узнать что принимает ардуинка по блютузу, но почему то данные выводятся в порт в десятичном виде. В описании библиотеки говорится что данные выводятся в виде символов ASCII?
Когда пишу Serial.println(analogValue, BYTE); вообще не определятся макроподстановка, если пишу Serial.println(analogValue, byte); макроподстановка определяет символ но все ровно не компилируется "error: expected primary-expression before ')' token"
=================================================================================
"
Передает данные через последовательное соединение как ASCII текст с следующим за ним символом переноса строки (ASCII символ 13 или '\r') и символом новой строки (ASCII 10 или '\n'). Пераметры и типы данных для этой функции такие же, как и для Serial.print().
Синтаксис
Serial.println(val)
Serial.println(val, format)"
Serial.println(analogValue); // print as an ASCII-encoded decimal
Serial.println(analogValue, DEC); // print as an ASCII-encoded decimal
Serial.println(analogValue, HEX); // print as an ASCII-encoded hexadecimal
Serial.println(analogValue, OCT); // print as an ASCII-encoded octal
Serial.println(analogValue, BIN); // print as an ASCII-encoded binary
Serial.println(analogValue, BYTE); // print as a raw byte value
Кто-то использовал этот протокол, понятно что для контроллеров имеющих этот интерфейс. Интересует нюансы подключения и тд и тп.
void setup()
{
void timer_COMPA_ON()
{
TCNT1 = 0x00;
OCR1A = 0x1194; // 4500 при этом значении прерывание произойдет примерно через 0.33 секунды. Канал А.
OCR1B = ---------; // рассчитаешь значение интервала который тебе нужен. Канал B.
TCCR1A = 0b00000000;
TCCR1B = 0b00000101;
TIMSK1 = 0b00000110;
}
}
//======================================================================
void loop() // loop.
{
}
эти функции обработки прерываний должны быть за пределами функций setup loop
ISR(TIMER1_COMPA_vect)
{
код опроса датчика
}
ISR(TIMER1_COMPB_vect)
{
код вывода на экран или что хочешь
TCNT1 = 0x00;
OCR1A = 0x1194;
OCR1B = ---------;
}
Код будет повторять циклический опрос твоих датчиков или что тебе там нужно.
Значение канала B должно быть больше канала A
Помогите разобраться с библиотекой eeprom. В файле eeprom.h есть прототипы функций для сохранения данных как байт и более, при попытке откомпилировать пишет: ('backlash' does not name a type). Кто то знает как адресуется память в этих функциях?
eeprom_read_byte (const uint8_t *__p)
eeprom_write_byte (uint8_t *__p, uint8_t __value);
eeprom_read_word (const uint16_t *__p);
eeprom_write_word (uint16_t *__p, uint16_t __value);
===================================================================================
#include <EEPROM.h>
volatile uint8_t backlash = 0;
uint8_t var_EEPROM[3] EEMEM; //массив для хранения переменных в eeprom памяти.
//----------------------------------------------------------------------------------------------------------
backlash = eeprom_read_byte(&var_EEPROM[0]);
https://ru.aliexpress.com/item/3-2-TFT-9cm-LCD-Touch-Screen-Expansion-Shield-With-Touch-Pen-New/32807113543.html?spm=a2g0s.9042311.0.0.uyiMoQ
Угораздило меня купить экранчик, не могу запустить ни одна библиотека не подходит. Может кто сталкивался с подобной проблемой?
goodspeedmen, опять слово пауза...Какая же это пауза если программа выполняется? Я так понял Вам нужны интервалы. Вот и напишите функцию интервалов на основе millis(). Это классика жанра, посмотрите пример мигания светодиодом . Для секундных и более интервалов вполне нормально.
Я бы сделал что то типа:
long oldtime, val; //первая переменная будет хранить предыдущее значение millis она должна быть глобальной
//и обнуляться только вначале кода, вторая переменная будет содержать нужный интервал.
boolean interval(val) {
long vartime = millis();
if ( val <= vartime-oldtime ) {
oldtime = vartime;
return true;
}
else {
return false;
}
}
Думаю идея понятна. В нужном месте программы делаете проверку прошел данный интервал или нет и выполняете по условию действие. Если нужно несколько разных интервалов надо несколько разных oldtime значений хранить. И несколько усложнить функцию передавая ей два значения нужный oldtime и val.
Честно сказать я не очень хорошо разбираюсь в этих "штуках", так "грызу" потихоньку
На сколько я смог понять эта функция возвращает булево значение true или false переменной interval, и принимает её параметр long val.
Я тут нацарапал так что бы было понятней, в цифрах. Переменная interval она работает как флаг, что функция отработала?
long oldtime (500), val (1000); //первая переменная будет хранить предыдущее значение millis она должна быть глобальной
//и обнуляться только вначале кода, вторая переменная будет содержать нужный интервал.
boolean interval(val)
{
long vartime = millis();
if(val(1000) <= vartime(1000...) - oldtime(500)) //
{
oldtime = vartime;
return true;
}
else
{
return false;
}
}
goodspeedmen пише:Генерация пауз возможно путем функции delay (20); (остановка программы, не всегда приемлемо). Или программным счетчиком, проблема в том, что чем больше операций выполняет микроконтроллер между подсчетом счётчика тем эта "пауза" увеличивается. Кто как решает эту проблему?
goodspeedmen, я например вообще ничего не понял, что Вам нужно, то Вы говорите о паузе ( delay() ) то о счетчике ( millis() ). А в приведенном коде комментарий :
"если будет нажата 1 кнопка то время подсчета будет одно а если 5 кнопок то оно увеличивается."
вообще вводит в ступор . Как эти кнопки будут нажаты, одновременно, произвольно или в какой то последовательности и вообще зачем их нажимать и какие такие паузы нужны а если не паузы то что интервалы какие то мерить надо. Как говорят половина ответа это ясно и правильно поставленный вопрос. Должен заметить что в АВР кроме упомянутых таймеров есть другие и если Вы не планируете использовать ШИМ никто Вам не запрещает использовать напрямую (читать и писать) регистры этих таймеров и использовать их прерывание. Возьмите даташит на используемый микроконтроллер и прочтете раздел о таймерах.
Но что то мне подсказывает что Ваша задача (а не поставленный мне например не понятный вопрос) решается банально той же millis() и переменной в которую после подсчета записываем значение millis при последующем считывании сравниваем текущее значение с переменной (таким образом получаем интервал) и опять записываем в переменную текущее значение и т.д.
Вероятно я не правильно объясняю. Мне нужны паузы в 1 или больше секунд без остановки процессора ( delay() ) все "те кнопки" должны продолжат сканироваться, был применен программный "счетчик - таймер" но во время этой "паузы" (счета счетчика) "нагрузка" на процессор изменяется и "пауза" получается разная в зависимости от нагрузки на процессор. Первый таймер занят, нулевой и второй таймер 328 меги 8 битные на максимальном предделителе они могут генерировать прерывание примерно в 16 миллисекунд, что конечно мало для моей цели. Это к тому о чем я писал выше о использование таймера с внешним генератором.
goodspeedmen текст толковый. но код - такое впечатление что другой человек делал. а вы его скопировали для красоты ) ну или издеваетесь )
goodspeedmen если код ниже читаете нормально.
возмите другой контроллер, не arduino. Вам просто не хватает понимания некоторых процессов./* --COPYRIGHT--,BSD_EX * Copyright (c) 2012, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ******************************************************************************* * * MSP430 CODE EXAMPLE DISCLAIMER * * MSP430 code examples are self-contained low-level programs that typically * demonstrate a single peripheral function or device feature in a highly * concise manner. For this the code may rely on the device's power-on default * register values and settings such as the clock configuration and care must * be taken when combining code from several examples to avoid potential side * effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware * for an API functional library-approach to peripheral configuration. * * --/COPYRIGHT--*/ //****************************************************************************** // MSP-FET430P140 Demo - Timer_A, Toggle P1.0, CCR0 Cont. Mode ISR, DCO SMCLK // // Description: Toggle P1.0 using software and TA_0 ISR. Toggles every // 50000 SMCLK cycles. SMCLK provides clock source for TACLK. // During the TA_0 ISR, P1.0 is toggled and 50000 clock cycles are added to // CCR0. TA_0 ISR is triggered every 50000 cycles. CPU is normally off and // used only during TA_ISR. // ACLK = n/a, MCLK = SMCLK = TACLK = default DCO ~800kHz // // MSP430F149 // --------------- // /|\| XIN|- // | | | // --|RST XOUT|- // | | // | P1.0|-->LED // // M. Buccini // Texas Instruments Inc. // Feb 2005 // Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.21A //****************************************************************************** #include <msp430.h> int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1DIR |= 0x01; // P1.0 output CCTL0 = CCIE; // CCR0 interrupt enabled CCR0 = 50000; TACTL = TASSEL_2 + MC_2; // SMCLK, contmode __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupt } // Timer A0 interrupt service routine #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=TIMERA0_VECTOR __interrupt void Timer_A (void) #elif defined(__GNUC__) void __attribute__ ((interrupt(TIMERA0_VECTOR))) Timer_A (void) #else #error Compiler not supported! #endif { P1OUT ^= 0x01; // Toggle P1.0 CCR0 += 50000; // Add Offset to CCR0 }
Я так понимаю это код для MSP430F149. Это "си" с условной компиляцией в которой я не очень разбираюсь.
goodspeedmen пише:if(если нажата кнопка) { какой то код выполняется analogRead(Ax); и тд и тп } if(если нажата кнопка) { какой то код выполняется analogRead(Ax); и тд и тп } if(если нажата кнопка) { какой то код выполняется analogRead(Ax); и тд и тп } if(если нажата кнопка) { какой то код выполняется analogRead(Ax); и тд и тп } if(если нажата кнопка) { какой то код выполняется analogRead(Ax); и тд и тп } ........................ если будет нажата 1 кнопка то время подсчета будет одно а если 5 кнопок то оно увеличивается. if (time == 0x4000) { какой то код time = 0; } time++;
what is "time" ?
Это и есть программный счётчик разве нет?
Если использовать тактирование 0 таймера с захватом по высокому уровню, к примеру частотой в 10 герц, то можно записывать в регистр сравнения число сколько нужно отсчитать по 0.1 секунде. но если нужно несколько пауз с разной продолжительностью Можно попробовать написать программу так, что если используется пауза высчитывается её продолжительность и если она больше действующей то в прерывании сбрасывается флаг первой паузы по ссылке в регистр сравнения дописывается время второй паузы...
Админы почистите тему, ребята если не знаете или не хотите отвечать то лучше не пишите, спасибо.