#include"uart1.h"
uchar Recv_buf[60];//接收字节缓冲区
uchar flagFrame = 0; //帧接收完成标志,即接收到一帧新数据
unsigned char cntRxd = 0; //接收字节计数
/**********************************************************************************
- 功能描述: 串口1初始化
- 隶属模块: 外部
- 参数说明: 无
- 返回说明: 无
- 注: 都是9600波特率
**********************************************************************************/
void Uart1_init(ushort baud)
{
//接收状态和控制(RCSTAx)
TXSTA1bits.BRGH=0;//发送状态和控制(TXSTAx) 波特率选择位 1 = 高速,0 = 低速
BAUDCON1bits.BRG16=0; //波特率控制(BAUDCONx)16 位波特率寄存器使能位,1 = 16 位波特率发生器??SPBRGHx 和SPBRGx,0 = 8 位波特率发生器??仅限SPBRGx (兼容模式), SPBRGHx 值被忽略
SPBRG1=baud;
SPBRGH1=baud>>8;
TXSTA1bits.SYNC = 0;//异步模式 EUSART 模式选择位,1 = 同步模式,0 = 异步模式,
RCSTA1bits.SPEN = 1;//使能串口,串口使能位,1 = 使能串口(将RXx/DTx 和TXx/CKx 引脚配置为串口引脚),0 = 禁止串口(保持在复位状态)
TRISC |= 0x80;//RCbits.RC7 = 1;RX1 接收
TRISC &= 0xBF;//RCbits.RC6 = 0; TX1 发送
TXSTA1bits.TXEN = 1;//发送使能 发送使能位
RCSTA1bits.CREN = 1;//接收使能 连续接收使能位
RCREG1 = 0;//EUSART1 接收寄存器
IPR1bits.RC1IP = 0;//设置串口接收中断为低优先级中断 EUSART 接收中断优先级位
PIE1bits.RC1IE = 1;//串口1接收中断允许
}
/**********************************************************************************
- 功能描述: 串口发送一个字节
- 隶属模块: 外部
- 参数说明:
- 返回说明:
- 注:
***********************************************************************************/
void Uart_PutByte(uchar byte)
{
TXREG1 = byte;//EUSART1 发送寄存器
while(! TXSTA1bits.TRMT) ; //发送移位寄存器状态位,1 = TSR 空,0 = TSR 满
}
/**********************************************************************************
- 功能描述: 串口发送一串字节
- 隶属模块: 外部
- 参数说明:
- 返回说明:
- 注:
***********************************************************************************/
void SendArrayUart(uchar* array,uchar len)
{
while (len--) //循环发送所有字节
{
TXREG1 = *array++;//EUSART1 发送寄存器
while(! TXSTA1bits.TRMT) ; //发送移位寄存器状态位,1 = TSR 空,0 = TSR 满
}
}
/* 串口数据读取函数,buf-接收指针,len-指定的读取长度,返回值-实际读到的长度 */
unsigned char UartRead(unsigned char *buf, unsigned char len)
{
unsigned char i;
if (len > cntRxd) //指定读取长度大于实际接收到的数据长度时,
{ //读取长度设置为实际接收到的数据长度
len = cntRxd;
}
for (i=0; i<len; i++) //拷贝接收到的数据到接收指针上
{
*buf++ = Recv_buf[i];
}
cntRxd = 0; //接收计数器清零
return len; //返回实际读取长度
}
/* 串口接收监控,由空闲时间判定帧结束,需在定时中断中调用,ms-定时间隔 */
void UartRxMonitor(unsigned char ms)
{
static unsigned char cntbkp = 0;
static unsigned char idletmr = 0;
if (cntRxd > 0) //接收计数器大于零时,监控总线空闲时间
{
if (cntbkp != cntRxd) //接收计数器改变,即刚接收到数据时,清零空闲计时
{
cntbkp = cntRxd;
idletmr = 0;
}
else //接收计数器未改变,即总线空闲时,累积空闲时间
{
if (idletmr < 30) //空闲计时小于30ms时,持续累加
{
idletmr += ms;
if (idletmr >= 30) //空闲时间达到30ms时,即判定为一帧接收完毕
{
flagFrame = 1; //设置帧接收完成标志
}
}
}
}
else
{
cntbkp = 0;
}
}
/* 串口动作函数,根据接收到的命令帧执行响应的动作
buf-接收到的命令帧指针,len-命令帧长度 */
void UartAction(unsigned char *buf, unsigned char len)//处理雷达数据和RTU指令
{
unsigned int xiaoyan=0;//校验计算缓存
unsigned int signal_buf=0;//信号计算缓存
unsigned int juli_buf=0;//距离计算缓存
unsigned char xiaoyan2=0;
unsigned char i=0;
unsigned int crc;
unsigned char crch, crcl;
//收到字符 return 返回参数当前值
if( (buf[0] == 'r')&&(buf[1]== 'e')&&(buf[2]== 't')&&(buf[3]== 'u')&&(buf[4]== 'r')&&(buf[5] == 'n'))//收到字符 return 返回参数当前值
{
buf[0]=(unsigned char)(signal_up>>8);//信号强度上限
buf[1]=(unsigned char)signal_up;//信号强度上限
buf[2]=(unsigned char)(signal_down>>8);//信号强度下限
buf[3]=(unsigned char)signal_down;
buf[4]=(unsigned char)(juli_up>>8);//距离上限
buf[5]=(unsigned char)juli_up;
buf[6]=(unsigned char)(juli_down>>8);//距离下限
buf[7]=(unsigned char)juli_down;
buf[8]=(unsigned char)(led_on_time>>8);//开灯时间
buf[9]=(unsigned char)led_on_time;
buf[10]=Add;//灯地址
buf[11]=(unsigned char)(relay_jiange_time>>8);//继电器开启间隔时间
buf[12]=(unsigned char)relay_jiange_time;
buf[13]=(unsigned char)(relay_out_time>>8);//继电器开启时间
buf[14]=(unsigned char)relay_out_time;
SendArrayUart(buf,15);
return;
}
//处理雷达数据
if(len==9)//处理雷达数据 0=59 1=59 2距离低 3距离高CM 4STREN低 5STREN高 大于100且不等于65535距离有效 6TEMP低 7TEMP高 8校验 前8字节相加 取低8位
{
for(i=0;i<8;i++)
{
xiaoyan+=buf[i];
}
xiaoyan2=(unsigned char)xiaoyan;
if(xiaoyan2!=buf[8])return;
signal_buf=buf[5];
signal_buf<=8;
signal_buf+=buf[4];
if( (signal_buf<signal_down)||(signal_buf>signal_up) )return;//信号强度小于下限 大于上限 不处理
juli_buf=buf[3];//计算距离
juli_buf<=8;
juli_buf+=buf[2];
if( (juli_buf>juli_down)&&(juli_buf<juli_up) )//距离大于下限 小于上限 点灯
{
led_on_fig=1;//开灯标志 1开灯 2关灯
led_on_cnt=2;//开灯次数
}
return;
}
//处理RTU数据 设置参数
if (buf[0] != Add) //本例中的本机地址设定为0x01,
{ //如数据帧中的地址字节与本机地址不符,
return; //则直接退出,即丢弃本帧数据不做任何处理
}
crc = GetCRC16(buf, len-2); //计算CRC校验值
crch = crc >> 8;
crcl = crc & 0xFF;
if ((buf[len-2]!=crch) || (buf[len-1]!=crcl))
{
return; //如CRC校验不符时直接退出
}
switch (buf[1])
{
case 0x10://写多个寄存器 01 10 20 00 (00 0a寄存器数量) (14字节数) (寄存器值1) (寄存器值2) (寄存器值3) (寄存器值4) (寄存器值5) (寄存器值6) (寄存器值7) (寄存器值8) (寄存器值9) (寄存器值10) 校验
if((buf[2]==0x20) && (buf[3]==0x00))
{
if((buf[4]==0x00) && (buf[5]==0x0a))//寄存器个数00 02
{
if(buf[6]==0x14)//字节数 20个
{
signal_up=buf[7];//信号强度上限
signal_up<<=8;
signal_up+=buf[8];
signal_down=buf[9];//信号强度下限
signal_down<<=8;
signal_down+=buf[10];
juli_up=buf[11];//距离上限
juli_up<<=8;
juli_up+=buf[12];
juli_down=buf[13];//距离下限
juli_down<<=8;
juli_down+=buf[14];
led_on_time=buf[15];//LED点亮时间
led_on_time<<=8;
led_on_time+=buf[16];
Add=buf[18];//灯地址
relay_jiange_time=buf[19];//继电器输出间隔时间
relay_jiange_time<<=8;
relay_jiange_time+=buf[20];
relay_out_time=buf[21];//继电器输出时长
relay_out_time<<=8;
rel
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
22CPU1.zip (66个子文件)
45k22CPU1
45k22
Source
eeprom.c 4KB
uart1.h 475B
uart1.c 9KB
main.c 6KB
timer.c 2KB
timer.h 609B
uart2.h 482B
relay.c 298B
crc16.h 211B
config.h 1KB
pic_it.c 1KB
config.c 1KB
uart2.c 5KB
eeprom.h 411B
relay.h 175B
crc16.c 4KB
Project
CPU1.X
dist
default
production
CPU1.X.production.rlf 346KB
CPU1.X.production.mum 465B
CPU1.X.production.obj 37KB
CPU1.X.production.sym 19KB
CPU1.X.production.sdb 18KB
memoryfile.xml 449B
CPU1.X.production.cmf 62KB
CPU1.X.production.hex 11KB
CPU1.X.production.hxl 5KB
CPU1.X.production.lst 270KB
CPU1.X.production.map 59KB
CPU1.X.production.elf 28KB
build
default
production
_ext
1787047461
eeprom.pre 169KB
config.p1.d 161B
pic_it.pre 169KB
uart2.p1.d 208B
config.pre 168KB
relay.pre 168KB
uart2.pre 170KB
eeprom.p1.d 187B
crc16.p1.d 183B
uart1.pre 172KB
timer.pre 168KB
main.pre 172KB
crc16.pre 171KB
timer.p1.d 183B
uart2.p1 333KB
uart1.p1.d 208B
timer.p1 325KB
pic_it.p1 326KB
uart1.p1 342KB
main.p1.d 306B
config.p1 324KB
relay.p1 323KB
pic_it.p1.d 261B
eeprom.p1 327KB
relay.p1.d 183B
main.p1 337KB
crc16.p1 336KB
Makefile 3KB
debug
default
nbproject
Makefile-variables.mk 411B
Makefile-genesis.properties 491B
private
SuppressibleMessageMemo.properties 69B
configurations.xml 1024B
Makefile-default.mk 26KB
project.xml 1KB
Package-default.bash 1KB
configurations.xml 9KB
Makefile-impl.mk 2KB
Makefile-local-default.mk 2KB
共 66 条
- 1
资源评论
- weixin_472846752022-08-18用MPLAB XC8用的是哪个版本打开的,我打开后好多都显示没定义IOCB = 0; // pb口,电平变化中断允许 WPUB = 0; // pb口,弱上拉功能 HLVDCON = 0; // 高低压检测 SLRCON = 0; // 压摆控制寄存器 ANSELC = 0x00; ANSELD小白q_57935452023-07-05用MPLAB XIDE这个开发环境
- zhaomingfu19852022-09-10感谢资源主分享的资源解决了我当下的问题,非常有用的资源。
小白q_5793545
- 粉丝: 19
- 资源: 90
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功