各路大神,看看这个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; } |
STMS005K6T6 如何采集内部参考电压。
stm8s003 adc中断和通道切换的问题
adc施密特触发器stm8
stm8l051f3 TSSOP20 封装,待机模式下,2天后,电流突然增加到140UA
STM8S用STVP烧录怎么加密?
如何使用ST官网例程_LIN总线通讯_STM8AF
STM8 LIN
IAR代码编辑太费劲了,想问一下有没有好的方法,试了VScode但是头文件老是报错,调了很久也没调好,想换个方法了。
想问一下各位大佬,IAR下载调试代码时出现 warning: is an illegal data sample expression IAR是什么意思啊?
STM8S标准库TIM1编码器功能不计数,请大师帮我看看
基于MODBUS RTU的STM8S单片机与电脑之间的通信
不好意思,没有做过这个功能,帮不上
那版主能把你写的程序给我看看吗,我用的是stm8s105k4t6c这个芯片,小弟急需,在此先行谢过了!