modbusASCII模式源代码.docx
#include "main.h"#include "intrins.h"#include "nokia_5110.h"#include "ds18b20.h" #include "EEPROM.h"/*modbus ASSCII 的C51程序 单片机STC89C52通信波特率 9600 8位数据 1位停止位 232通位接口*/uint8sendBuf_12435,receBuf_12435; /发送接收缓冲区uint16 reg_1245; /寄存器uint16 wendu_124; /温度值unsigned int zhengshu_124,xiaoshu_124;char temperature_124=" . "uint8 code table_124= /数码管码 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e;uint8receTimeOut_124;/接收超时bit f1ms_124=0,f10ms_124=0,f100ms_124=0;/定时标志位uint8 c10ms_124,c100ms_124; /定时计数/*/ /*函数名称: commIntProc() *输入参数: 共 0 个参数; *输出参数: 共 0 个参数; *返回值: *需储存的参数: 共 0 个参数; *功能介绍:串口中断函数 *修改日志: *2010-12-14 Ver. 1.00 开始编写;2010-12-7 完成; 2010-12-7 /* */ /*/ void commIntProc_124() interrupt 4 / 串行中断程序if(TI)TI = 0; if(sendPosi_124 < sendCount_124) sendPosi_124+;SBUF = sendBuf_124sendPosi_124;else receTimeOut_124 = 10;b232Send_124 = 1; /发送完后将232置于接收状态receCount_124 = 0; /清接收地址偏移寄存器/checkoutError = 0; else if(RI)RI = 0;/receTimeOut = 10; /通讯超时值receBuf_124receCount_124 = SBUF;receCount_124+; /接收地址偏移寄存器加1if(receBuf_124receCount_124-1=0x0A)&&(receBuf_124receCount_124-2=0x0D)flag=1; /定时器0 1ms 中断void timer0IntProc() interrupt 1TH0=(65536-18432)/256;TL0=(65536-18432)%256;f1ms_124=1;c10ms_124+;if(c10ms_124>=10)c10ms_124 = 0; /10ms计时器清零 f10ms_124=1; / void Timer0IntProc()/*/ /*函数名称: save_124(void) *输入参数: 共 0 个参数; *输出参数: 共 0 个参数; *返回值: *需储存的参数: 共 0 个参数; *功能介绍:保存掉电寄存器数据 *修改日志: *2010-12-14 Ver. 1.00 开始编写;2010-12-14 完成; 2010-12-14 /* */ /*/ void save_124(void) /保存掉电寄存器数据uint8 tempdata_124;tempdata_124=P1;IapEraseSector_124(0x2000); IapProgramByte_124(0x2000,reg_1240);IapProgramByte_124(0x2001,reg_1241);IapProgramByte_124(0x2002,reg_1242);IapProgramByte_124(0x2003,reg_1243);IapProgramByte_124(0x2004,reg_1244);IapProgramByte_124(0x2005,tempdata_124);/*/ /*函数名称: read_124(void) *输入参数: 共 0 个参数; *输出参数: 共 0 个参数; *返回值: *需储存的参数: 共 0 个参数; *功能介绍:开机读取掉电时的寄存器数据 *修改日志: *2010-12-14 Ver. 1.00 开始编写;2010-12-14 完成; 2010-12-14 /* */ /*/ void read_124(void) /开机读取掉电时的寄存器数据reg_1240=IapReadByte_124(0x2000); reg_1241=IapReadByte_124(0x2001);reg_1242=IapReadByte_124(0x2002);reg_1243=IapReadByte_124(0x2003);P1=IapReadByte_124(0x2005);/*/ /*函数名称: displaytempr(void) *输入参数: 共 0 个参数; *输出参数: 共 0 个参数; *返回值: *需储存的参数: 共 0 个参数; *功能介绍:读取温度值并且显示出来 *修改日志: *2010-12-14 Ver. 1.00 开始编写;2010-12-14 完成; 2010-12-14 /* */ /*/ void displaytempr_124(void)wendu_124=read_T_124();if(wendu_124<2048) /温度为0上的温度 wendu_124&=0x07ff; zhengshu_124=wendu_124/16; /计算温度的整数部分 xiaoshu_124=(wendu_124*25/4)%100; /计算温度的小数部分 temperature_1240=zhengshu_124/100+48; /计算温度的各位的字符值 temperature_1241=(zhengshu_124%100)/10+48; temperature_1242=zhengshu_124%10+48; temperature_1244=xiaoshu_124/10+48; temperature_1245=xiaoshu_124%10+48;elsewendu_124=(wendu_124-1); zhengshu_124=wendu_124/16; /计算温度的整数部分xiaoshu_124=(wendu_124*25/4)%100; /计算温度的小数部分 temperature_1240='-' temperature_1241=zhengshu_124/10+48; /计算温度的各位的字符值 temperature_1242=zhengshu_124%10+48; temperature_1244=xiaoshu_124/10+48; temperature_1245=xiaoshu_124%10+48; reg_1244= zhengshu_124; LCD_write_english_string_124(42,5, temperature_124);/*/ /*函数名称: init() *输入参数: 共 0 个参数; *输出参数: 共 0 个参数; *返回值: *需储存的参数: 共 0 个参数; *功能介绍:初始化单片机的定时器串口中断等 *修改日志: *2010-12-14 Ver. 1.00 开始编写;2010-12-7 完成; 2010-12-7 /* */ /*/ void init_124() TMOD=0x21;TH0=(65536-18432)/256;TL0=(65536-18432)%256;TH1=0xfd;TL1=0xfd;TR0=1;TR1=1;SM0=0;SM1=1;REN=1;IP=0X10;EA=1; ET0=1;ET1=0;ES=1;PCON=0x00;Coil0_124=0;b232Send_124= 1;void timeProc_124(void)if(f1ms_124=1) f1ms_124=0; if(receTimeOut_124>0) receTimeOut_124-; if(receTimeOut_124=0 && receCount_124>0) /判断通讯接收是否超时 b232Send_124 = 0; /将232置为接收状态 receCount_124 = 0; /将接收地址偏移寄存器清零 checkoutError_124 = 0; if(f10ms_124=1)f10ms_124=0;if(reg_1244>reg_1242)|(reg_1244<reg_1243)alarm_124=0;elsealarm_124=1;save_124();c100ms_124+;if(c100ms_124>=10) c100ms_124=0; displaytempr_124(); bRunLED_124 = bRunLED_124;void main(void)init_124(); /初始化单片机的寄存器 read_124(); /开机去读上次断电的寄存器和线圈状态receCount_124=0;kaiji_124(); /开机显示汉字 chushixianshi_124(); /显示寄存器值和线圈的状态while(1)checkCommdModbus_124(); /接收上位机命令,然后做出响应处理timeProc_124(); /定时去读温度,保存数据,判断是否报警#include "reg52.h"typedef unsigned charuint8;typedef unsigned intuint16;typedef unsigned longuint32;sbit Coil0_124 = P10;sbit Coil1_124 = P11;sbit Coil2_124 = P12;sbit Coil3_124 = P13;sbit Coil4_124 = P14;sbit Coil5_124 = P15;sbit Coil6_124 = P16;sbit Coil7_124 = P17;/sbit shuanmaen_124 = P10;sbitbRunLED_124 =P24;/系统运行指示灯sbitb232Send_124= P25;/发送接收状态sbitalarm_124 = P27; /报警位sbit checkoutError_124 =P26; /报错位#define TIMER_HIGHT_1240xf8#define TIMER_LOW_1240xcd extern uint8 code table_124;extern uint8 sendBuf_12435,receBuf_12435;extern uint16 reg_1245;/extern uint8checkoutError;/ =2 偶校验错 /extern uint8receTimeOut;/extern uint16dwTickCount;#include "modbus.h"#include "main.h"#include "nokia_5110.h"uint8sendCount_124;/发送字节个数uint8receCount_124=0; /接收到的字节个数uint8sendPosi_124; /发送位置uint8 flag=0;/*/ /*函数名称: uh_ASCIIh_124(uint8 uh_124) *输入参数: 共 1 个参数; *输出参数: 共 1 个参数; *返回值: asciih *需储存的参数: 共 1 个参数; *功能介绍: 把一个16进制uh的高四位值取出转换为相应的ASCII码 *修改日志: *2010-12-14 Ver. 1.00 开始编写;2010-12-7 完成; 2010-12-7 /*/ uint8 uh_ASCIIh_124(uint8 uh_124)uint8 temph_124;uint8 asciih_124;temph_124=uh_124/16; if(temph_124<10)asciih_124=temph_124+0x30;else asciih_124=temph_124+0x37; return asciih_124;/*/ /*函数名称: uh_ASCIIl_124(uint8 uh_124) *输入参数: 共 1 个参数; *输出参数: 共 1 个参数; *返回值: asciil *需储存的参数: 共 1 个参数; *功能介绍: 把一个16进制uh的低四位值取出转换为相应的ASCII码 *修改日志: *2010-12-14 Ver. 1.00 开始编写;2010-12-7 完成; 2010-12-7 /* */ /*/ uint8 uh_ASCIIl_124(uint8 uh_124)uint8 templ_124;uint8 asciil_124;templ_124=uh_124%16;if(templ_124<10)asciil_124=templ_124+0x30;else asciil_124=templ_124+0x37; return asciil_124;/*/ /*函数名称: ASCII_uh_124(uint8 asciih_124,uint8 asciil_124) *输入参数: 共 2 个参数; *输出参数: 共 1 个参数; *返回值: uh *需储存的参数: 共 1 个参数; *功能介绍: 把两个ASCII码转换为10进制的值 *修改日志: *2010-12-14 Ver. 1.00 开始编写;2010-12-7 完成; 2010-12-7 /* */ /*/ uint8 ASCII_uh_124(uint8 asciih_124,uint8 asciil_124)uint8 uh_124;if(asciih_124<=57)asciih_124=asciih_124-48;else asciih_124=asciih_124-55; if(asciil_124<=57)asciil_124=asciil_124-48;else asciil_124=asciil_124-55;uh_124=asciih_124*16+asciil_124;return uh_124;/*/ /*函数名称: lrc_124(uint8 *p_124, uint8 usDataLen_124) *输入参数: 共 2 个参数; *输出参数: 共 1 个参数; *返回值: uh *需储存的参数: 共 1 个参数; *功能介绍: 把指针p所指向的一串ASCII码,从第二个开始把两个连续的ASCII码转换为16进制的值, 然后把转换后的usDataLen_124个字节累加,然后取反加1,然后返回这和值。实现了LRC功能! *修改日志: *2010-12-14 Ver. 1.00 开始编写;2010-12-7 完成; 2010-12-7 /* */ /*/ uint8 lrc_124(uint8 *p_124, uint8 usDataLen_124)uint8 uchLRC_124 = 0 ;uint8 temp_124;uint8 q_124=0;while(usDataLen_124) usDataLen_124-;q_124=q_124+2;temp_124= ASCII_uh_124(p_124q_124-1,p_124q_124);uchLRC_124 += temp_124;uchLRC_124=255-uchLRC_124+1;return uchLRC_124;/*/ /*函数名称: beginSend_124(void) *输入参数: 共 0 个参数; *输出参数: 共 0 个参数; *返回值: uh *需储存的参数: 共 0 个参数; *功能介绍: 把要发送的数组第一个值赋给SBUF,然后开始进入中断发送 *修改日志: *2010-12-14 Ver. 1.00 开始编写;2010-12-7 完成; 2010-12-7 /* */ /*/ void beginSend_124(void)b232Send_124 = 0;/设为发送sendPosi_124 = 0;sendCount_124-;SBUF = sendBuf_1240;/void beginSend(void)/*/ /*函数名称: readCoil_124(void) *输入参数: 共 0 个参数; *输出参数: 共 0 个参数; *返回值: uh *需储存的参数: 共 n 个参数; *功能介绍: 读线圈,一共有八个线圈,为p2口 ,根据接收到的命令后,从起始地址读n个线圈,然后按照协议封装成帧发送! *修改日志: *2010-12-14 Ver. 1.00 开始编写;2010-12-8 完成; 2010-12-8 /* */ /*/ void readCoil_124(void) /功能1,读线圈9 uint8 addrhh_124; uint8 addrhl_124;uint8 addrh_124;uint8 addrlh_124; uint8 addrll_124;uint8 addrl_124; uint8 counthh_124;uint8 counthl_124;uint8 counth_124;uint8 countlh_124;uint8 countll_124;uint8 countl_124;uint8 tempdat_124=0;uint8 lrcdat_124; addrhh_124=receBuf_1245;addrhl_124=receBuf_1246;addrh_124= ASCII_uh_124(addrhh_124,addrhl_124);addrlh_124=receBuf_1247;addrll_124=receBuf_1248;addrl_124= ASCII_uh_124(addrlh_124,addrll_124);counthh_124= receBuf_1249;counthl_124= receBuf_12410;counth_124 =ASCII_uh_124(counthh_124,counthl_124);countlh_124= receBuf_12411;countll_124= receBuf_12412;countl_124 = ASCII_uh_124(countlh_124,countll_124);tempdat_124=P1;diaplaycoils_124();if(addrl_124=0) tempdat_124=tempdat_124&yu_124(countl_124); if(addrl_124=1)tempdat_124=tempdat_124>>1;tempdat_124=tempdat_124&yu_124(countl_124);if(addrl_124=2)tempdat_124=tempdat_124>>2;tempdat_124=tempdat_124&yu_124(countl_124);if(addrl_124=3)tempdat_124=tempdat_124>>3;tempdat_124=tempdat_124&yu_124(countl_124);if(addrl_124=4)tempdat_124=tempdat_124>>4;tempdat_124=tempdat_124&yu_124(countl_124);if(addrl_124=5)tempdat_124=tempdat_124>>5;tempdat_124=tempdat_124&yu_124(countl_124);if(addrl_124=6)tempdat_124=tempdat_124>>6;tempdat_124=tempdat_124&yu_124(countl_124);if(addrl_124=7)tempdat_124=tempdat_124>>7;tempdat_124=tempdat_124&yu_124(countl_124); sendBuf_1247=uh_ASCIIh_124(tempdat_124); sendBuf_1248=uh_ASCIIl_124(tempdat_124);sendBuf_1240 = 0X3A;sendBuf_1241 = 0x30;sendBuf_1242 = 0x31;sendBuf_1243 = 0x30;sendBuf_1244 = 0x31;sendBuf_1245 = 0x30;sendBuf_1246 = 0x31;lrcdat_124 =lrc_124(sendBuf_124,4);sendBuf_1249=uh_ASCIIh_124(lrcdat_124);sendBuf_12410=uh_ASCIIl_124(lrcdat_124);sendBuf_12411= 0x0D;sendBuf_12412= 0x0A;sendCount_124=13;beginSend_124();/*/ /*函数名称: forceSingleCoil_124(void) *输入参数: 共 0 个参数; *输出参数: 共 0 个参数;