роботы робототехника микроконтроллеры


 Страниц (1): [1]   

> Описание: Прошу совета
поручик Post Id


Рядовой


Сообщений всего: 4
Дата рег-ции: Янв. 2015  



Доброго времени суток! Строю робота. Роботов, приведённых в примерах, уже собрал, всё работает... Задумка вкратце такова: используя встроенный SPI в атмега8, обеспечить простейшее дискретное радиоуправление. Принцип в целом понятен, т.е, записываем байт с управляющим кодом, на месте его читаем и сравниваем... Для простоты пока чисто на проводах, без радиомодуля. В Сети нашел примеры для CVavr... Но. Хотелось бы как-то решить проблему на winavr10, всё-таки единственная среда, в которой хоть какие-то навыки... Раньше с МК не работал вообще, с железом опыт достаточно большой. Даже пропорционалку из известной книги господина Миля собирал). Прошу показать пример кода работы с SPI, желательно с пояснениями для чайников)).
 
 Top
SlavikMIPT Post Id



Рядовой


Сообщений всего: 13
Дата рег-ции: Июль 2011  



uart + bluetooth какой нить мейнстримовый типа hc-06
 
 Top
mihail Post Id



Гуру


Сообщений всего: 1065
Дата рег-ции: Март 2010  



SPI
Учебный курс AVR. Работа с SPI м одулем. Ч1
Учебный курс AVR. Работа с SPI м одулем. Чтение и запись данных. Ч2
Учебный курс AVR. Работа с SPI м одулем. Управление сдвиговыми ре гистрами. Ч3
 
 Top
поручик Post Id


Рядовой


Сообщений всего: 4
Дата рег-ции: Янв. 2015  



Спасибо! Попытался собрать код, компилятор, естественно, ругается)
CODE:

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

#define SPI_PORTX PORTB
#define SPI_DDRX DDRB

#define SPI_MISO 6
#define SPI_MOSI 5
#define SPI_SCK 7
#define SPI_SS 4

/*инициализация SPI модуля в режиме master*/
void SPI_Init(void)
{
/*настройка портов ввода-вывода
все выводы, кроме MISO выходы*/
SPI_DDRX |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(0<<SPI_MISO);
SPI_PORTX |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(1<<SPI_MISO);

/*разрешение spi,старший бит вперед,мастер, режим 0*/
SPCR = (1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(1<<SPR1)|(0<<SPR0);
SPSR = (0<<SPI2X);
}
{
DDRD = 0x00; // все выводы порта D сконфигурировать как входы
PORTD = 0xff; // установить "1" на всех выводах порта D,
// включаем подтягивающие резисторы
}
while (1) { // Бесконечный цикл

// ПРОВЕРЯЕМ СИГНАЛ НИЗКОГО УРОНЯ С КНОПКИ

if (!(PIND & (1<<PIND1))) // проверить "0" на линии 1 порта D
{
data=0x01;
}
else
{
data=0x02;
}

int main(void) SPI_WriteByte(uint8_t data)
{
SPI_PORTX &= ~(1<<SPI_SS);
SPDR = data;
while(!(SPSR & (1<<SPIF)));
SPI_PORTX |= (1<<SPI_SS);
}

Подскажите, плиз, что не так? Понимаю, что "не так" может быть очень много, но это первая попытка что-то составить самостоятельно)). Извините мою безграмотность)
(Добавление)
Вот в таком виде компилится, но линкер выдает undefined reference to main. При вставке кода из примера - то же самое.
CODE:

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

#define SPI_PORTX PORTB
#define SPI_DDRX DDRB

#define SPI_MISO 6
#define SPI_MOSI 5
#define SPI_SCK 7
#define SPI_SS 4

/*инициализация SPI модуля в режиме master*/
void SPI_Init(void)
{
/*настройка портов ввода-вывода
все выводы, кроме MISO выходы*/
SPI_DDRX |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(0<<SPI_MISO);
SPI_PORTX |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(1<<SPI_MISO);

/*разрешение spi,старший бит вперед,мастер, режим 0*/
SPCR = (1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(1<<SPR1)|(0<<SPR0);
SPSR = (0<<SPI2X);
}


void SPI_WriteByte(uint8_t data)
{

DDRD = 0x00; // все выводы порта D сконфигурировать как входы
PORTD = 0xff; // установить "1" на всех выводах порта D,
// включаем подтягивающие резисторы

SPI_PORTX &= ~(1<<SPI_SS);
SPDR = data;
while(!(SPSR & (1<<SPIF)));
SPI_PORTX |= (1<<SPI_SS);


// ПРОВЕРЯЕМ СИГНАЛ НИЗКОГО УРОНЯ С КНОПКИ

if (!(PIND & (1<<PIND1))) // проверить "0" на линии 1 порта D
{
data=0x01;
}
else
{
data=0x02;
}

}
 
 Top
Механик Post Id



Полковник


Сообщений всего: 76
Дата рег-ции: Апр. 2014  



поручик пишет:
Подскажите, плиз, что не так?

Бесконечный цикл должен находится в теле функции int main (void), ну или в какой-либо другой, но никак не висеть неизвестно где, это по поводу ведущего(первый код)
Во втором, вообще отсутствует главная функция, а без неё никак нельзя:
вот так можно вторую програмкку модернизировать:
CODE:

void SPI_WriteByte(uint8_t data) { // функция отправки байта
SPI_PORTX &= ~(1<<SPI_SS);
SPDR = data;
while(!(SPSR & (1<<SPIF)));
SPI_PORTX |= (1<<SPI_SS);
}
int main (void) { // главная функция
DDRD = 0x00; // все выводы порта D сконфигурировать как входы
PORTD = 0xff; // установить "1" на всех выводах порта D,
// включаем подтягивающие резисторы
void SPI_Init(); // запускаем инициализацию SPI интерфейса
while(1==1) { // бесконечный цикл
// ПРОВЕРЯЕМ СИГНАЛ НИЗКОГО УРОНЯ С КНОПКИ

if (!(PIND & (1<<PIND1))) // проверить "0" на линии 1 порта D
{
data=0x01;
SPI_WriteByte(data);
}
else
{
data=0x02;
SPI_WriteByte(data);
}
}// конец бесконечного цикла

так вроде должно заработать.
(Добавление)
А ну ещё оставить нужно функцию инициализации, макросы, библиотеки(как раньше)
 
 Top
поручик Post Id


Рядовой


Сообщений всего: 4
Дата рег-ции: Янв. 2015  



Спасибо! В таком виде выдал ошибки, возможно, из-за наличия двух бесконечных циклов? Их вообще может быть несколько без прерываний? Вот в таком виде компилируется, сейчас засуну в протеус...
CODE:

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

#define SPI_PORTX PORTB
#define SPI_DDRX DDRB

#define SPI_MISO 6
#define SPI_MOSI 5
#define SPI_SCK 7
#define SPI_SS 4

/*инициализация SPI модуля в режиме master*/
void SPI_Init(void)
{
/*настройка портов ввода-вывода
все выводы, кроме MISO выходы*/
SPI_DDRX |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(0<<SPI_MISO);
SPI_PORTX |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(1<<SPI_MISO);

/*разрешение spi,старший бит вперед,мастер, режим 0*/
SPCR = (1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(1<<SPR1)|(0<<SPR0);
SPSR = (0<<SPI2X);
}



void SPI_WriteByte(uint8_t data) { // функция отправки байта
SPI_PORTX &= ~(1<<SPI_SS);
SPDR = data;
while(!(SPSR & (1<<SPIF)));
SPI_PORTX |= (1<<SPI_SS);
}
int data;
int main (void) { // главная функция
DDRD = 0x00; // все выводы порта D сконфигурировать как входы
PORTD = 0xff; // установить "1" на всех выводах порта D,
// включаем подтягивающие резисторы
// бесконечный цикл
// ПРОВЕРЯЕМ СИГНАЛ НИЗКОГО УРОНЯ С КНОПКИ

if (!(PIND & (1<<PIND1))) // проверить "0" на линии 1 порта D
{
data=0x01;
SPI_WriteByte(data);
}
else
{
data=0x02;
SPI_WriteByte(data);
}
}// конец бесконечного цикла
 
 Top
mihail Post Id



Гуру


Сообщений всего: 1065
Дата рег-ции: Март 2010  



Есть хорошая книга: Шпак Ю.А. Программирование на языке C для AVR и PIC микроконтроллеров.
 
 Top
Predator Супермодератор Post Id


Супермодератор


Сообщений всего: 1307
Дата рег-ции: Июль 2012  



а вот тут нет бесконечного цикла:
программа начнет работать со слова main -> попадет в эту функцию со старта.
а там: настроит порт D, попытается отправить что-то по SPI - и ничего из этого не выйдет,
и уйдет в простой (стоять будет).

теперь почему так:
функция SPI_Init - описана, но нигде не вызывается - модуль SPI- не инициализирован.
а того самого бесконечного цикла таки нет.
это могло выглядеть примерно так:
CODE:


void SPI_Init(void)
{
тут всякие настройки модуля SPI
}

void Init_all(void)
{
DDRD = 0x00;
PORTD = 0xff;
SPI_Init(); // вызов инициализации SPI

тут всякие настройки еще могут быть
}

void SPI_WriteByte(uint8_t data)
{ // тут отправка байта
}

void main(void) // а вот эта функция единственная, которая выполняется сама (ну кроме обработчиков прерываний)
{
Init_all(); //вызов настройки всего, настройка SPI- вызовется уже внутри
while(1) // условие которое выполняется всегда- именно оно проверяется на каждом "обороте" и обеспечивает бесконечность цикла
{
SPI_WriteByte(0x02); // действие, которое будет выполняться на каждом "обороте"
}
}



админам на заметку: форматирование теряется....

(Отредактировано автором: 09 Января, 2015 - 19:22:26)

 
 Top
поручик Post Id


Рядовой


Сообщений всего: 4
Дата рег-ции: Янв. 2015  



Спасибо всем, с winavr так и не разобрался, полез в кодевижн и неожиданно получилось передать и принять). Пытаюсь адаптировать схему робота из примера под радиоуправление... Никто случайно не пробовал подсоединять компас от ардуины к роботу в качестве датчика направления без самой ардуины?
 
 Top
morokoriss Post Id



Генералиссимус


Сообщений всего: 697
Дата рег-ции: Нояб. 2011  



Оставь эту затею. Компас, по крайней мере который я встречал, передаёт данные по I2C. Для робота без дуньки понять то, что он присылает как для тебя читать на ассемблере. Без дуины можно в принципе, но только с STM например)
 
 Top
Страниц (1): [1]
« С чего начать? »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 





Powered by Exclusive Bulletin Board
ExBB FM 1.0 RC1 Smiles by Fool from Foolstown
  Яндекс.Метрика   Рейтинг@Mail.ru