|
Как передать по USART?, Вместо числа приходит точка |
|
|
|
Nov 23 2008, 18:29
|
Частый гость
 
Группа: Новичок
Сообщений: 85
Регистрация: 2-10-08
Пользователь №: 40 646

|
В устройстве требуются простенькие часы. Я задал структуру: Код typedef struct{ unsigned char sec; //Cекунды unsigned char min; //Минуты unsigned char hour; //Часы }time;
time t; Прерывание по переполнению таймера. Код interrupt [TIM1_COMPA] void timer1_compa_isr(void) { if (++t.sec==60) { t.sec=0; if (++t.min==60) { t.min=0; if (++t.hour == 24) { t.hour =0; } } }
} Допустим, отправляю UDR = t.sec. (t.sec к примеру = 7) И на выходе я получаю символ “.” C хекс кодом 07, и так с любым числом, всегда точки. Вот вопрос как передать это по USART?
|
|
|
|
|
Nov 23 2008, 22:45
|
Частый гость
 
Группа: Новичок
Сообщений: 85
Регистрация: 2-10-08
Пользователь №: 40 646

|
Цитата(rezident @ Nov 23 2008, 21:40)  Если вы хотите получить в терминале символьное значение, то до того как передавать, преобразуйте число в символьную строку. И передавайте всю символьную строку байт за байтом. А не могли бы вы привести пример кода, использую CVAVR и как то у меня не получается подружиться с этими символьными строками! 2Aesthete Animus UNIX TimeStamp вроде как сложновато, посмотрел примеры, слишком код большой, а у меня уже 85% памяти МК занято, мне что нить попроще! да не айс, подключил библиотеку для использования printf, и все не хватает памяти ((
|
|
|
|
|
Nov 24 2008, 09:17
|
Частый гость
 
Группа: Новичок
Сообщений: 85
Регистрация: 2-10-08
Пользователь №: 40 646

|
Цитата(SysRq @ Nov 24 2008, 02:17)  В лоб: Код void send_value(unsigned char value) { while(!(UCSRA & _BV(UDRE))); UDR = value / 10 + (unsigned char) 0x30; while(!(UCSRA & _BV(UDRE))); UDR = value % 10 + (unsigned char) 0x30; } Спасибо, то что надо, ещё сразу вопрос while(!(UCSRA & _BV(UDRE))); эта строка в не для CVAVR! нашел замену (пример из книги) Код #DEFINE UDRE 5 while(!(UCSRA & (1<<UDRE))); c ней у меня вообще ничего не передаёт! сделал вот так while(UCSRA.5 != 1) {}Все передает, но меня мучает вопрос правильно ли это? Незнаю как это узнать! Но вроде передает без ошибок.
|
|
|
|
|
Nov 24 2008, 11:19
|

Местный
  
Группа: Свой
Сообщений: 319
Регистрация: 3-09-05
Из: Беларусь, Новополоцк
Пользователь №: 8 188

|
Цитата(SysRq @ Nov 24 2008, 01:17)  В лоб: Код void send_value(unsigned char value) { while(!(UCSRA & _BV(UDRE))); UDR = value / 10 + (unsigned char) 0x30; while(!(UCSRA & _BV(UDRE))); UDR = value % 10 + (unsigned char) 0x30; } Небольшое замечание ('SysRq' мне друг, но истина дороже): работает только с числами меньше 100. Для работы "больше 100", нужно еще пару строк (и т.д. для 1000, 10000, ...). Более общий подход для таких дел: использовать BCD. IMHO.
|
|
|
|
|
Nov 24 2008, 13:00
|
Частый гость
 
Группа: Новичок
Сообщений: 85
Регистрация: 2-10-08
Пользователь №: 40 646

|
Цитата(SysRq @ Nov 24 2008, 13:14)  МК у вас какой? Смысл этой строки - проверить свободен ли UDR для записи. Конкратнея реализаци здесь - ждать флага Data Register Empty.. мк тини 2313 про строку я знаю, но вроде как моя строчка тоже должна работать, как UDRE =1, так можно слать новый байт. Цитата(shasik @ Nov 24 2008, 14:19)  Небольшое замечание ('SysRq' мне друг, но истина дороже): работает только с числами меньше 100. Для работы "больше 100", нужно еще пару строк (и т.д. для 1000, 10000, ...). Более общий подход для таких дел: использовать BCD. IMHO. Мне достаточно до 100
|
|
|
|
|
Nov 24 2008, 14:55
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 18-05-08
Пользователь №: 37 607

|
или так (без деления): Код void uchartostr(unsigned char arg) { unsigned char ones, tens; ones=arg; tens=0; while(ones>10) { ones-=10; tens++; //десятки } //в ones теперь - еденицы tens+=0x30; //преобразуем в ascii ones+=0x30; //преобразуем в ascii while(!(UCSRA&(1<<5))); UDR=tens; while(!(UCSRA&(1<<5))); UDR=ones; } и вызывайте, соответственно: uchartostr(t.sec);
Сообщение отредактировал Paulina - Nov 24 2008, 15:00
|
|
|
|
|
Nov 24 2008, 15:48
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 18-05-08
Пользователь №: 37 607

|
Цитата(SysRq @ Nov 24 2008, 18:44)  GCC именно так сам и сделает. CodeVision тоже так сделает, это просто для образовательных целей
|
|
|
|
|
Feb 6 2010, 18:38
|
Группа: Участник
Сообщений: 3
Регистрация: 6-02-10
Пользователь №: 55 333

|
В продолжение темы.
Начал изучать AVR. Есть ATmega8 на макетке, программатор, IAR Assembler for AVR 5.30.0 (5.30.0.50166), AVR студия 4.16
Кавыряюсь над задачей, как с МК передавать на ПК значения. Прочел документацию, написал прогу. Эроров нет. Но не работает.
При дэбаге показывает зависание на попытке отослать третий байт, останавливаясь на условии while(!(UCSRA&(1<<5)));
Если поставить бит руками, то итерация в дэбаге проходит.
На ситуацию не влияют: - степень оптимизации кода - вид функции (передача за вызов одного байта или разбитие и передача нескольких байт за один вызов)
UDRE не устанавливается...
Подскажите, что не так.
|
|
|
|
|
Feb 6 2010, 21:24
|
Частый гость
 
Группа: Участник
Сообщений: 149
Регистрация: 2-06-08
Из: Москва
Пользователь №: 38 003

|
Цитата(Okada @ Feb 6 2010, 21:38)  UDRE не устанавливается... Подскажите, что не так. Вы наверное в студийном симуляторе прогу прогоняете? Если да, то ждете наверное мало, AVR студия 4.16 не в реальном времени считает, ждать долго надо. А вообще, прогу в железо и посмотрите, ну и код что-ли выложите весь, может что подскажут.
|
|
|
|
|
Feb 9 2010, 05:42
|
Группа: Участник
Сообщений: 3
Регистрация: 6-02-10
Пользователь №: 55 333

|
Цитата(smac @ Feb 7 2010, 00:24)  Вы наверное в студийном симуляторе прогу прогоняете? Если да, то ждете наверное мало, AVR студия 4.16 не в реальном времени считает, ждать долго надо. А вообще, прогу в железо и посмотрите, ну и код что-ли выложите весь, может что подскажут. Железка выдаёт два байта и виснет. Трасировал пошагово. проджект прилагаю.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|