📄 main.c
字号:
//------------------------
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <compat/twi.h>
#include <avr/delay.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
//------------------------
//宏定义
#define fosc 7372800 //晶振7.3728MHZ
#define baud 9600 //波特率
//nrf905
#define CONTROL_PORT PORTD
#define CONTROL_DDR DDRD
#define CONTROL_PIN PIND
#define TRX_CE PD6
#define TXEN PD5
#define PWR_UP PD7
//#define AM PD1 //INT1
//#define CD PD2 //INT2
#define DR PD2 //INT0
#define CSN PD4
unsigned char tx_data_buf[32]; //发送缓冲区
unsigned char rx_data_buf[32]; //接收缓冲区
unsigned char xxx[10]; //配置RF寄存器的数据缓冲区
//地址寄存器
const unsigned char tx_address_reg_buf[4]={
0xa5, //TX_ADDRESS_BYTE0=RX_ADDRESS_BYTE0
0xb5, //TX_ADDRESS_BYTE1=RX_ADDRESS_BYTE1
0xc5, //TX_ADDRESS_BYTE2=RX_ADDRESS_BYTE2
0xd5, //TX_ADDRESS_BYTE3=RX_ADDRESS_BYTE3
};
//配置寄存器为10个字节
//芯片上电后初始化值为6C 00 44 20 20 E7 E7 E7 E7 E7
//DATASHEET P20
const unsigned char config_reg_buf[10]={
0x4c,//0b01001100, //CH_NO[7:0]=76,RFfreq=422.4+76/10=430MHZ
0x00,//0b00000000, //bit[7:6]:notused /bit5:AUTO_RETRAN=’0’
//bit4:RX_RED_PWR=’0’/bit[3:2]:PA_PWR=’00’-10dBm
//bit1:HFREQ_PLL=0, PLL=433MHZ /bit0:CH_NO[8]=’0’
0x44,//0b01000100, //bit7:not used/bit[6:4]:TX_AFW=’100’4Bytes
//bit3:not used/bit[2:0]:RX_AFW=’100’4Bytes
0x20,//0b00100000, //bit[7:6]:not use /bit[5:0]:RX_PW=’100000'32Bytes
0x20,//0b00100000, //bit[7:6]not use /bit[5:0]TX_PW=’100000’32Bytes
0xa5, //RX_ADDRESS_BYTE0=TX_ADDRESS_BYTE0
0xb5, //RX_ADDRESS_BYTE1=TX_ADDRESS_BYTE1
0xc5, //RX_ADDRESS_BYTE2=TX_ADDRESS_BYTE2
0xd5, //RX_ADDRESS_BYTE3=TX_ADDRESS_BYTE3
0xce //0b11001110 //bit7:CRC_MODE=’1’CRC16 /bit6:CRC_EN=’1’ CRC Enable
//bit[5:3]:XOF=’011’8MHZ /bit[2]UP_CLK_EN=’1’ Enable
//bit[1:0]:UP_CLK_FRE=’11’ 500KHZ
};
volatile unsigned char re_ok=0;
void delay_1us(void);
void delay_nus(unsigned int n);
void delay_1ms(void);
void delay_nms(unsigned int n);
//------------------------
void port_init(void)
{
//所有端口设为输入,所有端口的上拉电阻有效
//所有端口输出为高电平
// PortB
PORTB = 0xff;
DDRB = 0x00;
// PortC
PORTC = 0xff;
DDRC = 0x00;
// PortD
PORTD = 0xff;
DDRD = 0x00;
}
/*---------------UART0初始化----------------*/
void uart_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = (1<<URSEL )| 0x06; //URSEL=1时才能写UCSRC,8位
UBRRL=(fosc/16/(baud+1))%256;
UBRRH=(fosc/16/(baud+1))/256;
UCSRB = 0x18; //允许接收,允许发送。
//UCSRB = 0x98; //允许串口接收中断,允许接收,允许发送。
}
void SPI_MasterInit(void)
{
/* 设置MOSI 和SCK SS为输出,其他为输入 */
DDRB |= (1<<PB5)|(1<<PB3)|(1<<PB2);
/* 使能SPI 主机模式,设置时钟速率为fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}
void SPI_transmit(char cData)
{
/* 启动数据传输 */
SPDR = cData;
/* 等待传输结束 */
while(!(SPSR & (1<<SPIF)))
;
}
unsigned char SPI_receive(void)
{
/* 启动数据传输 */
SPDR = 0x00;
/* 等待传输结束 */
while(!(SPSR & (1<<SPIF)))
;
return SPDR;
}
//串口接收完成中断程序
SIGNAL(SIG_UART_RECV)
{
}
//===============================================
//串口函数
//===============================================
/*---------------字符输出函数---------------*/
void put1char(unsigned char c)
{
while (!(UCSRA&(1<<UDRE)));
UDR=c;
}
/*---------------字符输入函数---------------*/
unsigned char get1char(void)
{
while (!(UCSRA&(1<<RXC)));
return UDR;
}
/*---------------字符串输出函数-------------*/
int puts(char *s)
{
while (*s)
{
put1char(*s);
s++;
}
put1char(0x0a);//回车换行
put1char(0x0d);
return 1;
}
/*---------不含回车换行的字符串输出函数----*/
void putstr(char *s)
{
while (*s)
{
put1char(*s);
s++;
}
}
//===============================================
//延时函数
//===============================================
//1us延时函数
void delay_1us(void)
{
asm( "nop" ); //4m时为1us,8m时为0.125us,16m时为0.25us.
asm( "nop" );
asm( "nop" );
asm( "nop" );
asm( "nop" ); //4m时为1us,8m时为0.125us,16m时为0.25us.
asm( "nop" );
asm( "nop" );
asm( "nop" );
}
//n us 延时函数
void delay_nus(unsigned int n)
{
unsigned int i;
for(i=0;i<n;i++)delay_1us();
}
//1ms延时函数
void delay_1ms(void)
{
unsigned int i;
for(i=0;i<600;i++) delay_1us();
}
//n ms延时函数
void delay_nms(unsigned int n)
{
unsigned int i;
for(i=0;i<n;i++)delay_1ms();
}
//======================================================
//以下是有关NRF905的函数
//======================================================
//写TX地址4个字节
void write_tx_address(unsigned char tx_address_bytes_num)
{
unsigned char i;
CONTROL_PORT &= ~(1<<CSN);
SPI_transmit(0x22);//0b00100010
i=0;
while(tx_address_bytes_num--)
{
SPI_transmit(tx_address_reg_buf[i]);
i++;
}
CONTROL_PORT |= (1<<CSN);
}
//写TX有效数据32个字节
void write_tx_payload(unsigned char tx_payload_bytes_num)
{
unsigned char i=0;
CONTROL_PORT &= ~(1<<CSN);
SPI_transmit(0x20);//0b00100000
while(tx_payload_bytes_num--)
{
SPI_transmit(tx_data_buf[i]);
i++;
}
//SPI_transmit(tx_data_buf[1]);
//SPI_transmit(tx_data_buf[2]);
CONTROL_PORT |= (1<<CSN);
}
void read_rx_payload(unsigned char rx_payload_bytes_num)
{
unsigned char i;
//CSN=0;
CONTROL_PORT &= ~(1<<CSN);
SPI_transmit(0x24);//0b00100100
i=0;
while(rx_payload_bytes_num--)
{
rx_data_buf[i]=SPI_receive();
i++;
}
//CSN=1;
CONTROL_PORT |= (1<<CSN);
}
void send_rx_data_to_pc(void)
{
unsigned char i;
i=0;
for(i=0;i<32;i++) //send ASCII char'Comait CRM401XNC'use UART
{
put1char(rx_data_buf[i]);
}
}
//发送RF数据
void send_rf_data(void)
{
unsigned char i;
write_tx_address(4);
write_tx_payload(32);
CONTROL_PORT |= (1<<TRX_CE);
i=100;
while(i--); //等待NRF905数据传输完成
CONTROL_PORT &= ~(1<<TRX_CE);
}
//发送模式
void transmit_mode(void)
{
//nrf905进入发送模式
CONTROL_PORT |= (1<<PWR_UP);
CONTROL_PORT |= (1<<TRX_CE);
CONTROL_PORT |= (1<<TXEN);
delay_nms(2);
}
//接收模式
void receive_mode(void)
{
//nrf905进入接收模式
CONTROL_PORT |= (1<<PWR_UP);
CONTROL_PORT |= (1<<TRX_CE);
CONTROL_PORT &= ~(1<<TXEN);
delay_nms(2);
}
void read_config(void)
{
unsigned char i ;
CONTROL_PORT &= ~(1<<CSN);
SPI_transmit(0x10); //0b00010000
i =0;
for(i=0;i<10;i++)
{
xxx[i]=SPI_receive();
}
CONTROL_PORT |= (1<<CSN);
}
void write_config(void)
{
unsigned char i ;
CONTROL_PORT &= ~(1<<CSN);
SPI_transmit(0x00); //发送写配置寄存器的命令
i =0;
for(i=0;i<10;i++)
{
SPI_transmit(config_reg_buf[i]);
}
CONTROL_PORT |= (1<<CSN);
}
//nrf905初始化
void nrf905_init(void)
{
unsigned char i;
delay_nms(10);
//STANDBY和SPI编程模式
CONTROL_PORT |= (1<<PWR_UP);
CONTROL_PORT &= ~(1<<TRX_CE);
CONTROL_PORT &= ~(1<<TXEN);
CONTROL_PORT |= (1<<CSN);
i=0;
for(i=0;i<32;i++) //Clear the data buffer 清接收缓冲区
{
rx_data_buf[i]=0;
tx_data_buf[i]=0;
}
write_config();
}
//外部中断0中断服务函数
SIGNAL(SIG_INTERRUPT0)
{
read_rx_payload(32); //保存在rx_data_buf里
re_ok=1;
}
//====================================================================
//主程序开始
//====================================================================
int main(void)
{
//------------------------
cli();
port_init();
uart_init();
SPI_MasterInit();
sei();
DDRD |= (1<<PD3); //LED
CONTROL_DDR |= (1<<TRX_CE);
CONTROL_DDR |= (1<<TXEN);
CONTROL_DDR |= (1<<PWR_UP);
CONTROL_DDR |= (1<<CSN);
//standby 模式
CONTROL_PORT |= (1<<PWR_UP);
CONTROL_PORT &= ~(1<<TRX_CE);
nrf905_init();
receive_mode(); //接收模式
delay_nms(5);
//外部中断0上升沿中断
MCUCR |= (1<<ISC01)|(1<<ISC00);
GICR |= (1<<INT0);
while(1)
{
if(re_ok==1)
{
re_ok=0;
send_rx_data_to_pc();
tx_data_buf[0]=rx_data_buf[0]++;
tx_data_buf[1]=rx_data_buf[1]++;
tx_data_buf[2]=rx_data_buf[2]++;
tx_data_buf[3]=rx_data_buf[3]++;
tx_data_buf[4]=rx_data_buf[4]++;
transmit_mode(); //发射模式
send_rf_data();
receive_mode(); //接收模式
PORTD ^= (1<<PD3); //LED
}
if(get1char()==0x26)
{
tx_data_buf[0]=0x88;
tx_data_buf[1]=0x77;
tx_data_buf[2]=0x66;
tx_data_buf[3]=0x55;
tx_data_buf[4]=0x33;
transmit_mode(); //发射模式
send_rf_data();
receive_mode(); //接收模式
PORTD ^= (1<<PD3); //LED
}
/*
if(bit_is_set(PIND,2) != 0) //DR(PD.2)
{
read_rx_payload(32); //保存在rx_data_buf里
send_rx_data_to_pc();
}
*/
} //while
} //main
//====================================================================
//主程序结束
//====================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -