📄 自己修改的主机程序.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 + -