立即注冊(cè) 登錄
返回首頁(yè)

uid:280979的個(gè)人空間

日志

單路輸入輸出帶485通訊modbus RTU控制

已有 1867 次閱讀2018-2-1 13:10

#include "main.h"
#include "init.h"

#define ENABLE_IAP 0x83 //系統(tǒng)工作時(shí)鐘<12MHz 時(shí),對(duì)IAP_CONTR 寄存器設(shè)置此值
#define CMD_IDLE 0
#define CMD_READ 1
#define CMD_PROGRAM 2
#define CMD_ERASE 3
#define ENABLE_IAP 0x83//SYSCLK<12MH
#define IAP_ADDRESS 0x0000 //存儲(chǔ)地址


uint8 add;    //掉電保持485的地址
uint8 j=0;
uint8 dat=0X00;    
bit flag_zx=0;

uint8 sendPosi=0;     //發(fā)送緩沖區(qū)指針
uint8 receCount=0;    //接收緩沖區(qū)指針
uint8 sendCount=0;    //需要發(fā)送數(shù)據(jù)個(gè)數(shù)
uint8 receTimeOut=0;  //通訊超時(shí)值
uint8 byteCount=5;    //發(fā)送個(gè)數(shù)

uint8 sendBuf[10];  //發(fā)送緩沖區(qū)
uint8 receBuf[10];    //接收緩沖區(qū)

/********************************************************************
                           定義數(shù)據(jù)類型
*********************************************************************/
uint8 TBUF,RBUF;
uint8 TDAT,RDAT;
uint8 TCNT,RCNT;
uint8 TBIT,RBIT;
bit TING,RING;
bit TEND,REND;
bit bz1=0;
uint8 t,r,ii;  //定義數(shù)據(jù)類型
uint8 but[16];  //數(shù)據(jù)存儲(chǔ)數(shù)組
/********************************************************************
                            定義 ISP/IAP/EEPROM 命令
*********************************************************************/

void IapIdle();//禁用 ISP/IAP/EEPROM functionmake 單片機(jī) 在 一 安全 狀態(tài)
uint8 IapReadByte(uint16 addr);//讀數(shù)據(jù)
void IapProgramByte(uint16 addr, uint8 dat);//寫數(shù)據(jù)
void IapEraseSector(uint16 addr);//擦除數(shù)據(jù)


void delay()//延時(shí)程序
{
uint8 m,n,s;
for(m=100;m>0;m--)
for(n=200;n>0;n--)
for(s=248;s>0;s--);
}
void delay1()//延時(shí)程序
{
uint8 m,n,s;
for(m=10;m>0;m--)
for(n=20;n>0;n--)
for(s=148;s>0;s--);
}
/****************發(fā)送函數(shù)*********************/
void send1()
{   
sendBuf[0]=add;;
sendBuf[1]=0x00;
sendBuf[2]=0x00;
sendBuf[3]=0xAC;
sendBuf[4]=0xAC;
}
/****************發(fā)送函數(shù)*********************/
void senduart2()
{    RS485_DIR=1;
        for(ii=0;ii<5;ii++)
{
    if(TEND)  //允許發(fā)送
{
TEND=0;
TBUF=sendBuf[t++&0x0F];
TING=1;
}
while(!TEND);
}
t=0;
RS485_DIR=0;
}
/*****************清空發(fā)送緩沖區(qū)*************************/
void clear_receBuf()
{
    uint8 i;
for(i=0;i<8;i++)
{
   receBuf[i]=0;
}
}
void main()
{
  delay();
    clear_receBuf();
    add= IapReadByte(0x01);//讀取存儲(chǔ)的值
if(add==0xff)
  add=0x00;
    ConfigUART1();

TR0=1;
EA=1;
//   TEND=0;
// REND=0;       

    while(1)
{  
  if((IN1==0)&&(bz1==0)){delay1();if(IN1==0){send1();senduart2();clear_receBuf();bz1=1;OUT1=!OUT1;}}if((IN1==1)&&(bz1==1)){bz1=0;}
  if(REND)  //如果有接收
  { 
    REND=0; //接收標(biāo)志清零
    receBuf[r++&0x0F]=RBUF;     //把接受的數(shù)據(jù)存儲(chǔ)到BUT數(shù)組中
if(receBuf[0]!=add){r=0;}
if(r>=8)
{ r=0;

   flag_zx=1;
}
  }
  if(flag_zx==1)
  {    

       flag_zx=0;
   //0         1       2       3        4
//起始位   地址位  功能位   數(shù)據(jù)位  結(jié)束位
if((receBuf[1]==0x05)&&(receBuf[2]==0x00)&&(receBuf[3]==0x01))  //如果開(kāi)始位和結(jié)束位,還有地址都正確,進(jìn)行下一步判斷
  if(receBuf[4]==0xff)  //修改板子地址
  {
OUT1=1; clear_receBuf();r=0;
             
  }
else if(receBuf[4]==0x00)  //修改板子地址
  {
OUT1=0; clear_receBuf();r=0;
   //add=receBuf[3];
 //IapEraseSector(0);  //擦除扇區(qū)
          //IapProgramByte(0x01,add);//寫入新的地址           
  }
}
if((receBuf[1]==0x06)&&(receBuf[3]==0x10))
{
        add=receBuf[5];
IapEraseSector(0);  //擦除扇區(qū)
        IapProgramByte(0x01,add);//寫入新的地址  
send1();senduart2();clear_receBuf();
}
clear_receBuf();r=0;
}
}
}


// /**********************************************************
//放在主函數(shù),定時(shí)0溢出中斷函數(shù),
//*********************/
void tm0()interrupt 1 using 1
{
 if(RING)
  {
   if(--RCNT==0)
    {
RCNT=3;
if(--RBIT==0)
        {
RBUF=RDAT;
RING=0;
         REND=1;
}
else
{
RDAT>>=1;
if(RXB)RDAT|=0X80;
}

    }
  }
    else if(!RXB)
{
RING=1;
RCNT=4;
RBIT=9;
}
    if(--TCNT==0)
{
TCNT=3;


if(TING)
{
 if(TBIT==0)
 {
 TXB=0;
 TDAT=TBUF;
 TBIT=9;
 }
 else
 {
 TDAT>>=1;
 if(--TBIT==0)
 {
  TXB=1;
  TING=0;
  TEND=1;
 }
 else
 {
 TXB=CY;
 }
 }
}
}
}
void IapIdle(){//禁用 ISP/IAP/EEPROM functionmake 單片機(jī) 在 一 安全 狀態(tài)
    IAP_CONTR = 0;   //
IAP_CMD = 0;   //
IAP_TRIG = 0;   //
IAP_ADDRH = 0x80;  //
IAP_ADDRL = 0;   //
}
uint8 IapReadByte(uint16 addr){//讀數(shù)據(jù)
   uint8 dat;
   IAP_CONTR = ENABLE_IAP;
   IAP_CMD = CMD_READ; 
   IAP_ADDRL = addr;
   IAP_ADDRH = addr >> 8;
   IAP_TRIG = 0x5A;
   IAP_TRIG = 0xA5;
   _nop_();
   dat = IAP_DATA;
   IapIdle();
   return dat;
}
void IapProgramByte(uint16 addr, uint8 dat){//寫數(shù)據(jù)
   IAP_CONTR = ENABLE_IAP;
   IAP_CMD = CMD_PROGRAM;
   IAP_ADDRL = addr;
   IAP_ADDRH = addr >> 8;
   IAP_DATA = dat;
   IAP_TRIG = 0x5A;
   IAP_TRIG = 0xA5;
   _nop_();
   IapIdle();
}
void IapEraseSector(uint16 addr){//擦除數(shù)據(jù)
   IAP_CONTR = ENABLE_IAP;
   IAP_CMD = CMD_ERASE;
   IAP_ADDRL = addr;
   IAP_ADDRH = addr >> 8;
   IAP_TRIG = 0x5A;
   IAP_TRIG = 0xA5;
   _nop_();
   IapIdle();
}

路過(guò)

雞蛋

鮮花

握手

雷人

全部作者的其他最新日志

評(píng)論 (0 個(gè)評(píng)論)

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

返回頂部