Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.05.2018, 19:29   #1
RenvY
Новичок
Джуниор
 
Регистрация: 04.05.2018
Сообщений: 1
По умолчанию Настройка UART на Atmega8 (язык С)

Здраствуйте. Есть задача написать программу для ATmega8, которая при получении байт по UART, должна находить среднее арифметическое значение этих байт и отправлять результат по UART. Код пишу в AlmelStudio, для ввода чисел использую виртуальный терминал в Proteus. Опыта общения с языком С никакого. Пока удалось составить такой код.

Код:
#define F_CPU 8000000
#define BAUD 9600L
#define UBRRL_value (F_CPU/(BAUD*16))-1

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

unsigned int b,d,s;

void init_USART() 
{	
	UBRRL = UBRRL_value;					 
	UBRRH = UBRRL_value >> 8;				    
	UCSRB |=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE);				 
	UCSRC |=(1<< URSEL)|(1<< UCSZ0)|(1<< UCSZ1);		 
}

void send_UART(char value) 
{
	while(!( UCSRA & (1 << UDRE)));				 
	UDR = value;								
}

ISR(USART_RXC_vect) //здесь пока набросок дальнейших действий, пока пытаюсь осознать работу прерывания по получению бита на массиве с 3-мя элементами
{
	int b;
	b = UDR;

	d=0;
	int a[3];
	a[d]=b;
	d=d+1;
	
	s=(a[0]+a[1]+a[2])/3;
	send_UART(s);	
}

int main(void)
{
	init_USART(); 

	send_UART('V'); 
	send_UART('v'); 
	send_UART('o');
	send_UART('d');
	send_UART(0x0d);
	send_UART(0x0a);
	
	sei();
        while(1)
	{}
}
Скорее всего ввод фразы по буквам у знающих людей вызовет фейспалм. Как это реализовать более изящно я не знаю и мои попытки что-то изобразить из кусков кода случайных статей по теме ни к чему не привели. Работает и работает.
Вопросы пока у меня следующие: Основную работу с массивами нужно писать в обработчике прерываний или в основном цикле программы?
Есть ли возможность как то проверить построчно что у меня в какой переменной находится? Хочется отследить запись чисел в массив.
На данном этапе при прошивке виртуального МК в Протеусе не терминале выводится прописанная буквами фраза, есть возможность вводить числа, но больше ничего не происходит.
RenvY вне форума Ответить с цитированием
Старый 11.05.2018, 18:41   #2
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

1. При получении прерывания их нужно сразу ЗАПРЕТИТЬ (иначе, могут валится еще и все в итоге отвалится из-за бесконечной рекурсии), а по окончании обработки - РАЗРЕШИТЬ (тут не совсем помню, там у ардуины визарды код генерят, в котором это уже как бы есть не явно ... но в коде "с нуля" нужно делать, как я сказал).
2. Насчет "основная"... тут все зависит от времени. Обработка прерывания должна быть максимально быстрой (см 1, пока оно обрабатывается - все остальные теряются).
3. Насчет всего остального - учите уже С++/С. За вас делать никто не будет. Учите что-то для компа в режиме консоли. Для контроллера можно вполне писать на современном С++ со всеми плюшками и наворотами, НО! добавить флаги компиляции
Цитата:
set(ARDUINO_C_FLAGS " -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -fdce")
Т.о. по размеру конечный блоб будет байт в байт равен С. Более того, в особо сложных проектах, видел ручную реализацию полиморфизма на С. Это миф. С++ натуральный получается в коде меньше, чем велики от программистов.
Цитата:
Верьте своему компилятору.

Последний раз редактировалось alexzk; 11.05.2018 в 18:49.
alexzk вне форума Ответить с цитированием
Старый 11.05.2018, 22:08   #3
digitalis
Старожил
 
Аватар для digitalis
 
Регистрация: 04.02.2011
Сообщений: 4,537
По умолчанию

Цитата:
Сообщение от alexzk Посмотреть сообщение
1. При получении прерывания их нужно сразу ЗАПРЕТИТЬ
Не нужно. При входе в прерывание флаг I в SREG сбрасывается, при выходе из прерывания по RETI устанавливается. Даже наоборот: чтобы разрешить вложенные прерывания, приходится производить определенные телодвижения, да это и не нужно, можно в них запутаться.
RenvY для передачи/приема чего-нибудь по UART нужен протокол - или стандартный какой-нибудь (напр., MODBUS), или по крайности свой простейший. Из него будет ясно: передаем байты по счетчику или до признака конца сообщения. И в соответствии с этим организуем цикл. Заодно и на приемной стороне будут знать - пакет закончился - или еще ждать до хзч .
Работа с массивами в прерываниях в МК считается плохим стилем. В прерывании след. находиться мин. время (почему - см. выше), обмен с главной программой - через буферы и флаги.

Последний раз редактировалось digitalis; 12.05.2018 в 10:48.
digitalis вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Что надо записать в регистры UART для передачи данных через сом порт? седьмой Общие вопросы C/C++ 3 23.06.2017 15:26
Serial uart mrprim Python 5 04.08.2016 19:54
Генератор на Atmega8 (AVR). Код на C dem66 Общие вопросы C/C++ 4 05.02.2013 08:22
Чтение UART через read dfyz.s Общие вопросы C/C++ 2 15.11.2012 10:14
ШИМ для мк atmega8 pimple2006 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 4 09.02.2012 04:11