Форум myROBOT.ru » Шаг за шагом » С чего начать? » Управление роботом через RF-модуль

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

1. поручик - 08 Января, 2015 - 14:47:22 - перейти к сообщению
Доброго времени суток! Строю робота. Роботов, приведённых в примерах, уже собрал, всё работает... Задумка вкратце такова: используя встроенный SPI в атмега8, обеспечить простейшее дискретное радиоуправление. Принцип в целом понятен, т.е, записываем байт с управляющим кодом, на месте его читаем и сравниваем... Для простоты пока чисто на проводах, без радиомодуля. В Сети нашел примеры для CVavr... Но. Хотелось бы как-то решить проблему на winavr10, всё-таки единственная среда, в которой хоть какие-то навыки... Раньше с МК не работал вообще, с железом опыт достаточно большой. Даже пропорционалку из известной книги господина Миля собирал). Прошу показать пример кода работы с SPI, желательно с пояснениями для чайников)).
2. SlavikMIPT - 08 Января, 2015 - 18:07:19 - перейти к сообщению
uart + bluetooth какой нить мейнстримовый типа hc-06
4. поручик - 08 Января, 2015 - 21:14:12 - перейти к сообщению
Спасибо! Попытался собрать код, компилятор, естественно, ругается)
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;
}

}
5. Механик - 09 Января, 2015 - 08:31:12 - перейти к сообщению
поручик пишет:
Подскажите, плиз, что не так?

Бесконечный цикл должен находится в теле функции 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);
}
}// конец бесконечного цикла

так вроде должно заработать.
(Добавление)
А ну ещё оставить нужно функцию инициализации, макросы, библиотеки(как раньше)
6. поручик - 09 Января, 2015 - 13:10:19 - перейти к сообщению
Спасибо! В таком виде выдал ошибки, возможно, из-за наличия двух бесконечных циклов? Их вообще может быть несколько без прерываний? Вот в таком виде компилируется, сейчас засуну в протеус...
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);
}
}// конец бесконечного цикла
7. mihail - 09 Января, 2015 - 13:19:11 - перейти к сообщению
Есть хорошая книга: Шпак Ю.А. Программирование на языке C для AVR и PIC микроконтроллеров.
8. Predator - 09 Января, 2015 - 19:21:25 - перейти к сообщению
а вот тут нет бесконечного цикла:
программа начнет работать со слова 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); // действие, которое будет выполняться на каждом "обороте"
}
}



админам на заметку: форматирование теряется....
9. поручик - 09 Января, 2015 - 22:38:49 - перейти к сообщению
Спасибо всем, с winavr так и не разобрался, полез в кодевижн и неожиданно получилось передать и принять). Пытаюсь адаптировать схему робота из примера под радиоуправление... Никто случайно не пробовал подсоединять компас от ардуины к роботу в качестве датчика направления без самой ардуины?
10. morokoriss - 11 Января, 2015 - 21:36:22 - перейти к сообщению
Оставь эту затею. Компас, по крайней мере который я встречал, передаёт данные по I2C. Для робота без дуньки понять то, что он присылает как для тебя читать на ассемблере. Без дуины можно в принципе, но только с STM например)