你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

跪求!!!各路大神指导STM8S的程序

[复制链接]
xiaocaicai110 提问时间:2015-4-24 17:37 /
各路大神,看看这个STM8S的程序是否能实现单片机与电脑之间的modbus rtu通讯协议,如有问题,还请各路大神不吝赐教!!!此程序是把51的程序改成STM8S的,本人不懂STM8S单片机
//File name: modbusMain.c
//Function : modbus rtu  
//Programed by peirui 2013.6.25
/*********************************************************************************/
//#include <iostm8s105k4.h>
//#include <intrins.h>
/*********************************************************************************/
/*********************************************************************************/
#define GlobalIntEnable()  asm("rim")
#define GlobalIntDisable() asm("sim")
#define SerialIntEnable()  UART2_CR1_PIEN=1
#define SerialIntDisable() UART2_CR1_PIEN=0

/*********************************************************************************/
#define MIN_TIME_INT  2                            
#define MAX_TIME_INT  4                               
#define MAX_REC_COUNT 60

#define  MY_ADDR           0x01
#define  MAX_PACKET               100                                            
#define  MAX_ADDR_NUM      255                                                                       

#define         FUNC_NUM_ERR      0x01                                                                       
#define  REG_ADDR_ERR      0x02
#define  REG_NUM_ERR       0x03                  
#define  OSFREQ 2000000       

unsigned char  DI[]={0x00, // coils 8-1        //Input Coils
                                   0x00, // coils 16-9
                                         0x68, // coils 24-17
                                         0x5E, // coils 32-25
                                         0x93, // coils 40-33
                                         0x75, // coils 48-41
                                         0xD8, // coils 56-49
                                         0x00,}; // coils 64-57

unsigned char  DO[]={0x00, // coils 8-1         //Output Coils
                                   0x00, // coils 16-9
                                         0x68, // coils 24-17
                                         0x5E, // coils 32-25
                                         0x93, // coils 40-33
                                         0x75, // coils 48-41
                                         0xD8, // coils 56-49
                                         0x00,}; // coils 64-57



unsigned char    AI[]={0xF1,0xF2, // address 0      //Input Registers
                             0xF3,0xF4, // address 1
                                                                       0xF5,0xF6,
                                                                       0xF7,0xF8,
                             0xF9,0xFA,
                                                                       0xFB,0xFC,
                             0xFD,0xFE,
                                                                       0xFF,0xF0,
                             0xE1,0xE2,
                                                                       0xE3,0xE4,
                             0xE5,0xE6,
                                                                       0xE7,0xE8,
                             0xE9,0xEA,
                                                                       0xEB,0xEC,
                             0xED,0xEE,
                                                                       0xEF,0xE0};  // address 15                
unsigned char   AO[]={0x01,0x02, // address 0      //Hold Registers
                             0x03,0x04, // address 1
                                                                       0x05,0x06, // address 2
                                                                                                   0x07,0x08, // address 3
                             0x09,0x0A, // address 4
                                                                       0x0B,0x0C, // address 5
                             0x0D,0x0E, // address 6
                                                                       0x0F,0x10, // address 7
                             0x11,0x12, // address 8
                                                                       0x13,0x14, // address 9
                             0x15,0x16, // address 10
                                                                       0x17,0x18, // address 11
                             0x19,0x1A, // address 12
                                                                       0x1B,0x1C, // address 13
                             0x1D,0x1E, // address 14
                                                                       0x1F,0x20};  // address 15       
unsigned char  ReceiveData[MAX_PACKET];                                                   
unsigned char sendbuf[MAX_PACKET];                                                               
                                                       
unsigned char g_RecCounter = 0;                            
unsigned char g_RecDisable = 0;                               
unsigned char g_TimeInterval=0;       

/*********************************************************************************/
void SendStringToCom(unsigned char *pStrToSend,unsigned int sendLength);
unsigned int Cal_CRC16(unsigned char *puchMsg, unsigned char usDataLen);
//unsigned int cal_crc(unsigned char *ptr, unsigned int len);
static unsigned char GetBit(unsigned int address,unsigned char function);
static void ProcessFun1_2(unsigned char address, unsigned char len);       
static void ProcessFun3(unsigned char address, unsigned char len);
static void ProcessFun4(unsigned char address, unsigned char len);
static void SendMbError(char ErrorCode);
void ModbusFunProcess();
void InitTimer0();
void InitSerial();
void SendByteToCom(unsigned char dataToSend);
void SendStringToCom(unsigned char *pStrToSend,unsigned int sendLength);
                                                                                                 

/*********************************************************************************/
static unsigned char  Cal_CRC_Hi[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,                                                            
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40         
} ;
static unsigned char  Cal_CRC_Lo[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
};
/*********************************************************************************/
unsigned int Cal_CRC16(unsigned char *puchMsg, unsigned char usDataLen)
{
        unsigned char uchCRCHi = 0xFF ;                   
        unsigned char uchCRCLo = 0xFF ;           
        unsigned int  uIndex ;                 
        while (usDataLen--)                               
  {
            uIndex = uchCRCHi ^ *puchMsg++ ;      
            uchCRCHi = uchCRCLo ^ Cal_CRC_Hi[uIndex] ;
            uchCRCLo = Cal_CRC_Lo[uIndex] ;
  }       
        return (uchCRCHi << 8 | uchCRCLo) ;
}
/*********************************************************************************/
/*
main()
{        
    InitSerial();                     
    InitTimer0();                         
    GlobalIntEnable();                 
    SerialIntEnable();             
    g_RecDisable = 0;
    while(1)
    {       
              if (g_RecDisable)
            {
               ModbusFunProcess();                       
                   g_RecDisable=0;       
                   g_RecCounter=0;               
            }                
    }
}
*/
/*********************************************************************************/
//void RecIntProcess() interrupt 4 using 3
__interrupt void UART2_R_OR_IRQHandler(void)
{
        //GlobalIntDisable();
        asm("sim");


        //if(RI)
        if(UART2_SR_RXNE)
        {
                if((g_TimeInterval>MIN_TIME_INT)&&(g_TimeInterval<=MAX_TIME_INT))
                {
                        g_RecCounter=0;                                         
                }
                if(g_RecCounter>MAX_REC_COUNT)
                {
                        g_RecCounter=0;                                    
                }                                         
                ReceiveData[g_RecCounter++]=UART2_DR;  
                g_TimeInterval=0;                                       
                //RI=0;
                UART2_SR_RXNE=0;
        }
        //GlobalIntEnable();                                               
        //ET0=1;                                               
        asm("rim");
         TIM2_IER = 0x01;
}
/*--------------------------------------------------------------------------*/
//void Timer0IntProcess()  interrupt 1 using 2
__interrupt void UART2_R_OR_Timer4IntProcess(void)
{
        /*
        ET0=0;
        TL0 = 0x18  ;                        //0xFC40=65536-((11059200/12)/9600)*10
        TH0 = 0xFC;       
        g_TimeInterval++;
        if((g_TimeInterval>MAX_TIME_INT) && (g_RecCounter>0))         
        {                                                                                                                        
                g_RecDisable=1;
        }else
        {
                ET0=1;               
        }
        */
         TIM2_IER = 0x00;
         TIM2_CNTRH = 0x03;          // 设定计数器的初值
         TIM2_CNTRL = 0xE8;            
         g_TimeInterval++;
        if((g_TimeInterval>MAX_TIME_INT) && (g_RecCounter>0))         
        {                                                                                                                        
                g_RecDisable=1;
        }else
        {
                TIM2_IER = 0x01;               
        }
}

/*********************************************************************************/
static unsigned char GetBit(unsigned int address,unsigned char function)
{
        unsigned char  Offset;
        unsigned char  temp;
        unsigned char  *Myaddress;  
        Offset=(char)address&0x07;                 
        switch (function)                 
        {
                   case 2:
                   Myaddress=DI;
                   break;
                   case 1:
                   Myaddress=DO;            
                   break;
                   default:
                   return 2;
          }
          temp=(char)(address>>3);                  
          temp=*(Myaddress+temp);                                   
          temp>>=(Offset);                                         
          if (temp&0x01)
            return 1;
          else
            return 0;
}
/*********************************************************************************/
//ProcessFun1_2
/*********************************************************************************/
static void ProcessFun1_2(unsigned char address, unsigned char len)
{
  unsigned char  i;
  unsigned char  j;
  unsigned char  length;
  unsigned char  function;
        unsigned int   temp;
         
        length=0;
        sendbuf[0]=ReceiveData[0];                        
        sendbuf[1]=ReceiveData[1];                     
        function=sendbuf[1];

          for (i=1;i<=len;i++)
          {
                length++;
                 sendbuf[2+length]=0;                        
            for (j=0;j<8;j++)
            {
                          sendbuf[2+length]=sendbuf[2+length]|(GetBit(address,function)<<j);
                           address++;
                           i++;
                           if(i>len)break;
            }
            i--;
        }
  sendbuf[2]=length;                                     
        temp=Cal_CRC16(sendbuf,length+3);                 
        sendbuf[3+length]=(char)(temp>>8);                 
        sendbuf[4+length]=(char)temp;                         
        SendStringToCom(sendbuf,length+5);                               
}

/*********************************************************************************/
//ProcessFun3
/*********************************************************************************/
static void ProcessFun3(unsigned char address, unsigned char len)
{
        unsigned char  i;
        unsigned char  msendbuf[MAX_PACKET];
        unsigned int   temp;
       
        msendbuf[0]=ReceiveData[0];                  
        msendbuf[1]=ReceiveData[1];                         
        msendbuf[2]=2*len;                         
        address=2*address;
        for(i=0;i<len;i++)
        {
                msendbuf[3+2*i]=AO[address++];               
                msendbuf[4+2*i]=AO[address++];                  
        }
        temp=Cal_CRC16(msendbuf,2*len+3);         
        msendbuf[3+2*len]=temp>>8;   
        msendbuf[4+2*len]=(char)temp;
        SendStringToCom(msendbuf,2*len+5);
}
/*********************************************************************************/
//ProcessFun4
/*********************************************************************************/
static void ProcessFun4(unsigned char address, unsigned char len)
{
        unsigned char  i;
        unsigned int   temp;

        sendbuf[0]=ReceiveData[0];
        sendbuf[1]=ReceiveData[1];
        sendbuf[2]=2*len;
        address=2*address;
        for(i=0;i<len;i++)
        {
                sendbuf[3+2*i]=AI[address++];               
                sendbuf[4+2*i]=AI[address++];                  
        }
        temp=Cal_CRC16(sendbuf,2*len+3);
        sendbuf[3+2*len]=(char)(temp>>8);
        sendbuf[4+2*len]=(char)temp;
        SendStringToCom(sendbuf,2*len+5);
}
/*********************************************************************************/
//ProcessFun5
/*********************************************************************************/
static void ProcessFun5(unsigned char address)
{
        unsigned int  temp;
        unsigned char Offset;
        unsigned char *sendbuf;
        unsigned char *pDO;
        pDO=DO;
        Offset=(unsigned char)address&0x07;
        temp=address>>3;

        if((0x00==ReceiveData[4])&&(0x00==ReceiveData[5]))
                pDO[temp]&=~(1<<Offset);                                                       
        else if((0xFF==ReceiveData[4])&&(0x00==ReceiveData[5]))
                pDO[temp]|=(1<<Offset);                                                            
        else
        {};
        sendbuf=ReceiveData;
        SendStringToCom(sendbuf,8);
}
/*********************************************************************************/
//ProcessFun6
/*********************************************************************************/
static void ProcessFun6(unsigned char address)
{
        unsigned int   temp;
        unsigned char  *sendbuf;
        unsigned char  *pAO;

        temp=2*address;                                          
        pAO=AO;
        pAO[temp]=ReceiveData[4];
        pAO[temp+1]=ReceiveData[5];

        sendbuf=ReceiveData;
        SendStringToCom(sendbuf,8);       
}
/*********************************************************************************/
//ProcessFun15
/*********************************************************************************/
static void ProcessFun15(unsigned char address, unsigned char len)
{
        unsigned char  i;
        unsigned char  j;
        unsigned int   temp;
        unsigned char  Offset,test;
        unsigned char  byteNum;
        unsigned char  *sendbuf;
        unsigned char  *pDO;
        unsigned char  tempdata;

        Offset=(unsigned char)address&0x07;         
        temp=address>>3;  
        pDO=DO;
               
        byteNum=((len-1+Offset)>>3) + 1;

        for(i=0;i<byteNum;i++)
        {
                for(j=0;j<8;j++)
                {               
                         test=(Offset+j)>>3;
                         tempdata=ReceiveData[7+i]>>j;
                         tempdata&=0x01;

                         if(len==(j+8*i))
                                 break;
                         else
                         {
                         if(tempdata)
                                 pDO[temp+i+test]|=(0x01<<((Offset+i*8+j)&0x07));
                         else
                                 pDO[temp+i+test]&=(~(0x01<<((Offset+i*8+j)&0x07)));
                         }          
                }
        }
        sendbuf=ReceiveData;
        temp=Cal_CRC16(sendbuf,6);
        sendbuf[6]=temp>>8;
        sendbuf[7]=temp&0xFF;       
        SendStringToCom(sendbuf,8);       
}
/*********************************************************************************/
//ProcessFun16
/*********************************************************************************/
static void ProcessFun16(unsigned char address, unsigned char len)
{
        unsigned char  i;
        unsigned char  *pSendBuf;

        unsigned int   temp;
       
        pSendBuf=ReceiveData;
        address=2*address;
        for(i=0;i<len;i++)
        {
                AO[address++]=ReceiveData[7+2*i];
                AO[address++]=ReceiveData[8+2*i];
        }

        temp=Cal_CRC16(pSendBuf,6);  
        pSendBuf[6]=(char)(temp>>8);
        pSendBuf[7]=(char)temp;

        SendStringToCom(pSendBuf,8);       
       
}
/*********************************************************************************/
static void SendMbError(char ErrorCode)
{
        unsigned int temp;
        sendbuf[0]=ReceiveData[0];
        sendbuf[1]=ReceiveData[1]|0x01;
        sendbuf[2]=ErrorCode;
        temp=Cal_CRC16(sendbuf,3);
        sendbuf[3]=(unsigned char)(temp>>8);
        sendbuf[4]=(unsigned char)temp;
        SendStringToCom(sendbuf,5);       
}
/*********************************************************************************/
void ModbusFunProcess()
{
        unsigned int temp;//temp1;
            unsigned char address;
            unsigned char length;
            unsigned char *pRecBuf;
        unsigned char mb_function;

        //unsigned char tmp[2];

        if(g_RecCounter<=3) return;
        pRecBuf=ReceiveData;
        temp=pRecBuf[g_RecCounter-2]<<8;
        temp|=pRecBuf[g_RecCounter-1];

        mb_function=pRecBuf[1];

        if(MY_ADDR==pRecBuf[0]&&temp==Cal_CRC16(pRecBuf,g_RecCounter-2))
        {
                address=pRecBuf[3];
                length=pRecBuf[5];

                if(address<MAX_ADDR_NUM)
                {
                        switch(mb_function)
                        {
                                case 1:
                                case 2:
                                                ProcessFun1_2(address,length);
                                                break;
                                case 3:
                                                ProcessFun3(address,length);
                                                break;
                                   case 4:
                                                ProcessFun4(address,length);
                                                break;
                                case 5:
                                                ProcessFun5(address);
                                                break;
                                case 6:
                                                ProcessFun6(address);
                                                break;
                                case 15:
                                                ProcessFun15(address,length);
                                                break;
                                case 16:
                                                ProcessFun16(address,length);
                                                break;
                                default:
                                        SendMbError(0x81);
                                                break;
                        }
                }
                else
                {
                        SendMbError(0x82);
                }
        }
        else
        {
                SendMbError(0x83);
        }

        g_RecCounter=0;
        return;
}

收藏 评论5 发布时间:2015-4-24 17:37

举报

5个回答
liyiui 回答时间:2015-4-24 19:26:06
程序比较长,主要是实现什么功能了
xiaocaicai110 回答时间:2015-4-24 20:45:42
liyiui 发表于 2015-4-24 19:26
程序比较长,主要是实现什么功能了

基于MODBUS RTU的STM8S单片机与电脑之间的通信
liyiui 回答时间:2015-4-26 07:44:23
xiaocaicai110 发表于 2015-4-24 20:45
基于MODBUS RTU的STM8S单片机与电脑之间的通信

不好意思,没有做过这个功能,帮不上
那片清茶 回答时间:2015-5-6 10:24:29
程序太长,看不出来能否实现功能,但是我用STM8S写过这个协议,肯定是没问题的。
xiaocaicai110 回答时间:2015-5-6 11:53:25
本帖最后由 xiaocaicai110 于 2015-5-6 11:54 编辑
那片清茶 发表于 2015-5-6 10:24
程序太长,看不出来能否实现功能,但是我用STM8S写过这个协议,肯定是没问题的。 ...

那版主能把你写的程序给我看看吗,我用的是stm8s105k4t6c这个芯片,小弟急需,在此先行谢过了!
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版