03.02.2013, 13:06
|
|
Частый гость
Регистрация: 29.01.2013
Сообщений: 31
Сказал спасибо: 13
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
UART к PC на CodeVision
Продолжая изучение AVR ATxmega128A1 столкнулся с проблемой при подключении платы с компьютером, а именно отправка слов (string) через UART.
При отправке сообщения "0", я получаю "0x98", что не есть "0".
При отправке сообщения "012345", часть "01234" приходит правильно, но добавляются лишние пакеты. К тому же пропадает предпоследний символ 0x0A.
Красным выделил ошибочные пакеты:
Send_UART("0");
41 98 0A 0D
Send_UART("012345");
41 30 31 32 33 34 4D 43 50 8A 92 9A A2 D6 52 0D Вот мой скрипт:
Код:
|
//send_uart.h
#include ‹string.h›
#include ‹xmega128a1.h›
void Send_UART(char *data)
{
char counter = 0x00;
char lenght = 0x00;
lenght = strlen(data); // returns the length of the string
while (!( USARTC0.STATUS & USART_DREIF_bm));
USARTC0.DATA = 0x41; // A
while(counter ‹ lenght)
{
while (!(USARTC0.STATUS & USART_DREIF_bm)); // ((USARTC0.STATUS & USART_DREIF_bm) == 0);
USARTC0.DATA = *(data+counter);
counter++;
}
counter = 0x00;
while (!( USARTC0.STATUS & USART_DREIF_bm));
USARTC0.DATA = 0x0A; // LF new line
while (!( USARTC0.STATUS & USART_DREIF_bm));
USARTC0.DATA = 0x0D; //CR corriage return |
отправляю через:
Код:
|
Send_UART("012345"); // Send_UART("0"); |
Скорость передачи (9600) настроена верно. Ошибку предполагаю в команде strlen(data), так как через нее я хочу определить количество символов, которое "скачет".
Если проблема в этом, как можно ее обойти?
Последний раз редактировалось Fogtech; 03.02.2013 в 13:09.
|
|
|
|
03.02.2013, 13:16
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 6,792
Сказал спасибо: 2,912
Сказали Спасибо 3,120 раз(а) в 2,111 сообщении(ях)
|
Re: UART к PC на CodeVision
М.б. тут
Сообщение от Fogtech
|
Send_UART("012345");
|
надо не просто литерал, а как-то указать, что это именно строка? Т.е. какой-то модификатор, приводящий при вызове Send_UART к аналогии такой примерно записи:
Код:
|
char test_string[] = "012345";
Send_UART(test_string); |
Ещё - в книжке написано, что strlen учитывает ноль, находящийся в конце строки.
Или нет?
|
|
|
|
03.02.2013, 13:19
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.06.2008
Сообщений: 1,394
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
|
Re: UART к PC на CodeVision
Сообщение от Fogtech
|
while(counter ‹ lenght)
{
while (!(USARTC0.STATUS & USART_DREIF_bm)); // ((USARTC0.STATUS & USART_DREIF_bm) == 0);
USARTC0.DATA = *(data+counter);
counter++;
}
|
Да сделайте проще - без strlen
while(*data)
{
while (!(USARTC0.STATUS & USART_DREIF_bm)); // ((USARTC0.STATUS & USART_DREIF_bm) == 0);
USARTC0.DATA = *data++;
}
|
|
|
|
03.02.2013, 13:27
|
|
Частый гость
Регистрация: 29.01.2013
Сообщений: 31
Сказал спасибо: 13
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
Re: UART к PC на CodeVision
Сообщение от ForcePoint
|
М.б. тут
надо не просто литерал, а как-то указать, что это именно строка? Т.е. какой-то модификатор, приводящий при вызове Send_UART к аналогии такой примерно записи:
Код:
|
char test_string[] = "012345";
Send_UART(test_string); |
|
Исходник брал отсюда. По всей видимости написано для WinAVR.
Код:
|
void Send_UART(char data[])
{
char Counter = 0x00;
char lenght = 0x00;
lenght = strlen(data);
while(Counter ‹ lenght)
{
while (!(USARTC0.STATUS & USART_DREIF_bm));
USARTC0.DATA = data[Counter];
Counter++;
}
Counter = 0x00;
while (!( USARTC0.STATUS & USART_DREIF_bm));
USARTC0.DATA = 0x0A;
while (!( USARTC0.STATUS & USART_DREIF_bm));
USARTC0.DATA = 0x0D;
} |
При компиляции CodeVision почему-то ругался на массивы.
function argument #1 of type 'flash unsigned char [11]' is incompatible with required parameter of type 'unsigned char []'
Пришлось код подогнать.
Код:
|
Ещё - в книжке написано, что strlen учитывает ноль, находящийся в конце строки.
Или нет? |
Возможно (кстати в какой книге? не помешает самому почитать) только вот 6 лишних символов этим не объяснить.
|
|
|
|
03.02.2013, 13:38
|
|
Частый гость
Регистрация: 29.01.2013
Сообщений: 31
Сказал спасибо: 13
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
Re: UART к PC на CodeVision
Сообщение от Boba_spb
|
Да сделайте проще - без strlen
while(*data)
{
while (!(USARTC0.STATUS & USART_DREIF_bm)); // ((USARTC0.STATUS & USART_DREIF_bm) == 0);
USARTC0.DATA = *data++;
}
|
Спасибо за код. Действительно проще написан, но результат увы тот же.
Send_UART("012345")
41 30 31 32 33 34 4D 43 50 8A 92 9A A2 D6 52 0D
Правда теперь strlen как причина отпадает.
|
|
|
|
03.02.2013, 13:43
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 6,792
Сказал спасибо: 2,912
Сказали Спасибо 3,120 раз(а) в 2,111 сообщении(ях)
|
Re: UART к PC на CodeVision
Сообщение от Fogtech
|
Пришлось код подогнать.
|
В результате, КМК, у Вас получается, что обращаетесь по указателю и пытаетесь применить к нему функцию для работы со строками. Она смотрит по указателю в память, ищет заверщающий строку ноль (я не знаю точно, но, м.б. литерал не содержит его) и возвращает что-то от балды найдя "чужой" ноль.
Сообщение от Fogtech
|
Возможно (кстати в какой книге? не помешает самому почитать) только вот 6 лишних символов этим не объяснить.
|
"Турбо С ++, язык и его применение", Цимбал и др. Или Керниган и Ричи.
|
|
|
|
03.02.2013, 14:19
|
|
Частый гость
Регистрация: 29.01.2013
Сообщений: 31
Сказал спасибо: 13
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
Re: UART к PC на CodeVision
Сообщение от ForcePoint
|
В результате, КМК, у Вас получается, что обращаетесь по указателю и пытаетесь применить к нему функцию для работы со строками. Она смотрит по указателю в память, ищет заверщающий строку ноль (я не знаю точно, но, м.б. литерал не содержит его) и возвращает что-то от балды найдя "чужой" ноль.
|
Похоже на правду. Пока правда не имею представления, как иначе описать функцию без указателей. Как я говорил, массивы "оторгаются" компилятором.
Книгу увы найти не удалось (.
|
|
|
|
03.02.2013, 14:48
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.06.2008
Сообщений: 1,394
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
|
Re: UART к PC на CodeVision
В С строка заканчиваться нулевым байтом. strlen - дает длину без нуля.
ASM - не ставит ноль.
Надо смотреть что там во flash лежит на месте "01234"
|
|
|
|
03.02.2013, 19:29
|
|
Частый гость
Регистрация: 29.01.2013
Сообщений: 31
Сказал спасибо: 13
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
Re: UART к PC на CodeVision
Пошел путем меньшего сопротивления, оставив флеш на потом.
Решил использовать команду putsf из библиотеки stdio.h. Работает.
@ForcePoint и @Boba_spb
Спасибо за подсказки!
Последний раз редактировалось Fogtech; 03.02.2013 в 19:51.
|
|
|
|
19.02.2013, 00:39
|
|
Частый гость
Регистрация: 29.01.2013
Сообщений: 31
Сказал спасибо: 13
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
Re: UART к PC на CodeVision
Работая над связью между ПК и Xmega128A1 столкнулся с проблемой, которую никак не могу обойти. А именно: МК отправляет данные только тогда, когда получает сигнал из вне. Для коммуникаций использую следующие функции:
Код:
|
/*...*/
//====================== Write to USARTC0 Transmitter ==========================
void putchar_usartc0(unsigned char trans[12])
{
while (!(USARTC0.STATUS & USART_DREIF_bm));
puts(trans); // Send string through RS232
}
//====================== Receive from USARTC0 ==================================
char getchar_usartc0(void)
{
unsigned char rec; //
while (1)
{
while (!(USARTC0.STATUS & USART_RXCIF_bm));
rec=USARTC0.DATA;
if((USARTC0.STATUS & (USART_FERR_bm | USART_PERR_bm | USART_BUFOVF_bm)) == 0)
return rec;
}
}
/*...*/ |
Пробовал изменять статусы (USARTC0.STATUS) и циклы, все напрасно... Прошу подсказать как должна выглядеть функция регулярной отправки. Спасибо.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 20:56.
|
|