⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 自己修改的主机程序.txt

📁 主机发送指令 采样AD,从机接受指令 产生波形
💻 TXT
字号:
// ********************************************************
// CMainPrg.c 简易信号发生器主机程序(原先是主机程序)
// 开发日期 : 2007年11月27日
// 开发环境 : 无线龙C51RF-2开发系统
// ******************************************************** 

#include <Nordic\reg9e5.h>             // nRF9E5的头文件
#include "hWLT.H"                      // 自定义系统头文件 

// 配置寄存器 
code unsigned char NRF9E5Config[10] = {
              0x6a,                    // 频道配置
              0x0c,         // 输出功率433MHz(0),10db(11), 自动重发关(0),发送节电模式关(0),即(0X00001100)
              0x44,                    // 收发地址都为4字节
              0x01,                    // 接收数据长度1字节
              0x01,                    // 发送数据长度1字节
              0xe7,
              0xe7,
              0xe7,
              0xe7,
              0xdf                     // CRC开,16位校验,16MHz晶振,外部时钟启用500KHz输出
};

// ******************************************************** 
// 2007年11月27日  系统主程序
// SysStatus 为系统状态存储器
//  0x00  主机模式, AD采样数据,不进行数据分析,只进行有效的数据信息的传输, 
//  0x80  从机模式, 需要对接受到的数据进行分析,产生方波

void main(void)
{ 
  EA = 0;                              // 禁止所有中断 

  InitCpu();                           // 初始化CPU(含I/O端口)
  Init9E5();                           // 初始化9E5
  InitTimer0();                        // 初始化TIMER0
  InitUart();		// 初始化串行通信UART端口         
  InitADC();                           // 初始化ADC
  SysStatus = 0x00;                    // 主机模式  
 
  EA = 1;                              // 开总中断

 PutStr("Wireless SSI \n");           //用途? 表示开始无线通讯?
  while(1)
{ PCON |= 0x01;					       // 待机模式
}
}


// ******************************************************** 
// 2007年7月7日  TIMER0定时器中断服务程序
// 对于 TH0=0xEB / TL0 = 0x2B, 则定时中断周期为4ms
// 该定时器的工作模式设置为1
// 该中断主要用于定时进行AD转换与通信信息的分析处理

void ISPTimer0() interrupt 1     
{ 
  unsigned char adcl;                  // ADC低8位
  unsigned char adch;                  // ADC高8位


  ET0  = 0;                            // 在进行温度采样时, 关中断

  TF0 = 0;	                           // 清除TIMER0中断标志
  TR0 = 0;				// 禁止TIMER0计数
  TH0 = 0xEB;
  TL0 = 0x2B;    
  RACSN = 0;                           // 关闭AD转换
  SpiRW(SAV | 0x03);                   // 第3通道开始转换(选择转换通道)
  RACSN = 1;                           // 开始AD转换

  while(EOC == 0);                     // 等待AD转换完成
		   
  RACSN = 0;                           // 关闭AD转换      
  SpiRW(RAD);                          //串口SPI读AD采样数据(读操作起始位置)
  adcl = SpiRW(0);                     //将采样结果放在ADC中  
  adch = SpiRW(0);                    
  RACSN = 1;

 if (UTRx.Flag = 0x0A)		 // 如果主机UART接收到AD采样的数据,则对UART接收到的数据直接转移到待发送数组RFTRx.TBUF中
  {if (SysStatus == 0x00)		       // 主机模式, 不需要解码
     { RFTRx.TBUF[0] = STCB;       // 存入数据返回头字符“#”
       RFTRx.TBUF[1] = WFG;        // 无线数据标志字符“w”
       RFTRx.TBUF[2] = LOCA.NO[0]; // 地址高字节
       RFTRx.TBUF[3] = LOCA.NO[1]; // 地址低字节
       RFTRx.TBUF[4] = adcl;       // AD转换结果高字节
       RFTRx.TBUF[5] = adch;     // AD转换结果低字节
       RFTRx.TBUF[6] = MEND;    // 结束符
       RFTRx.TNum = 7;        //待发送数组RFTRx.TBUF元素总共有7个,利用RFTRx.TNum来分析是否发送完毕
       TXMChar();	    // 采样数据通过RF转发输出
       UTRx.Flag = 0;             // uart接收标志复位
      }
 }
  TR0 = 1;							   // 开始重新计时
  TRX_CE = 1;                          // 重复将RF状态置为收
  TXEN = 0;   
  ET0  = 1; 				               // 中断总允许开启
}       

// ******************************************************** 
// 2007年7月7日  串行通信 接收中断服务程序
// 该程序主要用于与PC进行串行通信, 当接收的数据时, 产生中断
// 并根据收到的数据进行分析
// 首先确定该数据是否是本机的合法数据, 其次要根据收到的数据
// 进行相关的处理

void ISPUart() interrupt 4      
{ 
  EA = 0;
  LED3_D=0;  
  if (RI == 1)                         // RI=1为串行接收中断请求,于是接收中断处理部分    
    { UGetChar = SBUF;                  // UGetChar 暂存收到的字符(SBUF为串口缓冲寄存器)
                                    // 如下对收到的字符进行分析
     if (UTRx.Flag != 0x0A)  //当UART不处于接受状态或者接受未完成时,开始转移数据
     { UTRx.RBUF[UTRx.RNum] = UGetChar;         // 利用数组存储UART收到的字符
	if (UTRx.RNum == 0)			   // 先判断第一个字符
	   { if(UGetChar == STCB)      // 读数据命令首字符   
                UTRx.RNum ++;			   // 是首字符
	     else 
	       UTRx.RNum = 0;			   // 不是首字符, 重新等待接收
	   }
	else 
	 { if (UTRx.RNum <= MAXC)	   // 最大的接收字符数
	       UTRx.RNum ++;			   // 计数器 +
	   if (UTRx.RNum >  MAXC)	   // 超过计数, 未收到结束符
	       UTRx.RNum = 0;			   // 清 0 重新收
           if (UGetChar == MEND)	   // 判结束符
	     { if (UTRx.RBUF[1] == WFG) // 无线标志位
		 { UTRx.Flag = 0x0A;      // 置接收完成标志, 在主流程中分析
                   LOCA.NO[0] =  UTRx.RBUF[2] ;                 
                   LOCA.NO[1] =  UTRx.RBUF[3] ;
                 }
		if (UTRx.RBUF[1] != WFG) // 无线标志位
		{ UTRx.RNum = 0;		   // 清 0 重新收
		 UTRx.Flag = 0x00;
	    }
	  }
	       
         }
       }
	 RI = 0;						   // 清除接收标志位
   }
  
 if (TI == 1)                         // 发送中断处理部分
 { TI = 0;						   // 清除发送中断标志
 }
 EA = 1;
}

// ******************************************************** 
// 2007年7月7日  RF接收中断服务程序

void ISRRF905(void) interrupt 10
{ 
  EA = 0;
  EXIF = EXIF & 0xBF;
  RACSN = 0;
  SpiRW(RRP);             //读RX有效字节,0-32字节,从0开始读取数据
  GRFChar = SpiRW(0);     //通过RF接受到的字符,从0开始暂时存放于GRFChar,以下是依次判断接受到的RF数据是否合法?
  if (RFTRx.Flag != 0x0A) //RF接收是否未完成?以下开始依次接受数据
   { RFTRx.RBUF[RFTRx.RNum] = GRFChar;
     if (RFTRx.RNum == 0)				   // 先判断第一个字符
      { if(GRFChar == STCD)		           // 数据返回命令首字符
          RFTRx.RNum ++;				   // 是首字符. 继续等待其他字符
        else 
	      RFTRx.RNum = 0;				   // 不是首字符, 忽略重等
      }
     else 
      { if (RFTRx.RNum <= MAXC)			    // 字符串最大长度18=12(字节数)+6(数据/命令首字符)
	       RFTRx.RNum ++;
	    if (RFTRx.RNum  > MAXC)
	       RFTRx.RNum = 0;
        if (GRFChar == MEND) 	           // 判结束符 CR
         { if (RFTRx.RBUF[1] == WFG)       // 无线标志位
               RFTRx.Flag = 0x0A;            // 置接收完成标志, 在主流程中分析
	   if (RFTRx.RBUF[1] != WFG)       // 无线标志位
		    { RFTRx.RNum = 0;		       // 清 0 重新收
	              RFTRx.Flag = 0x00;
		    }
	   if (RFTRx.RBUF[2] != LOCA.NO[0])// 检测地址高位
		    { RFTRx.RNum = 0;		       // 清 0 重新收
		      RFTRx.Flag = 0x00;
		    }
	   if (RFTRx.RBUF[3] != LOCA.NO[1])// 检测地址低位
		    { RFTRx.RNum = 0;		       // 清 0 重新收
	              RFTRx.Flag = 0x00;
		    }
     	 }

	  }
   }
  RACSN = 1;
  EA = 1;
}

// ******************************************************** 
// 2007年7月7日  通过串行口发送字符串子程序
// 以串的方式通过UART发送

void PutStr(const char *Str)
{ 
  EN_485 = 1; 						   // 发送使能
  while(*Str != '\n')
   { EA = 0;						   // 禁止中断
     TI = 0;                           // 清发送完成标志
     SBUF = *Str++;                    // 将数据写入串行通讯数据寄存器
     while(TI == 0);				   // 等待发送完成标志
     TI = 0;						   // 清发送完成标志
     EA = 1;						   // 开总中断
   }
   EN_485 = 0;						   // 接收使能
  }

// ******************************************************** 
// 2007年7月7日  通过串行口发送字符数组
// 该发送为查询方式发送

void PutMChar(void)
{ 
 unsigned char Loop = 4; 
 EN_485 = 1; 				 // 发送使能
 ES = 0;				  // UART中断关闭
 while(Loop < 6) 
  { TI = 0;                           // 清发送完成标志
    SBUF = UTRx.TBUF[Loop];             // 将数据写入串行通讯数据寄存器
    while (TI == 0);
    Loop ++;
    TI = 0;				  // 清发送完成标志
   }
 ES = 1;				  // 重新开启UART中断
 EN_485 = 0;				 // 接收使能
}

// ******************************************************** 
// 2007年7月7日  RF字符串发送程序
// 通过无线发送字符串

void TXMChar(void)
{ 
  unsigned char Loop = 0;
  TXEN = 1;
  while (Loop < RFTRx.TNum)    //依次将待发送的数据发送出去
   { 
     RACSN = 0;	     
     SpiRW(WTP);
     SpiRW(RFTRx.TBUF[Loop]);
     RACSN = 1;
     TRX_CE = 1;	
     Delay(30);
     TRX_CE = 0;
     while (DR == 0) ;             //等到数据包被全部读出DR置低
     Loop ++;
   }
  TRX_CE = 1;
  TXEN = 0;
  LED3_D=1;
}

// ******************************************************** 
// 2007年7月7日  SPI端口读写程序

unsigned char SpiRW(unsigned char Data)
{ 
  EXIF &= ~0x20;                       // 清除SPI中断标志
  SPI_DATA = Data;                     // 将命令字或数据SPI数据寄存器
  while((EXIF & 0x20) == 0x00) ;        // 循环等待SPI数据成功发送
  return SPI_DATA;                     // 返回接收到的数据
}

//******************************************************** 
// 2007年7月7日  CPU初始化程序

void InitCpu(void)
{ unsigned char Temp;				   // 临时变量                                      
                                       // SPI 设置, 涉及SPICLK/SPI_DATA/SPI_CTRL三个寄存器
									   // 本段设置, 可开启内部CPU与nRF905的SPI通讯
  SPICLK = 0;                          // 最大的SPI时钟,为CPU时钟的1/2
  SPI_CTRL = 0x02;                     // 内部SPI控制寄存器
  CKCON |= 0x00;                                   // 00-SPI未用 / 01-SPI TO P1 / 02- SPI TO 905  
									   // 第9个RF寄存器
  RACSN = 0;                           // SPI 的片选
  SpiRW(RRC | 0x09);                   // 读RF配置寄存器, 从第9字节开始
  Temp = SpiRW(0) | 0x04;                // SPI 的禁止

  RACSN = 0;                           // SPI 的片选
  SpiRW(WRC | 0x09);                   // 写RF配置寄存器(配置处理器/时钟)
  SpiRW(Temp);                         // 允许CRC校验/16位CRC/20MHZ晶振/SPI采用外部时钟/500KHZ
  RACSN = 1;                           // SPI 的禁止
  EX4 = 1;                             // 允许RF中断
  PX4 = 1;
}

// ******************************************************** 
// 2007年7月7日  nRF9E5初始化程序

void Init9E5(void)
{unsigned char i;
  TRX_CE = 0;
  TXEN = 0;
  RACSN = 0;
  SpiRW(WRC);
  for(i=0;i<10;i++)
 {SpiRW(NRF9E5Config[i]);
 }
 RACSN =1;
}

// ******************************************************** 
// 2007年7月7日  UART串行通讯程序

void InitUart(void)
{
 EN_485 = 0;                       // 接收选通 / 发送关闭
 TI     = 0;		           // 清除发送中断标志
 RI     = 0;			   // 清除接收中断标志
 TH1    = 0xE6;                    // 9600@16MHz (when T1M=1 and SMOD=1)
                        // 波特率设置 TH1 = 256 - 2^SMOD * 16000000 / (128 * 9600)
 CKCON |= 0x30;                     // T1M=1 (/4 timer clock)
 PCON  |= 0x80;                     // SMOD = 1 (double baud rate)
 SCON  |= 0x52;                     // 串行工作模式1/单机/接收使能/8位收发/)
 TMOD  |= 0x20;                    // Timer1 8bit 自动装载 

 TR1    = 0;			               // 停止 TIMER1 运行 
 ET1    = 0;			               // 禁止 TIMER1 中断
 ES     = 1;						   // 串行通讯中断使能
 PS     = 0;                          // UART 低优先级
 TR1    = 1;                          // Start timer1
 P0_ALT = 0x06;                    // Select alternate functions on pins P0.1 and P0.2
 P0_DIR = 0x92;		   // P00-EN485 / P01-RxD  / P02-TxD / P03-DS1820_D
                                       // P04-LED2  / P05-LED3 / P06-JP1 / P07-JP2 
}

// ******************************************************** 
// 2007年7月7日  初始化TIMER0

void InitTimer0(void)
{ 			   // 定时器0的设置
  TR0   = 0;
  TH0   = 0xEB;
  TL0   = 0x2B;
  TMOD |= 0x01;            // Timer0 定时器模式 计数器工作模式 
  ET0   = 1;   	           // Timer0 中断使能
  TR0   = 1;	          // 开启定时器 0
}

// ******************************************************** 
// 2007年7月7日  初始化ADC

void InitADC(void)
{ 
 RACSN = 0;
 SpiRW(WAC);                           // 写ADC配置命令
 SpiRW(0x35);                          // 选择AIN3,ADC启用,内部1.22V电压基准
 SpiRW(0x0B);                          // 12位精度,转换结果右对齐
 RACSN = 1;
} 
// ******************************************************** 
// 2007年7月7日  系统延时子程序

void Delay(unsigned int Num)
{ 
 while(Num--) ;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -