|
|
  |
Проблема с sscanf_P, или StringToInt |
|
|
|
Dec 21 2007, 07:38
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Для преобразования строки в целое число попробовал сделать так: Код sscanf_P(lcd_buf, "%d", &mn); printf_P("\n\rMONTH %d", mn); ................... sscanf_P(lcd_buf, "%d", &dt); printf_P("\n\rDATE %d", dt); .................... sscanf_P(lcd_buf, "%d", &yr); printf_P("\n\rYEAR %d", yr); rtc_set_time(0,min,hr,dy,dt,mn,yr-2000); Терминал честно выводит переменную yr= 2007. Точно так же делаю с другими переменными времени. Проблема в том, что эти переменные не пишутся в RTC. Вернее пишут, но 0. Точнее записалось только значение года ("2007").Хотя если явно инициализировать эти переменные какими-то значениеми или преобразовать с помощью ф-ции StrToInt(), то эти "какие-то"значения или результат ф-ции StrToInt() запишутся без проблем в RTC. В ф-ции rtc_set_time() каждое значение делается dec2bcd. В чем дело?
|
|
|
|
|
Dec 21 2007, 08:25
|
Частый гость
 
Группа: Свой
Сообщений: 151
Регистрация: 21-02-06
Пользователь №: 14 561

|
Цитата(alux @ Dec 21 2007, 10:38)  Для преобразования строки в целое число попробовал сделать так: Код sscanf_P(lcd_buf, "%d", &yr); printf_P("\n\rYEAR %d", yr); rtc_set_time(0,min,hr,dy,dt,mn,yr-2000); Терминал честно выводит переменную yr= 2007. Точно так же делаю с другими переменными времени. Проблема в том, что эти переменные не пишутся в RTC. Вернее пишут, но 0. Точнее записалось только значение года ("7").Хотя если явно инициализировать эти переменные какими-то значениеми или преобразовать с помощью ф-ции StrToInt(), то эти "какие-то"значения или результат ф-ции StrToInt() запишутся без проблем в RTC. В ф-ции rtc_set_time() каждое значение делается dec2bcd. В чем дело? ...подробней можно? Покажите прототипы функций и как объявлены переменные
|
|
|
|
|
Dec 21 2007, 09:08
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(tag @ Dec 21 2007, 12:25)  ...подробней можно? Покажите прототипы функций и как объявлены переменные Переменные объявлены как глобальные. В компиляторе включена опция --string_literals_in_flash. void rtc_set_time(unsigned char second, unsigned char minute, unsigned char hour, unsigned char day, unsigned char date, unsigned char month, unsigned int year); int sscanf_P(const char *__s, PGM_P __format,…); int printf_P(PGM_P __format,…); Использую CLIB
|
|
|
|
|
Dec 21 2007, 10:15
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(alux @ Dec 21 2007, 10:38)  Для преобразования строки в целое число попробовал сделать так: Терминал честно выводит переменную yr= 2007. Точно так же делаю с другими переменными времени. Проблема в том, что эти переменные не пишутся в RTC. Вернее пишут, но 0. Точнее записалось только значение года ("7").Хотя если явно инициализировать эти переменные какими-то значениеми или преобразовать с помощью ф-ции StrToInt(), то эти "какие-то"значения или результат ф-ции StrToInt() запишутся без проблем в RTC. В ф-ции rtc_set_time() каждое значение делается dec2bcd. В чем дело? а все остальные переменные тоже выводите в терминал, и они тоже имеют правильные значения? и прям таки если после вывода в терминал эти переменные инициализировать повторно тем же значением, то все нормально пишется? чудеса прям какие-то получаются
|
|
|
|
|
Dec 21 2007, 11:19
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(alux @ Dec 21 2007, 13:41)  Все остальные переменные точно так же вывожу на терминал. Чудес не бывает. Должно быть какое-то логическое объяснение. вот именно, что должно. поскольку у значений памяти нет, должно быть все равно, откуда они берутся - если у Вас х == 5, и это значение видно в терминале, то выполнение операции х = 5 не должно влиять на последующий вызов f(x), иначе это чудеса и есть. рыть надо в сторону определения разницы между результатом выполнения sscanf() и простым присваиванием. для начала я бы напечатал отладочную информацию на предмет выполнения условия равентсва тех значений, что вы получаете из sscanf() с теми, которые Вы ожидаете получить
|
|
|
|
|
Dec 21 2007, 12:44
|
Частый гость
 
Группа: Свой
Сообщений: 151
Регистрация: 21-02-06
Пользователь №: 14 561

|
Цитата(alux @ Dec 21 2007, 12:08)  Переменные объявлены как глобальные. В компиляторе включена опция --string_literals_in_flash. void rtc_set_time(unsigned char second, unsigned char minute, unsigned char hour, unsigned char day, unsigned char date, unsigned char month, unsigned int year);
int sscanf_P(const char *__s, PGM_P __format,…); int printf_P(PGM_P __format,…); Использую CLIB ...практически ничего не прояснили. Код покажите пожалуйста.
|
|
|
|
|
Dec 21 2007, 13:21
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(Dog Pawlowa @ Dec 21 2007, 16:17)  А почему Вы решили, что RTC способен принять это значение года одной переменной? Потому что, у DS1338 год пишется переменной в диапазоне 0...99. Код void rtc_set_time(unsigned char second, unsigned char minute, unsigned char hour, unsigned char day, unsigned char date, unsigned char month, unsigned int year) { i2c_start(RTC_ADDR|W); // write slave address + write i2c_write(0x00); // write register address, 1st clock register //Установить системное время : i2c_write(dec2bcd(second)); i2c_write(dec2bcd(minute)); i2c_write(dec2bcd(hour));
// Установить системную дату : i2c_write(dec2bcd(day)); i2c_write(dec2bcd(date)); i2c_write(dec2bcd(month)); i2c_write(dec2bcd(year)); // Настроить выход на генерацию 32768Гц : i2c_write(0x13); // enable sqwe, 32768Hz output, clear OSF bit i2c_stop(); } Весь код показывать не буду. Слишком большой. Суть проблемы в следующем: в результате действия программы загрузил в lcd_buf строку"2007". Сделал sscanf_P в переменную YR. Вывел на терминал значение YR. Показывает 2007. Дальше загрузил в lcd_buf строку"12". Сделал sscanf_P в переменную MN. Вывел на терминал значение MN. Показывает 12. И т.д. со следующими переменными. Когда инициализировал таким образом последнюю переменную MIN, вызываю ф-цию rtc_set_time(). В результате - в часах - одни "0" . Кроме года. Если перед вызовом rtc_set_time() присвоить этим переменным значения непосредственно вот так: yr=2007, mn=12, dt=23, dy=6, ..., то эти значения запишутся в RTC. Добавлено
Только что проверил значения переменных непосредственно перед вызовом ф-ции rtc_set_time(). Значения переменных, кроме года равны 0 ! Где-то херятся переменные. Провел простой эксперимент: Редактирую переменные в такой последовательности: YR,MN,DT,DY,HR,MIN ; на терминал вывожу значение переменной + предыдущее значение отредактированной переменной. Выяснилось, что при редактировании DT обнуляется MN и т.д. И в этом вся проблема. Но тогда вопрос в следующем. Почему простая замена функций sscanf_P на StrToInt сохраняет значения переменных? Виновата sscanf_P? Прикладываю файл. Если кто-нибудь в нем разберется  Функция выводит статические надписи в разные строки и значения переменных с координаты х=49. Редактирование значения текущего символа, который выделен мигающим курсором , осуществляется с клавиатуры 4х4. UP, DOWN смещение курсора в пределах строки. Число с цифровой клавиатуры заменяет текущее знакоместо и переносит курсор на следующее. ENTER - сохранение отредактированной переменной. При чем когда сохраняем последнюю отредактированную переменную, то вызывается ф-ция rtc_set_time. Хочется услышать ваше мнение. Громоздко получилось или это нормально?
|
|
|
|
|
Dec 21 2007, 14:09
|
Частый гость
 
Группа: Свой
Сообщений: 151
Регистрация: 21-02-06
Пользователь №: 14 561

|
Цитата(alux @ Dec 21 2007, 16:21)  Весь код показывать не буду. Слишком большой. Суть проблемы в следующем: в результате действия программы загрузил в lcd_buf строку"2007". Сделал sscanf_P в переменную YR. Вывел на терминал значение YR. Показывает 2007. Дальше загрузил в lcd_buf строку"12". Сделал sscanf_P в переменную MN. Вывел на терминал значение MN. Показывает 12. И т.д. со следующими переменными. Когда инициализировал таким образом последнюю переменную MIN, вызываю ф-цию rtc_set_time(). В результате - в часах - одни "0" . Кроме года. Если перед вызовом rtc_set_time() присвоить этим переменным значения непосредственно вот так: yr=2007, mn=12, dt=23, dy=6, ..., то эти значения запишутся в RTC. Непосредственно перед вызовом ф-ции вывожу на терминал все переменные, инициализированные sscanf_P. Показывает на терминале нужные значения. А в RTC писать не хочет. Что еще непонятного? ...чудес не бывает. Например меня смущает что у вас параметр (функция rtc_set_time) year имеет тип unsigned int, а все остальные unsigned char...хотя функция dec2bcd() наверняка принимает параметр типа char. Типичная ошибка такая - порт I2C разделяется еще с каким либо устройством так что в процессе обмена с часами (при распараллеливании задач) выполняется еще обмен с этим устройством и вот вам неизвестные значения. Посмотрите может у вас переменные используются где-то еще
|
|
|
|
|
Dec 21 2007, 14:31
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(tag @ Dec 21 2007, 18:09)  Например меня смущает что у вас параметр (функция rtc_set_time) year имеет тип unsigned int, а все остальные unsigned char...хотя функция dec2bcd() наверняка принимает параметр типа char. Пусть Вас это не смущает. Код static unsigned int bcd2dec(unsigned int bcd); static unsigned int dec2bcd(unsigned int dec); Цитата(tag @ Dec 21 2007, 18:09)  Типичная ошибка такая - порт I2C разделяется еще с каким либо устройством так что в процессе обмена с часами (при распараллеливании задач) выполняется еще обмен с этим устройством и вот вам неизвестные значения. Посмотрите может у вас переменные используются где-то еще Ключевой вопрос : почему тогда с функцией unsigned char StrToInt(char *pStr, unsigned int *pResult);, нет такой проблемы?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|