|
|
  |
Как сделать нормальный putchar |
|
|
|
Mar 16 2009, 07:44
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 27-01-09
Пользователь №: 43 990

|
Всем привет. В CodeVision для AVR использовал конструкцию putchar('S') и на экране в терминале получал символ S. В ИАРе такая конструкция не работает. Почему? Обмен MSP PC нормальный. Передаю значения путем помещения его в TXBUF0. Как сделать чтоб работала конструкция putchar('s')? Заранее спасибо.
|
|
|
|
|
Mar 16 2009, 08:22
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 27-01-09
Пользователь №: 43 990

|
Цитата(Dog Pawlowa @ Mar 16 2009, 11:51)  А UART проинициализирован? Скорость, разрешение передачи... А при чем здесь это? Я же написал что обмен уже работает, но только через непосредственную запись значений в регистр. Как сделать чтоб работал putchar?
|
|
|
|
|
Mar 16 2009, 08:53
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(tvilsa @ Mar 16 2009, 11:22)  А при чем здесь это? Я же написал что обмен уже работает, но только через непосредственную запись значений в регистр. Как сделать чтоб работал putchar? То есть? где то записанная запись значения в регистр работает, а в самом putchar - нет? Цитата(MrYuran @ Mar 16 2009, 11:34)  Насколько я помню, в ИАре putchar() и printf() - это обёртки функции put_one_symbol(), которую надо определить самостоятельно (по крайней мере я так делал) Странно, может в старых версиях так было. Сам putchar нужно определить самостоятельно. А printf - обертка, конечно же.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Mar 16 2009, 10:07
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 27-01-09
Пользователь №: 43 990

|
Цитата(Dog Pawlowa @ Mar 16 2009, 12:53)  То есть? где то записанная запись значения в регистр работает, а в самом putchar - нет? именно. передача простой записью в регистр работает т.е. при выполнении TXBUF0 = 0х30; работает,а putchar('s'); не работает
|
|
|
|
|
Mar 17 2009, 04:16
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 27-01-09
Пользователь №: 43 990

|
Цитата(rezident @ Mar 16 2009, 20:35)  Я с вас дивлюся, мужики! Неужели пару страничек хелпа сложно прочитать?  Если я правильно понял то функцию putchar надо описывать самому. Простое использование putchar('s') непрокатит. Жаль. И зачем она тогда нужна?
|
|
|
|
|
Mar 17 2009, 05:21
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 120
Регистрация: 17-06-04
Пользователь №: 37

|
Библиотечная пустая функция putchar() нужна как затычка. Пустая функция __low_level_init() у Вас вопросы не вызывает? При отсутствии Вашей функции putchar() вызывается она. Ведь вывод можно делать и на индикатор (графический, семисигментный, символьный и т.д.), и последовательный порт, и даже в какую нибудь eeprom-ку. Кроме Вас никто не знает, куда будет выводить Ваш putchar() и к каким ногам/портам он подключен. Так вот Ваша функция putchar() должна обеспечивать низкоуровневый вывод символа на Ваше устройство. Код /* --- putchar() ------------------------------------------------------------ ** * Вывод байта в терминал * -------------------------------------------------------------------------- */ int putchar( int c ) { if ( !c ) return( 0 ); return( uart0_tx( c )); }
// или что-то такое, немного кастрировано
/* --- putchar() ------------------------------------------------------------ ** * Вывод байта на символьный индикатор или принтер * Универсальный, для ЖКИ любого размера. * Используется перекодировка из таблицы win1251 в таблицу, применяемую в ЖКИ. * \a (\007) - Звуковой сигнал 50 ms, окончания звука не ожидает, пищит в фоне. * \b (\010) - Возврат на шаг (забой), из начала первой строки перейдет в конец последней * \t (\011) - Табуляция горизонтальная (сдвиг по ...). С конца последней строки переходит на начало первой! * \n (\012) - Перевод строки (новая строка), с последней строки индикатора осуществляется переход на первую. * \v (\013) - Переход в начало экрана (gotoxy(0,0)) * \f (\014) - Очистка экрана + Переход в начало экрана (gotoxy( 0, 0 )) * \r (\015) - Возврат каретки (на начало строки) * \0 (\000) - Ничего не делает, просто возвращает 0, и все. * \016 - символ '\000' дополнительного знакогенератора * \017 - символ '\007' дополнительного знакогенератора * \033 - ESC-команда см. esc_cmd.h * lcd_pos указывает на позицию курсора, т.е. после выполнения функции указывает на место, в которое будет * выводиться при следующем вызове функции. Позиции STROKA * STOLB и 0 эквивалентны! * -------------------------------------------------------------------------- */ int putchar( int c ) { static const char perecod[] = // перекодировка русских букв из таблицы win1251 в таблицу, применяемую в ЖКИ { 'A' , 0xa0, 'B' , 0xa1, 0xe0, 'E' , 0xa3, 0xa4, 0xa5, 0xa6, 'K' , 0xa7, 'M' , 'H' , 'O' , 0xa8, // 0xc0..0xcf 'P' , 'C' , 'T' , 0xa9, 0xaa, 'X' , 0xe1, 0xab, 0xac, 0xe2, 0xad, 0xae, 'b' , 0xaf, 0xb0, 0xb1, // 0xd0..0xdf 'a' , 0xb2, 0xb3, 0xb4, 0xe3, 'e' , 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 'o' , 0xbe, // 0xe0..0xef 'p' , 'c' , 0xbf, 'y' , 0xe4, 'x' , 0xe5, 0xc0, 0xc1, 0xe6, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 // 0xf0..0xff }; static int previos; // 10.05.04г. добавил для корректной работы последовательностей "\f\n", "\v\n" и "\n\n" int c_old = 0;
// if ( c ) // { if ( c >= 'А' ) // А - по русски это 0xc0 в win1251 // c = perecod[c - 'А']; // русские буквы в кодировке win1251 // else if ( c >= 0x80 ) // спецсимволы, расположенные в знакогенераторе lcd // c += 0x40; // мы их немного перенесли (символы с кодом 0xc0..0xff перенесены в область 0x80..0xc0
int a; // пришлось ввести переменную и вынести ее расчет из perecod[c - 'А'], ато "крутой" оптимизатор от ИАР МСП v3.30а заоптимизировывает...
if ( c ) { if ( flag.redirect == ON ) // перенаправление putchar() на принтер return( prn_byte( c )); c_old = c; a = c - 'А'; // А - по русски это 0xc0 в win1251 if ( a >= 0 ) c = perecod[a]; // А - по русски это 0xc0 в win1251 else if ( c >= 0x80 ) // спецсимволы, расположенные в знакогенераторе lcd { if ( c == 0xa8 ) // буква "Ё" c = 0xa2; else if ( c == 0xb8 ) // буква "ё" c = 0xb5; else c += 0x40; // мы их немного перенесли (символы с кодом 0xc0..0xff перенесены в область 0x80..0xc0 } switch ( c ) { case '\a': // Звуковой сигнал beep( 50 ); break; case '\b': // возврат на один символ (забой) if ( !lcd_pos ) lcd_pos = STROKA * STOLB; if (( lcd_pos-- % STROKA ) == 0 ) // последний символ в конце строки goto_pos(); else lcd_send_com( LCD_CURS_MOV_LEFT ); lcd_send_dat( ' ' ); lcd_send_com( LCD_CURS_MOV_LEFT ); break; case '\t': // табуляция. С конца последней строки переходит на начало первой! if (( lcd_pos += TAB_SIZE ) <= STROKA * STOLB ) lcd_pos = ( lcd_pos / TAB_SIZE ) * TAB_SIZE; else lcd_pos = 0; goto_pos(); break; case '\n': // на новую строку if ( previos == '\n' || previos == '\f' || previos == '\v' || ( lcd_pos % STROKA ) != 0 ) // игнорируем, если позиция кратна строке (уже сделан \n) { lcd_pos /= STROKA; if ( ++lcd_pos == STOLB ) lcd_pos = 0; else lcd_pos *= STROKA; goto_pos(); } break; case '\v': // в начало экрана (gotoxy(0,0)) if ( flag.cls_ind != ON ) // если установлен флаг - надо делать '\f' { lcd_send_com( LCD_HOME ); // lcd_gotoxy( 0, 0 ); lcd_pos = 0; break; } case '\f': // очистка экрана + gotoxy(0,0) lcd_send_com( LCD_CLS_HOME ); flag.cls_ind = OFF; lcd_pos = 0; break; case '\r': // возврат на начало строки без очистки экрана if ( lcd_pos == STROKA * STOLB ) // Если находимся в самой последней позиции lcd_pos--; // подумаем, что она предпоследняя lcd_pos -= lcd_pos % STROKA; goto_pos(); break; case '\033': // Обработка ESC-команд esc_cmd(); break; case '\016': // код '\000' c = 0; default: // собственно выводим символ на индикатор if (( lcd_pos % STROKA ) == 0 ) // переходить ли на следующую строку? goto_pos(); lcd_send_dat( c ); if ( lcd_pos++ == STROKA * STOLB ) // Позиции STROKA * STOLB и 0 эквивалентны! lcd_pos = 1; break; } previos = c_old; } else flag.redirect = OFF; return( c_old ); }
--------------------
Если зайца бить, его можно и спички научить зажигать Сколько дурака не бей - умнее не будет. Зато опытнее
|
|
|
|
|
Mar 17 2009, 05:57
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(rezident @ Mar 16 2009, 19:35)  Я с вас дивлюся, мужики! Неужели пару страничек хелпа сложно прочитать?  Не, хелп читать это когда совсем ничего не выходит а я залез в папку с примерами и увидел там putchar.c и printf.c - сделал а-ля и успокоился CODE /* PUTCHAR.C
The ANSI "putchar" function.
The putchar function writes the character c to the output-stream pointed to by stream. The function returns the character written. If an writing error occurs the putchar shall return EOF.
$Revision: 1.3 $
Copyright 1986 - 1999 IAR Systems. All rights reserved. */
#include <stdio.h>
int putchar(int ch) { /* put your own putchar-function here */ return ch; }
/* - PRINTF.C -
The ANSI "printf" function.
$Revision: 1.3 $
Copyright 1986 - 1999 IAR Systems. All rights reserved. */
#include "stdarg.h" #include "stdio.h" #include "icclbutl.h"
static void put_one_char(char c, void *dummy) { putchar ©; (void)dummy; /* Warning on this line OK (Optimized Away) */ }
int printf(const char *format, ...) /* Our main entry */ { va_list ap; int nr_of_chars;
va_start(ap, format); /* Variable argument begin */ nr_of_chars = _formatted_write(format, put_one_char, (void *) 0, ap); va_end(ap); /* Variable argument end */ return nr_of_chars; /* According to ANSI */ }
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Mar 17 2009, 06:02
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 27-01-09
Пользователь №: 43 990

|
Всем огромное спасибо.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|