Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2006529
  • 博文数量: 356
  • 博客积分: 8284
  • 博客等级: 中将
  • 技术积分: 4580
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-15 20:25
个人简介

天行健,君子以自强不息

文章分类

全部博文(356)

文章存档

2018年(1)

2016年(4)

2015年(13)

2014年(14)

2013年(2)

2012年(25)

2011年(43)

2010年(65)

2009年(189)

分类: C/C++

2010-05-15 20:25:49

画了将近四天的时间做了一块atmega16的开发板,用覆铜板做的。提供的接口有1602液晶,12864液晶,nrf905无线模块,SPI接口,串口。同时12864兼容浩豚电子的TFT彩屏。
原理图如下:
 
pcb图如下:
 
相关工程图文件:
文件: atmega16.rar
大小: 550KB
下载: 下载
说明:
1、由于做的是覆铜板,pcb图中,max232附近的有两根线尚未接上。
2、由于个人疏忽,电源部分的ams117芯片管脚不对,可以不焊接进去,依然可以照常使用。但是如果要焊接的话,须仔细比对原理图。
3、液晶的数据接口采用的是PORTC,jtag下载的相关接口就在其内,开始没注意,不论怎么写程序,测得的PORTC2,3,4,5管脚电压都是高电平。这也是液晶测试程序仿真时正确,下载上去却无法正常工作的原因。
解决方法是,在下载的时候需对下载的软件进行设置熔丝位,把JTAGEN前面的钩钩去掉即可。下面以SLISP为例:
1)
2)
3)
 
 
整整花了四天的时间。
1602的测试程序已经写好,如下:

#define uchar unsigned char
#define uint unsigned int
#include
#define RS 4
#define RW 5
#define EN 6
#define PORT_CTL PORTA
#define DDR_CTL DDRA
#define DATA_PORT   PORTC
#define DATA_DDR    DDRC
#define DATA_PIN    PINC
void s_ms(uint ms)
{
 for(;ms>1;ms--);

//查忙
void busy(void)
{
    uchar temp;
 s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 while(temp)
 {
  PORT_CTL|=(1<  s_ms(500);
  DATA_DDR=0x00;      //A口变输入
  DATA_PORT =0xff;     //上拉使能
  s_ms(500);
  temp =DATA_PIN&0x80;    //读取A口
  s_ms(500);     
  DATA_DDR=0xff;     
  DATA_PORT =0xff;        //A口变输出
  s_ms(500);
  PORT_CTL&=~(1<  s_ms(500);
 }
}

//写指令
void writecom(uchar com)
{
 busy();
 s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 DATA_PORT = com;       //输出指令
 s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
}

//1602初始化
void LcdInit(void)
{
 writecom(0x38);
 s_ms(1000);
 writecom(0x01);
 s_ms(10000);
 s_ms(1000);
 s_ms(1000);
 s_ms(1000);
 s_ms(1000);
 s_ms(1000);
 s_ms(1000);
 writecom(0x02);
 s_ms(1000);
 writecom(0x06);
 s_ms(1000);
 writecom(0x0c);
 s_ms(1000);
 writecom(0x38); 
 s_ms(1000);

//写数据
void writedata(uchar data)
{
 busy();
 s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 DATA_PORT= data;      //输出数据
 s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
}


//读数据
uchar readdata(void)
{
 uchar temp;
 busy();
 s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 DATA_DDR=0x00;       //A端口变输入
 s_ms(500);
 temp = DATA_PIN;     //读A端口
 s_ms(500);
 DATA_DDR=0xff;       //A端口变输出
 s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
 return temp; 
}

//=================================================
// 描述: 写LCD内部CGRAM函数
// 入口: ‘num’要写的数据个数
//        ‘pbuffer’要写的数据的首地址
// 出口: 无
//================================================
void WriteCGRAM(uint num, const uint *pBuffer)
{
 uint i,t;
 writecom(0x40);
 PORT_CTL|=(1< PORT_CTL&=~(1< for(i=num;i!=0;i--)
 {
  t = *pBuffer;
  PORT_CTL|=(1<  DATA_PORT = t;
  PORT_CTL&=~(1<  pBuffer++;
 }
 
}

//=================================================
//描述:写菜单函数,本程序使用的LCD规格为 16 * 2
//入口:菜单数组首地址
//出口:无
//=================================================
void WriteMenu(const uchar *pBuffer)
{
 uchar i,t;
 writecom(0x80);   //数据地址
 
 PORT_CTL|=(1< PORT_CTL&=~(1< s_ms(50);
 for(i=0;i<16;i++)
 {
  t = *pBuffer;
  DATA_PORT = t;
  PORT_CTL|=(1<  s_ms(50);
  PORT_CTL&=~(1<  pBuffer++;
 }
 writecom(0xC0);

 PORT_CTL|=(1< PORT_CTL&=~(1< s_ms(50); 
 for(i=0;i<16;i++)
 {
  t = *pBuffer;
  DATA_PORT = t;
  PORT_CTL|=(1<  s_ms(50);
  PORT_CTL&=~(1<  pBuffer++;
 }
}
//====================================================
// 描述:在任意位置写数字函数
// 入口:’row‘表示要写数字所在的行地址,只能为1或2
//       ’col‘表示要写数字所在的列地址,只能为0--15
//   ‘num’表示要写的数字,只能为0--9
// 出口:无
//===================================================
void WriteNum(uchar row,uchar col,uchar num)
{
 if (row == 1) row = 0x80 + col;
 else row = 0xC0 + col;
 writecom(row);

 PORT_CTL|=(1< s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
 DATA_PORT = num;
 s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 PORT_CTL&=~(1< s_ms(500);   
}
//================================================================
// 描述:在任意位置写任意多个字符
// 入口:’row‘要写的字符所在的行,只能为1或2;
//       ‘col’要写的字符所在的列,只能为0---15
//       ‘num’要写字符的个数
//       ‘pbuffer’要写字符的首地址
//==================================================================
void WriteChar(uchar row,uchar col,uint num,uchar *pBuffer)
{
 uchar i,t;
 if (row == 1) row = 0x80 + col;
 else row = 0xC0 + col;
 writecom(row);


 PORT_CTL|=(1< s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
 for(i=num;i!=0;i--)
 {
  t = *pBuffer;
  s_ms(500);
  DATA_PORT = t;
  s_ms(500);
  PORT_CTL|=(1<  s_ms(500);
  PORT_CTL&=~(1<  s_ms(500);  
  pBuffer++;
 }
 
}
uchar wz[]={"
"};
uchar gd[]={"Good Luck!"};

main()
{
DATA_DDR=0xff;
DATA_PORT=0xff;
DDR_CTL=0xff;
PORT_CTL=0xff;
LcdInit();
while(1)
{
WriteChar(1,1,13,wz);
WriteChar(2,3,10,gd);
}
}

NRF905无线模块双向计数测试程序:

发送部分:

/*注:发送部分的硬件电路是用以前做的16的最小系统版和数码管模块用杜邦线搭建的。PORTA1-4是位选,PORTC0-7是段选              */

//ICC-AVR application builder : 2010-5-22
// Target : M16
// Crystal: 8.0000Mhz
#include
#include
#define uint  unsigned int
#define uchar unsigned char
uint i,j;
/*//////////////////////////模式控制定义////////////////////////////////*/
//#define  nrf905_TX_EN   PB0     //输出1  
#define   Low_nrf905_TX_EN     PORTB &= ~(1 << PB0)
#define   Hign_nrf905_TX_EN    PORTB |= (1 << PB0)
//#define  nrf905_TRX_CE  PD4     //输出1
#define   Hign_nrf905_TRX_CE    PORTD |= (1 << PD4) 
#define   Low_nrf905_TRX_CE     PORTD &= ~(1 << PD4)
//#define  nrf905_PWR     PB1      //输出1
#define   Hign_nrf905_PWR    PORTB |= (1 << PB1)
#define   Low_nrf905_PWR     PORTB &= ~(1 << PB1)
//--------------------------------SPI口定义--------------
//#define  nrf905_MISO   PB6    //输入0
//#define  nrf905_MOSI    PB5     //输出1
//#define  nrf905_SCK     PB7     //输出1
#define   Low_nrf905_SCK     PORTB &= ~(1 << PB7)
//-------------------------------------------------------
//#define  nrf905_CSN     PB4  //输出1  
#define   Hign_nrf905_CSN    PORTB |= (1 << PB4) 
#define   Low_nrf905_CSN     PORTB &= ~(1 << PB4)    
//-------------------------------状态输出口-------------------------------------
//#define  nrf905_CD      PD3     //输入0
#define   Hign_nrf905_CD    PORTD |= (1 << PD3)
#define   Low_nrf905_CD     PORTD &= ~(1 << PD3)
#define   Read_nrf905_CD    PINB & (1 << PD3)
//#define  nrf905_AM      PB3     //输入0
#define   Hign_nrf905_AM    PORTB |= (1 << PB3)
#define   Low_nrf905_AM     PORTB &= ~(1 << PB3)
#define   Read_nrf905_AM    PINB & (1 << PB3)
//#define  nrf905_DR      PB2    //输入0
#define   Hign_nrf905_DR    PORTB |= (1 << PB2)
#define   Low_nrf905_DR     PORTB &= ~(1 << PB2)
#define   Read_nrf905_DR    PINB & (1 << PB2)
/*
//读取键值KEY2-KEY3-KEY4 
#define   Read_KEY_2       PINA & (1 << PA5)       
//甲队加3分
#define   Read_KEY_3     PINA & (1 << PA6)
//乙队加2分
#define   Read_KEY_4        PINA & (1 << PA7)  
//乙队加3分
*/
//------------------------------数码管位选--------------------------------------
//#define Display1   PA1        //输出1
#define   Hign_Display1     PORTA |= (1 << PA1);  
#define   Low_Display1    PORTA &= ~(1 << PA1);
//#define Display2      PA2    //输出1
#define   Hign_Display2     PORTA |= (1 << PA2);  
#define   Low_Display2    PORTA &= ~(1 << PA2);
//#define Display3     PA3    //输出1
#define   Hign_Display3     PORTA |= (1 << PA3);  
#define   Low_Display3     PORTA &= ~(1 << PA3);
//#define Display4      PA4   //输出1
#define   Hign_Display4     PORTA |= (1 << PA4);  
#define   Low_Display4     PORTA &= ~(1 << PA4);
//----------------------------------905-SPI指令---------------------------------
#define WC 0x00
#define RRC 0x10
#define WTP 0x20
#define RTP 0x21
#define WTA 0x22
#define RTA 0x23
#define RRP 0x24
//---------------------------------发送数据缓冲区-------------------------------
uchar TxRxBuf[4];
//----------------------------------接收地址------------------------------------
uchar TxAddress[4]={0xcc,0xcc,0xcc,0xcc };   
uchar tf;
uchar seg[10]={0xc0,0xfc,0x89,0x83,0xa6,0x92,0x90,0xc7,0x80,0x82};  //共阳  0-9
//------------------------------------------------------------------------------
//----------------------------------寄存器配置----------------------------------
uchar RFConf[11]=
{
  0x00,                             //配置命令//
  0x4c,                             //CH_NO,配置频段在430MHZ
  0x0C,                             //输出功率为10db,不重发,节电为正常模式
  0x44,                             //地址宽度设置,为4字节
  0x04,0x04,                        //接收发送有效数据长度为4字节
  0xCC,0xCC,0xCC,0xCC,              //接收地址
  0x58,                              //CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振
};
//----------------------------------函数申明------------------------------------
void Delay(uint x);
void Spi_initial();
uchar SpiReadSpiWrite(uchar DATA);
void system_Init(void);
void Config905(void);
void TxPacket(uchar TxBUF[4]);
void SetTxMode(void);
void TX(void);
void StartUART(void);
void R_S_Byte(uchar R_Byte);
//----------------------------------100us延时子程序-----------------------------
void Delay(uint x)
{
 uint i;
 while(x--)
 for(i=0;i<80;i++);
}
//----------------------------------SPI初始化-----------------------------------
void Spi_initial()
{
 SPCR   = (1<}
//---------------------------------SPI读写程序---------------------------------- 
uchar SpiReadSpiWrite(unsigned char cData)//r
{
 SPDR = cData;
 while(!(SPSR & (1< {};   // 等待SPI发送完毕
 return SPDR;
}
//---------------------------------系统状态初始化-------------------------------
void system_Init(void)   //r
{

    Hign_nrf905_CSN;    // Spi  disable
 Low_nrf905_SCK;    // Spi clock line init low
 Low_nrf905_DR;    // Init DR for input
 Low_nrf905_AM;    // Init AM for input
 Low_nrf905_CD;    // Init nrf905_CDfor input
 Hign_nrf905_PWR;    // nRF905 power on
 Low_nrf905_TRX_CE;   // Set nRF905 in standby mode
 Low_nrf905_TX_EN ;   // set radio in Rx mode
}
//--------------------------------NRF905寄存器初始化函数------------------------
void Config905(void)
{
 uchar i;
 Low_nrf905_CSN; 
 Delay(1);    // Spi enable for write a spi command
 //SpiWrite(WC);    // Write config command写放配置命令
 for (i=0;i<11;i++)   // Write configration words  写放配置字
 {
  SpiReadSpiWrite(RFConf[i]);
 }
 Hign_nrf905_CSN;     // Disable Spi
}
//--------------------------------NRF905待发数据打包----------------------------
void TxPacket(uchar TxBUF[4])
{
 uchar i;
 Low_nrf905_CSN;        // 使能Spi,允许对nrf905进行读写操作
 Delay(1);
 SpiReadSpiWrite(WTP);    // 写数据前先写写数据命令
 for (i=0;i<4;i++)
 {
 SpiReadSpiWrite(TxBUF[i]);  // 待发送的32字节数据
 }      
 Hign_nrf905_CSN;
 Delay(1);       // 关闭Spi,不允许对nrf905进行读写操作
 Low_nrf905_CSN;        // 使能Spi
 SpiReadSpiWrite(WTA);    // 写地址前首先先写地址命令
 for (i=0;i<4;i++)     // 写 4 bytes 地址
 {
 SpiReadSpiWrite(TxAddress[i]);
 }
 Hign_nrf905_CSN;     // 关闭Spi
 Hign_nrf905_TRX_CE;     // Set TRX_CE high,start Tx data transmission
 Delay(1);       // 等待DR变高
 Low_nrf905_TRX_CE;       // 设置TRX_CE=0
}
//-------------------------------发送模式激发-----------------------------------
void SetTxMode(void)
{
 Low_nrf905_TRX_CE;    //
 Hign_nrf905_TX_EN;    //发送使能
 Delay(2);     // delay for mode change(>=650us)根据晶振不同要改变
}
//------------------------------------------------------------------------
//------------------------------设置接收模式激发--------------------------------
void SetRxMode(void)
{
 Low_nrf905_TX_EN;
 Hign_nrf905_TRX_CE;
 Delay(1000);      // delay for mode change(>=650us)
}
//-----------------------------------读接收数据包-------------------------------
void RxPacket(void)       //读数据
{
 uchar i;
    Low_nrf905_TRX_CE;
 Low_nrf905_CSN;          // 使能SPI
    Delay(1);
 SpiReadSpiWrite(RRP);       // 写入数据接收缓冲区数据命令
 for (i = 0 ;i < 4 ;i++)
 {  
 TxRxBuf[i]=SpiReadSpiWrite(0);   // 读取数据接收缓冲区数据      
 }
 Hign_nrf905_CSN;
    Delay(2);                            //
 Hign_nrf905_TRX_CE;       
}
//--------------------------------设置接收模式----------------------------------
void  RX(void)
{
    SetRxMode();             //设置NRF905接收模式
 RxPacket();                     //读取接收数据缓冲区
 Delay(10);
 if(TxRxBuf[0]==0x29)
 {
  PORTC=seg[1];
  Low_Display4;
  Hign_Display3;
  Hign_Display2;
  Hign_Display1;
 }
 if(TxRxBuf[0]==0x30)
 {
  PORTC=seg[2];
  Hign_Display4;
  Low_Display3;
  Hign_Display2;
  Hign_Display1;
 }
 if(TxRxBuf[0]==0x31)
 {
  PORTC=seg[3];
  Hign_Display4;
  Hign_Display3;
  Low_Display2;
  Hign_Display1;

 }
}
//----------------------------------数码管初始化程序----------------------------
void led_init()
{
    DDRA|=((1<<1)|(1<<2)|(1<<3)|(1<<4));  //PA.1-4设置为输出
 DDRC=0xff;   //LED端口设置
 PORTA|=((1<<1)|(1<<2)|(1<<3)|(1<<4));
}
//---------------------------------数码管显示子函数-----------------------------
void led_display(uint z)
{

  uint k;
  k=z;
  PORTC=seg[k/1000];
  Low_Display4;
  Hign_Display3;
  Hign_Display2;
  Hign_Display1;
  Delay(10);

    
  PORTC=seg[k%1000/100];
  Hign_Display4;
  Low_Display3;
  Hign_Display2;
  Hign_Display1;
  Delay(10);

  PORTC=seg[k%100/10];
  Hign_Display4;
  Hign_Display3;
  Low_Display2;
  Hign_Display1;
  Delay(10);
 
  PORTC=seg[k%10];
  Hign_Display4;
  Hign_Display3;
  Hign_Display2;
  Low_Display1;
  Delay(10);
}

void timer0_init()
{
  TCNT0=0X00;
  TCCR0=0X03;
  TIMSK=0X01;
  SREG=0X80;
}


//------------------------------主函数------------------------------------------
void main(void)

 //uint i,j;

 DDRD|=(1<<4);
 DDRD&=~(1<<3);
 DDRB=0xB3;   //905相关管脚初始化
 
 Spi_initial();
 system_Init();
 Config905();
 
 led_init();
 timer0_init();
 while(1)
 {
   
  TxRxBuf[0]=j/1000;
  TxRxBuf[1]=j%1000/100;
  TxRxBuf[2]=j%100/10;
  TxRxBuf[3]=j%10;
  led_display(j);
  SetTxMode();    // 激发数据发s送
  TxPacket(TxRxBuf);   // 装载待发送数据                  
  }
}

#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
 
 TCNT0=0X00;
 i++;
 if(i>=50)
 {
  i=0;
  j++;
 }
}

 

接收部分:

/*接收部分的硬件电路即为上图中的自制的avr开发板,采用1602显示*/

1)yj1602.h文件

#define uchar unsigned char
#define uint unsigned int
#include
#define RS 4
#define RW 5
#define EN 6
#define PORT_CTL PORTA
#define DDR_CTL DDRA
#define DATA_PORT   PORTC
#define DATA_DDR    DDRC
#define DATA_PIN    PINC
uchar table[11]={"0123456789 "};
void s_ms(uint ms)
{
 for(;ms>1;ms--);

//查忙
void busy(void)
{
    uchar temp;
 s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 while(temp)
 {
  PORT_CTL|=(1<  s_ms(500);
  DATA_DDR=0x00;      //A口变输入
  DATA_PORT =0xff;     //上拉使能
  s_ms(500);
  temp =DATA_PIN&0x80;    //读取A口
  s_ms(500);     
  DATA_DDR=0xff;     
  DATA_PORT =0xff;        //A口变输出
  s_ms(500);
  PORT_CTL&=~(1<  s_ms(500);
 }
}

//写指令
void writecom(uchar com)
{
 busy();
 s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 DATA_PORT = com;       //输出指令
 s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
}

//1602初始化
void LcdInit(void)
{
    DATA_DDR=0xff;
    DATA_PORT=0xff;
    DDR_CTL|=  ((1<    PORT_CTL|= ((1<

 writecom(0x38);
 s_ms(1000);
 writecom(0x01);
 s_ms(10000);
 s_ms(1000);
 s_ms(1000);
 s_ms(1000);
 s_ms(1000);
 s_ms(1000);
 s_ms(1000);
 writecom(0x02);
 s_ms(1000);
 writecom(0x06);
 s_ms(1000);
 writecom(0x0c);
 s_ms(1000);
 writecom(0x38); 
 s_ms(1000);

//写数据
void writedata(uchar data)
{
 busy();
 s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 DATA_PORT= data;      //输出数据
 s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
}


//读数据
uchar readdata(void)
{
 uchar temp;
 busy();
 s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 DATA_DDR=0x00;       //A端口变输入
 s_ms(500);
 temp = DATA_PIN;     //读A端口
 s_ms(500);
 DATA_DDR=0xff;       //A端口变输出
 s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
 return temp; 
}

//=================================================
// 描述: 写LCD内部CGRAM函数
// 入口: ‘num’要写的数据个数
//        ‘pbuffer’要写的数据的首地址
// 出口: 无
//================================================
void WriteCGRAM(uint num, const uint *pBuffer)
{
 uint i,t;
 writecom(0x40);
 PORT_CTL|=(1< PORT_CTL&=~(1< for(i=num;i!=0;i--)
 {
  t = *pBuffer;
  PORT_CTL|=(1<  DATA_PORT = t;
  PORT_CTL&=~(1<  pBuffer++;
 }
 
}

//=================================================
//描述:写菜单函数,本程序使用的LCD规格为 16 * 2
//入口:菜单数组首地址
//出口:无
//=================================================
void WriteMenu(const uchar *pBuffer)
{
 uchar i,t;
 writecom(0x80);   //数据地址
 
 PORT_CTL|=(1< PORT_CTL&=~(1< s_ms(50);
 for(i=0;i<16;i++)
 {
  t = *pBuffer;
  DATA_PORT = t;
  PORT_CTL|=(1<  s_ms(50);
  PORT_CTL&=~(1<  pBuffer++;
 }
 writecom(0xC0);

 PORT_CTL|=(1< PORT_CTL&=~(1< s_ms(50); 
 for(i=0;i<16;i++)
 {
  t = *pBuffer;
  DATA_PORT = t;
  PORT_CTL|=(1<  s_ms(50);
  PORT_CTL&=~(1<  pBuffer++;
 }
}
//====================================================
// 描述:在任意位置写数字函数
// 入口:’row‘表示要写数字所在的行地址,只能为1或2
//       ’col‘表示要写数字所在的列地址,只能为0--15
//   ‘num’表示要写的数字,只能为0--9
// 出口:无
//===================================================
void WriteNum(uchar row,uchar col,uchar num)
{
 if (row == 1) row = 0x80 + col;
 else row = 0xC0 + col;
 writecom(row);

 PORT_CTL|=(1< s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
 DATA_PORT = num;
 s_ms(500);
 PORT_CTL|=(1< s_ms(500);
 PORT_CTL&=~(1< s_ms(500);   
}
//================================================================
// 描述:在任意位置写任意多个字符
// 入口:’row‘要写的字符所在的行,只能为1或2;
//       ‘col’要写的字符所在的列,只能为0---15
//       ‘num’要写字符的个数
//       ‘pbuffer’要写字符的首地址
//==================================================================
void WriteChar(uchar row,uchar col,uint num,uchar *pBuffer)
{
 uchar i,t;
 if (row == 1) row = 0x80 + col;
 else row = 0xC0 + col;
 writecom(row);


 PORT_CTL|=(1< s_ms(500);
 PORT_CTL&=~(1< s_ms(500);
 for(i=num;i!=0;i--)
 {
  t = *pBuffer;
  s_ms(500);
  DATA_PORT = t;
  s_ms(500);
  PORT_CTL|=(1<  s_ms(500);
  PORT_CTL&=~(1<  s_ms(500);  
  pBuffer++;
 }
 
}
uchar wz[]={"
"};
uchar gd[]={"Good Luck!"};
uchar dd1[]={"NRF 905 DEMO"};
uchar dd2[]={"the key is:    "};


2)main.c文件:

//ICC-AVR application builder : 2010-5-20
// Target : M16
// Crystal: 8.0000Mhz
#include
#include
#include "yj1602.h"
#define uint  unsigned int
#define uchar unsigned char
///////////////////////////模式控制定义/////////////////////////////////
//#define  nrf905_TX_EN   PB0     //输出1  
#define   Low_nrf905_TX_EN     PORTB &= ~(1 << PB0)
#define   Hign_nrf905_TX_EN    PORTB |= (1 << PB0)
//#define  nrf905_TRX_CE  PD4     //输出1
#define   Hign_nrf905_TRX_CE    PORTD |= (1 << PD4) 
#define   Low_nrf905_TRX_CE     PORTD &= ~(1 << PD4)
//#define  nrf905_PWR     PB1      //输出1
#define   Hign_nrf905_PWR    PORTB |= (1 << PB1)
#define   Low_nrf905_PWR     PORTB &= ~(1 << PB1)
//--------------------------------SPI口定义-------------------------------------
//#define  nrf905_MISO   PB6    //输入0
//#define  nrf905_MOSI    PB5     //输出1
//#define  nrf905_SCK     PB7     //输出1
#define   Low_nrf905_SCK     PORTB &= ~(1 << PB7)
//------------------------------------------------------------------------------
//#define  nrf905_CSN     PB4  //输出1  
#define   Hign_nrf905_CSN    PORTB |= (1 << PB4) 
#define   Low_nrf905_CSN     PORTB &= ~(1 << PB4)    
//-------------------------------状态输出口-------------------------------------
//#define  nrf905_CD      PD3     //输入0
#define   Hign_nrf905_CD    PORTD |= (1 << PD3)
#define   Low_nrf905_CD     PORTD &= ~(1 << PD3)
#define   Read_nrf905_CD    PINB & (1 << PD3)
//#define  nrf905_AM      PB3     //输入0
#define   Hign_nrf905_AM    PORTB |= (1 << PB3)
#define   Low_nrf905_AM     PORTB &= ~(1 << PB3)
#define   Read_nrf905_AM    PINB & (1 << PB3)
//#define  nrf905_DR      PB2    //输入0
#define   Hign_nrf905_DR    PORTB |= (1 << PB2)
#define   Low_nrf905_DR     PORTB &= ~(1 << PB2)
#define   Read_nrf905_DR    PINB & (1 << PB2)

//----------------------------------905-SPI指令---------------------------------
#define WC 0x00
#define RRC 0x10
#define WTP 0x20
#define RTP 0x21
#define WTA 0x22
#define RTA 0x23
#define RRP 0x24
//---------------------------------发送数据缓冲区-------------------------------
uchar TxRxBuf[4];
//----------------------------------接收地址------------------------------------
uchar TxAddress[4]={0xcc,0xcc,0xcc,0xcc };   
uchar tf;

//------------------------------------------------------------------------------
//----------------------------------寄存器配置----------------------------------
uchar RFConf[11]=
{
  0x00,                             //配置命令//
  0x4c,                             //CH_NO,配置频段在430MHZ
  0x0C,                             //输出功率为10db,不重发,节电为正常模式
  0x44,                             //地址宽度设置,为4字节
  0x04,0x04,                        //接收发送有效数据长度为4字节
  0xCC,0xCC,0xCC,0xCC,              //接收地址
  0x58,                              //CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振
};
//----------------------------------函数申明------------------------------------
void Delay(uint x);
void Spi_initial();
uchar SpiReadSpiWrite(uchar DATA);
void system_Init(void);
void Config905(void);
void TxPacket(uchar TxBUF[4]);
void SetTxMode(void);
void TX(void);
void StartUART(void);
void R_S_Byte(uchar R_Byte);
//----------------------------------100us延时子程序-----------------------------
void Delay(uint x)
{
 uint i;
 while(x--)
 for(i=0;i<80;i++);
}
//----------------------------------SPI初始化-----------------------------------
void Spi_initial()
{
 //SPCR=0x50;
 //SPSR=0x00; 
 SPCR   = (1<}
//---------------------------------SPI读写程序---------------------------------- 
uchar SpiReadSpiWrite(unsigned char cData)//r
{
 SPDR = cData;
 while(!(SPSR & (1< {};   // 等待SPI发送完毕
 return SPDR;
}
//---------------------------------系统状态初始化-------------------------------
void system_Init(void)   
{

    Hign_nrf905_CSN;    // Spi  disable
 Low_nrf905_SCK;    // Spi clock line init low
 Low_nrf905_DR;    // Init DR for input
 Low_nrf905_AM;    // Init AM for input
 Low_nrf905_CD;    // Init nrf905_CDfor input
 Hign_nrf905_PWR;    // nRF905 power on
 Low_nrf905_TRX_CE;   // Set nRF905 in standby mode
 Low_nrf905_TX_EN ;   // set radio in Rx mode
}
//--------------------------------NRF905寄存器初始化函数------------------------
void Config905(void)
{
 uchar i;
 Low_nrf905_CSN; 
 Delay(1);    // Spi enable for write a spi command
 //SpiWrite(WC);    // Write config command写放配置命令
 for (i=0;i<11;i++)   // Write configration words  写放配置字
 {
  SpiReadSpiWrite(RFConf[i]);
 }
 Hign_nrf905_CSN;     // Disable Spi
}
//--------------------------------NRF905待发数据打包----------------------------
void TxPacket(uchar TxBUF[4])
{
 uchar i;
 Low_nrf905_CSN;           // 使能Spi,允许对nrf905进行读写操作
 Delay(1);
 SpiReadSpiWrite(WTP);    // 写数据前先写写数据命令
 for (i=0;i<4;i++)
 {
 SpiReadSpiWrite(TxBUF[i]);  // 待发送的32字节数据
 }      
 Hign_nrf905_CSN;
 Delay(1);       // 关闭Spi,不允许对nrf905进行读写操作
 Low_nrf905_CSN;        // 使能Spi
 SpiReadSpiWrite(WTA);    // 写地址前首先先写地址命令
 for (i=0;i<4;i++)     // 写 4 bytes 地址
 {
 SpiReadSpiWrite(TxAddress[i]);
 }
 Hign_nrf905_CSN;     // 关闭Spi
 Hign_nrf905_TRX_CE;     // Set TRX_CE high,start Tx data transmission
 Delay(1);       // 等待DR变高
 Low_nrf905_TRX_CE;       // 设置TRX_CE=0
}
//-------------------------------发送模式激发-----------------------------------
void SetTxMode(void)
{
 Low_nrf905_TRX_CE;    //
 Hign_nrf905_TX_EN;    //发送使能
 Delay(2);     // delay for mode change(>=650us)根据晶振不同要改变
}
//------------------------------设置接收模式激发--------------------------------
void SetRxMode(void)
{
 Low_nrf905_TX_EN;
 Hign_nrf905_TRX_CE;
 Delay(1000);      // delay for mode change(>=650us)
}
//-----------------------------------读接收数据包-------------------------------
void RxPacket(void)       //读数据
{
 uchar i;
    Low_nrf905_TRX_CE;
 Low_nrf905_CSN;          // 使能SPI
    Delay(1);
 SpiReadSpiWrite(RRP);       // 写入数据接收缓冲区数据命令
 for (i = 0 ;i < 4 ;i++)
 {  
 TxRxBuf[i]=SpiReadSpiWrite(0);   // 读取数据接收缓冲区数据      
 }
 Hign_nrf905_CSN;
    Delay(2);                           
 Hign_nrf905_TRX_CE;       
}

void RX_YJ1602(void)
{
    SetRxMode();             //设置NRF905接收模式
 RxPacket();                     //读取接收数据缓冲区
 Delay(10);
 dd2[11]=table[TxRxBuf[0]];
 dd2[12]=table[TxRxBuf[1]];
 dd2[13]=table[TxRxBuf[2]];
 dd2[14]=table[TxRxBuf[3]];
 WriteChar(2,1,15,dd2);
}
void port_init_905()
{
    DDRD&=~(1<<3);    //将905设置为接收状态
 DDRD|=(1<<4);
 DDRB=0xB3;    //将905设置为接收状态
}
//------------------------------主函数------------------------------------------
void main(void)

 uint i,j,temp[32];
 port_init_905();
 LcdInit();
 Spi_initial();
 system_Init();
 Config905();
 WriteChar(1,1,12,dd1);
   while(1)
  {
  RX_YJ1602();              
  }
}

 

阅读(2731) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~