xiaocaicai110 发表于 2015-4-24 17:37:41

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

各路大神,看看这个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_INT2                          
#define MAX_TIME_INT4                               
#define MAX_REC_COUNT 60

#defineMY_ADDR         0x01
#defineMAX_PACKET             100                                          
#defineMAX_ADDR_NUM      255                                                                       

#define       FUNC_NUM_ERR      0x01                                                                       
#defineREG_ADDR_ERR      0x02
#defineREG_NUM_ERR       0x03                  
#defineOSFREQ 2000000       

unsigned charDI[]={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 charDO[]={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 charReceiveData;                                                   
unsigned char sendbuf;                                                               
                                                       
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 charCal_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 charCal_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 intuIndex ;               
        while (usDataLen--)                               
{
            uIndex = uchCRCHi ^ *puchMsg++ ;      
            uchCRCHi = uchCRCLo ^ Cal_CRC_Hi ;
            uchCRCLo = Cal_CRC_Lo ;
}       
        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=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 charOffset;
        unsigned chartemp;
        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 chari;
unsigned charj;
unsigned charlength;
unsigned charfunction;
        unsigned int   temp;
       
        length=0;
        sendbuf=ReceiveData;                        
        sendbuf=ReceiveData;                   
        function=sendbuf;

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

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

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

        if((0x00==ReceiveData)&&(0x00==ReceiveData))
                pDO&=~(1<<Offset);                                                       
        else if((0xFF==ReceiveData)&&(0x00==ReceiveData))
                pDO|=(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=ReceiveData;
        pAO=ReceiveData;

        sendbuf=ReceiveData;
        SendStringToCom(sendbuf,8);       
}
/*********************************************************************************/
//ProcessFun15
/*********************************************************************************/
static void ProcessFun15(unsigned char address, unsigned char len)
{
        unsigned chari;
        unsigned charj;
        unsigned int   temp;
        unsigned charOffset,test;
        unsigned charbyteNum;
        unsigned char*sendbuf;
        unsigned char*pDO;
        unsigned chartempdata;

        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>>j;
                       tempdata&=0x01;

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

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

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

        SendStringToCom(pSendBuf,8);       
       
}
/*********************************************************************************/
static void SendMbError(char ErrorCode)
{
        unsigned int temp;
        sendbuf=ReceiveData;
        sendbuf=ReceiveData|0x01;
        sendbuf=ErrorCode;
        temp=Cal_CRC16(sendbuf,3);
        sendbuf=(unsigned char)(temp>>8);
        sendbuf=(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;

        if(g_RecCounter<=3) return;
        pRecBuf=ReceiveData;
        temp=pRecBuf<<8;
        temp|=pRecBuf;

        mb_function=pRecBuf;

        if(MY_ADDR==pRecBuf&&temp==Cal_CRC16(pRecBuf,g_RecCounter-2))
        {
                address=pRecBuf;
                length=pRecBuf;

                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;
}

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这个芯片,小弟急需,在此先行谢过了!
页: [1]
查看完整版本: 跪求!!!各路大神指导STM8S的程序