C51--Task08 串口通信实验

一、发送字符

具体任务:

 采用按键发送一串字符至串口助手。要求:每次按下KEY1后,能够发送“HelloWorld”至串口助手

代码:

/*********************************************************************************************************
* 模块名称: main.c
* 摘    要: 主文件,包含初始化函数和main函数
* 当前版本: 1.0.0
* 作    者: 努摆的皮卡皮
* 完成日期: 2022年8月12日
* 内    容: 
* 注    意: 
**********************************************************************************************************
* 取代版本: 
* 作    者: 
* 完成日期: 
* 修改内容: 
* 修改文件: 
*********************************************************************************************************/
/*********************************************************************************************************
*                                              包含头文件
*********************************************************************************************************/
#include 

/*********************************************************************************************************
*                                              宏定义
*********************************************************************************************************/

/*********************************************************************************************************
*                                              位定义
*********************************************************************************************************/
sbit KEY1 = P3^2;   //定义按键KEY1

/*********************************************************************************************************
*                                              枚举结构体定义
*********************************************************************************************************/

/*********************************************************************************************************
*                                              内部变量
*********************************************************************************************************/

/*********************************************************************************************************
*                                              内部函数声明
*********************************************************************************************************/
static void InitUART();        //串口配置
static void UART_Handlen();   //中断服务
static void InitInterrupt();   //中断配置


/*********************************************************************************************************
*                                              内部函数实现
*********************************************************************************************************/
/*********************************************************************************************************
* 函数名称: InitInterrupt
* 函数功能: 中断配置
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
static void InitInterrupt()
{     
  ES = 1;         //打开 串口接受中断允许
  EA = 1;         //打开 总中断允许
}

/*********************************************************************************************************
* 函数名称: InitUART
* 函数功能: 串口配置
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
static void InitUART()
{
  SCON = 0X50;           //设置 串口 工作模式1,并打开接收允许
  TMOD = 0X20;           //设置 定时器1 工作模式2(8位自动重装定时器)
  PCON = 0X80;           //设置 波特率加倍
  TL1  = 0XF3;           //设置 定时器1 计数初值,波特率为4800
  TH1  = TL1;            //设置 定时器1重装载值,等于计数初值
  TR1  = 1;              //打开 定时器1
}

/*********************************************************************************************************
* 函数名称: main
* 函数功能: 主函数
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
void main()
{
  InitInterrupt();    //初始化(配置)中断
  InitUART();         //初始化串口
  while (1)
  {
    
  }
}

//延迟函数
static void DelayNms(int nms)
{
  unsigned int i,j;
  for(i = 0; i < nms; i++)
  {
    for(j = 0; j < 123; j++)
    {
      
    } 
  }
}

/*********************************************************************************************************
* 函数名称: UART_Handler
* 函数功能: 串口中断服务函数
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
void UART_Handler() interrupt 4
{
  unsigned char arrString[]="Hello world";
	unsigned char i;
	
 if(0 == KEY1)           //KEY1按下
    {
      DelayNms(50);       //等50ms
      if(0 == KEY1)       //再次检测到KEY1按下
      {
        for(i = 0; i<=20; i++)   //输出字符串
        {   
            SBUF = arrString[i];
            while(!TI)   //等待发送完成
            {
        
            }
            TI = 0;   //清除发送中断请求标志位
         }
			 }
		 }
		 
}
    

二、数字控制LED

具体任务:

使用串口助手控制51核心板上的硬件。要求:能够使用数字“1”、“2”、“3”和“4”命令控制LED1、LED2、LED3和LED4打开或关闭。

代码:

/*********************************************************************************************************
* 模块名称: main.c
* 摘    要: 主文件,包含初始化函数和main函数
* 当前版本: 1.0.0
* 作    者:努摆的皮卡皮
* 完成日期: 2022年8月12日
* 内    容: 
* 注    意: 
**********************************************************************************************************
* 取代版本: 
* 作    者: 
* 完成日期: 
* 修改内容: 
* 修改文件: 
*********************************************************************************************************/
/*********************************************************************************************************
*                                              包含头文件
*********************************************************************************************************/
#include 

/*********************************************************************************************************
*                                              宏定义
*********************************************************************************************************/

/*********************************************************************************************************
*                                              位定义
*********************************************************************************************************/
sbit LED1 = P2^4;   
sbit LED2 = P2^5;   
sbit LED3 = P2^6;   
sbit LED4 = P2^7; 

/*********************************************************************************************************
*                                              枚举结构体定义
*********************************************************************************************************/

/*********************************************************************************************************
*                                              内部变量
*********************************************************************************************************/

/*********************************************************************************************************
*                                              内部函数声明
*********************************************************************************************************/
static void InitUART();        //串口配置
static void UART_Handlen();   //中断服务
static void InitInterrupt();   //中断配置


/*********************************************************************************************************
*                                              内部函数实现
*********************************************************************************************************/
/*********************************************************************************************************
* 函数名称: InitInterrupt
* 函数功能: 中断配置
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
static void InitInterrupt()
{     
  ES = 1;         //打开 串口接受中断允许
  EA = 1;         //打开 总中断允许
}

/*********************************************************************************************************
* 函数名称: InitUART
* 函数功能: 串口配置
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
static void InitUART()
{
  SCON = 0X50;           //设置 串口 工作模式1,并打开接收允许
  TMOD = 0X20;           //设置 定时器1 工作模式2(8位自动重装定时器)
  PCON = 0X80;           //设置 波特率加倍
  TL1  = 0XF3;           //设置 定时器1 计数初值,波特率为4800
  TH1  = TL1;            //设置 定时器1重装载值,等于计数初值
  TR1  = 1;              //打开 定时器1
}

/*********************************************************************************************************
* 函数名称: main
* 函数功能: 主函数
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
void main()
{
  InitInterrupt();    //初始化(配置)中断
  InitUART();         //初始化串口
  while (1)
  {
    
  }
}


/*********************************************************************************************************
* 函数名称: UART_Handler
* 函数功能: 串口中断服务函数
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
void UART_Handler() interrupt 4
{
  static unsigned char s_iBuffer;
	
	//数据接收
    if(1 == RI)             //当接收中断请求标志位被置位
    {
        s_iBuffer = SBUF;   //将数据从串口数据缓冲寄存器中取出
        RI = 0;   //清除中断请求标志位
    }
    
	//数据发送
    SBUF = s_iBuffer;   //将数据放入寄存器
    
    if('1' == s_iBuffer)   //输入的数据是 '1' 时
    {
        if(LED1 == 0)   //如果LED开了
        {
            LED1 = 1;   //就关掉
        }
        else
        {
            LED1 = 0;   //否则就打开
        }
    }
    
    if('2' == s_iBuffer)   //同理
    {
        if(LED2 == 0)
        {
            LED2 = 1;
        }
        else
        {
            LED2 = 0;
        }
    }
    
    if('3' == s_iBuffer)   
    {
        if(LED3 == 0)
        {
            LED3 = 1;
        }
        else
        {
            LED3 = 0;
        }
    }
    
    if('4' == s_iBuffer)   
    {
        if(LED4 == 0)
        {
            LED4 = 1;
        }
        else
        {
            LED4 = 0;
        }
    }
    
    while(!TI)   //等待数据发送完成
    {
        
    }
    TI = 0;   //清除发送中断请求标志位
		
}
    

三、字符串控制LED

具体任务:

在任务1的基础上,尝试使用使用“LED1”、“LED2”、“LED3”和“LED4”等类似的字符串命令控制控制LED1、LED2、LED3和LED4打开或关闭。

代码:

/*********************************************************************************************************
* 模块名称: main.c
* 摘    要: 主文件,包含初始化函数和main函数
* 当前版本: 1.0.0
* 作    者: 努摆的皮卡皮
* 完成日期: 2022年8月12日
* 内    容: 
* 注    意: 
**********************************************************************************************************
* 取代版本: 
* 作    者: 
* 完成日期: 
* 修改内容: 
* 修改文件: 
*********************************************************************************************************/
/*********************************************************************************************************
*                                              包含头文件
*********************************************************************************************************/
#include 

/*********************************************************************************************************
*                                              宏定义
*********************************************************************************************************/

/*********************************************************************************************************
*                                              位定义
*********************************************************************************************************/
sbit LED1 = P2^4;   
sbit LED2 = P2^5;   
sbit LED3 = P2^6;   
sbit LED4 = P2^7; 

/*********************************************************************************************************
*                                              枚举结构体定义
*********************************************************************************************************/

/*********************************************************************************************************
*                                              内部变量
*********************************************************************************************************/

/*********************************************************************************************************
*                                              内部函数声明
*********************************************************************************************************/
static void InitUART();        //串口配置
static void UART_Handlen();   //中断服务
static void InitInterrupt();   //中断配置


/*********************************************************************************************************
*                                              内部函数实现
*********************************************************************************************************/
/*********************************************************************************************************
* 函数名称: InitInterrupt
* 函数功能: 中断配置
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
static void InitInterrupt()
{     
  ES = 1;         //打开 串口接受中断允许
  EA = 1;         //打开 总中断允许
}

/*********************************************************************************************************
* 函数名称: InitUART
* 函数功能: 串口配置
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
static void InitUART()
{
  SCON = 0X50;           //设置 串口 工作模式1,并打开接收允许
  TMOD = 0X20;           //设置 定时器1 工作模式2(8位自动重装定时器)
  PCON = 0X80;           //设置 波特率加倍
  TL1  = 0XF3;           //设置 定时器1 计数初值,波特率为4800
  TH1  = TL1;            //设置 定时器1重装载值,等于计数初值
  TR1  = 1;              //打开 定时器1
}

/*********************************************************************************************************
* 函数名称: main
* 函数功能: 主函数
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
void main()
{
  InitInterrupt();    //初始化(配置)中断
  InitUART();         //初始化串口
  while (1)
  {
    
  }
}


/*********************************************************************************************************
* 函数名称: UART_Handler
* 函数功能: 串口中断服务函数
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
void UART_Handler() interrupt 4
{
    static char i,j,k;           //定义过渡字符
    char arrBuffer[4];
    static unsigned char s_iCounter = 0;   //定义计数变量
    char arrLED[3] ="LED";
    char LED[4] = "1234";
	 
    //数据接收
    if(1 == RI)   //当接收中断请求标志位被置位
    {
        for(s_iCounter = 0;s_iCounter<4; s_iCounter++)
        {
            arrBuffer[s_iCounter] = SBUF;  //将数据从串口数据缓冲寄存器中取出
						RI = 0;   //清除中断请求标志位
				}
    }
		
		//数据发送(四个数字的通讯传递过程中,中断服务函数会运行4次,所以多次用IF语句检测输入的字符)
     SBUF = arrBuffer[s_iCounter];  //将数据放入寄存器 
    
    if(arrLED[0] == arrBuffer[0])   //如果数据第一个字母是L
    {
        i=1;
    }
    
    if(arrLED[1] == arrBuffer[1] && i==1)   //如果数据第二个字母是E且第一个字母是L 
    {
        j=1;
    }
    
    if(arrLED[2] == arrBuffer[2] && i==1 && j==1)   //同理
    {
        k=1;
    }
    
    if(LED[0] == arrBuffer[3] && i==1 && j==1 && k==1)   //数据前面是LED后,看第四个数字如果是1  
    {
        if(LED1 == 0)   //看 LED1 状态,亮了关,关了开
        {
            LED1 = 1;
        }
        else
        {
            LED1 = 0;
        }
    }
    
    if(LED[1] == arrBuffer[3] && i==1 && j==1 && k==1)   //如果是LED2
    {
        if(LED2 == 0)
        {
            LED2 = 1;
        }
        else
        {
            LED2 = 0;
        }
    }
    
    if(LED[2] == arrBuffer[3] && i==1 && j==1 && k==1)   //如果是LED3
    {
        if(LED3 == 0)
        {
            LED3 = 1;
        }
        else
        {
            LED3 = 0;
        }
    }
    
    if(LED[3] == arrBuffer[3] && i==1 && j==1 && k==1)   //如果是LED4
    {
        if(LED4 == 0)
        {
            LED4 = 1;
        }
        else
        {
            LED4 = 0;
        }
    }
    
    
    while(!TI)   //等待数据发送完成
    {
        
    }
    TI = 0;   //清除发送中断请求标志位
		
}
    

四、发送数字

具体任务:

在任务3的基础上,通过串口助手发送4位数字,并且能在数码管上显示。

代码:

/*********************************************************************************************************
* 模块名称: main.c
* 摘    要: 主文件,包含初始化函数和main函数
* 当前版本: 1.0.0
* 作    者: 努摆的皮卡皮
* 完成日期: 2022年8月12日
* 内    容: 
* 注    意: 
**********************************************************************************************************
* 取代版本: 
* 作    者: 
* 完成日期: 
* 修改内容: 
* 修改文件: 
*********************************************************************************************************/
/*********************************************************************************************************
*                                              包含头文件
*********************************************************************************************************/
#include 

/*********************************************************************************************************
*                                              宏定义
*********************************************************************************************************/

/*********************************************************************************************************
*                                              位定义
*********************************************************************************************************/
sbit SegmentG1 = P2^3;
sbit SegmentG2 = P2^2;
sbit SegmentG3 = P2^1;
sbit SegmentG4 = P2^0;

/*********************************************************************************************************
*                                              枚举结构体定义
*********************************************************************************************************/

/*********************************************************************************************************
*                                              内部变量
*********************************************************************************************************/
static unsigned char s_arrNumber[] = {0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};   //显示数字0~9;
static char a=0,b=0,c=0,d=0;

/*********************************************************************************************************
*                                              内部函数声明
*********************************************************************************************************/
static void InitUART();        //串口配置
static void UART_Handlen();   //中断服务
static void InitInterrupt();   //中断配置
static void DelayNms(int nms);

/*********************************************************************************************************
*                                              内部函数实现
*********************************************************************************************************/

/*********************************************************************************************************
* 函数名称: DelayNms
* 函数功能: 延时函数
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年8月12日
* 注    意: 
*********************************************************************************************************/
static void DelayNms(int nms)
{
    unsigned int i,j;
    for(i = 0; i < nms; i++)
    {
        for(j = 0; j < 123; j++)
        {
            
        }
    }
}

/*********************************************************************************************************
* 函数名称: InitInterrupt
* 函数功能: 中断配置
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
static void InitInterrupt()
{     
  ES = 1;         //打开 串口接受中断允许
  EA = 1;         //打开 总中断允许
}

/*********************************************************************************************************
* 函数名称: InitUART
* 函数功能: 串口配置
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
static void InitUART()
{
  SCON = 0X50;           //设置 串口 工作模式1,并打开接收允许
  TMOD = 0X20;           //设置 定时器1 工作模式2(8位自动重装定时器)
  PCON = 0X80;           //设置 波特率加倍
  TL1  = 0XF3;           //设置 定时器1 计数初值,波特率为4800
  TH1  = TL1;            //设置 定时器1重装载值,等于计数初值
  TR1  = 1;              //打开 定时器1
}

/*********************************************************************************************************
* 函数名称: main
* 函数功能: 主函数
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
void main()
{
  InitInterrupt();    //初始化(配置)中断
  InitUART();         //初始化串口
  while (1)
  {
   //一直在显示可以放主函数里
  P0 = s_arrNumber[a]; 
  SegmentG1 = 0;       
  DelayNms(1);         
  SegmentG1 = 1;       

  P0 = s_arrNumber[b]; 
  SegmentG2 = 0;       
  DelayNms(1);         
  SegmentG2 = 1;       

  P0 = s_arrNumber[c]; 
  SegmentG3 = 0;       
  DelayNms(1);         
  SegmentG3 = 1;      

  P0 = s_arrNumber[d]; 
  SegmentG4 = 0;       
  DelayNms(1);         
  SegmentG4 = 1;     
  }
}


/*********************************************************************************************************
* 函数名称: UART_Handler
* 函数功能: 串口中断服务函数
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2022年2月1日
* 注    意: 
*********************************************************************************************************/
void UART_Handler() interrupt 4
{
    static char i=0;   //过渡变量
    int arrBuffer[4];  //定义数组
    static unsigned char s_iCounter = 0;   //计数变量
    
		//数据接收
    if(1 == RI)    //当接收中断请求标志位被置位
    {
        for(s_iCounter = 0;s_iCounter<4; s_iCounter++)   //给数组赋值
        {
            arrBuffer[s_iCounter] = SBUF;
            RI = 0;   //清除中断请求标志位
				}
    }
		
		//数据发送(四个数字的通讯传递过程中,中断服务函数会运行4次,所以多次用IF语句检测输入的字符)
     SBUF = arrBuffer[s_iCounter];  //将数据放入寄存器 
   
    i++;
    if(i==1)   //第一遍,传递第一个数字
    {
        a=arrBuffer[0]-'0';   //数组里的数字不能直接用,需要通过一定变换才可以,在此用了减0的运算
    }
    
    if(i==2)
    {
        b = arrBuffer[1]-'0';   //传第二个数字
    }

    if(i==3)
    {
        c = arrBuffer[2]-'0';   //传第三个数字
    }

    if(i==4)
    {
        d = arrBuffer[3]-'0';   //传第四个数字
        i = 0;   //为了方便下一轮运行,把i清零
    }

    
    while(!TI)   //等待数据发送完成
    {
        
    }
    TI = 0;   //清除发送中断请求标志位
		
}
    

你可能感兴趣的:(C51,51单片机)