【STC15】串口使用

一般我们玩单片机都要研究串口,串口一开始最头痛的无非就是波特率和中断

波特率初始化可以用STC-ISP生成代码,比如STC15W408AS这一款单片机,只有串口0和串口2,需要波特率9600,则可以在STC-ISP中输入如下参数

【STC15】串口使用_第1张图片

点击生成C代码,即可自动生成如下代码

void UartInit(void)     //9600
{
    SCON = 0x50;        //sfr SCON  = 0x98;
    AUXR |= 0x04;       //sfr   AUXR = 0x8E;
    T2L = 0xE0;         //sfr   T2L  = 0xD7;
    T2H = 0xFE;         //sfr   T2H  = 0xD6;
    AUXR |= 0x10;       //
    ES = 1;                 //sbit ES   = IE^4;  sfr IE    = 0xA8; 
}

其实就是调定时器,两个接口速率相同才可以通讯,核心在于T2L和T2H的值,其他的则是选择哪个口哪个定时器什么的(那些位啊选择啊什么的太复杂就不讲了)

如果直接把上面的内容复制进去,可能会有报错,说找不到像SCON ,AUXR这些地址,其实都在头文件里定义好的,如果没有头文件也可以在ISP中找
【STC15】串口使用_第2张图片

获取以后包含进来即可

中断函数的编写如下

void Uart() interrupt 4
{
        ES=0;   //
    if (RI)
    {
      RI=0;         //
            buffer[First_Int] = SBUF;     //
            First_Int++;                            //
            if(First_Int > Buf2_Max)            //
            {
                First_Int = 0;
            }
    }
    if (TI)
    {
      TI=0;         //
    }
        ES=1;   //
}

相关的全局变量和定义

typedef     unsigned char   u8;
typedef     unsigned int    u16;
u8 First_Int = 0;
#define Buf2_Max        64    
xdata u8 buffer[Buf2_Max];

每次TI或者RI检测到1,并且串口中断ES打开,就进入中断,进入中断以后判断是收到信息还是发送信息,收到信息则将信息存入buffer数组,用来存储数据的数组最好用xdata加快速度,当数组满了就退出,发出信息则直接把发送信息位清0,最后再打开中断。
中断的开关速度是非常快的,每次一串信息8位过来,都会立刻触发8次中断,每次中断存一位数据。
全局变量First_Int是用于检测buffer是否满了,满了就清0,初始化为0即可。

以上内容实际上只有接收部分,数据存到buffer以后还有很多事情要做,字符串的处理(这才是核心),数据到达以后怎么存储,怎么判断逻辑,怎么发送等

发送字符串函数UART1_SendString(“你好”);

void UART1_SendString(char *s)
{
    while(*s)//
    {
        UART1_SendData(*s++);//
    }
}
void UART1_SendData(u8 dat)
{
    ES=0;                   
    SBUF=dat;   //sfr SBUF  = 0x99;     
    while(TI!=1);   
    TI=0;   //sbit TI   = SCON^1;       sfr SCON  = 0x98;           
    ES=1;                   
}

UART1_SendData函数是发送每一位字符的函数,当发送一串字符串时,调用很多次这个函数。

以下是一个比较简单的发送AT指令并请求返回值的函数,是从泥人模块上扣下来的代码,其实上面的很多代码都是扣泥人的,毕竟人家比较专业,废话不多说,这个函数可以帮助深刻理解上面的内容,比如
Second_AT_Command(”AT”,”OK”,3);
就是向模块发送AT,然后查询模块是否返回包含“OK”这个字符,等待时间为3s。

void Second_AT_Command(u8 *b,u8 *a,u8 wait_time)       //  typedef  unsigned char   u8;
{
    u8 i;
    u8 *c;
    c = b;                                      //
    CLR_Buf2(); //清除buffer
    i = 0;
    while(i == 0)                    
    {
            if( !Find(a) ) {//while循环中每次发送一次数据,回到这寻找buffer中是否有a字符
                    if(Timer0_start == 0){
                            CLR_Buf2(); 
                            b = c;                          //
                            for (b; *b!='\0';b++){
                                    UART1_SendData(*b);
                            }
                            UART1_SendLR(); 
                            Times = 0;
                            shijian = wait_time;
                            Timer0_start = 1;
                   }
            }else{
                i = 1;
                Timer0_start = 0;
            }

    }//while
}

上面的代码比较简单,代码量很少,基本逻辑就是循环中不断使用UART1_SendData发送AT,然后检查buffer中是否有OK,最精彩的地方在于代码控制部分,也是串口收发的核心之一,着重观察Timer0_start值的变化

相关全局变量和函数的定义

void CLR_Buf2(void)
{
        u16 k;//typedef     unsigned int    u16;
        for(k=0;k//
        {
            buffer[k] = 0x00;
        }
        First_Int = 0;              //
}
u8 Find(u8 *a)
{ 
  if(strstr(buffer,a)!=NULL)
        return 1;
    else
            return 0;
}

#include"string.h"
bdata u8 Flag;
sbit Timer0_start = Flag^0; 

u8 shijian=0,Times = 0;
#define UART1_SendLR() UART1_SendData(0X0D);UART1_SendData(0X0A)

总结一下串口使用,先用keil新建一个工程,然后到STC-ISP中获取头文件,再用ISP生成初始化串口函数,写中断用来存数据,写发送函数。之后就根据自己需求定制了,基本上最难的就是这部分,代码控制和逻辑,比如我使用TLSR8266时,由于要求比较简单,基本上只有一个功能,所以只写了一点点

void main(void)
{
    int io1=0,key1;
    UartInit();
    EA=1;   //sbit EA   = IE^7;  sfr IE    = 0xA8; 
    while(1){
        if(KEY)key1 = 1;
        if(KEY==0&&key1){
            key1 = 0;
            if(io1==0){
                io1=1;
                Second_AT_Command("AT+IO1=L","OK",3);

            }else{
                io1=0;
                Second_AT_Command("AT+IO1=H","OK",3);

            }
        }               
    }   
}

如果是弄GPS定位之类比较大型的代码,则需要更多对字符串操作函数的掌握和使用,如strtok分割字符串,strcmp字符串匹配函数,strcat字符串追加函数,以及最重要的代码控制,说白了串口使用还是对C的学习。

你可能感兴趣的:(【STC15】串口使用)