有会编写485通讯C程序的吗

如题所述

//-----------------------函数声明,变量定义---------------------
#include <reg51.h>
sbit RE_DE=P1^0;
#define COUNT 10 // 定义接收缓冲区大小
#define Slaver_NUM 10

unsigned char bdata flag; //在可位寻址去定义一个标志变量
sbit time_over_flag =flag^0; //接收超时标志

unsigned char buffer[COUNT]; //定义缓冲区
unsigned char point; //定义缓冲区位置指示

unsigned char Slave_AD[Slaver_NUM]; //定义有效地址存放区
unsigned char ADD_num; //有效地址个数

unsigned char idata count_10ms; //用于表示有多少次10ms中断

unsigned char idata send_data[7]={
0x31,0x32,0x33,0x34,0x35,0x36,0x37}; //与定义发送数据,共7位

void UART_init(); //串口初始化函数
void COM_send(void); //串口接收函数
unsigned char CLU_checkdata(void); //计算校验位函数

//---------------------------------------------------------------
// 函数名称: UART_init()串口初始化函数
// 函数功能: 在系统时钟为11.059MHZ时,设定串口波特率为9600bit/s
// 串口接收中断允许,发送中断禁止,设定定时器中断允许
//---------------------------------------------------------------
void UART_init()
{
//初始化串行设置
SCON =0x58; //选择串口工作方式为1,打开接收允许,TB8=1
TMOD =0x21; //定时器1工作在方式2,定时器0工作在方式1
TR1 =1; //启动定时器T1
ES=1; //允许串行口中断
PS=1; //设计串行口中断优先级
//初始化定时器1
TH1 =0xfd; //实现波特率9600(系统时钟11.0592MHZ)
ET1 =0; //定时器1中断禁止
}
//---------------------------------------------------------------
// 函数名称: timer0_init()初始化定时器0
// 函数功能: 设置timer0工作模式
//---------------------------------------------------------------
void timer0_init()
{
time_over_flag=0;
count_10ms=0;
ADD_num=0;
TL0=0x0F0; //T0用于产生10ms的中断
TH0=0x0D8; //50次T0中断产生1次超时溢出
ET0=1; //允许定时器0中断
}
//---------------------------------------------------------------
// 函数名称: system_init()系统初始化
// 函数功能: 调用串口、定时器初始化函数,完成系统初始化
//---------------------------------------------------------------
void system_init(void)
{
//系统总设置
UART_init();
timer0_init();
EA =1; //单片机中断允许
}
//---------------------------------------------------------------
// 函数名称: com_interrup()串口接收中断处理函数
// 函数功能: 接收包括起始位"S"在内的十位数据到数据缓冲区
//---------------------------------------------------------------
com_interrupt(void) interrupt 4 using 3
{
unsigned char RECEIVR_buffer;
if(RI) //处理接收中断
{RI=0; //清除中断标志位
RECEIVR_buffer=SBUF; //接收串口数据
if(point==0) //如果还没有接收到起始位
{
if(RECEIVR_buffer==0xFE) //判断是否起始标志位
{
buffer[point++]=RECEIVR_buffer;//把接收到的数据放入接收缓存区
}
else
point=0; //不是,继续等待起始位
}
else if(point>0&&point<10) //判断是否接收够十位数据
buffer[point++]=RECEIVR_buffer; //不够,把接收到的数据放入接收缓存区
else if(point==10)
{
if(RECEIVR_buffer==0xEF) //判断结束标志位是否正确
{
buffer[point]=RECEIVR_buffer; //把接收到的数据放入接收缓存区
Slave_AD[ADD_num++]=buffer[2]; //把接收到的地址放到地址存储器
//表示该地址有有效设备
}
else
point=0; //不是,继续等待起始位
}
else point=0; //缓冲区已满,清除缓存区内数据重新接收
}
if(TI) //串口发送中断
{
TI=0; //清除发送中断
}
}
//---------------------------------------------------------------
// 函数名称: timer0_interrup()
// 函数功能:定时器T0中断服务程序
// 函数说明:T0枚10ms中断一次,连续中断50次置time_over_flag=1;
//---------------------------------------------------------------
timer0_interrupt(void) interrupt 1 using 2
{
count_10ms++;
if(count_10ms==50)
{
ET0=0; //关闭定时器T0中断
TR0=0; //停止定时器T0
time_over_flag=1;//设置接收超时标志
count_10ms=0x00; //10ms计数器复位
}
else
{
TL0=0x0F0; //重装定时器初始值
TH0=0x0D8;
}
}

//---------------------------------------------------------------
// 函数名称: COM_send()串口发送函数
// 函数功能: 把数据缓冲区的十位数据发送出去
//---------------------------------------------------------------
void COM_send(void)
{
RE_DE=1; //设置MAX483进入发送状态
for(point=0;point<=10,TI=1;point++) //连续发送十位数据
//把缓存区的数据都发送到串口
{
SBUF=buffer[point];
TI=0;
}
RE_DE=0; //设置MAX483进入接收状态

}
//---------------------------------------------------------------
// 函数名称: write_buffer()
// 函数功能: 写发送缓冲区十位数据
//---------------------------------------------------------------
void write_buffer(unsigned char slaver_add)
{
unsigned char i;
TB8=1; //打开多机通信方式
buffer[0]=0xFE;
buffer[1]=slaver_add;
for(i=2;i<9;i++) //连续发送十位数据
//把缓存区的数据都发送到串口
{
buffer[i]=send_data[i-2];
}
buffer[9]=0xEF;
}

//---------------------------------------------------------------
// 函数名称: 主函数
// 函数功能: 调度个子函数,完成通信过程
//---------------------------------------------------------------
void main(void)
{
unsigned char i=0;
system_init(); //系统初始化
do{ //查旬0到10好地址有没有对应设备
write_buffer(i++); //写查询第i号设备的发送信息
COM_send(); //调用发送函数,完成发送
timer0_init(); //完成一次查询,重新初始定时器0,准备下一次查询
}
while(time_over_flag&&i<10);
}
这个比较详细注释,希望对你有所帮助吧!
温馨提示:答案为网友推荐,仅供参考
第1个回答  2020-01-01
//-----------------------函数声明,变量定义---------------------
#include
<reg51.h>
sbit
RE_DE=P1^0;
#define
COUNT
10
//
定义接收缓冲区大小
#define
Slaver_NUM
10
unsigned
char
bdata
flag;
//在可位寻址去定义一个标志变量
sbit
time_over_flag
=flag^0;
//接收超时标志
unsigned
char
buffer[COUNT];
//定义缓冲区
unsigned
char
point;
//定义缓冲区位置指示
unsigned
char
Slave_AD[Slaver_NUM];
//定义有效地址存放区
unsigned
char
ADD_num;
//有效地址个数
unsigned
char
idata
count_10ms;
//用于表示有多少次10ms中断
unsigned
char
idata
send_data[7]={
0x31,0x32,0x33,0x34,0x35,0x36,0x37};
//与定义发送数据,共7位
void
UART_init();
//串口初始化函数
void
COM_send(void);
//串口接收函数
unsigned
char
CLU_checkdata(void);
//计算校验位函数
//---------------------------------------------------------------
//
函数名称:
UART_init()串口初始化函数
//
函数功能:
在系统时钟为11.059MHZ时,设定串口波特率为9600bit/s
//
串口接收中断允许,发送中断禁止,设定定时器中断允许
//---------------------------------------------------------------
void
UART_init()
{
//初始化串行设置
SCON
=0x58;
//选择串口工作方式为1,打开接收允许,TB8=1
TMOD
=0x21;
//定时器1工作在方式2,定时器0工作在方式1
TR1
=1;
//启动定时器T1
ES=1;
//允许串行口中断
PS=1;
//设计串行口中断优先级
//初始化定时器1
TH1
=0xfd;
//实现波特率9600(系统时钟11.0592MHZ)
ET1
=0;
//定时器1中断禁止
}
//---------------------------------------------------------------
//
函数名称:
timer0_init()初始化定时器0
//
函数功能:
设置timer0工作模式
//---------------------------------------------------------------
void
timer0_init()
{
time_over_flag=0;
count_10ms=0;
ADD_num=0;
TL0=0x0F0;
//T0用于产生10ms的中断
TH0=0x0D8;
//50次T0中断产生1次超时溢出
ET0=1;
//允许定时器0中断
}
//---------------------------------------------------------------
//
函数名称:
system_init()系统初始化
//
函数功能:
调用串口、定时器初始化函数,完成系统初始化
//---------------------------------------------------------------
void
system_init(void)
{
//系统总设置
UART_init();
timer0_init();
EA
=1;
//单片机中断允许
}
//---------------------------------------------------------------
//
函数名称:
com_interrup()串口接收中断处理函数
//
函数功能:
接收包括起始位"S"在内的十位数据到数据缓冲区
//---------------------------------------------------------------
com_interrupt(void)
interrupt
4
using
3
{
unsigned
char
RECEIVR_buffer;
if(RI)
//处理接收中断
{RI=0;
//清除中断标志位
RECEIVR_buffer=SBUF;
//接收串口数据
if(point==0)
//如果还没有接收到起始位
{
if(RECEIVR_buffer==0xFE)
//判断是否起始标志位
{
buffer[point++]=RECEIVR_buffer;//把接收到的数据放入接收缓存区
}
else
point=0;
//不是,继续等待起始位
}
else
if(point>0&&point<10)
//判断是否接收够十位数据
buffer[point++]=RECEIVR_buffer;
//不够,把接收到的数据放入接收缓存区
else
if(point==10)
{
if(RECEIVR_buffer==0xEF)
//判断结束标志位是否正确
{
buffer[point]=RECEIVR_buffer;
//把接收到的数据放入接收缓存区
Slave_AD[ADD_num++]=buffer[2];
//把接收到的地址放到地址存储器
//表示该地址有有效设备
}
else
point=0;
//不是,继续等待起始位
}
else
point=0;
//缓冲区已满,清除缓存区内数据重新接收
}
if(TI)
//串口发送中断
{
TI=0;
//清除发送中断
}
}
//---------------------------------------------------------------
//
函数名称:
timer0_interrup()
//
函数功能:定时器T0中断服务程序
//
函数说明:T0枚10ms中断一次,连续中断50次置time_over_flag=1;
//---------------------------------------------------------------
timer0_interrupt(void)
interrupt
1
using
2
{
count_10ms++;
if(count_10ms==50)
{
ET0=0;
//关闭定时器T0中断
TR0=0;
//停止定时器T0
time_over_flag=1;//设置接收超时标志
count_10ms=0x00;
//10ms计数器复位
}
else
{
TL0=0x0F0;
//重装定时器初始值
TH0=0x0D8;
}
}
//---------------------------------------------------------------
//
函数名称:
COM_send()串口发送函数
//
函数功能:
把数据缓冲区的十位数据发送出去
//---------------------------------------------------------------
void
COM_send(void)
{
RE_DE=1;
//设置MAX483进入发送状态
for(point=0;point<=10,TI=1;point++)
//连续发送十位数据
//把缓存区的数据都发送到串口
{
SBUF=buffer[point];
TI=0;
}
RE_DE=0;
//设置MAX483进入接收状态
}
//---------------------------------------------------------------
//
函数名称:
write_buffer()
//
函数功能:
写发送缓冲区十位数据
//---------------------------------------------------------------
void
write_buffer(unsigned
char
slaver_add)
{
unsigned
char
i;
TB8=1;
//打开多机通信方式
buffer[0]=0xFE;
buffer[1]=slaver_add;
for(i=2;i<9;i++)
//连续发送十位数据
//把缓存区的数据都发送到串口
{
buffer[i]=send_data[i-2];
}
buffer[9]=0xEF;
}
//---------------------------------------------------------------
//
函数名称:
主函数
//
函数功能:
调度个子函数,完成通信过程
//---------------------------------------------------------------
void
main(void)
{
unsigned
char
i=0;
system_init();
//系统初始化
do{
//查旬0到10好地址有没有对应设备
write_buffer(i++);
//写查询第i号设备的发送信息
COM_send();
//调用发送函数,完成发送
timer0_init();
//完成一次查询,重新初始定时器0,准备下一次查询
}
while(time_over_flag&&i<10);
}
这个比较详细注释,希望对你有所帮助吧!
第2个回答  2012-11-07
百度文库 里有

还有

建议 去 我的领地 5d6d 的 proteus 论坛看看

那里有很多 单片机仿真实例,包括仿真图 和 源码
搜 5d6d 和 proteus 2个关键词

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网