Продолжаю свои потуги в познании мира МК, в наличии имеется: nrf24l01 и atmega16.
Я нашёл код для avr studuio (http://we.easyelectronics.ru/Radio/radiomodul-nrf24l01-bystryy-start.html), но я пишу в Codevision AVR.
Как мог изменил, код, но что-то пошло не так и не компилируются ничего
У меня вот так заняты порты:
IRQ - PB2;
SCN - PB3;
SS - PB4;
Вот "адаптированный" код:
Спойлер
Код: Выделить всё
/*******************************************************
This program was created by the
CodeWizardAVR V3.12 Advanced
Automatic Program Generator
© Copyright 1998-2014 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project :
Version : v2
Date : 1.12.2014
Author :
Company :
Comments:
Chip type : ATmega16A
Program type : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*******************************************************/
#include <mega16a.h>
#include <delay.h>
#include <stdio.h>
#include <io.h>
#include <math.h>
// NRF24L01
//#include <nrf24l01.h>
#include <inttypes.h>
//Функции.
void w_register(unsigned int, unsigned int);
unsigned int r_register(unsigned int);
void prx(void);
void ptx(void);
void send_byte(unsigned int);
//Описание команд
#define R_REGISTER 0x00 //читаем регистр
#define W_REGISTER 0x20 //пишем в регистр
#define R_RX_PAYLOAD 0x61 //считывание из буфера принятых данных из космоса
#define W_TX_PAYLOAD 0xA0 //запись данных в буфер для отправки в космос
#define FLUSH_TX 0xE1 //очистка буфера отправки
#define FLUSH_RX 0xE2 //очистка буфера приема
#define REUSE_TX_PL 0xE3
#define ACTIVATE 0x50
#define R_RX_PL_WID 0x60
#define W_ACK_PAYLOAD 0xA8
#define W_TX_PAYLOAD_NOACK 0x58
#define NOP 0xFF //команда заглушка, ничего не делает.
//Описание регистров nRF24L01
/*регистр CONFIG*/ //Конфигурационный регистр
#define CONFIG 0x00
#define MASK_RX_DR 6 //вкл/откл прерывание от бита RX_DR в рег. STATUS. 0-вкл, 1-выкл.
#define MASK_TX_DS 5 //вкл/откл прерывание от бита TX_DS в рег. STATUS. 0-вкл, 1-выкл.
#define MASK_MAX_RT 4 //вкл/откл прерывание от бита MAX_RT в рег. STATUS. 0-вкл, 1-выкл.
#define EN_CRC 3 //включение CRC. По умолчанию вкл. если один из битов регистра EN_AA включен.
#define CRCO 2 //режим CRC. 0-1 байт, 1-2 байта.
#define PWR_UP 1 //1-POWER UP, 0-POWER DOWN, по умолчанию 0.
#define PRIM_RX 0 //0-режим передачи, 1-режим приема.
/*регистр EN_AA*/
#define EN_AA 0x01
#define ENAA_P5 5
#define ENAA_P4 4
#define ENAA_P3 3
#define ENAA_P2 2
#define ENAA_P1 1
#define ENAA_P0 0
/*регистр EN_RXADDR*/
#define EN_RXADDR 0x02
#define ERX_P5 5
#define ERX_P4 4
#define ERX_P3 3
#define ERX_P2 2
#define ERX_P1 1
#define ERX_P0 0
/*регистр SETUP_AW*/
#define SETUP_AW 0x03
#define AW1 1
#define AW0 0
/*регистр SETUP_RETR*/
#define SETUP_RETR 0x04
#define ARD3 7
#define ARD2 6
#define ARD1 5
#define ARD0 4
#define ARC3 3
#define ARC2 2
#define ARC1 1
#define ARC0 0
/*регистр RF_CH*/
#define RF_CH 0x05
#define RF_CH6 6
#define RF_CH5 5
#define RF_CH4 4
#define RF_CH3 3
#define RF_CH2 2
#define RF_CH1 1
#define RF_CH0 0
/*регистр RF_SETUP*/
#define RF_SETUP 0x06
#define PLL_LOCK 4
#define RF_DR 3
#define RF_PWR1 2
#define RF_PWR0 1
#define LNA_HCURR 0
/*регистр STATUS*/
#define STATUS 0x07
#define RX_DR 6 /*прерывание: данные получены. Для сброса записать 1.*/
#define TX_DS 5 /*прерывание: данные переданы. Для сброса записать 1.*/
#define MAX_RT 4 /*прерывание: данные не переданы. Для сброса записать 1.*/
#define RX_P_NO2 3
#define RX_P_NO1 2
#define RX_P_NO0 1
#define TX_FULL0 0 /*флаг переполнения TX FIFO буфера передачи. 1-переполнен, 0-есть еще место.*/
/*регистр OBSERVE_TX*/
#define OBSERVE_TX 0x08
/*регистр CD*/
#define CD 0x09
/*регистр RX_ADDR_P0*/
#define RX_ADDR_P0 0x0A
/*регистр RX_ADDR_P1*/
#define RX_ADDR_P1 0x0B
/*регистр RX_ADDR_P2*/
#define RX_ADDR_P2 0x0C
/*регистр RX_ADDR_P3*/
#define RX_ADDR_P3 0x0D
/*регистр RX_ADDR_P4*/
#define RX_ADDR_P4 0x0E
/*регистр RX_ADDR_P5*/
#define RX_ADDR_P5 0x0F
/*регистр TX_ADDR*/
#define TX_ADDR 0x10
/*регистр RX_PW_P0*/
#define RX_PW_P0 0x11
/*регистр RX_PW_P1*/
#define RX_PW_P1 0x12
/*регистр RX_PW_P2*/
#define RX_PW_P2 0x13
/*регистр RX_PW_P3*/
#define RX_PW_P3 0x14
/*регистр RX_PW_P4*/
#define RX_PW_P4 0x15
/*регистр RX_PW_P5*/
#define RX_PW_P5 0x16
/*регистр FIFO_STATUS*/
#define FIFO_STATUS 0x17
#define TX_REUSE 6
#define TX_FULL 5
#define TX_EMPTY 4
#define RX_FULL 1
#define RX_EMPTY 0
/*регистр DYNPD*/
#define DYNPD 0x1C
#define DPL_P5 5
#define DPL_P4 4
#define DPL_P3 3
#define DPL_P2 2
#define DPL_P1 1
#define DPL_P0 0
/*регистр FEATURE*/
#define FEATURE 0x1D
#define EN_DPL 2
#define EN_ACK_PAY 1
#define EN_DYN_ACK 0
#define CSN PORTB.3 /*SPI*/
#define SCK PORTB.7 /*SPI*/
#define CE PORTB.4 /*вход-nRf*/
#define IRQ PORTB.2 /*выход прерываний-nRf*/
/***********************************************************
//reg : имя переменной, регистра
//bit : позиция бита
//val : 0 или 1
************************************************************/
#define Bit(bit) (1<<(bit))
#define ClearBit(reg, bit) reg &= (~(1<<(bit)))
//пример: ClearBit(PORTB, 1); //сбросить 1-й бит PORTB
#define SetBit(reg, bit) reg |= (1<<(bit))
//пример: SetBit(PORTB, 3); //установить 3-й бит PORTB
#define SetBitVal(reg, bit, val) do{if ((val&1)==0) reg &= (~(1<<(bit)));\
else reg |= (1<<(bit));}while(0)
//пример: SetBitVal(PORTB, 3, 1); //установить 3-й бит PORTB
// SetBitVal(PORTB, 2, 0); //сбросить 2-й бит PORTB
/***********************************************************/
#define BitIsClear(reg, bit) ((reg & (1<<(bit))) == 0)
//пример: if (BitIsClear(PORTB,1)) {...} //если бит очищен
#define BitIsSet(reg, bit) ((reg & (1<<(bit))) != 0)
//пример: if(BitIsSet(PORTB,2)) {...} //если бит установлен
#define InvBit(reg, bit) reg ^= (1<<(bit))
//пример: InvBit(PORTB, 1); //инвертировать 1-й бит PORTB
// I2C Bus functions
//#include <i2c.h>
// Alphanumeric LCD functions
#include <alcd.h>
char lcd_buffer[33];
// SPI functions
#include <spi.h>
interrupt [SPI_STC] void spi_isr(void)
{
unsigned char data;
data=SPDR;
// тут обработка
}
void main(void)
{
// Declare your local variables here
char u = 'f';
// Input/Output Ports initialization
// Port A initialization
// Function: Bit7=Out Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRA=(1<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);
// Port B initialization
// Function: Bit7=Out Bit6=In Bit5=Out Bit4=Out Bit3=In Bit2=In Bit1=In Bit0=In
DDRB=(1<<DDB7) | (0<<DDB6) | (1<<DDB5) | (1<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=0 Bit6=T Bit5=0 Bit4=0 Bit3=T Bit2=T Bit1=T Bit0=T
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
// Port C initialization
// Function: Bit7=Out Bit6=Out Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out
DDRC=(1<<DDC7) | (1<<DDC6) | (1<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);
// State: Bit7=0 Bit6=0 Bit5=0 Bit4=0 Bit3=0 Bit2=0 Bit1=0 Bit0=0
PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);
// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=Out Bit1=In Bit0=In
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (1<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (1<<CS02) | (1<<CS01) | (0<<CS00);
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (1<<CS12) | (1<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0<<AS2;
TCCR2=(0<<PWM2) | (0<<COM21) | (0<<COM20) | (0<<CTC2) | (1<<CS22) | (1<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (0<<TOIE0);
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
MCUCSR=(0<<ISC2);
// USART initialization
// USART disabled
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (0<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
// ADC initialization
// ADC Clock frequency: 1000,000 kHz
// ADC Voltage Reference: AREF pin
// ADC Auto Trigger Source: Free Running
ADMUX=ADC_VREF_TYPE;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (1<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
SFIOR=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 2000,000 kHz
// SPI Clock Phase: Cycle Start
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR=(0<<SPIE) | (1<<SPE) | (0<<DORD) | (1<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);
SPSR=(0<<SPI2X);
// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);
// Bit-Banged I2C Bus initialization
// I2C Port: PORTC
// I2C SDA bit: 1
// I2C SCL bit: 0
// Bit Rate: 100 kHz
// Note: I2C settings are specified in the
// Project|Configure|C Compiler|Libraries|I2C menu.
//i2c_init();
// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTC Bit 0
// RD - PORTC Bit 1
// EN - PORTD Bit 0
// D4 - PORTD Bit 3
// D5 - PORTD Bit 4
// D6 - PORTD Bit 5
// D7 - PORTD Bit 6
// Characters/line: 16
lcd_init(16);
// Global enable interrupts
#asm("sei")
while (1)
{ // Place your code here
if (BitIsClear(PINC,IRQ))
{
unsigned int a= r_register(STATUS);//прочитали статус регистр
w_register(STATUS, a);//сброс флагов прерываний - обязательно
if (BitIsSet(a,RX_DR))
{
u = r_register(R_RX_PAYLOAD);//чтение 1 байта из буфера приема RX_FIFO в озу buf
}
}
sprintf(lcd_buffer,"Mess = %d", u);
lcd_clear();
lcd_puts(lcd_buffer);
}
}
void w_register(unsigned int a,unsigned int b)//а-адрес регистра, b-что пишем в регистр.
{
a=a | W_REGISTER;
ClearBit(PORTB,CSN);
SPDR=a;
while(BitIsClear(SPSR,SPIF));
if (b==0 && a!=W_TX_PAYLOAD)
{
a=SPDR;//для сброса флага SPIF
SetBit(PORTB,CSN);
return;
}
SPDR=b;
while(BitIsClear(SPSR,SPIF));
a=SPDR;//для сброса флага SPIF
SetBit(PORTB,CSN);
}//W_REGISTER (CONFIG,0b00000110);
unsigned int r_register(unsigned int a)//чтение байта из озу. a-адрес байта
{
ClearBit(PORTB,CSN);//Прижимаем вывод CSN(SS) МК к земле, тем самым сообщаем о начале обмена данных.
SPDR=a;
while(BitIsClear(SPSR,SPIF));//ожидаем когда освободится SPI для последующей записи байта
if (a==STATUS)
{
SetBit(PORTB,CSN);//Вывод CSN(SS) МК к питанию, обмен данных завершен.
return SPDR;
}
SPDR=NOP;
while(BitIsClear(SPSR,SPIF));
SetBit(PORTB,CSN);//Вывод CSN(SS) МК к питанию, обмен данных завершен.
return SPDR;
}//uint8_t a=r_register(EN_AA);
void prx(void)//Настроим nRF на прием.
{
w_register(CONFIG,(1<<PWR_UP)|(1<<EN_CRC)|(1<<PRIM_RX));
SetBit(PORTC,CE);
delay_us(135);
//режим према RX
}
void ptx(void)//Настроим nRF на передачу.
{
ClearBit(PORTC,CE);
w_register(CONFIG,(1<<PWR_UP)|(1<<EN_CRC)|(0<<PRIM_RX));
SetBit(PORTC,CE);
delay_us(15);
ClearBit(PORTC,CE);
delay_us(135);
}
void send_byte(unsigned int a)//отправка байта.
{
w_register(W_TX_PAYLOAD,a);//запись байта в буфер TX для отправки
ptx();//передача байта
while (BitIsSet(PINC,IRQ));//Ждем пока байт не передан
unsigned int b= r_register(STATUS);//прочитали статус регистр
w_register(STATUS, b);//сброс флагов прерываний - обязательно
prx();//на прием
}