• STC15F2K60S2串口通信的应用。


    前言:由于不可抗拒因素,初始的STC12C5A60S2芯片由于无法进行烧录(。。。因为没带有锁紧座的开发板),暂且使用STC15F2K60S2芯片。。

    一 串行通信概述:

    串口通信有SPI IIC UART 等多种,最常见的是UART ,大部分情况下,串口通信指的就是UART.

    • 关于波特率:串口每秒钟传输的位数
    • UART 的数据发送与接收:
    1. 串口有两个缓冲寄存器SBUF,一个是发送寄存器,一个是接收寄存器,在物理结构上是完全独立的,他们都是字节寻址的寄存器。
    2. 串行发送时,CPU向SBUF 写入数据,例如SBUF=0x58;此时TI置1。
    3. 串行接收时,CPU从SBUF 读出数据,例如Date=SBUF;此时RI置1。

    二 代码

    1.初始化

    可利用STC-ISP计算生成波特率等初始化数据。

    void UartInit(void)		//9600bps@11.0592MHz
    {
    	PCON &= 0x7F;		//波特率不倍速
    	SCON = 0x50;		//8位数据,可变波特率
    	AUXR |= 0x40;		//定时器1时钟为Fosc,即1T
    	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
    	TMOD &= 0x0F;		//清除定时器1模式位
    	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
    	TL1 = 0xDC;		//设定定时初值
    	TH1 = 0xDC;		//设定定时器重装值
    	ET1 = 0;		//禁止定时器1中断
    	TR1 = 1;				//启动定时器1
    	EA=1;						//打开总中断
    	ES=1;						//打开接收中断
    	
    }

    注意:初始化函数STC-ISP没有生成总中断和接收中断,所以EA,ES注意补上。

    2.中断

    void Usart() interrupt 4	//串口中断函数接收程序
    {  
    	if (RI==1)
    	    {	    
    	  	receiveData = SBUF;
    			RI=0;  
    		}			
    }	
    

    串口中断号如下:根据串口中断选取中断号。  

         中断源                                                           中断号     
         外部中断0          INT0                                    interrupt 0 
         定时器0中断      T0                                        interrupt 1 
         外部中断1          INT1                                    interrupt 2 
         定时器1中断      T1                                        interrupt 3 
         串口中断           TX/RX                                   interrupt 4
     

    如果接收到数据,将数据存储到变量receiveData中,同时记得要软件将RI置0。

    以上单片机可以接收到发来的数据,那么单片机如何发送数据呢?

    3.数据发送

    void send1_Byte(unsigned char byte)//发送hex字符
    {
    	SBUF = byte;
        while(TI==0);			   	    //发送完会自动置1
        TI=0;							//手动清零
    }
    
    void Send1_String(char *str)		//发送字符串
    {
    	while (*str!='')				//检测字符串结束标志
    		{                  
        	send1_Byte(*str++);
    		}
    }

    第一个函数是单片机发送hex字符,第二个是单片机发送一个字符串。

    当单片机发送结束后,TI会硬件置1,用此可以判断是否发送结束,同时,发送结束后记得用软件置0。

    发送字符串同理。

    4.具体功能的实现

    因为考虑到将来单片机外接的模块较多,所以通过串口(模拟各模块)发送不同的数据给单片机,从而使单片机产生不同的功能。

    void working()
    {
    	if(receiveData!=0x00)//发现有数据输入到单片机
    	{
    		switch(receiveData)
    		{
    			case 0x01: send1_Byte(11); receiveData=0x00; break;
    			case 0x02: send1_Byte(22); receiveData=0x00; break;
    			case 0x03: Send1_String("HELP!
    "); receiveData=0x00; break;
    			case 0x04: yy=1; receiveData=0x00; break;
    		}
    	}	
    }
    
    
    int main()
    {
    	uchar tt;
    	P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;   
    	UartInit();
    
    	while(1)
    	{
    		working();
    		while(yy==1)
    		{
    			for(tt=0;tt<5;tt++)//led灯闪烁5次,表示提醒。
    			{
    				P0=0x00;
    				Delay500ms();
    				P0=0xff;
    				Delay500ms();
    			}
    			yy=0;
    		}
    	}
    }

    当发送0x01,0x02,0x03,0x04时,产生不同的效果。当串口发送0x03时,单片机会发送字符串“HELP!”,同理也可以增加更多功能。

    三 总结

    
    #include <stc15f2k60s2.h>
    #include <intrins.h>
    #define uchar unsigned char
    #define uint unsigned int	
    uchar receiveData,m,yy;
    
    void UartInit(void)		//9600bps@11.0592MHz
    {
    	PCON &= 0x7F;		//波特率不倍速
    	SCON = 0x50;		//8位数据,可变波特率
    	AUXR |= 0x40;		//定时器1时钟为Fosc,即1T
    	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
    	TMOD &= 0x0F;		//清除定时器1模式位
    	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
    	TL1 = 0xDC;		//设定定时初值
    	TH1 = 0xDC;		//设定定时器重装值
    	ET1 = 0;		//禁止定时器1中断
    	TR1 = 1;				//启动定时器1
    	EA=1;						//打开总中断
    	ES=1;						//打开接收中断
    	
    }
    void send1_Byte(unsigned char byte)//发送hex字符
    {
    	SBUF = byte;
        while(TI==0);		//发送完会自动置1
        TI=0;				//手动清零
    }
    
    void Send1_String(char *str)	//发送字符串
    {
    	while (*str!='')			//检测字符串结束标志
    		{                  
        	send1_Byte(*str++);
    		}
    }
    
    void Usart() interrupt 4		//串口中断函数接收程序
    {      
    	
    	if (RI==1)
    		{	    
    	  	receiveData = SBUF;
    			RI=0;  
    		}			
    }	
    
    void working()
    {
    	if(receiveData!=0x00)       //发现有数据输入
    	{
    		switch(receiveData)
    		{
    			case 0x01: send1_Byte(11);receiveData=0x00;break;
    			case 0x02: send1_Byte(22);receiveData=0x00;break;
    			case 0x03: 
    				{
    					Send1_String("HELP!
    ");
    					receiveData=0x00;
    				}
    				break;
    			case 0x04:
    				{				
    					yy=1;
    					receiveData=0x00;
    				}
    				break;
    		}
    	}
    	
    }
    
    void Delay500ms()		//@11.0592MHz
    {
    	unsigned char i, j, k;
    
    	_nop_();
    	_nop_();
    	i = 22;
    	j = 3;
    	k = 227;
    	do
    	{
    		do
    		{
    			while (--k);
    		} while (--j);
    	} while (--i);
    }
    
    int main()
    {
    	uchar tt;
    	P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;   
    	UartInit();
    
    	while(1)
    	{
    			working();
    		while(yy==1)
    		{
    			for(tt=0;tt<5;tt++)
    			{
    				P0=0x00;
    				Delay500ms();
    				P0=0xff;
    				Delay500ms();
    			}
    			yy=0;
    		}
    	}
    }

    初步构想是首先通过模块与电脑,单片机与电脑通过串口的接受与发送进行调试,然后逐步过渡到单片机与模块直接的通信。

    博客园
  • 相关阅读:
    BZOJ2243: [SDOI2011]染色
    BZOJ3747: [POI2015]Kinoman
    BZOJ1293: [SCOI2009]生日礼物
    BZOJ3626 [LNOI2014]LCA
    BZOJ3514 Codechef MARCH14 GERALD07加强版
    BZOJ3295 [CQOI2011]动态逆序对
    BZOJ2588 [SPOJ10628]Count on a tree
    BZOJ1036 [ZJOI2008]树的统计Count
    CODEVS1490 [CTSC2008]网络管理
    BZOJ1070 [SCOI2007]修车
  • 原文地址:https://www.cnblogs.com/wang-zefeng/p/12555649.html
Copyright © 2020-2023  润新知