вот и решил попросить помощи на своем любимом сайте mega8 и nrf24l01 в codevision
- Vladcom
- Родился
- Сообщения: 10
- Зарегистрирован: Вс мар 24, 2013 17:06:02
- Откуда: Краснодарский край Староминская
mega8 и nrf24l01 в codevision
Всех с наступающим Новым годом! Прошу помощи
Я осваиваю codevision и застрял на spi а конкретнее на модуле nrf24l01 приобрел у косоглазых за шапку сухарей. Теперь ближе к телу имеется две меги8, два модуля и codevisin управлять надо гаражом открывать закрывать. Может у кого есть заготовки программы или конкретные решения очень прошу поделиться желательно с описанием. Гугл почемуто по этому поводу молчит
вот и решил попросить помощи на своем любимом сайте 
вот и решил попросить помощи на своем любимом сайте AVRМУЧИТЕЛЬ
- Vladcom
- Родился
- Сообщения: 10
- Зарегистрирован: Вс мар 24, 2013 17:06:02
- Откуда: Краснодарский край Староминская
Re: mega8 и nrf24l01 в codevision
Огромное спасибо дорогие коты за отклик но дело в том что многие из ваших ссылок я посещал конкретного под codevision я не нашел. Электроникой я занимаюсь очень давно а вот с написанием программ недавно, в далеком прошлом учил СИ и исходя из этого выбрал среду разработки codevision хотя понял что это далеко не лучший выбор
понравилась эта ссылка http://avrproject.ru/publ/kak_podkljuch ... 1/2-1-0-92 она ближе к моей теме но как я понимаю исходник написан на бэйсике а я от него далек. хотелось бы более конкретного в codevision
AVRМУЧИТЕЛЬ
- BCluster
- Собутыльник Кота
- Сообщения: 2512
- Зарегистрирован: Пн апр 06, 2009 19:33:29
- Откуда: Молдова, Кишинев
- Контактная информация:
Re: mega8 и nrf24l01 в codevision
какая разница какой компилятор? И любая из ссылок подходит. Если там код на Си. Какая разница что делает устройство? У вас логика работы простая как две копейки, основная трудность это разобраться с протоколом работы модулей. А это есть в любом проекте на них. Так что я не совсем понимаю в чем вопрос.
https://github.com/kehribar/nrf24L01_plus тут например есть библиотеки. Но по мне проще из готового проекта вытащить
https://github.com/kehribar/nrf24L01_plus тут например есть библиотеки. Но по мне проще из готового проекта вытащить
- Vladcom
- Родился
- Сообщения: 10
- Зарегистрирован: Вс мар 24, 2013 17:06:02
- Откуда: Краснодарский край Староминская
Re: mega8 и nrf24l01 в codevision
Ну вот, то что нужно!!! Огромное спасибо за ссылку github.com/kehribar/nrf24L01_plus зашел а там у автора ссылка на буржуйский сайт на котором и библиотека и примеры на си http://www.tinkerer.eu/AVRLib/nRF24L01
ща буду пробовать 

AVRМУЧИТЕЛЬ
- belyay
- Потрогал лапой паяльник
- Сообщения: 327
- Зарегистрирован: Пн авг 25, 2008 10:24:51
- Откуда: Россия, Магадан
Re: mega8 и nrf24l01 в codevision
Vladcom писал(а):Ну вот, то что нужно!!! Огромное спасибо за ссылку github.com/kehribar/nrf24L01_plus зашел а там у автора ссылка на буржуйский сайт на котором и библиотека и примеры на си http://www.tinkerer.eu/AVRLib/nRF24L01ща буду пробовать
Доброго дня, получилось подружить модули с CVAVR?
-
White_Leo
- Родился
- Сообщения: 11
- Зарегистрирован: Чт мар 26, 2009 00:25:02
- Откуда: Воронеж
- Контактная информация:
Re: mega8 и nrf24l01 в codevision
belyay писал(а):Vladcom писал(а):Ну вот, то что нужно!!! Огромное спасибо за ссылку github.com/kehribar/nrf24L01_plus зашел а там у автора ссылка на буржуйский сайт на котором и библиотека и примеры на си http://www.tinkerer.eu/AVRLib/nRF24L01ща буду пробовать
Доброго дня, получилось подружить модули с CVAVR?
а в чем проблема? там вроде все просто...
вот кусок кода:
Спойлер
Код: Выделить всё
//1-2. Питание, от 1.9 до 3.6В, не более (рекомендуется 3В)!
//однако на другие пины можно подавать до 5.25В (in datasheet we trust).
//3.CE: Chip Enable. Зависит от режима работы.
//Если чип сконфигурен как приемник, то высокий (HIGH)
//уровень на CE позволяет чипу мониторить среду и получать пакеты.
//Низкий (LOW) уровень переводит чип в Standby-I и такая
//возможность становится уже недоступна. Если чип настроен на
//передачу, CE всегда держится на низком уровне.
//В этом случае для передачи данных нужно положить их в
//очередь FIFO и дернуть CE минимум на 10мкс (LOW->HIGH, 10мкс, HIGH->LOW).
#define NRF_CE PORTD.4
//4. CSN. Chip Select Not. Not, потому что активный уровень - низкий.
//Пин всегда держится на высоком уровне, переводим на низкий уровень
//для начала общения между чипом и МК по SPI. Когда пообщались -
//снова возвращаем на высокий уровень.
#define NRF_CSN PORTC.3
//5. SCK. Стробирующий сигнал SPI. Дежурный уровень - LOW.
//Переход L->H говорит чипу что можно читать бит с MOSI и
//писать на MISO. nRF24 - SLAVE устройство. Оно никогда не
//инициирует связь с МК само, строб-сигнал SCK генерирует именно МК.
#define NRF_SCK PORTB.5
//6-7. MOSI+MISO. Собственно линии дуплексной передачи данных
//от чипа к МК и обратно. Когда МК вывел новый бит на линию MOSI
// и/или считал бит с MISO, он может дергать SCK, чтобы дать
// понять чипу, что он может читать/писать следующий бит.
#define NRF_MOSI PORTB.3
#define NRF_MISO PORTB.4
//8. IRQ. Interrupt Pin. Дежурный уровень - высокий.
//Пин полезно мониторить со стороны МК, дабы понять
//, не случилось ли чего интересного, например новый пакет
// пришел (прерывания настраиваются в чипе по SPI).
// Активный уровень - низкий. Когда случается прерывание -
// читаем статусный регистр и смотрим, что случилось. Всего прерываний три.
#define NRF_IRQ PORTD.2
#define NRF_CONFIG 0x00
#define NRF_STATUS 0x07
void NRF_INIT(void)
{
NRF_CSN=1;//дежурный режим
NRF_CE=0;
}
void NRF_STATUS(void)
{
NRF_CSN=0;
SPDR = NRF_STATUS;
while(!(SPSR & (1<<7)));//отправил
while(!(SPSR & (1<<7)));//прочитал
uart=SPDR;
}а с режимами придется самому поэкспериментировать.
Re: mega8 и nrf24l01 в codevision
Доброго времени суток, уважаемые Коты. Прошу вас помочь неофиту. Электроникой я занимаюсь более десяти лет, но так сложилось, что необходимость освоения микроконтроллеров, и, как следствие, программирования, возникла недавно. Поэтому заранее прошу простить мою дремучесть. Пишу в CVAVR - ибо только там пока что-то понял). Имеется отлаженный код, позволяющий общаться двум Атмега 8 по проводам. Вопрос такой: если использовать модули nrf24l01, просто подключив их к соответствующим выводам SPI и тупо подам на управляющие входы уровни в одном случае для приёмника, в другом - для передатчика (менять местами мастера и слейвов не надо - связь односторонняя), без дополнительных изменений в коде, для передачи одного байта, возможно? Или обязательно отдельно как-то общаться с регистрами самого радиомодуля? Под CVAVR примеров нигде нет, а без них пока ничего не могу, увы... Если несложно, подскажите плиз)
-
Jonson1974
- Открыл глаза
- Сообщения: 55
- Зарегистрирован: Сб мар 30, 2013 19:59:37
Re: mega8 и nrf24l01 в codevision
Не совсем понятна фраза:
В радиомодуле NRF24L01 нет управляющих входов. Он управляется настройкой внутренних регистров и подачей соотв. команд. Т.е. если Вы просто в разрыв линии связи двух Атмег (они общаются по SPI я правильно понял?) воткнете 2 радиомодуля - работать, конечно, ничего не будет. Нужно переписывать исходники.
корнет писал(а):... если использовать модули nrf24l01, просто подключив их к соответствующим выводам SPI и тупо подам на управляющие входы уровни в одном случае для приёмника, в другом - для передатчика ....
В радиомодуле NRF24L01 нет управляющих входов. Он управляется настройкой внутренних регистров и подачей соотв. команд. Т.е. если Вы просто в разрыв линии связи двух Атмег (они общаются по SPI я правильно понял?) воткнете 2 радиомодуля - работать, конечно, ничего не будет. Нужно переписывать исходники.
Re: mega8 и nrf24l01 в codevision
Jonson1974 писал(а):Не совсем понятна фраза:корнет писал(а):... если использовать модули nrf24l01, просто подключив их к соответствующим выводам SPI и тупо подам на управляющие входы уровни в одном случае для приёмника, в другом - для передатчика ....
В радиомодуле NRF24L01 нет управляющих входов. Он управляется настройкой внутренних регистров и подачей соотв. команд. Т.е. если Вы просто в разрыв линии связи двух Атмег (они общаются по SPI я правильно понял?) воткнете 2 радиомодуля - работать, конечно, ничего не будет. Нужно переписывать исходники.
Спасибо). Не подскажете, есть где-нибудь библиотеки именно под кодевижн? Не хотелось бы всё писать с нуля(
-
Jonson1974
- Открыл глаза
- Сообщения: 55
- Зарегистрирован: Сб мар 30, 2013 19:59:37
Re: mega8 и nrf24l01 в codevision
Я пишу код под Atmel Studio. Но, когда разбирался с этим модулем, за основу брал код из проекта под CodeVision. Где брал, естественно уже не помню.
Re: mega8 и nrf24l01 в codevision
Фу ты блин, так и хочется сказать ну ёлы палы, чего все кинулись искать библиотеки для NRF24L01, достаточно понять одно, что модуль NRF24L01 работает по ISP, и вам нужна одна библиотека а именно ISP даже если её нет она проста как дважды два. Достаточно понять как настроить модуль NRF24L01, а именно какие регистры за что отвечают, это всё что вам не обходимо чтобы заставить его работать.
Наипростейший пример, кстати в даташите всё описано
Быстрый старт
Вот в принцепе в кратце осветил быстрый старт для чипа NRF24L01, хотя об этом уже много кто писал
Удалось мне разобраться благодаря имено вот этой странице
Наипростейший пример, кстати в даташите всё описано
Быстрый старт
Спойлер
Код: Выделить всё
Настройка приёмника:
CSN = 0;
//выдаём адрес регистра пишем новое
//который хотим изменить значение в регистр
SPI1_Write(0x20); SPI1_Write(0b00001011); // включаем чип, работаем на приём
CSN = 1;
Delay_ms(1); //тайминги не помню наверное можно и меньше
CSN = 0;
SPI1_Write(0x31); SPI1_Write(0x01); //принимаем по одному байту
//в принципе не обязательно менять но тогда прерывания на ноге IRQ
//не будет после приёма пакета размером в один байт
CSN = 1;
CE = 1;//с этого момента приёмник готов к приёму
//теперь только остаётся ждать преравания на ноге IRQ или просто
//читать данные в цикле на предмет не изменилось ли чего
CSN = 0;//читаем данные с регистра 0x61, всё что принял кладёт сюда
SPI1_Write(0x61); text=SPI1_Read(temp); //чтение пакета
CSN = 1;
CSN = 0;
SPI1_Write(0x27); SPI1_Write(0x40); //снять прерывание
// в принцепе не обязательно, особенно если IRQ ногу вообще
//не планируешь использовать
CSN = 1;
настройка передатчика:
Chip_Select = 0;
Soft_SPI_Write(0xA0); Soft_SPI_Write(value); //пишем значение которое передадим
Chip_Select = 1;
Delay_us(50);
Chip_Select = 0;
Soft_SPI_Write(0x20); Soft_SPI_Write(0b00001010); //включение чипа, режим передачи
Chip_Select = 1;
Delay_us(50);
CE=1; //отправка пакета
Delay_us(50);
CE=0;
Delay_ms(1);
Chip_Select = 0;
Soft_SPI_Write(0x20); Soft_SPI_Write(0b00001000); //перевод чипа в слип режим
Chip_Select = 1;//необходимо при питании от батарейки
Вот в принцепе в кратце осветил быстрый старт для чипа NRF24L01, хотя об этом уже много кто писал
Удалось мне разобраться благодаря имено вот этой странице
Re: mega8 и nrf24l01 в codevision
Господа, все тему читают, хоть бы кто отписался, получилось у кого нибуть, помогла кому нибуть моя справка? 

- messaf
- Родился
- Сообщения: 7
- Зарегистрирован: Сб июл 12, 2014 02:46:53
- Откуда: Хабаровский край г. Комсомольск-на-Амуре
Re: mega8 и nrf24l01 в codevision
alex_ писал(а):Господа, все тему читают, хоть бы кто отписался, получилось у кого нибуть, помогла кому нибуть моя справка?
У меня получилось завести эти модули с помощью Atmel Studio 6.2 двух atmega8 и библиотеки https://github.com/kehribar/nrf24L01_plus.
Могу поделиться если нужно.
Re: mega8 и nrf24l01 в codevision
Все пишут легко и просто, куча инфы, а по факту нигде нет архива с работающим кодом. В основной массе примеров все завязано совместно с UART. Но если он не нужен?? Нужно просто радиокнопку сделать, понять принцип работы.
Re: mega8 и nrf24l01 в codevision
А как на счёт поднять голову и прочитать пост например от Пн янв 19, 2015 13:02:56 
Re: mega8 и nrf24l01 в codevision
Это кусок чего-то, и оно не работает.
Например передача, нету контроля IRQ, то есть железке пофиг есть в разъеме модуль nRF или нету. Добавил контроль IRQ, так вот он не падает в ноль после описанных в примере действий.
Выкладываю код на AVR Studio 4. SPI рабочий, проверялся отдельно.
А это приемник:
Не работает. Помогите, пожалуйста.
Надо как-то указывать канал передачи для модуля?
Например передача, нету контроля IRQ, то есть железке пофиг есть в разъеме модуль nRF или нету. Добавил контроль IRQ, так вот он не падает в ноль после описанных в примере действий.
Выкладываю код на AVR Studio 4. SPI рабочий, проверялся отдельно.
Код: Выделить всё
//#define F_CPU 8000000UL // Тактовая частота микроконтроллера
// Подключаю стандартные библиотеки
#include <avr/io.h> // Ножки ввода-вывода
#include <util/delay.h> // Задержки
#include <avr/interrupt.h> // Прерывания
#include <avr/eeprom.h>
#define MISO 4
#define MOSI 3
#define SCK 5
#define SS 2
#define CE 1
#define IRQ 0
char RX_DR,TX_DS,MAX_RT;
//RX_DR 6 /*прерывание: данные получены. Для сброса записать 1.*/
//TX_DS 5 /*прерывание: данные переданы. Для сброса записать 1.*/
//MAX_RT 4 /*прерывание: данные не переданы. Для сброса записать 1.*/
//--------SPI---------------------------------------------------------------------------
/*
1. установка низкого логического уровня на линии SS
2. загрузка данных в регистр SPDR
3. ожидание окончания передачи (проверка флага SPIF)
4. сохранение принятых данных (чтение SPDR), если требуется
5. возврат на 2-ой шаг, если переданы не все данные
6. установка высокого логического уровня на линии SS
*/
void SPI_MasterInit(void)
{
DDRB = (1<<MOSI)|(1<<SCK)|(1<<SS); ///Set MOSI,SS and SCK output, MISO input
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);// Enable SPI, Master, set clock rate fck/16
}
void SPI_SlaveInit(void)
{
DDRB = (1<<MISO); // Set MISO output, all others input
SPCR = (1<<SPE); // Enable SPI
}
void WriteByte(char data)
{
PORTB &= ~(1<<SS);
SPDR = data; // Start transmission
while(!(SPSR & (1<<SPIF))); // Wait for transmission complete
PORTB |= (1<<SS);
}
char ReadByte(void)
{
while(!(SPSR & (1<<SPIF)));// Wait for reception complete
return SPDR; // Return data register
}
//----------
//----------
void transmit(void)
{
PORTB&=~(1<<SS);
WriteByte(0xA0); WriteByte(0x55); //пишем значение которое передадим
PORTB|= (1<<SS);
_delay_us(50);
WriteByte(0x20); WriteByte(0b00001010);//включение чипа, режим передачи
PORTB|= (1<<SS);
_delay_us(50);
PORTB|= (1<<CE);//отправка пакета
_delay_us(50);
PORTB&=~(1<<CE);
_delay_us(135);
while ((PINB & (1<<IRQ)) != 0);//Ждем пока байт не передан
WriteByte(0x04); ReadByte(); MAX_RT=SPDR;
WriteByte(0x05); ReadByte(); TX_DS =SPDR;
WriteByte(0x06); ReadByte(); RX_DR =SPDR;
if(MAX_RT==1)
{
WriteByte(0x04); WriteByte(0x01);
}
if(TX_DS==1)
{
WriteByte(0x05); WriteByte(0x01);
}
if(RX_DR==1)
{
WriteByte(0x06); WriteByte(0x01);
}
PORTD&=~(1<<7); //индикатор
}
/*
настройка передатчика:
Chip_Select = 0;
Soft_SPI_Write(0xA0); Soft_SPI_Write(value); //пишем значение которое передадим
Chip_Select = 1;
Delay_us(50);
Chip_Select = 0;
Soft_SPI_Write(0x20); Soft_SPI_Write(0b00001010); //включение чипа, режим передачи
Chip_Select = 1;
Delay_us(50);
CE=1; //отправка пакета
Delay_us(50);
CE=0;
Delay_ms(1);
Chip_Select = 0;
Soft_SPI_Write(0x20); Soft_SPI_Write(0b00001000); //перевод чипа в слип режим
Chip_Select = 1;//необходимо при питании от батарейки
----------
Настройка приёмника:
CSN = 0;
//выдаём адрес регистра пишем новое
//который хотим изменить значение в регистр
SPI1_Write(0x20); SPI1_Write(0b00001011); // включаем чип, работаем на приём
CSN = 1;
Delay_ms(1); //тайминги не помню наверное можно и меньше
CSN = 0;
SPI1_Write(0x31); SPI1_Write(0x01); //принимаем по одному байту
//в принципе не обязательно менять но тогда прерывания на ноге IRQ
//не будет после приёма пакета размером в один байт
CSN = 1;
CE = 1;//с этого момента приёмник готов к приёму
//теперь только остаётся ждать преравания на ноге IRQ или просто
//читать данные в цикле на предмет не изменилось ли чего
CSN = 0;//читаем данные с регистра 0x61, всё что принял кладёт сюда
SPI1_Write(0x61); text=SPI1_Read(temp); //чтение пакета
CSN = 1;
CSN = 0;
SPI1_Write(0x27); SPI1_Write(0x40); //снять прерывание
// в принцепе не обязательно, особенно если IRQ ногу вообще
//не планируешь использовать
CSN = 1;
*/
//----------
int main (void)
{
DDRD=(1<<7); //диод индикации
PORTC=(1<<2); //подтяжка к питанию
//--------SPI---------
SPI_MasterInit();
//----------
while(1)
{
while (!(PINC&(1<<2))); // работаем по размыканию кнопки на землю
PORTD|=(1<<7); //индикатор
transmit();
while(1);
}
}
А это приемник:
Код: Выделить всё
//#define F_CPU 8000000UL // Тактовая частота микроконтроллера
// Подключаю стандартные библиотеки
#include <avr/io.h> // Ножки ввода-вывода
#include <util/delay.h> // Задержки
#include <avr/interrupt.h> // Прерывания
#include <avr/eeprom.h>
#define MISO 4
#define MOSI 3
#define SCK 5
#define SS 2
#define CE 1
#define IRQ 0
char RX_DR,TX_DS,MAX_RT;
char text;
//RX_DR 6 /*прерывание: данные получены. Для сброса записать 1.*/
//TX_DS 5 /*прерывание: данные переданы. Для сброса записать 1.*/
//MAX_RT 4 /*прерывание: данные не переданы. Для сброса записать 1.*/
//--------SPI---------------------------------------------------------------------------
/*
1. установка низкого логического уровня на линии SS
2. загрузка данных в регистр SPDR
3. ожидание окончания передачи (проверка флага SPIF)
4. сохранение принятых данных (чтение SPDR), если требуется
5. возврат на 2-ой шаг, если переданы не все данные
6. установка высокого логического уровня на линии SS
*/
void SPI_MasterInit(void)
{
DDRB = (1<<MOSI)|(1<<SCK)|(1<<SS); ///Set MOSI,SS and SCK output, MISO input
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);// Enable SPI, Master, set clock rate fck/16
}
void SPI_SlaveInit(void)
{
DDRB = (1<<MISO); // Set MISO output, all others input
SPCR = (1<<SPE); // Enable SPI
}
void WriteByte(char data)
{
PORTB &= ~(1<<SS);
SPDR = data; // Start transmission
while(!(SPSR & (1<<SPIF))); // Wait for transmission complete
PORTB |= (1<<SS);
}
char ReadByte(void)
{
while(!(SPSR & (1<<SPIF)));// Wait for reception complete
return SPDR; // Return data register
}
//----------
//----------
void receive(void)
{
PORTB&=~(1<<SS);
WriteByte(0x20); WriteByte(0b00001011); // включаем чип, работаем на приём
PORTB|= (1<<SS);
_delay_ms(1);
PORTB&=~(1<<SS);
WriteByte(0x31); WriteByte(0x01); //принимаем по одному байту
PORTB|= (1<<SS);
PORTB|= (1<<CE); //с этого момента приёмник готов к приёму
while ((PINB & (1<<IRQ)) != 0);//Ждем прерывание
PORTB&=~(1<<SS);//читаем данные с регистра 0x61, всё что принял кладёт сюда
WriteByte(0x61); ReadByte(); text=SPDR;
PORTB|= (1<<SS);
PORTB&=~(1<<SS);
WriteByte(0x27); WriteByte(0x40); //снять прерывание
PORTB|= (1<<SS);
}
/*
Настройка приёмника:
CSN = 0;
//выдаём адрес регистра пишем новое
//который хотим изменить значение в регистр
SPI1_Write(0x20); SPI1_Write(0b00001011); // включаем чип, работаем на приём
CSN = 1;
Delay_ms(1); //тайминги не помню наверное можно и меньше
CSN = 0;
SPI1_Write(0x31); SPI1_Write(0x01); //принимаем по одному байту
//в принципе не обязательно менять но тогда прерывания на ноге IRQ
//не будет после приёма пакета размером в один байт
CSN = 1;
CE = 1;//с этого момента приёмник готов к приёму
//теперь только остаётся ждать преравания на ноге IRQ или просто
//читать данные в цикле на предмет не изменилось ли чего
CSN = 0;//читаем данные с регистра 0x61, всё что принял кладёт сюда
SPI1_Write(0x61); text=SPI1_Read(temp); //чтение пакета
CSN = 1;
CSN = 0;
SPI1_Write(0x27); SPI1_Write(0x40); //снять прерывание
// в принцепе не обязательно, особенно если IRQ ногу вообще
//не планируешь использовать
CSN = 1;
----------
настройка передатчика:
Chip_Select = 0;
Soft_SPI_Write(0xA0); Soft_SPI_Write(value); //пишем значение которое передадим
Chip_Select = 1;
Delay_us(50);
Chip_Select = 0;
Soft_SPI_Write(0x20); Soft_SPI_Write(0b00001010); //включение чипа, режим передачи
Chip_Select = 1;
Delay_us(50);
CE=1; //отправка пакета
Delay_us(50);
CE=0;
Delay_ms(1);
Chip_Select = 0;
Soft_SPI_Write(0x20); Soft_SPI_Write(0b00001000); //перевод чипа в слип режим
Chip_Select = 1;//необходимо при питании от батарейки
----------
*/
//----------
int main (void)
{
DDRD=(1<<7); //диод индикации
PORTC=(1<<2); //подтяжка к питанию
//--------SPI---------
SPI_MasterInit();
//----------
while(1)
{
while (!(PINC&(1<<2))); // работаем по размыканию кнопки на землю
receive();
if(text==0x55) PORTD|=(1<<7);
_delay_ms(100);
}
}
Не работает. Помогите, пожалуйста.
Надо как-то указывать канал передачи для модуля?
- Вложения
-
- IMG_20180201_161435.jpg
- Вот две одинаковых платы. Передатчик и приемник. В одном случае диод индикатор отправки. В другом - приема.
- (221.31 КБ) 303 скачивания
Re: mega8 и nrf24l01 в codevision
Скажу сразу я в codevision и AVR студии не писал поэтому некоторые моменты с моей точки зрения могут выглядеть как ошибка но сточки зрения этих компиляторов возможно не являться ошибкой.
Передатчик
Приёмник
Ну и ещё бывает проблема даже не в настройке модуля а в не правильном подключении, ну или проводок где нибудь отвалился или контакт плохой, для начала попробуй считать содержание регистров модуля, если он выплюнет одни нули то надо будет сначала с этим разбираться, тут косяк или в подключении или модуль не рабочий. Далее если данные с модуля читаются, уже пробовать передавать и принимать.
Для начала можно просто взять один модуль и попытаться передавать в пустоту при этом будет срабатывать MAX_RT.
Передатчик
Спойлер
Код: Выделить всё
//#define F_CPU 8000000UL // Тактовая частота микроконтроллера
// Подключаю стандартные библиотеки
#include <avr/io.h> // Ножки ввода-вывода
#include <util/delay.h> // Задержки
#include <avr/interrupt.h> // Прерывания
#include <avr/eeprom.h>
#define MISO 4
#define MOSI 3
#define SCK 5
#define SS 2
#define CE 1
#define IRQ 0
char RX_DR,TX_DS,MAX_RT;
//RX_DR 6 /*прерывание: данные получены. Для сброса записать 1.*/
//TX_DS 5 /*прерывание: данные переданы. Для сброса записать 1.*/
//MAX_RT 4 /*прерывание: данные не переданы. Для сброса записать 1.*/
//--------SPI---------------------------------------------------------------------------
/*
1. установка низкого логического уровня на линии SS
2. загрузка данных в регистр SPDR
3. ожидание окончания передачи (проверка флага SPIF)
4. сохранение принятых данных (чтение SPDR), если требуется
5. возврат на 2-ой шаг, если переданы не все данные
6. установка высокого логического уровня на линии SS
*/
void SPI_MasterInit(void)
{
DDRB = (1<<MOSI)|(1<<SCK)|(1<<SS); ///Set MOSI,SS and SCK output, MISO input
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);// Enable SPI, Master, set clock rate fck/16
}
void SPI_SlaveInit(void)
{
DDRB = (1<<MISO); // Set MISO output, all others input
SPCR = (1<<SPE); // Enable SPI
}
void WriteByte(char data)
{
PORTB &= ~(1<<SS);
SPDR = data; // Start transmission
while(!(SPSR & (1<<SPIF))); // Wait for transmission complete
PORTB |= (1<<SS);
}
char ReadByte(void)
{
while(!(SPSR & (1<<SPIF)));// Wait for reception complete
return SPDR; // Return data register
}
//----------
//----------
void transmit(void)
{
PORTB&=~(1<<SS);
WriteByte(0xA0); WriteByte(0x55); //пишем значение которое передадим
PORTB|= (1<<SS);
_delay_us(50);
WriteByte(0x20); WriteByte(0b00001010);//включение чипа, режим передачи
PORTB|= (1<<SS);
_delay_us(50);
PORTB|= (1<<CE);//отправка пакета
_delay_us(50);
PORTB&=~(1<<CE);
_delay_us(135);
while ((PINB & (1<<IRQ)) != 0);//Ждем пока байт не передан
WriteByte(0x04); ReadByte(); MAX_RT=SPDR;
WriteByte(0x05); ReadByte(); TX_DS =SPDR;
WriteByte(0x06); ReadByte(); RX_DR =SPDR;
<-<-<тут если пытаешься сбросить прерывание то надо писать не 0x04 эту команду он просто проигнорит, надо так WriteByte(0x27);WriteByte(0x40);>->->
if(MAX_RT==1)
{
WriteByte(0x04); WriteByte(0x01);
}
if(TX_DS==1)
{
WriteByte(0x05); WriteByte(0x01);
}
if(RX_DR==1)
{
WriteByte(0x06); WriteByte(0x01);
}
PORTD&=~(1<<7); //индикатор
}
//----------
int main (void)
{
DDRD=(1<<7); //диод индикации
PORTC=(1<<2); //подтяжка к питанию
//--------SPI---------
SPI_MasterInit();
//----------
while(1)
{
while (!(PINC&(1<<2))); // работаем по размыканию кнопки на землю <-<-<тут может лучше сделать не по кнопке а по таймеру>->->
PORTD|=(1<<7); //индикатор
transmit();
while(1); <-<-<могу ошибаться но полагаю что из этого цикла контроллер скорее всего уже не выйдет сам>->->
}
}Спойлер
Код: Выделить всё
//#define F_CPU 8000000UL // Тактовая частота микроконтроллера
// Подключаю стандартные библиотеки
#include <avr/io.h> // Ножки ввода-вывода
#include <util/delay.h> // Задержки
#include <avr/interrupt.h> // Прерывания
#include <avr/eeprom.h>
#define MISO 4
#define MOSI 3
#define SCK 5
#define SS 2
#define CE 1
#define IRQ 0
char RX_DR,TX_DS,MAX_RT;
char text;
//RX_DR 6 /*прерывание: данные получены. Для сброса записать 1.*/
//TX_DS 5 /*прерывание: данные переданы. Для сброса записать 1.*/
//MAX_RT 4 /*прерывание: данные не переданы. Для сброса записать 1.*/
//--------SPI---------------------------------------------------------------------------
/*
1. установка низкого логического уровня на линии SS
2. загрузка данных в регистр SPDR
3. ожидание окончания передачи (проверка флага SPIF)
4. сохранение принятых данных (чтение SPDR), если требуется
5. возврат на 2-ой шаг, если переданы не все данные
6. установка высокого логического уровня на линии SS
*/
void SPI_MasterInit(void)
{
DDRB = (1<<MOSI)|(1<<SCK)|(1<<SS); ///Set MOSI,SS and SCK output, MISO input
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);// Enable SPI, Master, set clock rate fck/16
}
void SPI_SlaveInit(void)
{
DDRB = (1<<MISO); // Set MISO output, all others input
SPCR = (1<<SPE); // Enable SPI
}
void WriteByte(char data)
{
PORTB &= ~(1<<SS);
SPDR = data; // Start transmission
while(!(SPSR & (1<<SPIF))); // Wait for transmission complete
PORTB |= (1<<SS);
}
char ReadByte(void)
{
while(!(SPSR & (1<<SPIF)));// Wait for reception complete
return SPDR; // Return data register
}
//----------
//----------
void receive(void)
{
PORTB&=~(1<<SS);
WriteByte(0x20); WriteByte(0b00001011); // включаем чип, работаем на приём
PORTB|= (1<<SS);
_delay_ms(1);
PORTB&=~(1<<SS);
WriteByte(0x31); WriteByte(0x01); //принимаем по одному байту
PORTB|= (1<<SS);
PORTB|= (1<<CE); //с этого момента приёмник готов к приёму
while ((PINB & (1<<IRQ)) != 0);//Ждем прерывание
PORTB&=~(1<<SS);//читаем данные с регистра 0x61, всё что принял кладёт сюда
WriteByte(0x61); ReadByte(); text=SPDR;
PORTB|= (1<<SS);
PORTB&=~(1<<SS);
WriteByte(0x27); WriteByte(0x40); //снять прерывание
PORTB|= (1<<SS);
}
//----------
int main (void)
{
DDRD=(1<<7); //диод индикации
PORTC=(1<<2); //подтяжка к питанию
//--------SPI---------
SPI_MasterInit();
//----------
while(1)
{
while (!(PINC&(1<<2))); // работаем по размыканию кнопки на землю <-<-<Включать приёмник по кнопке в режиме теста, ну это уж лишнее, лучше мониторить IRQ>->->
receive();
if(text==0x55) PORTD|=(1<<7);
_delay_ms(100);
}
}
Ну и ещё бывает проблема даже не в настройке модуля а в не правильном подключении, ну или проводок где нибудь отвалился или контакт плохой, для начала попробуй считать содержание регистров модуля, если он выплюнет одни нули то надо будет сначала с этим разбираться, тут косяк или в подключении или модуль не рабочий. Далее если данные с модуля читаются, уже пробовать передавать и принимать.
Для начала можно просто взять один модуль и попытаться передавать в пустоту при этом будет срабатывать MAX_RT.
Re: mega8 и nrf24l01 в codevision
Привет, Алекс.
Считываю вроде регистр СТАТУС, все три бита в единице. Но после отправки посылки ничего не меняется. Не могу въехатьс методикой выбора регистра и записи инфы в них. Как маску наложить, и где адреса регистров...Вроде статус это 0х07, а конфиг 0х00.
Делаю так, но не выходит пока ничего...Не получается сбросить регистры.
Считываю вроде регистр СТАТУС, все три бита в единице. Но после отправки посылки ничего не меняется. Не могу въехатьс методикой выбора регистра и записи инфы в них. Как маску наложить, и где адреса регистров...Вроде статус это 0х07, а конфиг 0х00.
Делаю так, но не выходит пока ничего...Не получается сбросить регистры.
Код: Выделить всё
WriteByte(0x07); //читаем регистр STATUS
ReadByte(); //читаем регистр STATUS
text=SPDR;
send_Uart(text);
_delay_us(20);
WriteByte(0x27); WriteByte(0b00001110);
_delay_us(20);
WriteByte(0x07); //читаем регистр STATUS
ReadByte();
text=SPDR;
send_Uart(text);