Нескольно простых вопросов о программировании AVR на Си.

Обсуждаем контроллеры компании Atmel.
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение OKF »

[uquote="FreshMan",url="/forum/viewtopic.php?p=4125869#p4125869"]

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

char str[] = "\0";
[/uquote]
массив размером в 2 символа, инициализирован двумя 0-ми.


[uquote="FreshMan",url="/forum/viewtopic.php?p=4125869#p4125869"]

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

char *str = "\0";
[/uquote]
Указателю str присваивается символьное значение. Как минимум, должно быть предупреждение.
Реклама
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Reflector »

[uquote="OKF",url="/forum/viewtopic.php?p=4126020#p4126020"]Указателю str присваивается символьное значение. Как минимум, должно быть предупреждение.[/uquote]
Тут тоже?

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

void foo(const char* s) {}

foo("bar");
Реклама
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение FreshMan »

есть три типа прерываний по UART
1) прием завершен
2)передача завершена
3)регистр данных передатчика пуст
какая разница между последними двумя ?
Tell Me The Truth
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18556
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение ARV »

передача завершена - когда данные ушли по физическим линиям
регистр пуст - значит, можно записать новый байт на передачу, но предыдущий еще до конца не отправился.

передатчик буфферизирован, т.е. там как бы очередь из 2 (или более) регистров, из которых "виден" программисту только первый - когда он пуст, в него можно записывать новое. а непосредственно в линию выдаются данные из самого последнего, сдвигового регистра.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Эиком - электронные компоненты и радиодетали
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Reflector »

[uquote="ARV",url="/forum/viewtopic.php?p=4130062#p4130062"]регистр пуст - значит, можно записать новый байт на передачу, но предыдущий еще до конца не отправился.[/uquote]
Про предыдущий тут лишнее.
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18556
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение ARV »

ну, в общем, согласен: входной регистр останется пустым и после ухода текущего передаваемого байта...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение FreshMan »

[uquote="ARV",url="/forum/viewtopic.php?p=4130062#p4130062"]передача завершена - когда данные ушли по физическим линиям
регистр пуст - значит, можно записать новый байт на передачу, но предыдущий еще до конца не отправился.[/uquote]

в каких случаях нужно использовать ПЕРЕДАЧА ЗАВЕРШЕНА, а в каких РЕГИСТР ДАННЫХ ПЕРЕДАТЧИКА ПУСТ ?
почему тогда просто не оставили режим РЕГИСТР ДАННЫХ ПЕРЕДАТЧИКА ПУСТ ? как я понимаю он шустрее
Tell Me The Truth
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Starichok51 »

когда ты прочитаешь принятый байт из регистра данных, то он тоже станет пуст.
а потом в прерывании по пустому регистру ты начнешь гадать, от чего он пуст - по окончании передачи или по окончании приема.
лично я использую прерывание "передача завершена" и там посылаю следующий байт на передачу.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Аватара пользователя
mickbell
Друг Кота
Сообщения: 16422
Зарегистрирован: Пт мар 30, 2012 05:17:29
Откуда: Екатеринбург

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение mickbell »

[uquote="FreshMan",url="/forum/viewtopic.php?p=4130221#p4130221"]в каких случаях нужно использовать ПЕРЕДАЧА ЗАВЕРШЕНА[/uquote]Для управления направлением потока данных: например, для выключения передатчика или управления RS-485. Отключать передачу следует именно по факту завершения передачи последнего байта, а не по факту вычитывания его из регистра. Иначе пакет окажется обрезан сзади.
И хрюкотали зелюки,
Как мюмзики в мове.

На каждый РКН
Найдётся VPN.
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Starichok51 »

mickbell, а разве кто-то говорил, что отключать передачу надо посреди телеграммы?
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение FreshMan »

написал тестовую программу

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

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define BAUD_RATE 2400L

unsigned char ch[2] = "A";

void UART0_Init(void) {

	UBRR0 = (F_CPU + 4 * BAUD_RATE) / (8 * BAUD_RATE) - 1; // если с кварцем

	UCSR0A = 1 << U2X0; // удвоение скорости обмена( предделитель уменьшается с 16 до 8)

	UCSR0B = 1 << TXEN0 |  // разрешение передачи
			 1 << TXCIE0;  // разрешение прерывания по завершению передачи
	UCSR0C = 1 << UCSZ00 | 1 << UCSZ01 | // определение размера слова данных в 8 бит
			 1 << USBS0;   // передатчик посылает 2 СТОП-бита
}


void uart_send_char(unsigned char *ch){

	while (! (UCSR0A & _BV(UDRE0)) );  // Wait for empty transmit buffer
	UDR0 = *ch;
}

int main(void) {

UART0_Init();

sei (); // Global enable interrupts

while(1){

	uart_send_char(ch);

}

}
подключил терминал
Изображение Изображение

как вычислить почему в терменале нет переданных с мк данных ?
Tell Me The Truth
Аватара пользователя
mickbell
Друг Кота
Сообщения: 16422
Зарегистрирован: Пт мар 30, 2012 05:17:29
Откуда: Екатеринбург

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение mickbell »

[uquote="Starichok51",url="/forum/viewtopic.php?p=4130337#p4130337"]mickbell, а разве кто-то говорил, что отключать передачу надо посреди телеграммы?[/uquote]Отключать передачу надо сразу же (!) после отправки последнего стоп-бита. Уточняю: по окончании передачи этого бита. Осталось понять, каким образом узнать, что этот самый момент таки случился.

Добавлено after 6 minutes 1 second:
[uquote="FreshMan",url="/forum/viewtopic.php?p=4130364#p4130364"]как вычислить почему в терменале нет переданных с мк данных ?[/uquote]Прежде всего, осциллографом посмотреть, что делается на линии TXD (со стороны МК) - RXD (со стороны компа): есть там сигнал или нет. Затем посмотреть, какова длительность передачи бита, и сравнить с заявленной скоростью, возможно, они не соответствуют. Если всё правильно, то надо подать на комп сигнал с другого источника - возможно, порт помер.
И хрюкотали зелюки,
Как мюмзики в мове.

На каждый РКН
Найдётся VPN.
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение FreshMan »

на просторах ютуба нашел максимально упрощенный вариант работы передатчика USART
https://www.youtube.com/watch?v=3_omxGI ... nHardDrive
может кому и пригодится :tea:

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

#include <avr/io.h>
#include <util/delay.h>


#define F_CPU 16000000
#define BAUD 9600
#define BRC ((F_CPU/16/BAUD)-1) // baud rate calculation


int main(void) {

UBRR0H = (BRC >> 8);
UBRR0L = BRC;


UCSR0B = _BV(TXEN0); // разрешение работы передачика USART
UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); // определение размера слова данных в 8 бит

while(1){

	UDR0 = 'W'; // инициализация передачи
	_delay_ms(100);

}

}

Posted after 4 minutes 24 seconds:
на основе приобретенных знаний написал свою ф-цию передачи данных
прошу подсказать и поправить если можна это реализовать проще :tea:

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

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

//#define F_CPU 16000000
#define BAUD 9600
#define BRC ((F_CPU/16/BAUD)-1) // baud rate calculation
#define TX_BUFFER_SIZE 128


#define enable_interrupt_when_data_register_USART_is_empty   UCSR0B |=  _BV(UDRIE0)
#define disable_interrupt_when_data_register_USART_is_empty  UCSR0B &= ~(1 << UDRIE0)

char TX_BUFFER[TX_BUFFER_SIZE] = " String №1 \n\r";
//char *p_str = " String №2 \n\r";

char *p;



ISR (USART0_TX_vect){// передача закончена

}

ISR (USART0_UDRE_vect){ // регистр данных пуст

	if (*p == '\0'){
		disable_interrupt_when_data_register_USART_is_empty;
	} else {
		UDR0 = *p;
		p++;
	}

}

void uart_send_string(char *s){

	if(bit_is_clear(UCSR0A,TXC0)){ // если предыдущая передача закончена
	    p = s;
	    UDR0 = *p;
	    p++;
	    enable_interrupt_when_data_register_USART_is_empty;
	}

}


int main(void) {

DDRB |= _BV(7);

UBRR0H = (BRC >> 8);
UBRR0L = BRC;
//UBRR0 = BRC ;

UCSR0B =  _BV(TXEN0)| // разрешение работы передачика USART
		 _BV(TXCIE0); // разрешение прерывания по завершению передачи


UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); // определение размера слова данных в 8 бит

sei (); // Global enable interrupts

while(1){

	uart_send_string(TX_BUFFER);
	_delay_ms(1000);


}

}

Tell Me The Truth
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18556
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение ARV »

включаю зануду.
FreshMan писал(а):void uart_send_string(char *s){

   if(bit_is_clear(UCSR0A,TXC0)){ // если предыдущая передача закончена
       p = s;
       UDR0 = *p;
       p++;
       enable_interrupt_when_data_register_USART_is_empty;
   }

}
а если предыдущая передача не закончена, что тогда? _delay_ms(1000) для надежности? и зачем тогда огород с передачей по прерываниям, если все равно ждать время?

выключаю зануду.

лично я, хоть меня и критиковали не раз за такой подход, в исключительно редких случаях реализовывал передачу по прерываниям, в основном меня всегда удовлетворяет передача по тупому ожиданию:

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

void send_char(c){
  while_bit_is_set(UCSR0A, UDRE);
  UDR0 = c;
}

void send_str(char *s){
  while(*s) send_char(s++);
}
тем более, что подобный принцип прекрасно поддерживается системными функциями printf, использовать которые для вывода на компьютерную консоль - милое дело! и практически весь UNIX вырос из именно такого, блокирующего printf...


а вот прием чаще всего удобнее именно по прерыванию. для меня лично, конечно...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение FreshMan »

[uquote="ARV",url="/forum/viewtopic.php?p=4131237#p4131237"]включаю зануду.
FreshMan писал(а):void uart_send_string(char *s){

   if(bit_is_clear(UCSR0A,TXC0)){ // если предыдущая передача закончена
       p = s;
       UDR0 = *p;
       p++;
       enable_interrupt_when_data_register_USART_is_empty;
   }

}
а если предыдущая передача не закончена, что тогда? _delay_ms(1000) для надежности? и зачем тогда огород с передачей по прерываниям,[/uquote]

относительно _delay_ms(1000) , я его вставил специально чтобы вывод на терминал был медленным, в реальном проэкте такого конечно же не будет :))
относительно законченности предыдущей задачи: мне представляется, изходя из своего опыта, что было бы правильней не начинать новую передачу пока старая не закончена. Допустим у нас сработали два внешние прерывания с периодичностью в 5мс, и на каждое из них мне нужно как-то отреагировать, допустим послать по юарту 2/3 книги война и мир, это пример явно зафантазированный, но как говорится чем ярче краски тем красивее картинка, так вот исходя из данного примера сообщение второго прерывания нужно бы поставить в очередь пока инфа с первого не передастся, а потом уже чтобы автоматом запустилось второе.
Вот такое мое видение, допускаю что можна проще.
Интересует сам принцип, насколько он правильный ? :roll:

Posted after 5 minutes 24 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=4131237#p4131237"]включаю зануду.

тем более, что подобный принцип прекрасно поддерживается системными функциями printf, использовать которые для вывода на компьютерную консоль - милое дело! .[/uquote]
а можна по подробней об этом ?
Tell Me The Truth
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18556
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение ARV »

FreshMan писал(а):было бы правильней не начинать новую передачу пока старая не закончена.
ну так и где это условие у вас? у вас, если флажок пустоты буфера не установлен, функция тупо ничего не сделает, а вызвавший её код никак об этом не узнает...
FreshMan писал(а):а можна по подробней об этом ?
да уж писал много раз... вот тут, например: https://simple-devices.ru/articles/7-so ... omment-392 (там, после смены владельца сайта, порушились врезки кода, но, если напрячься, все будет понятно)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение COKPOWEHEU »

[uquote="ARV",url="/forum/viewtopic.php?p=4131237#p4131237"]лично я, хоть меня и критиковали не раз за такой подход, в исключительно редких случаях реализовывал передачу по прерываниям, в основном меня всегда удовлетворяет передача по тупому ожиданию[/uquote]
Но ведь по прерываниям удобнее. Сказал камню "выведи мне там Хелло-ворлд" и занимаешься своими делами, потом время от времени спрашиваешь сколько там байтов пришло в ответ (может и ноль).
Я не представляю как подход на задержках встраивать в конечный автомат.

Добавлено after 1 minute 55 seconds:
тем более, что подобный принцип прекрасно поддерживается системными функциями printf, использовать которые для вывода на компьютерную консоль - милое дело! и практически весь UNIX вырос из именно такого, блокирующего printf...
В UNIX изначально была многозадачность, то есть пока интерактивный поток ждет пользователя, демоны вполне себе выполняются.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18556
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение ARV »

COKPOWEHEU писал(а):Но ведь по прерываниям удобнее.
удобнее, как проще. конечный автомат написать - это думать надо... а так - не надо :)
COKPOWEHEU писал(а):и занимаешься своими делами
это когда дел много...
COKPOWEHEU писал(а):то есть пока интерактивный поток ждет пользователя, демоны вполне себе выполняются
так в МК то же самое. просто для меня приоритеты расставлены так: то, что должно делаться быстро, делается по прерываниям, а то, что может и подождать - в основном цикле. отсюда прием по прерываниям в фоне, а вывод - без прерываний в цикле.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение COKPOWEHEU »

удобнее, как проще. конечный автомат написать - это думать надо... а так - не надо :)
Э-э-э... Вы что, работу с UART каждый раз с нуля пишете? А если кольцевой буфер и прерывания уже написаны, подключение ничем не отличается от работы на задержках.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18556
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение ARV »

COKPOWEHEU писал(а):А если кольцевой буфер и прерывания уже написаны, подключение ничем не отличается от работы на задержках.
тогда, пожалуйста, покажите, как просто кольцевой буфер с прерываниями скрестить с prntf?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Ответить

Вернуться в «AVR»