Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="VladislavS",url="/forum/viewtopic.php?p=4009662#p4009662"]но что мешает ей писать во внешнюю?[/uquote]
Ничего не мешает как писать во внешнюю EEPROM, так и использовать менее проблемную FRAM :)
Реклама
Опытный кот
Сообщения: 768
Зарегистрирован: Вс янв 19, 2014 00:55:09

Сообщение MOHCTEP »

Здоровья всем!
Возможно ли как-то узнать длину (количество элементов) массива, записанного в флеш память? Если со строками все просто, там рулит признак eol, то как разобраться с числовыми массивами?
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

MOHCTEP, длину должен знать тот кто писал массив в память. Спросите у него.
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

MOHCTEP, нет, нельзя. Когда передают указатель на данные (не важно где - в RAM или FLASH), передают другим аргументом и их длину, если она не фиксирована как-то заранее. Пусть тот, кто пишет у вас данные во флэш, пишет еще и их размер сначала.
Реклама
Эиком - электронные компоненты и радиодетали
Опытный кот
Сообщения: 768
Зарегистрирован: Вс янв 19, 2014 00:55:09

Сообщение MOHCTEP »

Понятно. Спасибо!
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2142
Зарегистрирован: Чт дек 12, 2013 11:18:14
Откуда: Украина, Черновцы

Сообщение Hand-Maker »

Всем привет!
Подскажите, пжлст, что обозначают вот эти строки:

(void) USART->SR;
(void) USART->DR;

собственно SR и DR я понимаю, что это регистры модуля ЮАРТ. объединённые в структуру.
Меня интересует именно смысл этой конструкции с void-ом вначале, и что она делает.

Перед этими строками идет включение тактирования ЮАРТа, после них -- обнуление регистров. Тут вопросов нет.
Реклама
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

Hand-Maker, прочитает их во временный регистр (не сохраняя дальше никуда). Смысл в том, чтобы обратиться к этому регистру. С некоторыми регистрами аппаратно что-то происходит от того, что их читают, и иногда это надо делать. Чтение DR/SR там вроде сбрасывает что-то... точно не помню, смотреть лениво.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2142
Зарегистрирован: Чт дек 12, 2013 11:18:14
Откуда: Украина, Черновцы

Сообщение Hand-Maker »

То есть такой себе пинок системе...
Ясно, спасибо, буду изучать дальше.
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Hand-Maker",url="/forum/viewtopic.php?p=4020368#p4020368"]Подскажите, пжлст, что обозначают вот эти строки:[/uquote]Если почитать RM, то там будет написано, что последовательное чтение регистров SR и DR очищает статусы порта. Когда есть сомнения, что делает код, то хорошо подсматривать в листинг.

Код: Выделить всё

//USART1->SR;
        LDR.W    R0,??DataTable2
        LDR      R1,[R0, #+0]   
//USART1->DR;
        LDR      R0,[R0, #+4]  
        

??DataTable2:
        DATA32
        DC32     0x40013800
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18813
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Hand-Maker писал(а):(void) USART->SR;
зачем тут приведение типа?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

ARV, ворнинг исключить какой-нибудь может? Точно не необходимость, будет и без этого работать.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18813
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

я тут немножко удивился...

Код: Выделить всё

#include <stdio.h>
#include <limits.h>


int main(void) {
	int var = INT_MIN;

	printf("abs(%d) > 0 ?\n%s\n", var, abs(var) > 0 ? "YES" : "NO");

	return 0;
}
вот никогда не догадался бы, что напечатает этот код, если б не попробовал скомпилировать...
кто сможет ответить до компиляции?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

Ну раз неожиданно, то видимо NO :)
А так видимо потому что в знаковых целых отрицательный минимум на 1 больше по модулю, чем максимум. Получаем abs(INT_MIN) = 0 из-за переполнения? Отправляю пост и иду проверять )

Добавлено after 5 minutes 51 second:
Проверил. От части я прав. Вернется NO, но abs(INT_MIN) будет не 0, а неизменно -2147483648, забыл что у abs возвращаемое значение тоже знаковое. Ну понятно, это результат работы abs просто, где оно в данном случае оборачивается просто "по кругу" на данном числе.
Друг Кота
Аватара пользователя
Сообщения: 7385
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Есть регистр CRC32->DI32. Он 16 разрядный, но я хочу данные ему скармливать побайтно. Как это написать?
(uint8_t) (CRC32->DI32) = *ptr++; - даёт ошибку "expression must be a modifiable lvalue".
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18813
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

если uint8_t *ptr; то CRC32->DI32 = *ptr++; и будет побайтно получать данные
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Настоящая байтовая запись в регистр (если он это поддерживает) делается так

Код: Выделить всё

*(volatile uint8_t *)&CRC32->DI32 = *ptr++;
Для побайтого чтения источника данных достаточно uint8_t *ptr;

Нужно вам побайтовое чтение или побайтовая запись читайте описание регистра вашего микроконтроллера.
Друг Кота
Аватара пользователя
Сообщения: 7385
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Да, мне нужна "байтовая" запись. Вы же заметили, что регистр принадлежит аппаратному вычислителю CRC. А ему не всё равно, записать 0xFF или 0x00FF.

Когда я запряг под это дело DMA с байтовым обменом - всё считалось правильно, а когда попытался вот так ручками - сумма не сходилась.
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Давеча экспериментировал со стартапом. Заметил, что GCC распознаёт паттерны копирования и установки памяти и заменяет их вызовами memcpy и memset. Вот эти два варианта после компиляции дают одинаковый результат.

Код: Выделить всё

extern uint32_t _sidata[], _sdata[], _edata[];
for(uint32_t *pSrc=_sidata, *pDst=_sdata; pDst!=_edata; *pDst++=*pSrc++);
 	
extern uint32_t _sbss[], _ebss[];
for(uint32_t *pDst=_sbss; pDst!=_ebss; *pDst++=0);

Код: Выделить всё

extern uint8_t _sidata[], _sdata[], _edata[];
memcpy(_sdata, _sidata, _edata-_sdata);

extern uint8_t _sbss[], _ebss[];
memset(_sbss, 0, _ebss-_sbss);
И в обоих случаях это будет побайтовое копирование, причём и при оптимизации на скорость. Что, по меньшей мере, странно. Чтобы уговорить компилятор быстро пословно скопировать надо volatile расставить.

Код: Выделить всё

for(volatile uint32_t *pSrc=_sidata, *pDst=_sdata; pDst!=_edata; *pDst++=*pSrc++);
for(volatile uint32_t *pDst=_sbss; pDst!=_ebss; *pDst++=0);
Получается редкий случай, когда volatile и скорости добавляет, и размер уменьшает (если memset или memcpy больше нигде в коде не используются).
Опытный кот
Аватара пользователя
Сообщения: 867
Зарегистрирован: Пт фев 27, 2015 12:00:53
Откуда: Рязанская область

Сообщение Serzh2000 »

сделал часы с датчиком BME280
все работает как я хотел, НО зависает все (то есть на экране часы, температура, давление, влажность написаны, но не изменяются и на кнопки не реагирует) питание отключишь все работает дальше и часы не сбиваются правильно идут.
могут час или пять , полдня работать , а потом опять зависнуть. самое большое полтора суток отработали.
ардуино менял. мне кажется в коде накосячил... :facepalm: может кто глянет свежим глазом что не так! :dont_know:
Спойлер//--------------Kлавиатура,------------------------------------------------------------
#define BUTTON_1 2 // Пин клавиши 1
#define BUTTON_2 3 // Пин клавиши 2
#define BUTTON_3 4 // Пин клавиши 3

//-------------------------------------------------------------
int hour,minute,second; //
int year,month,day,dayOfWeek; //
//------------------------------------------------Подключаем библиотеки внешние и в наших закладках-------------------------------------------------------
#include <Wire.h> // Подключаем библиотеку I2C
#include "rtc.h" // Подключаем нашу библиотеку часов
#include <EEPROM.h> // Импортируем бмблиотеку
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (133)
Adafruit_BME280 bme; // I2C
#define BME280_ADDRESS (0x77)
#include <LCD_1602_RUS.h> // подключаем библиотеку LCD_1602_RUS
LCD_1602_RUS lcd(0x27,20,4); // присваиваем имя LCD для дисплея

//------------------------------------------------ Инициализируем переменные-------------------------------------------------------------------------------

int h1,h0,m1,m0,s1,s0; // h1 - десятки часов, h0 - еденицы часов и так далее,
int d1, d0, mn1, mn0, day_0,day_1,day_2,month_0,month_1,month_2, sec; // d1 - десятки дней, d0 - еденицы дней и так далее...

float bme_Pressure;
float bme_Humidity;
float bme_temp, bme_temp_0,bme_temp_1,bme_temp_2;// Переменная температуры

int flag=0;
int mode=0; // моде - режим вывода на экран,

uint32_t startTime; // какая то задержка 0,025 сек
int setMode=0;
int key=0; // в зависимости от нажатых клавиш принимает значение 0, 1, 2, 3 - по номерам кнопок
int keyOld=0; // старое значение нажатой клавиши
int keySpeed=0; // переменная задает скорость повтора нажатых клавиш

unsigned long now; // переменная для счетчиков реального времени
unsigned long nov; // переменная для счетчиков гошения экрана по времени

const int timerMenu=30000; // время (в мс) перед автоматическим выходом из режима настроек
static unsigned long oldMillis = 0;

//------------------------------------------------ void SETUP----------------------------------------------------------------------------------------------
void setup(){ //

Serial.begin (9600); //
digitalWrite(BUTTON_1, INPUT_PULLUP); //
digitalWrite(BUTTON_2, INPUT_PULLUP); //
digitalWrite(BUTTON_3, INPUT_PULLUP); //


lcd.init();
lcd.backlight();
lcd.clear();


bool status;
status = bme.begin();
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
lcd.setCursor(0,2); lcd.print("НЕТ BME280");
while (1);
}


// Получаем данные из EEPROM
EEPROM.get(0, day_0); EEPROM.get(5, month_0); EEPROM.get(10,bme_temp_0);
EEPROM.get(15,day_1); EEPROM.get(20,month_1); EEPROM.get(25,bme_temp_1);
EEPROM.get(30,day_2); EEPROM.get(35,month_2); EEPROM.get(40,bme_temp_2);

// Вывести полученное значение
Serial.println(day_0);Serial.println(month_0); Serial.println(bme_temp_0); Serial.println("----------");
Serial.println(day_1);Serial.println(month_1); Serial.println(bme_temp_1); Serial.println("----------");
Serial.println(day_2);Serial.println(month_2); Serial.println(bme_temp_2); Serial.println("----------");
Serial.println(analogRead(0) * 5.0 / 1024.0);Serial.println(analogRead(0));
Serial.println("==================");

}

//================= void LOOP=======================
void loop(){
startTime=millis();
if (millis()-nov>2) {
getRTCDateTime();
h1=hour/10; // десятки часов
h0=hour%10; // еденицы часов
d1=day/10; // десятки дней
d0=day%10; // еденицы дней
m1=minute/10; // десятки минут
m0=minute%10; // еденицы минут
s1=second/10; // десятки секунд
s0=second%10; // еденицы секунд
}

if ((millis()-now>50000) && flag==0) {
mode=0; lcd.clear(); lcd.noBacklight();flag=1; //погасить свет экрана/показывать время тем.давл.влаж.
now=millis();
}

if (millis()-nov>5000 || second == 00) { //обращаться к датчику BME280 каждые пять сек.
bme_temp = bme.readTemperature();
bme_Pressure = bme.readPressure()/133.3;
bme_Humidity = bme.readHumidity();
nov=millis();
}

if ( hour==06 && minute==00 && second == 00 ){ // запомнить сегодняшнее, вчерашнее,позовчерашнее
day_2=day_1; day_1=day_0; day_0=day; //число
month_2=month_1; month_1=month_0; month_0=month; //месяц
bme_temp_2=bme_temp_1; bme_temp_1=bme_temp_0; bme_temp_0=bme_temp; //температура
delay(1500);
}


if(analogRead(0)<720){ //если попало питание запомнить в память
EEPROM.put(0, day_0);EEPROM.put(5, month_0);EEPROM.put(10, bme_temp_0); // Записать значение
EEPROM.put(15,day_1);EEPROM.put(20,month_1);EEPROM.put(25,bme_temp_1); // Записать значение
EEPROM.put(30,day_2);EEPROM.put(35,month_2);EEPROM.put(40,bme_temp_2); // Записать значение
lcd.clear(); Serial.println("ЗАПИСЬ");lcd.print("ЗАПИСЬ");
delay(1500);
}delay(2); //чтобы отдахнул I2C

if (mode==0){ //если экран показывает время тем.давл.влаж.
klav();disp_time(); //кнопки/обновить экран время тем.давл.влаж.
if(key==2||key==3){
now = millis(); lcd.clear();
while (millis()-now<5){
klav();
if(key==2||key==3)
lcd.clear(); mode=1; //вкл подсветку/ экран температур сегодняшнее, вчерашнее,позовчерашнее
}
key=0;
}
//------------------------------------

if(key==1){
now=millis(); lcd.clear(); // сбарсываем переменную счета таймера в (миллис)
if (millis()-now<2000){ // запускаем таймер на 2 секунду
klav();
if(key==1){
lcd.clear(); setMode=1; setUp();
}
else{
lcd.clear(); mode=1;
}
}
key=0;
}
}
//==============
if (mode==1){
klav();eeprom_lcd();
if (key==1){
now=millis(); lcd.clear(); // сбарсываем переменную счета таймера в (миллис)
while(millis()-now<5){
klav();
if(key == 1)
lcd.clear(); mode=0;
}
key=0;
}
if(key==2||key==3){
now = millis(); lcd.clear();
while (millis()-now<5){
klav();
if(key==2||key==3)
lcd.clear(); mode=0;
}
key=0;
}
}
}

//------------------------------------------------ ПРОЦЕДУРА ОПРОСА КЛАВИШ (кнопок)-----------------------------------------------------------------------
void klav(){
key=0; //
if(digitalRead(BUTTON_1)==LOW) key=1; // опрашиваем клавишу 1 и если нажата переменной присваиваем 1
if(digitalRead(BUTTON_2)==LOW) key=2; // тоже самое для клавиши 2
if(digitalRead(BUTTON_3)==LOW) key=3; // тоже длч клавиши 3, при чем если нажаты все одновременно - результат будет 3
if(key!=0){ lcd.backlight(); now = millis(); flag=0; // есил клавиши нажаты ,очищаем экран .включаем свет
delay(keySpeed<8? 200:20); // устанавливаем паузу между между опросами
keySpeed++; // эта переменная ружна для того что бы через 8 циклов уменьшить паузу между опрасами с 200 до 20
} //
if(key!=keyOld) keySpeed=0; // если была смена клавиш то флаг скорости опросов сбрасываем в 0
keyOld=key; // в переменную предыдущего состояния клавиш записываем текущее состояние клавиш
}
//-----------------------------------------------------------------------
void setUp(){
delay(500);
now = millis(); lcd.clear(); // сбарсываем переменную счета таймера в (миллис)
while (millis()-now < timerMenu){ // запускаем таймер
switch(setMode){

case 1: setUp_year(); lcd.setCursor(0,1);lcd.print("ГОД "); break;
case 2: setUp_month(); lcd.setCursor(0,1);lcd.print("МЕСЯЦ "); break;
case 3: setUp_day(); lcd.setCursor(0,1);lcd.print("ДЕНЬ "); break;
case 4: setUp_dayOfWeek();lcd.setCursor(0,1);lcd.print("НЕДЕЛЯ "); break;
case 5: setUp_hour(); lcd.setCursor(0,1);lcd.print("ЧАС "); break;
case 6: setUp_minute(); lcd.setCursor(0,1);lcd.print("МИНУТА "); break;
case 7: setUp_second(); lcd.setCursor(0,1);lcd.print("СЕКУНДЫ"); break;
case 8: return;

}
klav(); // Опрашиваем клавиши 0- не нажаты, 1-3 клавиши нажат
if(key == 1){ // если нажата
setMode++; // если нажата кнопка 1, то выходим из подпрограмы
if(setMode > 8) mode=0;
}
}
mode=0;
}
//--------------------------------------------------------------------------------------
void setUp_second(){
now = millis(); lcd.clear(); // сбарсываем переменную счета таймера в (миллис)
while (millis()-now < timerMenu){ // запускаем таймер автовыхода из подпрограмы, если мы сейчас в позии секунд то таймер увеличиваем на 60 секунд
getRTCDateTime(); // считываем данные часы, минуты, секунды
lcd.setCursor(0,1);lcd.print("СЕКУНДЫ ");lcd.print(second);//высвечиваем секунды
klav(); // Опрашиваем клавиши 0- не нажаты, 1-3 клавиши нажаты
if(key == 1){ lcd.clear(); // если нажата кнопка 1, то выходим из подпрограмы
setMode = 8;return;
}
if(key == 2 || key == 3 ){ // если нажата кнопка 2,3
now = millis(); lcd.clear(); // сбрасывае счетчик автовыхода из подпрограмы

if (second > 30){
minute++; second=0;
}
setRTCDateTime();
}
if(key == 2 || key == 3){ // если нажата кнопка 3,2
now = millis();
if (second < 30){
second=0;
}
setRTCDateTime();
}
}
}
//============
void setUp_minute(){
now = millis(); lcd.clear(); // сбарсываем переменную счета таймера в (миллис)
while (millis()-now < timerMenu){ // запускаем таймер автовыхода из подпрограмы,
getRTCDateTime(); // считываем данные часы, минуты, секунды
lcd.setCursor(0,1);lcd.print("МИНУТЫ ");lcd.print(minute);
klav(); // Опрашиваем клавиши 0- не нажаты, 1-3 клавиши нажаты
if(key == 1){ // если нажата кнопка 1, то выходим из подпрограмы
lcd.clear(); setMode = 7;return;
}
if(key == 2){ // если нажата кнопка 2, то переходим к следующей позиции установки
now = millis(); lcd.clear(); // сбрасывае счетчик автовыхода из подпрограмы
if (minute < 60){
minute++; if (minute==60)minute=0;
}
setRTCDateTime();}
if(key == 3){ // если нажата кнопка 3, то меняеме значение переменной отображаемой в данной позиции
now = millis(); lcd.clear();
if (minute >-1){
minute--; if (minute==-1)minute=59;
}
setRTCDateTime();
}
}
}
//============
void setUp_hour(){
now = millis(); lcd.clear(); // сбарсываем переменную счета таймера в (миллис)
while (millis()-now < timerMenu){ // запускаем таймер автовыхода из подпрограмы,
getRTCDateTime(); // считываем данные часы, минуты, секунды
lcd.setCursor(0,1);lcd.print("ЧАС ");lcd.print(hour);
klav(); // Опрашиваем клавиши 0- не нажаты, 1-3 клавиши нажаты
if(key == 1){ // если нажата кнопка 1, то выходим из подпрограмы
lcd.clear(); setMode = 6;return;
}
if(key == 2){ // если нажата кнопка 2, то переходим к следующей позиции установки
now = millis(); lcd.clear(); // сбрасывае счетчик автовыхода из подпрограмы

if (hour < 24){
hour++; if (hour==24)hour=0;
}
setRTCDateTime();}
if(key == 3){ // если нажата кнопка 3, то меняеме значение переменной отображаемой в данной позиции
now = millis(); lcd.clear();
if (hour >-1){
hour--; if (hour==-1)hour=23;
}
setRTCDateTime();
}
}
}
//---------------------------------------------------------------------------------------
void setUp_dayOfWeek(){ //

now = millis(); lcd.clear(); // сбарсываем переменную счета таймера в (миллис)
while (millis()-now < timerMenu){ // запускаем таймер автовыхода из подпрограмы, если мы сейчас в позии секунд то таймер увеличиваем на 60 секунд
getRTCDateTime(); // считываем данные часы, минуты, секунды

switch(dayOfWeek){
case 0:lcd.setCursor(0,1);lcd.print("ДЕНЬ НЕДЕЛИ");lcd.setCursor(0,2);lcd.print("ПОНЕДЕЛЬНИК");
break;
case 1:lcd.setCursor(0,1);lcd.print("ДЕНЬ НЕДЕЛИ");lcd.setCursor(0,2);lcd.print("ВТОРНИК ");
break;
case 2:lcd.setCursor(0,1);lcd.print("ДЕНЬ НЕДЕЛИ");lcd.setCursor(0,2);lcd.print("СРЕДА ");
break;
case 3:lcd.setCursor(0,1);lcd.print("ДЕНЬ НЕДЕЛИ");lcd.setCursor(0,2);lcd.print("ЧЕТВЕРГ ");
break;
case 4:lcd.setCursor(0,1);lcd.print("ДЕНЬ НЕДЕЛИ");lcd.setCursor(0,2);lcd.print("ПЯТНИЦА ");
break;
case 5:lcd.setCursor(0,1);lcd.print("ДЕНЬ НЕДЕЛИ");lcd.setCursor(0,2);lcd.print("СУББОТА ");
break;
case 6:lcd.setCursor(0,1);lcd.print("ДЕНЬ НЕДЕЛИ");lcd.setCursor(0,2);lcd.print("ВОСКРЕСЕНЬЕ");
break;
}

klav(); // Опрашиваем клавиши 0- не нажаты, 1-3 клавиши нажаты
if(key == 1){ // если нажата кнопка 1, то выходим из подпрограмы
lcd.clear(); setMode = 5;return; //
}
if(key == 2){ // если нажата кнопка 2, то переходим к следующей позиции установки
now = millis(); lcd.clear(); // сбрасывае счетчик автовыхода из подпрограмы
if (dayOfWeek < 7){
dayOfWeek++;if (dayOfWeek==7)dayOfWeek=0;
}
setRTCDateTime();
} //
if(key == 3){ // если нажата кнопка 3, то меняеме значение переменной отображаемой в данной позиции
now = millis(); lcd.clear();
if (dayOfWeek > -1){
dayOfWeek--;if (dayOfWeek==-1)dayOfWeek=6;
}
setRTCDateTime(); //запись в РТС
}
}
}
//---------------------------------------------------------------------------------------
void setUp_month(){ //

now = millis(); lcd.clear(); // сбарсываем переменную счета таймера в (миллис)
while (millis()-now < timerMenu){ // запускаем таймер автовыхода из подпрограмы,
getRTCDateTime(); // считываем данные часы, минуты, секунды
lcd.setCursor(0,1);lcd.print("МЕСЯЦ");
lcd.setCursor(0,2);
if (month==1) {lcd.print("ЯНВАРЬ");}
if (month==2) {lcd.print("ФЕВРАЛЬ");}
if (month==3) {lcd.print("МАРТ");}
if (month==4) {lcd.print("АПРЕЛЬ");}
if (month==5) {lcd.print("МАЙ");}
if (month==6) {lcd.print("ИЮНЬ");}
if (month==7) {lcd.print("ИЮЛЬ");}
if (month==8) {lcd.print("АВГУСТ");}
if (month==9) {lcd.print("СЕНТЯБРЬ");}
if (month==10) {lcd.print("ОКТЯБРЬ");}
if (month==11) {lcd.print("НОЯБРЬ");}
if (month==12) {lcd.print("ДЕКАБРЬ");}
klav(); // Опрашиваем клавиши 0- не нажаты, 1-3 клавиши нажаты
if(key == 1){ // если нажата кнопка 1, то выходим из подпрограмы
lcd.clear(); setMode = 3;return;
}
if(key == 2){ // если нажата кнопка 2, то переходим к следующей позиции установки
now = millis(); lcd.clear(); // сбрасывае счетчик автовыхода из подпрограмы

if (13 > month ){
month++; if (month==13)month=1;
}
setRTCDateTime();
}
if(key == 3){ // если нажата кнопка 3, то меняеме значение переменной отображаемой в данной позиции
now = millis(); lcd.clear();
if (month >0 ){
month--; if (month==0)month=12;
}
setRTCDateTime();
}
}
}
//------------------------------------------------------------------------------------
void setUp_day(){
now = millis(); lcd.clear(); // сбарсываем переменную счета таймера в (миллис)
while (millis()-now < timerMenu){ // запускаем таймер автовыхода из подпрограмы, если мы сейчас в позии секунд то таймер увеличиваем на 60 секунд
getRTCDateTime(); // считываем данные часы, минуты, секунды
lcd.setCursor(0,1);lcd.print("ДЕНЬ ");lcd.print(day);
klav(); // Опрашиваем клавиши 0- не нажаты, 1-3 клавиши нажаты
if(key == 1){ // если нажата кнопка 1, то выходим из подпрограмы
lcd.clear(); setMode = 4;return;
}
if(key == 2){ // если нажата кнопка 2,
now = millis(); lcd.clear(); // сбрасывае счетчик автовыхода из подпрограмы
if (day < 32){
day++; if (day==32)day=1;
setRTCDateTime();}
} //
if(key == 3){ // если нажата кнопка 3,
now = millis(); lcd.clear();
if (0 < day){
day--; if (day==0)day=31;
}
setRTCDateTime();
}
}
}
//-----------------------------------------------------------------------
void setUp_year(){
now = millis(); lcd.clear(); // сбарсываем переменную счета таймера в (миллис)
while (millis()-now < timerMenu){ // запускаем таймер автовыхода из подпрограмы, если мы сейчас в позии секунд то таймер увеличиваем на 60 секунд
getRTCDateTime(); // считываем данные часы, минуты, секунды
lcd.setCursor(0,1);lcd.print("ГОД ");lcd.print(year);
klav(); // Опрашиваем клавиши 0- не нажаты, 1-3 клавиши нажаты
if(key == 1){ // если нажата кнопка 1, то выходим из подпрограмы
lcd.clear(); setMode = 2;return;
}
if(key == 2){ // если нажата кнопка 2, то переходим к следующей позиции установки
now = millis(); lcd.clear(); // сбрасывае счетчик автовыхода из подпрограмы

if (year < 2100){
year++;
setRTCDateTime();}
} //
if(key == 3){ // если нажата кнопка 3, то меняеме значение переменной отображаемой в данной позиции
now = millis(); lcd.clear();
if (2020 < year){
year--;
}
setRTCDateTime();
}
}
}

//-------------------------- выводит на экран температур--------------------
void eeprom_lcd()
{
lcd.setCursor(0,0); lcd.print("ДАТА");lcd.setCursor(6,0);lcd.print("ТЕМПЕРАТУРА");
lcd.setCursor(0,1);lcd.print(day_0);lcd.print(".");lcd.print(month_0);lcd.setCursor(8,1);lcd.print(bme_temp_0); lcd.print(" °");lcd.print("C");


lcd.setCursor(0,2);lcd.print(day_1);lcd.print(".");lcd.print(month_1);lcd.setCursor(8,2);lcd.print(bme_temp_1); lcd.print(" °");lcd.print("C");


lcd.setCursor(0,3);lcd.print(day_2);lcd.print(".");lcd.print(month_2);lcd.setCursor(8,3);lcd.print(bme_temp_2); lcd.print(" °");lcd.print("C");
}




//----------------------выводит на экран время----------------------------------------------
void disp_time (){

lcd.setCursor(0,0);
if (h1>0){lcd.print(h1);lcd.print(h0);}
else {lcd.print(" ");lcd.print(h0);}


//lcd.print(hour);
lcd.print(":");lcd.print(m1);lcd.print(m0);lcd.print(":");
//lcd.print(second);
lcd.print(s1);lcd.print(s0);

lcd.setCursor(10,0);
if (d1>0){lcd.print(d1);lcd.print(d0);}
else {lcd.print(" ");lcd.print(d0);}

// lcd.print(day);
lcd.print(" ");

switch (dayOfWeek) {
case 0:
lcd.print("Пн");
break;
case 1:
lcd.print("Вт");
break;
case 2:
lcd.print("Ср");
break;
case 3:
lcd.print("Чт");
break;
case 4:
lcd.print("Пт");
break;
case 5:
lcd.print("Сб");
break;
case 6:
lcd.print("Вс");
break;
case 7:dayOfWeek=0;setRTCDateTime();
break;

}



lcd.setCursor(0,1); lcd.print("Темп = ");lcd.print(bme_temp); lcd.print(" °");lcd.print("C");

lcd.setCursor(0,2); lcd.print("Давл = ");lcd.print(bme_Pressure);lcd.print(" mm");

lcd.setCursor(0,3); lcd.print("Влаж = ");lcd.print(bme_Humidity); lcd.print(" % ");
}


//----------------------------------------------------------------------- конец---------------------------------------------------------------
Вложения
meteostanciya_moi.ino.hex
(59.51 КБ) 195 скачиваний
meteostanciya_moi.zip
(7.91 КБ) 197 скачиваний
Опытный кот
Аватара пользователя
Сообщения: 867
Зарегистрирован: Пт фев 27, 2015 12:00:53
Откуда: Рязанская область

Сообщение Serzh2000 »

ну зависает часы с датчиком ВМЕ280 хоть ты тресни...
скажите, а у меня датчик через провод (витая пара UTP 2х2х0,5 ) 3 метра подключен к ардуине, может из за этого виснуть?
или может все незадействованные ноги ардуино посадить на минус, чтобы не ловили помехи какие-нибудь
или подключить к земле, - используя параметр INPUT_PULLUP?
блоки питания менял и 5 вольтовый был , и сейчас 7,5 вольтовый через кренку, конденсатор 2200мкф, 0,1мкф стоит от какой-то тв приставки, все одно виснет...
посоветуйте , что еще бы можно сделать. :dont_know:
Ответить

Вернуться в «Разные вопросы по МК»