MODBUS协议ASCII模式串口通讯的实现(Arm2410,RS232/485)

发布者:buzzedy最新更新时间:2017-01-08 来源: eefocus关键字:MODBUS协议  ASCII模式  串口通讯 手机看文章 扫描二维码
随时随地手机看文章

资源使用说明: 2410+LINUX、UART(即RS-232串口)全双工通信、RS-485半双工通信

 

局部程序框图及其设计说明:

 

调试记录及调试结果:

 

 

MODBUS总结:

                                                             MODBUS协议

对比:

ASCII模式:用8位表示一个由内容字符转化而来的实际数值,直观;

RTU模式  :用4位表示一个由内容字符转化而来的实际数值,效率高。

其它编程注意点总结:

1、分母或乘数为2的n次方的乘除法用移位运算以提高效率,注意移位运算符的优先级比加减运算符低,别忘了加括号先算移位的;

2、short两个字节,long四个字节,int则与机器字长相关。

3、在使用多个输出函数连续进行多次输出时,有可能发现输出错误。因为下一个数据再上一个数据还没输出完毕,还在输出缓冲区中时,下一个printf就把另一个数据加入输出缓冲区,结果冲掉了原来的数据,出现输出错误。 在 prinf();后加上fflush(stdout); 强制马上输出,避免错误。

4、menset()用法:  char arr[20]; memset(arr,'\0',20);

5、#if 0   code    #endif :

(1)code中定义的是一些调试版本的代码,此时code完全被编译器忽略。如果想让code生效,只需把#if 0改成#if 1

(2)#if 0还有一个重要的用途就是用来当成注释,如果你想要注释的程序很长,这个时候#if 0是最好的,保证不会犯错误。(但是林锐的书上说千万不要把#if 0 来当作块注释使用)

#if 1可以让其间的变量成为局部变量。

(3)这个结构表示你先前写好的code,现在用不上了,又不想删除,就用这个方法,比注释方便。

 

程序代码清单:

/**************************************************************************   

// tzdcs.c, need insmod mfix.o & m485.o first.

//

//    Data Collect System  Ver1.0

//

//                 base on  MODBUS protocol (Mode:ASCII)     

//                          Processor: Arm2410

//   

// MODBUS protocol:   

//  (Mode:ASCII) 

// START FLAG ( 0x3A ---- ':' )   

// NET ADDRESS HIGH     

// NET ADDRESS LOW 

// COMMAND HIGH   

// COMMAND LOW

// DATA LENGTH ( two char: n like '02')   

// DATABUF ( n char: data_0 ~ data_n-1 )   

// LRC HIGH   

// LRC LOW   

// END FLAG ( two char: 0x0D 0x0A ---- 'CRLF' )  

//   

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//  START_FLAG AddrHigh AddrLow CmdHigh CmdLow DataLenHigh DataLenLow   DataBuf[]   LrcHigh LrcLow END_FLAG_1 END_FLAG_2

//     0x3A                                                          data_0~data_n-1                  0x0D       0x0A

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//   

// Author: JaneEstrong 

// Email:  JaneEstrong@gmail.com 

// Date:   2012.09.10

//   

**************************************************************************/  

 

#include

#include

#include

#include

#include

//#include

#include

 

////////////////////////////////////////

#define _485_IOCTRL_RE2DE            (0x10)                                   //send or receive

#define _485_RE                          0                                                        //receive

#define _485_DE                          1                                                        //send

 

//#define BAUDRATE B115200

#define COM1 "/dev/tts/1"//ttyS1  RS232

#define COM2 "/dev/tts/2"//       RS485

#define DEV485 "/dev/485/0raw"

 

////////////////////////////////////////

#define MASTER  //主机标志

#define START_FLAG 0x3A  //  ':'

#define END_FLAG_1 0x0D  //  CR

#define END_FLAG_2 0x0A  //  LF

 

// rx_result

#define NOT_SEND_TO_US   0

#define ERROR_LENGTH     1

#define ERROR_LRC        2

#define ERROR_END_FLAG   3

#define VALID_PACKET     4

 

//uchStatus

#define MASTER_WAITING_RECEIVE_FROM_PC 1

#define NOT_MASTER_WAITING_RECEIVE_FROM_PC 2

////////////////////////////////////////

 

typedef unsigned char uchar;

 

//struct   

//{   

//static uchar uchStartFlag;

            static uchar uchOurAddrHigh='0',uchOurAddrLow='1';  //Local Address

static uchar uchNetAddrHigh,uchNetAddrLow;

            static uchar uchCmd;

static uchar uchCmdHigh,uchCmdLow;

            static uchar uchDataLen;

static uchar uchDataLenHigh, uchDataLenLow;

static uchar auchDataBuf[222];

            static uchar uchCalcLrcCode;

static uchar uchCalcLrcHigh, uchCalcLrcLow;

            static uchar uchRxLrcCode;

static uchar uchRxLrcHigh, uchRxLrcLow; 

//static uchar uchEndFlag1,uchEndFlag2;

static uchar uchStatus=0;

//} Modbus_Protocol; 

 

/**************************  Functions Declare  **************************/

uchar Ascii_To_Num(uchar a);

uchar Num_To_Ascii(uchar n);

void Float16_To_String(float f, uchar *str);

 

void Send_Char(int fdcom, uchar ch);

void Receive_Char(int fdcom, uchar *ch);

void Modbus_Send_Packet(int fdcom);

uchar Modbus_Receive_Decode(int fdcom);

void Report_Rx_Result(uchar result);

void Reply(int fdcom, uchar rx_result);

 

static void Help_Menu(void);

static int Get_Baudrate(char** argv); 

 

/**********************************************************************

* 函数名称 : main

* 函数功能 : 程序主入口函数

* 入口参数 : 无        

* 出口参数 : 无

**********************************************************************/     

int main(int argc, char **argv)

{

            int fd485, fdcom1, fdcom2;

            struct termios oldtio1,newtio1,oldstdtio1,newstdtio1;

            struct termios oldtio2,newtio2,oldstdtio2,newstdtio2;

            int baud;

            /////////////////////////

            uchar rx_result;

            /////////////////////////

           

            if((argc > 3 ) ||(argc == 1)){

                       Help_Menu();

                       exit(0);

            }

           

            fd485 = open(DEV485,O_RDWR);

            if(fd485 < 0)

            {

                       printf("####s3c2410 485 device open fail####\n");

                       return (-1);

            }

            fdcom1 = open(COM1, O_RDWR );//| O_NOCTTY |O_NONBLOCK);

            if (fdcom1 <0)

            {

                    perror(COM1);

                    exit(-1);

          }

            fdcom2 = open(COM2, O_RDWR );

            if (fdcom2 <0)

            {

                    perror(COM2);

                    exit(-1);

          }

            if((baud=Get_Baudrate(argv)) == -1) {

                       printf("####s3c2410 RS device baudrate set failed####\n");

            }         

           

            /*RS232 Init*/

          tcgetattr(0,&oldstdtio1);//获取终端属性

          tcgetattr(fdcom1,&oldtio1); /* save current modem settings */

          tcgetattr(fdcom1,&newstdtio1); /* get working stdtio */

            newtio1.c_cflag = baud | CRTSCTS | CS8 | CLOCAL | CREAD;/*ctrol flag*/

            newtio1.c_iflag = IGNPAR; /*input flag*/

            newtio1.c_oflag = 0;                     /*output flag*/

           newtio1.c_lflag = 0;

           newtio1.c_cc[VMIN]=1;

            newtio1.c_cc[VTIME]=0;     

           tcflush(fdcom1, TCIFLUSH);//刷清未决输入和/或输出

            tcsetattr(fdcom1,TCSANOW,&newtio1);//设置终端属性

           

            /*RS485 Init*/

          tcgetattr(0,&oldstdtio2);//获取终端属性

          tcgetattr(fdcom2,&oldtio2); /* save current modem settings */

          tcgetattr(fdcom2,&newstdtio2); /* get working stdtio */

            newtio2.c_cflag = baud | CRTSCTS | CS8 | CLOCAL | CREAD;/*ctrol flag*/

            newtio2.c_iflag = IGNPAR; /*input flag*/

            newtio2.c_oflag &= ~(ICANON | ECHO | ECHOE | ISIG);             /*output flag*/

           newtio2.c_lflag &= ~OPOST;//原始数据输出

           newtio2.c_cc[VMIN]=1;//最少读取的字符数

            newtio2.c_cc[VTIME]=0;//设置读超时:read操作将会阻塞不确定的时间

           tcflush(fdcom2, TCIFLUSH);//刷清未决输入和/或输出

            tcsetattr(fdcom2,TCSANOW,&newtio2);//设置终端属性

 

            /////////////////////////////////////////////////

    #ifdef MASTER                                                                  

//         while(1)

            {                    

                       printf("\n/********************   PC--------->MASTER   *********************/\n");

 

                       //-------------------------------------------------------------1. MASTER_WAITING_RECEIVE_FROM_PC;   232    

                       uchStatus = MASTER_WAITING_RECEIVE_FROM_PC;

                       printf("\n1.MASTER_WAITING_RECEIVE_FROM_PC\n");

                       tcflush(fdcom1, TCIFLUSH);//Flush Memery Buf

                       rx_result = Modbus_Receive_Decode(fdcom1);

                       Report_Rx_Result(rx_result);

/*        //Imitate PC send to master:

                       uchStatus = MASTER_WAITING_RECEIVE_FROM_PC;

                       printf("\n1.MASTER_WAITING_RECEIVE_FROM_PC\n");

                       uchNetAddrHigh = '0';//Set target net address: 02

                       uchNetAddrLow  = '2'; 

                       uchCmdHigh     = '6';//Set cmd 65:Get AD1 Value

                       uchCmdLow      = '5';

                       strcpy(auchDataBuf,argv[2]);    //Set Data

                       uchDataLen = strlen(auchDataBuf);//Set data length

                       uchDataLenHigh = Num_To_Ascii(uchDataLen>>4);

                       uchDataLenLow = Num_To_Ascii(uchDataLen&0x0F);

*/

                       uchStatus = NOT_MASTER_WAITING_RECEIVE_FROM_PC; //clear wait PC flag          

           

            ///////////  if PC target net address is MASTER self or packet is invalid ///////////

                       if( (uchNetAddrHigh == uchOurAddrHigh) && (uchNetAddrLow == uchOurAddrLow) || (rx_result != VALID_PACKET) )//

                       {

                                   //-------------------------------------------------------------2. MASTER_REPLY_TO_PC  232

                                   printf("\n2.MASTER_REPLY_TO_PC\n");

                                   Reply(fdcom1, rx_result);

                       }  

           

            ///////////  PC target net address is not MASTER  ///////////

                       else // if( rx_result == VALID_PACKET )   

                       {

                                   printf("\n/********************   MASTER<--------->OTHERS   *********************/\n     ");      

                                   //-------------------------------------------------------------2.MASTER_SEND_TO_OTHERS  485

                                   printf("\n2.MASTER_SENDING_TO_OTHERS\n");

                                   ioctl(fd485, _485_IOCTRL_RE2DE, _485_DE );//Set 485 mode: send

                                   Modbus_Send_Packet(fdcom2);

                                   //-------------------------------------------------------------3.MASTER_WAITING_REPLY_FROM_OTHERS  485

                                   printf("\n3.MASTER_WAITING_REPLY_FROM_OTHERS\n");

                                   ioctl(fd485, _485_IOCTRL_RE2DE, _485_RE );//Set 485 mode: receive

                                   tcflush(fdcom2, TCIFLUSH);//Flush Memery Buf

                                   rx_result = Modbus_Receive_Decode(fdcom2);

                                   Report_Rx_Result(rx_result);    //Report rx_result

                                   //-------------------------------------------------------------4.MASTER_REPLY_TO_PC;  485       

                                   if( (rx_result != NOT_SEND_TO_US) ) //

                                   {

                                               printf("\n/********************   MASTER--------->PC   *********************/\n");

                                               printf("\n4.MASTER_REPLY_TO_PC\n");

                                               Reply(fdcom1, rx_result);// MASTER reply to PC

                                   }

                       }         

  }//END_while(1)

    /***************************************************************************************************/  

            #else

            //1.OTHERS_WAITING_RECEIVE_FROM_MASTER

            while(1)

            {  

                       printf("\n1.OTHERS_WAITING_RECEIVE_FROM_MASTER\n");

                       ioctl(fd485, _485_IOCTRL_RE2DE, _485_RE );//Set 485 mode: receive

                       tcflush(fdcom2, TCIFLUSH);//Flush Memery Buf

                       rx_result = Modbus_Receive_Decode(fdcom2);

                       Report_Rx_Result(rx_result);     //Report rx_result

                       if( rx_result != NOT_SEND_TO_US )

                       {

            //2.OTHERS_REPLY_TO_MASTER

                                   printf("\n2.OTHERS_REPLY_TO_MASTER\n");

                                   ioctl(fd485, _485_IOCTRL_RE2DE, _485_DE );//Set 485 mode: send

                                   Reply(fdcom2, rx_result);// Reply to MASTER

                       }

            }         

            #endif

 

            /////////////////////////////////////////////////

            close(fdcom1);

            close(fdcom2);

            close(fd485);

            return 0;

}

 

 

 

/*****************************************************

* 函数名称 : Ascii_To_Num

* 函数功能 : 将字符ASCII码值转换成实际数值

* 入口参数 : a为ASCII码

* 出口参数 : n为实际数值

*****************************************************/

uchar Ascii_To_Num(uchar a)

{

            uchar n;

            if(a>='0'&&a<='9')

                       n=a-0x30;

            else if (a>='A'&&a<='Z')

                       n=a-0x41+10;

            else if (a>='a'&&a<='z')

                       n=a-0x61+10;

            return n;

}

 

/*****************************************************

* 函数名称 : Num_To_Ascii

* 函数功能 : 将实际数值转换成字符ASCII码值

* 入口参数 : n为实际数值

* 出口参数 : a为ASCII码

*****************************************************/

uchar Num_To_Ascii(uchar n)

{

            uchar a;

            if( n>=0 && n<=9 )

                       a=n+0x30;

            else if ( n>=10 && n<=15 )

                       a=n-10+0x41;

            return a;

}

 

/*****************************************************

* 函数名称 : Float16_To_String

* 函数功能 : 把(1位整数,6位小数的)浮点数转换成一个字符串(不含小数点)

* 入口参数 : 浮点数f, 转换后的字符串存到str[]

* 出口参数 : 无

*****************************************************/

void Float16_To_String(float f, uchar *str)

{ // 1-interger, 6-small-num  like 2.123456 --> "2123456"

            uchar i;

    long l;

    l = f * 1000000;

    str[7]='\0';

    for(i=6; i>=0; i--)

    {

        str[i] = l % 10 + 0x30;

        l /= 10;

    }

}

 

/*****************************************************

* 函数名称 : Send_Char

* 函数功能 : 发送单个ASCII字符到目标串口(并显示发送的字符)

* 入口参数 : 目标串口fdcom, 要发送的ASCII字符ch

* 出口参数 : 无

*****************************************************/

void Send_Char(int fdcom, uchar ch)

{

            printf("%c", ch);

            fflush(stdout);

            write(fdcom,&ch,1);

            usleep(1000);//8bit/115200=70us; continue send must >70us.

}

 

/*****************************************************

* 函数名称 : Receive_Char

* 函数功能 : 从目标串口接收单个ASCII字符(并显示接收的字符)

* 入口参数 : 目标串口fdcom, 接收到的ASCII字符存到*ch

* 出口参数 : 无

*****************************************************/

void Receive_Char(int fdcom, uchar *ch)

{

            read(fdcom,ch,1);

            printf("%c", *ch);

            fflush(stdout);

}

 

/*****************************************************

* 函数名称 : Modbus_Send_Packet

* 函数功能 : 将MODBUS协议包逐个字符发送到目标串口(同时穿插进行LRC校验码的计算)

* 入口参数 : 目标串口fdcom

* 出口参数 : 无

* LRC校验算法:把每一个需要传输的[ASCII码值转化为实际数值]叠加(丢弃进位)后取反加1.

*****************************************************/

void Modbus_Send_Packet(int fdcom)  

{                                                                                       

            uchar i;

            uchDataLen = (Ascii_To_Num(uchDataLenHigh)<<4) + Ascii_To_Num(uchDataLenLow) ; // combine Cmd   

            for(  i = 0; i < 3; i++ ) // avoid the dirty char of begin

                       Send_Char(fdcom, 0x00);

                      

            Send_Char(fdcom, START_FLAG);         // Send START_FLAG

                      

    uchCalcLrcCode = Ascii_To_Num(uchNetAddrHigh);                      

            Send_Char(fdcom, uchNetAddrHigh);    // Send NetAddrHigh

            uchCalcLrcCode += Ascii_To_Num(uchNetAddrLow);

            Send_Char(fdcom, uchNetAddrLow);     // Send NetAddrLow

            uchCalcLrcCode += Ascii_To_Num(uchCmdHigh);

            Send_Char(fdcom, uchCmdHigh);        // Send CmdHigh

            uchCalcLrcCode += Ascii_To_Num(uchCmdLow); 

            Send_Char(fdcom, uchCmdLow);         // Send CmdLow

            uchCalcLrcCode += uchDataLen>>4; 

            Send_Char(fdcom, uchDataLenHigh);    // Send DataLenHigh

            uchCalcLrcCode += uchDataLen&0x0f;       

            Send_Char(fdcom, uchDataLenLow);     // Send DataLenLow

                      

            for ( i = 0; i < uchDataLen; i++ )

    { 

                        uchCalcLrcCode += Ascii_To_Num(auchDataBuf[i]); 

                       Send_Char( fdcom, auchDataBuf[i] );                 // Send Data[]

            }         

                      

    uchCalcLrcCode = (~uchCalcLrcCode)+1;             // Finished CalcLrcCode generation                     

            uchCalcLrcHigh = Num_To_Ascii(uchCalcLrcCode>>4);

            Send_Char(fdcom, uchCalcLrcHigh);    // Send CalcLrcHigh

            uchCalcLrcLow = Num_To_Ascii(uchCalcLrcCode&0x0f);

            Send_Char(fdcom, uchCalcLrcLow);     // Send CalcLrcLow

                      

            Send_Char(fdcom, END_FLAG_1);          // Send EndFlag1

            Send_Char(fdcom, END_FLAG_2);          // Send EndFlag2

}  

 

/*****************************************************

* 函数名称 : Modbus_Receive_Decode

* 函数功能 : 从目标串口逐个接收MODBUS协议包字符(同时穿插进行LRC校验码的计算)

* 入口参数 : 目标串口fdcom

* 出口参数 : 返回接收结果(有效包或者错误代号等)

* LRC校验算法:把每一个需要传输的[ASCII码值转化为实际数值]叠加(丢弃进位)后取反加1.

*****************************************************/

uchar Modbus_Receive_Decode(int fdcom)

{         

    uchar i,uch='\0';

           

            while( uch != START_FLAG ) Receive_Char(fdcom,&uch);//detect Start Flag

 

            Receive_Char(fdcom,&uchNetAddrHigh);       // receive NetAddrHigh

            if( (uchNetAddrHigh != uchOurAddrHigh) && (uchStatus != MASTER_WAITING_RECEIVE_FROM_PC) )

                       return (NOT_SEND_TO_US);

            uchCalcLrcCode = Ascii_To_Num(uchNetAddrHigh);

            Receive_Char(fdcom,&uchNetAddrLow);        // receive  NetAddrLow

            if( (uchNetAddrLow != uchOurAddrLow) && (uchStatus != MASTER_WAITING_RECEIVE_FROM_PC) )

                       return (NOT_SEND_TO_US);

            uchCalcLrcCode += Ascii_To_Num(uchNetAddrLow);

            Receive_Char(fdcom,&uchCmdHigh);       // receive CmdHigh

            uchCalcLrcCode += Ascii_To_Num(uchCmdHigh);

            Receive_Char(fdcom,&uchCmdLow);        // receive  CmdLow

            uchCalcLrcCode += Ascii_To_Num(uchCmdLow);

            uchCmd = (Ascii_To_Num(uchCmdHigh)<<4) + Ascii_To_Num(uchCmdLow); // combine Cmd

            Receive_Char(fdcom,&uchDataLenHigh);// receive  DataLenHigh

            Receive_Char(fdcom,&uchDataLenLow); // receive  DataLenLow

            uchDataLen = (Ascii_To_Num(uchDataLenHigh)<<4) + Ascii_To_Num(uchDataLenLow);            // combine DataLen

            if ( uchDataLen > sizeof(auchDataBuf) )  

                       return (ERROR_LENGTH);   // Length overflow               

            uchCalcLrcCode += uchDataLen >> 4;

            uchCalcLrcCode += uchDataLen & 0x0f;

            for ( i = 0; i < uchDataLen; i++ )

            {         

                       Receive_Char(fdcom,&auchDataBuf[i]); // receive Data[]

                       uchCalcLrcCode += Ascii_To_Num(auchDataBuf[i]);          

            }         

                                             

            uchCalcLrcCode = (~uchCalcLrcCode)+1;         // Finished RxLrcCode generation

            uchCalcLrcHigh = Num_To_Ascii(uchCalcLrcCode>>4);

            uchCalcLrcLow = Num_To_Ascii(uchCalcLrcCode&0x0f);         

                      

            Receive_Char(fdcom,&uchRxLrcHigh);

            Receive_Char(fdcom,&uchRxLrcLow);

            uchRxLrcCode = (Ascii_To_Num(uchRxLrcHigh)<<4) + Ascii_To_Num(uchRxLrcLow); // combine uchRxLrcCode

            if( uchRxLrcCode != uchCalcLrcCode)

                       return (ERROR_LRC);   // Lrc can't match

                                                         

            Receive_Char(fdcom,&uch);//detect EndFlag1

            if ( uch != END_FLAG_1 )

                       return(ERROR_END_FLAG);

            Receive_Char(fdcom,&uch);//detect EndFlag2

            if ( uch != END_FLAG_2 )

                       return(ERROR_END_FLAG);

            return (VALID_PACKET);    // Receive a valid packet

}

 

/*****************************************************

* 函数名称 : Report_Rx_Result

* 函数功能 : 报告显示接收结果以跟踪测试

* 入口参数 : 接收结果rx_result(有效包或者错误代号等)

* 出口参数 : 无

*****************************************************/

void Report_Rx_Result(uchar rx_result)

{

                       switch(rx_result)

                       {

                       //         case NOT_SEND_TO_US      : printf("NOT_SEND_TO_US!\n"); break;

                                   case ERROR_LENGTH        : printf("ERROR_LENGTH!\n"); break;

                                   case ERROR_LRC                                   : printf("ERROR_LRC!\n"); break;

                                   case ERROR_END_FLAG      : printf("ERROR_END_FLAG!\n"); break;

                                   case VALID_PACKET        : printf("VALID_PACKET!\n"); break;

                                   default                  : printf("UNKNOWN ERROR!\n"); break;

                       }

                       fflush(stdout);

}

 

/*****************************************************

* 函数名称 : Reply

* 函数功能 : 1.修改目标地址为01;

             2.若接收到有效包则根据命令执行相应功能并发送原包到目标串口作为应答;

                                      若为接收到无效包,则修改包内容后再发送到目标串口作为应答(令uchCmdHigh_7=1,并将长度为1的错误代号作为数据)。

* 入口参数 : 目标串口fdcom, 接收结果rx_result(有效包或者错误代号等)

* 出口参数 : 无

*****************************************************/

void Reply(int fdcom, uchar rx_result)

{                    

            uchNetAddrHigh = '0';//reply to MASTER adress: 01

            uchNetAddrLow  = '1'; 

            if( rx_result != VALID_PACKET )

            {

                       uchCmdHigh |= 0x80;   //Receive failed ,change uchCmdHigh_7=1;

                       uchDataLenHigh = '0'; //Error number length: one uchar

                       uchDataLenLow = '1';

                       auchDataBuf[0] = Num_To_Ascii(rx_result);//Error number                    

            }         

            else//if( rx_result == VALID_PACKET ) //exec Cmd

            {

            //         Exec_Cmd(uchCmd);//Control motor or get  AD value and repacket

            }

            Modbus_Send_Packet(fdcom);// Reply to MASTER 485

}  

 

/*****************************************************

* 函数名称 : Help_Menu

* 函数功能 : 帮助菜单

* 入口参数 : 无

* 出口参数 : 无

*****************************************************/

static void Help_Menu(void)

{

            printf("\n");

            printf("DESCRIPTION\n");

            printf("   Data Collect System \n");    

            printf("      arg0: tzdcs \n");    

            printf("      arg1: baudrate \n");        

            printf("      arg2: Send String \n");    

            printf("OPTIONS\n");

            printf("      -h or --help:    this menu\n");

            printf("\n");

}

 

 

/*****************************************************

* 函数名称 : Get_Baudrate

* 函数功能 : 从主函数的参数获取设置的波特率

* 入口参数 : 主函数的参数char** argv

* 出口参数 : 设置的波特率 或 -1

*****************************************************/

static int Get_Baudrate(char** argv)

{

            int v=atoi(argv[1]);

             switch(v)

             {

                       case 4800   : return B4800;     

                       case 9600   : return B9600;

                       case 19200  : return B19200;

                       case 38400  : return B38400;

                       case 57600  : return B57600;

                       case 115200 : return B115200;

                       default     : return -1;

             }        

 }   


关键字:MODBUS协议  ASCII模式  串口通讯 引用地址:MODBUS协议ASCII模式串口通讯的实现(Arm2410,RS232/485)

上一篇:arm920T与arm926的区别
下一篇:ARM的异常处理方式

推荐阅读最新更新时间:2024-03-16 15:29

基于S3C2410的振动测试分析仪的研制
引言 在大型旋转机械、桥梁、地下铁路、加工机床等领域,对振动信号进行采集和分析,可以实现危险预报、故障诊断、性能指标分析等多项功能。传统的便携式振动测量分析仪大多用单片机或RISC CPU作为核心处理器,一般是8位或16位的,内存只有几Kb,外部存储器的容量也只有1~2 Mb,再加上CPU的主频不高,进行大量数据运算(如FFT等),需要很长时间,图像显示基本上依靠黑白液晶屏,可以显示的内容少,因此对传统的便携式振动测试分析仪进行性能的改进很有必要。 本项目采用ARM9的S3C2410处理器,可以连续监测8个通道,提供转速、棒图、振动通频值、数据列表、时域波形、频谱图、伯德图等振动监测、分析图表。采用640×480的TFT彩色显
[应用]
基于ARM9微处理器S3C2410的IP电话通信设计
0 引言 IP电话以其通话费率低、方便集成和智能化等优势而得到了众多消费者的极大认可,并因此而对原有固定电话运营者的长途电话和国际电话业务造成了巨大冲击。因此,随着以太网接口的直接入户,开发出一种带有RJ-45以太网接口并直接连入因特网,从而使使用更加方便的IP电话非常需要。利用这种IP电话,用户可以直接拨叫远端的电话号码,并通过关守(gate keeper)把所拨的电话号码转换成远端IP电话的IP地址,从而建立通话连接。事实上,新型IP电话终端已经可以直接把输入语音信号数字化,并按照G.728或G.729等一定的语音压缩编码算法来完成对输入语音信号的实时压缩,使带宽从64kbps降低到8kbps,从而大大提高了信道的利用率。
[单片机]
基于ARM9微处理器S3C<font color='red'>2410</font>的IP电话通信设计
基于S3C2410X处理器和单片机实现多磁控管电源控制的设计方案
1、电路硬件整体设计 设计主要包括3个模块:1,人机交换模块(S3C2410芯片扩展电路)、2,功率输出模块(ATmega16L芯片扩展电路)、3,磁控管工作电路。人机交换模块主要用来接收使用者的命令数据,再传递给功率输出模块输出给定功率。同时接收功率输出模块电路中功率反馈回来的信息,使得使用者能对相应信息做出处理。整体框架如图1—1所示: 1.1基于S3C2410X处理器的控制电路设计 控制系统中采用韩国三星半道体公司的S3C2410X处理器作为主控制芯片。SBC2410X是一款基于ARM920T内核的16/32位RISC嵌入式微处理器,高性价格比,低功耗。应用该芯片作为主控制芯片,并扩展64M SDRAM、64M Nand
[单片机]
基于S3C<font color='red'>2410</font>X处理器和单片机实现多磁控管电源控制的设计方案
【ARM】2410裸机系列-按键查询式控制led
开发环境 硬件平台:FS2410 主机:Ubuntu 12.04 LTS LED灯原理图 按键原理图 按键的接线资源 KSCAN0 - GPE11 KSCAN1 - GPG6 KSCAN2 - GPE13 KSCAN3 - GPG2 EINT0 - GPF0 EINT2 - GPF2 EINT11 - GPG3 EINT19 - GPG11 程序主要原理 这里实现对 K1,K2,K3,K4 这四个键的查询。 主要涉及到K1,K2, K3, K4这四个按键,要用查询的方式进行判断哪个键被按下去了,因此: 将EINT11, EINT19设置为输入,用于读取; 将KSCAN0,KS
[单片机]
【ARM】<font color='red'>2410</font>裸机系列-按键查询式控制led
基于s3c2410 2.6.25内核cs8900网卡驱动的移植
因为在驱动中使用的是虚拟地址,因此要首先将网卡的物理地址映射到虚拟地址 ************************************************************** 1 。在include/asm-arm/plat-s3c24xx/common-smdk.h文件中添加 其中必须使用宏__phys_to_pfn 即将物理地址右移12位,跟踪源码可知 与struct map_desc中的pfn相关 #define pSMDK2410_ETH_IO __phys_to_pfn(0x19000000) #define vSMDK2410_ETH_IO S3C2410_ADDR(0x04000000) #de
[单片机]
s3c2410移植MPlayer到linux2.6
我使用的linux内核为2.6.14.1 MPlayer版本为MPlayer-1.0pre7try2.bz2 目前虽然已经添加了mad的mp3库,但播放声音文件回导致mplayer错误,放视频还得禁掉声音,怪了,madplay放mp3就很好 下面介绍下整个移植过程,也是参考了网上很多文章综合而来的 ================================================================= 1)编译器最好选择3.3.2 ,我使用3.4.1会出现snow.c编译错误,找不到解决办法 解压3.3.2到/usr/local/arm/下 并export PATH=http://www.eda-chin
[单片机]
ARM裸机——FS2410按键控制LED灯(查询方式)
一、开发环境 1、硬件平台:FS2410(s3c2410) 2、主机:Ubuntu 10.10 二、硬件的原理图(LED和按键) 1、LED灯的原理图: 2、按键的原理图: 按键的接线资源: KSCAN0 - GPE11 KSCAN1 - GPG6 KSCAN2 - GPE13 KSCAN3 - GPG2 EINT0 - GPF0 EINT2 - GPF2 EINT11 - GPG3 EINT19 - GPG11 三、程序的主要原理: 主要涉及到K1,K2, K3, K4这四个按键,要用查询的方式进行判断哪个键被按下去了,因此将EINT11, EINT19设置为输入,用
[单片机]
ARM裸机——FS<font color='red'>2410</font>按键控制LED灯(查询方式)
如何有效地使用串口通讯接收数据
引言 在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段数据是不定长的有如何高效接收呢? 同学A:数据来了就会进入串口中断,在中断中读取数据就行了! 中断就是打断程序正常运行,怎么能保证高效呢?经常把主程序打断,主程序还要不要运行了? 同学B:串口可以配置成用DMA的方式接收数据,等接收完毕就可以去读取了! 这个同学是对的,我们可以使用DMA去接收数据,不过DMA需要定长才能产生接收中断,如何接收不定长的数据呢? DMA简介 题外话:其实,上面的问题是很有必要思考一下的,不断思考,才能进步。 什么是DMA DMA :全称Direct Memory Access,即直接存储器访问
[单片机]
如何有效地使用<font color='red'>串口通讯</font>接收数据
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved