找回密码
 立即注册
查看: 632|回复: 0

STC15W4K32S4单片机开发带以太网及双RS485通讯 原理图+例程

[复制链接]

该用户从未签到

42

主题

7

回帖

246

积分

中级会员

积分
246
发表于 2023-7-10 11:30:01 | 显示全部楼层 |阅读模式
DSC_0008.JPG

DSC_0010.JPG

DSC_0016.JPG

邬继光-18035222929-通讯转换板需求工程_00.jpg

邬继光-18035222929-通讯转换板需求工程_01.jpg

邬继光-18035222929-通讯转换板需求工程_02.jpg



#define MAIN_Fosc                11059200L        //定义主时钟
#include        "15W4KxxS4.H"
#include <intrins.h>                                        // 加入此头文件后,可使用_nop_库函数
#include <string.h>           // 加入此头文件后,可使用strstr库函数

#define  uint8 unsigned char
#define  uint16  unsigned int

#define BAUD 9600                            // 波特率
#define TM (65536 - (MAIN_Fosc/4/BAUD))       
#define Buf_Max 50
#define S2_S  0x01       
#define S2RI 0x01
#define S2TI 0x02
#define S3RI 0x01
#define S3TI 0x02
#define S4RI 0x01
#define S4TI 0x02

uint8 xdata Rec_Buf1[Buf_Max];     //接收串口1缓存数组
uint8 xdata Rec_Buf2[Buf_Max];     //接收串口2缓存数组
uint8 xdata Rec_Buf3[Buf_Max];       //接收串口3缓存数组
uint8 xdata Rec_Buf4[Buf_Max];       //接收串口4缓存数组
uint8 i = 0;                         
uint8 j = 0;
uint8 m = 0;                         
uint8 n = 0;

/***************************************************************************
* 描  述 : 串口1/2/3/4初始化函数
* 入  参 : 无
* 返回值 : 无
备注:波特率9600bps   晶振11.0592MHz
**************************************************************************/
void Uart1234_Init(void)
{       
//  P_SW1|=0X80;        //选择P16 P17为串口1
//        P_SW1&=0XBF;        //选择P16 P17为串口1
//        P_SW2|=S2_S;        //选择P46 P47为串口2
        //串口1配置       
        PCON &= 0x3f;                    //串口1波特率不倍速,串行口工作方式由SM0、SM1决定
        SCON = 0x50;                    //串口1的8位数据,可变波特率,启动串行接收器
        AUXR |= 0x01;                    //串口1选择定时器2为波特率发生器
        //串口2配置       
        S2CON = 0x50;                    //串口2的8位数据,可变波特率       
  //串口3配置       
        S3CON |= 0x10;                  //串口3启动串行接收器
        S3CON &= 0x30;                  //串口3选择定时器2为波特率发生器,8位数据,可变波特率
        //串口4配置       
        S4CON |= 0x10;                  //启动串行接收器       
        S4CON &= 0x30;                  //8位数据,可变波特率,串口4选择定时器2为波特率发生器
       
        AUXR |= 0x04;                    //定时器2时钟为Fosc,即1T
        T2L = 0xE0;                      //设定定时初值
        T2H = 0xFE;         //设定定时初值
        AUXR |= 0x10;       //启动定时器2
}
//PWMC
/***************************************************************************
* 描  述 : 串口1发送数据函数
* 入  参 : uint8 数据
* 返回值 : 无
**************************************************************************/
void SendDataByUart1(uint8 dat)
{
    SBUF = dat;                 //写数据到UART数据寄存器
                while(TI == 0);             //在停止位没有发送时,TI为0即一直等待
                TI = 0;                     //清除TI位(该位必须软件清零)
}

/***************************************************************************
* 描  述 : 串口1发送字符串函数
* 入  参 : 字符串
* 返回值 : 无
**************************************************************************/
void SendStringByUart1(uint8 *s)
{
        while(*s)
        {
                SendDataByUart1(*s++);       //将字符串中的字符一个一个发送
        }
}

/**************************************
功能描述:握手成功与否函数
入口参数:uint8 *a
返回值:位
***************************************/
bit Hand1(uint8 *a)
{
    if(strstr(Rec_Buf1,a)!=NULL)     //判断字符串a是否是字符串Rec_Buf1的子串
            return 1;                      //如果字符串a是字符串Rec_Buf1的子串
          else
                  return 0;                      //如果字符串a不是字符串Rec_Buf1的子串
}

/**************************************
功能描述:清除串口1缓存内容函数
入口参数:无
返回值:无
***************************************/
void CLR_Buf1(void)
{
        uint8 k;
    for(k=0;k<Buf_Max;k++)      //将串口1缓存数组的值都清为零
            {
                           Rec_Buf1[k] = 0;
                  }
    i = 0;                    
}

/***************************************************************************
* 描  述 : 串口1中断服务函数
* 入  参 : 无
* 返回值 : 无
**************************************************************************/
void Uart1() interrupt UART1_VECTOR using 1
{
        ES = 0;                       // 串口1中断关闭
        if (RI)                       //串行接收到停止位的中间时刻时,该位置1
  {
      RI = 0;                   //清除RI位 (该位必须软件清零)
                        Rec_Buf1 = SBUF;       //把串口1缓存SBUF寄存器数据依次存放到数组Rec_Buf1中
                        i++;                     
            if(i>Buf_Max)             //接收数大于定义接收数组最大个数时,覆盖接收数组之前值
                                {
                                        i = 0;                 
                                }           
   }
   if (TI)                    //在停止位开始发送时,该位置1
   {
      TI = 0;                 //清除TI位(该位必须软件清零)
   }
         ES =  1;                   // 串口1中断打开
}

/***************************************************************************
* 描  述 : 串口2发送数据函数
* 入  参 : uint8 数据
* 返回值 : 无
**************************************************************************/
void SendDataByUart2(uint8 dat)
{
    S2BUF = dat;                 //写数据到UART数据寄存器
                while(!(S2CON&S2TI));        //在停止位没有发送时,S2TI为0即一直等待
    S2CON&=~S2TI;                //清除S2CON寄存器对应S2TI位(该位必须软件清零)
}

/***************************************************************************
* 描  述 : 串口2发送字符串函数
* 入  参 : 字符串
* 返回值 : 无
**************************************************************************/
void SendStringByUart2(uint8 *s)
{
  IE2 &= 0xFE;                                   // 串口2中断关闭
        while (*s)                  //检测字符串结束标志
  {
    SendDataByUart2(*s++);         //发送当前字符
  }
  IE2 |= 0x01;                     // 串口2中断打开
}

/**************************************
功能描述:握手成功与否函数
入口参数:uint8 *a
返回值:位
***************************************/
bit Hand2(uint8 *a)
{
  if(strstr(Rec_Buf2,a)!=NULL)      //判断字符串a是否是字符串Rec_Buf2的子串
           return 1;                      //如果字符串a是字符串Rec_Buf2的子串
        else
                 return 0;                      //如果字符串a不是字符串Rec_Buf2的子串
}

/**************************************
功能描述:清除串口2缓存内容函数
入口参数:无
返回值:无
***************************************/
void CLR_Buf2(void)
{
        unsigned char k;
  for(k=0;k<Buf_Max;k++)      //将串口2缓存数组的值都清为零
        {
                 Rec_Buf2[k] = 0;
  }
  j = 0;                    
}

/***************************************************************************
* 描  述 : 串口2中断服务函数
* 入  参 : 无
* 返回值 : 无
**************************************************************************/
void Uart2() interrupt UART2_VECTOR using 1
{
        IE2 &= 0xFE;                                                  // 串口2中断关闭
        if (S2CON & S2RI)                          //串行接收到停止位的中间时刻时,该位置1
  {
      S2CON &= ~S2RI;                        //清除S2CON寄存器对应S2RI位(该位必须软件清零)
                        Rec_Buf2[j] = S2BUF;                   //把串口2缓存SBUF寄存器数据依次存放到数组Rec_Buf2中
                        j++;                                   
            if(j>Buf_Max)                          //接收数大于定义接收数组最大个数时,覆盖接收数组之前值
                        {
                                        j = 0;
                        }           
   }
      if (S2CON & S2TI)                       //在停止位开始发送时,该位置1
      {
        S2CON &= ~S2TI;                                         //清除S2CON寄存器对应S2TI位(该位必须软件清零)
      }
         IE2 |= 0x01;                               // 串口2中断打开       
}

/***************************************************************************
* 描  述 : 串口3发送数据函数
* 入  参 : uint8 数据
* 返回值 : 无
**************************************************************************/
void SendDataByUart3(uint8 dat)
{
    S3BUF = dat;                 //写数据到UART数据寄存器
                while(!(S3CON&S3TI));        //在停止位没有发送时,S3TI为0即一直等待
    S3CON&=~S3TI;                //清除S3CON寄存器对应S3TI位(该位必须软件清零)
}

/***************************************************************************
* 描  述 : 串口3发送字符串函数
* 入  参 : 字符串
* 返回值 : 无
**************************************************************************/
void SendStringByUart3(char *s)
{
    IE2 &= 0xF7;                                        // 串口3中断关闭
          while (*s)                       //检测字符串结束标志
    {
      SendDataByUart3(*s++);         //发送当前字符
    }
    IE2 |= 0x08;                     // 串口3中断打开
}

/**************************************
功能描述:握手成功与否函数
入口参数:uint8 *a
返回值:位
***************************************/
bit Hand3(uint8 *a)
{
    if(strstr(Rec_Buf3,a)!=NULL)     //判断字符串a是否是字符串Rec_Buf3的子串
            return 1;                      //如果字符串a是字符串Rec_Buf3的子串
        else
                  return 0;                      //如果字符串a不是字符串Rec_Buf3的子串
}

/**************************************
功能描述:清除缓存内容函数
入口参数:无
返回值:无
***************************************/
void CLR_Buf3(void)
{
          uint8 k;
    for(k=0;k<Buf_Max;k++)      //将串口3缓存数组的值都清为零
          {
                           Rec_Buf3[k] = 0;
                }
    m = 0;                    
}

/***************************************************************************
* 描  述 : 串口3中断服务函数
* 入  参 : 无
* 返回值 : 无
**************************************************************************/
void Uart3() interrupt UART3_VECTOR using 1
{
        IE2 &= 0xF7;                                        // 串口3中断关闭
        if (S3CON & S3RI)                //串行接收到停止位的中间时刻时,该位置1
  {
      S3CON &= ~S3RI;              //清除S3CON寄存器对应S3RI位(该位必须软件清零)
                        Rec_Buf3[m] = S3BUF;         //把串口3缓存SBUF寄存器数据依次存放到数组Rec_Buf3中
                        m++;               
            if(m>Buf_Max)                //接收数大于定义接收数组最大个数时,覆盖接收数组之前值
                                {
                                        m = 0;
                                }     
   }
  if (S3CON & S3TI)                //在停止位开始发送时,该位置1
   {
      S3CON &= ~S3TI;                                //清除S3CON寄存器对应S3TI位(该位必须软件清零)
   }
         IE2 |= 0x08;                     // 串口3中断打开
}

/***************************************************************************
* 描  述 : 串口4发送数据函数
* 入  参 : uint8 数据
* 返回值 : 无
**************************************************************************/
void SendDataByUart4(uint8 dat)
{
    S4BUF = dat;                 //写数据到UART数据寄存器
                while(!(S4CON&S4TI));        //在停止位没有发送时,S4TI为0即一直等待
    S4CON&=~S4TI;                //清除S4CON寄存器对应S4TI位(该位必须软件清零)
}

/***************************************************************************
* 描  述 : 串口4发送字符串函数
* 入  参 : 字符串
* 返回值 : 无
**************************************************************************/
void SendStringByUart4(char *s)
{
  IE2 &= 0xEF;                                        //串口4中断关闭
        while (*s)                       //检测字符串结束标志
  {
    SendDataByUart4(*s++);         //发送当前字符
  }
  IE2 |= 0x10;                     //串口4中断打开
}

/**************************************
功能描述:握手成功与否函数
入口参数:unsigned char *a
返回值:位
***************************************/
bit Hand4(unsigned char *a)
{
  if(strstr(Rec_Buf4,a)!=NULL)       //判断字符串a是否是字符串Rec_Buf4的子串
            return 1;                      //如果字符串a是字符串Rec_Buf4的子串
        else
                  return 0;                      //如果字符串a不是字符串Rec_Buf4的子串
}

/**************************************
功能描述:清除缓存内容函数
入口参数:无
返回值:无
***************************************/
void CLR_Buf4(void)
{
        unsigned char k;
  for(k=0;k<Buf_Max;k++)         //将串口4缓存数组的值都清为零
        {
                 Rec_Buf4[k] = 0;
        }
  n = 0;                    
}

/***************************************************************************
* 描  述 : 串口4中断服务函数
* 入  参 : 无
* 返回值 : 无
**************************************************************************/
void Uart4() interrupt UART4_VECTOR
{                       
  IE2 &= 0xEF;                                   // 串口4中断关闭  
        if(S4CON & S4RI)           //串行接收到停止位的中间时刻时,该位置1
        {
                S4CON &= ~S4RI;                 //清除S4CON寄存器对应S4RI位(该位必须软件清零)
                Rec_Buf4[n] = S4BUF;     //把串口4缓存SBUF寄存器数据依次存放到数组Rec_Buf4中
                n++;               
          if(n>Buf_Max)            //接收数大于定义接收数组最大个数时,覆盖接收数组之前值
                {
                                n = 0;
                }
        }
        if(S4CON & S4TI)           //在停止位开始发送时,该位置1
        {
                S4CON &= ~S4TI;          //清除S4CON寄存器对应S4TI位(该位必须软件清零)
        }
         IE2 |= 0x10;              // 串口4中断打开
}



/***************************************************************************
* 描  述 : 主函数
* 入  参 : 无
* 返回值 : 无
**************************************************************************/
int main()
{
/////////////////////////////////////////////////
//注意: STC15W4K32S4系列的芯片,上电后所有与PWM相关的IO口均为
//      高阻态,需将这些口设置为准双向口或强推挽模式方可正常使用
//相关IO: P0.6/P0.7/P1.6/P1.7/P2.1/P2.2
//        P2.3/P2.7/P3.7/P4.2/P4.4/P4.5
/////////////////////////////////////////////////
        P1M1 &= 0x3F;        P1M0 &= 0x3F;          //设置P1.6~P1.7为准双向口
        P4M1 &= 0x3F;        P4M0 &= 0x3F;          //设置P4.6~P4.7为准双向口
       
        Uart1234_Init();                              // 串口1/2/3/4初始化
  ES = 1;                                       // 串口1中断打开                              
  IE2 |= 0x01;                                  // 串口2中断打开
        IE2 |= 0x08;                                  // 串口3中断打开
        IE2 |= 0x10;                                  // 串口4中断打开
        EA = 1;                                       // 总中断打开
       
        while(1)
        {
                if(Hand1("UART1"))                            //串口1收到字符串UART1
                {
                        ES = 0;                                                       // 串口1中断关闭
                        CLR_Buf1();                                 //将串口1缓存数组的值都清为零
                        SendStringByUart1("UART1 CHECK OK!\r\n");                //串口1发送字符串UART1 CHECK OK!
                        ES = 1;                                                                                // 串口1中断打开       
                }        
                if(Hand2("UART2"))                            //串口2收到字符串UART2
                {
                        IE2 &= 0xFE;                                                   // 串口2中断关闭
                        CLR_Buf2();                                 //将串口2缓存数组的值都清为零
                        SendStringByUart2("UART2 CHECK OK!\r\n");                //串口2发送字符串UART2 CHECK OK!
                        IE2 |= 0x01;                                // 串口2中断打开                       
                }        
                if(Hand3("UART3"))                            //  收到打开LED1的指令
                {
                        IE2 &= 0xF7;                                                   // 串口3中断关闭                       
                        CLR_Buf3();                                 //将串口3缓存数组的值都清为零
                        SendStringByUart3("UART3 CHECK OK!\r\n");                //串口3发送字符串UART3 CHECK OK!
                        IE2 |= 0x08;                                // 串口3中断打开                                       
                }
                if(Hand4("UART4"))                            //  收到打开LED1的指令
                {
                        IE2 &= 0xEF;                                                   // 串口4中断关闭               
                        CLR_Buf4();                                 //将串口4缓存数组的值都清为零
                        SendStringByUart4("UART4 CHECK OK!\r\n");                //串口4发送字符串UART4 CHECK OK!
                        IE2 |= 0x10;                                // 串口4中断打开                               
                }
        }
}  

回复 送花

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2024-5-22 09:45 , Processed in 0.071542 second(s), 31 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表