欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

【STC15】串口使用

发布时间:2023/12/9 67 豆豆
生活随笔 收集整理的这篇文章主要介绍了 【STC15】串口使用 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

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

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

点击生成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中找

获取以后包含进来即可

中断函数的编写如下

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(); //清除bufferi = 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<Buf2_Max;k++) //{buffer[k] = 0x00;}First_Int = 0; // } u8 Find(u8 *a) { if(strstr(buffer,a)!=NULL)return 1;elsereturn 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】串口使用的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。