📄 自己修改的从机程序.txt
字号:
// ********************************************************
// CMainPrg.c 简易信号发生器程序从机
// 开发日期 : 2007年11月27日
// 开发环境 : 无线龙C51RF-2开发系统
// ********************************************************
#include <Nordic\reg9e5.h> // nRF9E5的头文件
#include "hWLT.H" // 自定义系统头文件
// 配置寄存器
code unsigned char NRF9E5Config[10] = {
0x6a, // 频道配置
0x0c, // 自动重发关,发送节电模式关,输出功率10db,433MHz
0x44, // 收发地址都为4字节
0x01, // 接收数据长度1字节
0x01, // 发送数据长度1字节
0xe7,
0xe7,
0xe7,
0xe7,
0xdf // CRC开,16位校验,16MHz晶振,外部时钟启用500KHz输出
};
// ********************************************************
// 2007年7月7日 系统主程序
// SysStatus 为系统状态存储器
// 0x00 主机模式, AD采样数据,不进行数据分析,只进行有效的数据信息的传输,
// 0x80 从机模式, 需要对接受到的数据进行分析,产生方波
void main(void)
{
LED2_U=0;
EA = 0; // 禁止所有中断
InitCpu(); // 初始化CPU(含I/O端口)
Init9E5(); // 初始化9E5
InitTimer0(); // 初始化TIMER0
InitTimer2(); // 初始化TIMER2
InitUart(); // 初始化串行通信UART端口
SysStatus = 0x80; // 从机模式
if(SysStatus == 0x80)
// 读配置状态字与地址
LOCA.NO[0] = '0'; // 本机地址 01
LOCA.NO[1] = '1';
EA = 1; // 开总中断
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位
unsigned int adc; // ADC转换结果
unsigned int tmp;
EA = 0; // 在进行温度采样时, 关中断
TF0 = 0; // 清除TIMER0中断标志
TR0 = 0; // 禁止TIMER0计数
TH0 = 0xEB;
TL0 = 0x2B;
if (RFTRx.Flag == 0x0A) //RF接收完成?
{adcl = RFTRx.RBUF[4]; //将RF接收到的AD采样数据存储于数组中
adch = RFTRx.RBUF[5];
adc = adch;
adc = adcl+ (adc << 8);
adc = (unsigned int)((unsigned long)adc*186/4096+10);
tmp = (unsigned int)(65536-(unsigned long)adc*1000/3);
TL1i = tmp&0xff;
TH1i = (tmp&0xff00) >> 8;
RFTRx.Flag = 0; // RF接收标志复位
RFTRx.RNum = 0; // RF接收计数器清0
}
TR0 = 1; // 开始重新计时
TRX_CE = 1; // 重复将RF状态置为收
TXEN = 0;
EA = 1; // 中断总允许开启
}
// ********************************************************
// 2007年7月7日 串行通信接收中断服务程序
void ISPUart() interrupt 4
{
}
// ********************************************************
// 2007年4月23日 RF接收中断服务程序
void ISRRF905(void) interrupt 10
{
EA = 0;
EXIF = EXIF & 0xBF;
RACSN = 0;
SpiRW(RRP);
GRFChar = SpiRW(0);
if (RFTRx.Flag != 0x0A) //是否是接受有效标志,准备开始接受
{ RFTRx.RBUF[RFTRx.RNum] = GRFChar;
if (RFTRx.RNum == 0) // 先判断第一个字符
{ if (GRFChar == STCB) // 数据读取命令首字符
RFTRx.RNum ++; // 是首字符. 继续等待其他字符
else
RFTRx.RNum = 0; // 不是首字符, 忽略重等
}
else
{ if (RFTRx.RNum <= MAXC) // 字符串最大长度18
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语句用于检测地址的
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日 Timer2定时器中断服务程序
void ISPTimer2(void) interrupt 5
{ EA = 0; //关闭中断
TR2 = 0;
TF2 = 0;
TL2 = TL1i;
TH2 = TH1i;
Sloop++;
if(Sloop == 4)
{
Sloop = 0;
SOUT=~SOUT;
}
LED3_D=0;
EA = 1;
TR2 = 1;
}
// ********************************************************
// 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) ;
Loop ++;
}
TRX_CE = 1;
TXEN = 0;
}
// ********************************************************
// 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 |= 0x10; // 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日 初始化TIMER2
void InitTimer2(void)
{
TR2 = 0;
TL2 = TL1i;
TH2 = TH1i;
T2CON = 0; // 定时器2的设置//自动重装载模式
ET2 = 1; // 中断使能
PT2 = 1; // 高优先级
TR2 = 1;
}
// ********************************************************
// 2007年7月7日 系统延时子程序
void Delay(unsigned int Num)
{
while(Num--) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -