📄 send_485.c
字号:
/*****************************************************
* File name : Send_485.C
* Description : Header file of main_H.H
* Platform : ICCAVR
* Author : xiao xue
* Email : ay1509@yahoo.com
* Date : 2008-03-13
* Description :485 Communications
/********************头文件*************************/
#include"main_H.h"
#define fosc 8000000
#define baud 9600
/***************************485初始化***************************/
void RS485_init(void)
{
UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN); //接收完成中断使能
//充许发送、充许接收
UBRRL=(fosc/16/(baud+1))%256; //波特率为9600
UBRRH=(fosc/16/(baud+1))/256;
UCSRC=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);
PORTD&=~0x04; //允许接收数据
DDRD|=0x04; //数据方向
}
/******************485发送一个字节子程序************************/
void RS485_out_byte(uchar data )
{
while(!(UCSRA & (1<<UDRE)) ); //等待数据寄存器不为空
UDR=data;
while(!(UCSRA & (BIT(TXC)))); //等待USART发送完成
UCSRA|=BIT(TXC);
}
/**************************一次发送6个字节*********************/
void RS485_out_6byte(uchar *datas )
{
uint i=0;
CLI(); //关中断
PORTD|=0x04; //允许发送
while(i<6 ){
RS485_out_byte(*(datas+i)); //发送1个字节
i++;
}
delay_nms(5); //延时
PORTD&=~0x04; //允许接收
SEI();
}
/**************************485发送数据函数*****************/
void Send_485(void)
{
RS485_out_6byte(moto1); //给节点1发送数据
RS485_out_6byte(moto2); //给节点2发送数据
RS485_out_6byte(moto3);
RS485_out_6byte(moto4);
}
/***************************中断接收服务子程序*******************/
#pragma interrupt_handler RS485_ISR:iv_USART_RX
void RS485_ISR(void)
{
CLI(); //关中断
PORTD&=~0x04; //允许接收
getchar[RS_i]=UDR; //存储数据寄存器的值
RS_i++; //预备存储下一个
if(RS_i==6) //接收6个后清零
{RS_i=0;flag=3;}
SEI(); //开中断
}
/**********************接收数组判断存储子程序************************/
void data_decide(void)
{
uchar RS_j=0;
if(getchar[0]==0xaa){
switch(getchar[1]){
case 0x1e: //节点1
while(RS_j<6){
get[0+RS_j]=getchar[RS_j];
RS_j++;
}
break;
case 0x2d: //节点2
while(RS_j<6){
get[6+RS_j]=getchar[RS_j];
RS_j++;
}
break;
case 0x3c: //节点3
while(RS_j<6){
get[12+RS_j]=getchar[RS_j];
RS_j++;
}
break;
case 0x4b: //节点4
while(RS_j<6){
get[18+RS_j]=getchar[RS_j];
RS_j++;
}//end while
break;
}//end switch
}//end if
}
/***************************各电机停止函数,相关变量清零***********/
void moto_stop(void)
{
moto1[2]=0xb4; //向各节点停止命令
moto2[2]=0xb4;
moto3[2]=0xb4;
moto4[2]=0xb4;
get[2]=0x00; //接收控制指令数组清零
get[8]=0x00;
get[14]=0x00;
get[20]=0x00;
status[2]=0; //状态数组之时间清0
TIMSK=0x00; //定时器关闭
page=4; //显示第四页停止页面
flag=2; //flag标志清零
}
/**************运动到达指定循环步数之前***********/
void step_for(void)
{
moto1[4]=p[++i]; //存储各节点的运动速度(时间)
moto2[4]=p[i];
moto3[4]=p[i];
moto4[4]=p[i];
i++;
moto1[3]=p[i++]; //存储各节点的运动位置
moto2[3]=p[i++];
moto3[3]=p[i++];
moto4[3]=p[i];
flag=2; //主函数flag标志置数
}
/***************运动到达指定循环步数之后***********/
void step_back(void)
{
moto1[4]=p[i]; //存储各节点运动速度(时间)
moto2[4]=p[i];
moto3[4]=p[i];
moto4[4]=p[i];
i++; //变量加1,准备执行下一步
moto1[3]=p[i++]*status[1]/0x64; //运动位置转换后存储
moto2[3]=p[i++]*status[1]/0x64;
moto3[3]=p[i++]*status[1]/0x64;
moto4[3]=p[i++]*status[1]/0x64;
flag=2; //主函数flag标志置数
}
/***************************接收数据决断子程序*******************/
void RS485_getchar(void)
{
data_decide(); //接收数组判断存储子程序
while(1){
if(second==status[2]){ //运动时间到
moto_stop(); //电机停止函数
break;
}//end if
if((get[2]==0xff)&&(get[8]==0xff)&& //各节点电机都已停止
(get[14]==0xff)&&(get[20]==0xff)){
get[2]=0x00; //各节点控制指令清零
get[8]=0x00;
get[14]=0x00;
get[20]=0x00;
if(i<((p[1]-1)*5+1)){ //未到达设定的循环开始步数
step_for(); //相应处理函数
}//end if
else if((i>(p[1]-1)*5+1)&&(j==1)){ //已经到达设定的运动步数
step_back(); //相应处理函数
}//end else if
else{ //是否到达运动循环开始的第一步
j=1;
i=((p[1]-1)*5+2); //准备执行下一步
}//end else
if(i==(p[0]*5+2)){ //是否到达最后一步
i=(p[1]-1)*5+2; //重新从第一条指令开始执行
}//end if
}//end if
}//end while
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -