【STC15】串口使用
一般我們玩單片機(jī)都要研究串口,串口一開始最頭痛的無非就是波特率和中斷
波特率初始化可以用STC-ISP生成代碼,比如STC15W408AS這一款單片機(jī),只有串口0和串口2,需要波特率9600,則可以在STC-ISP中輸入如下參數(shù)
點(diǎn)擊生成C代碼,即可自動(dòng)生成如下代碼
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; }其實(shí)就是調(diào)定時(shí)器,兩個(gè)接口速率相同才可以通訊,核心在于T2L和T2H的值,其他的則是選擇哪個(gè)口哪個(gè)定時(shí)器什么的(那些位啊選擇啊什么的太復(fù)雜就不講了)
如果直接把上面的內(nèi)容復(fù)制進(jìn)去,可能會(huì)有報(bào)錯(cuò),說找不到像SCON ,AUXR這些地址,其實(shí)都在頭文件里定義好的,如果沒有頭文件也可以在ISP中找
獲取以后包含進(jìn)來即可
中斷函數(shù)的編寫如下
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; // }相關(guān)的全局變量和定義
typedef unsigned char u8; typedef unsigned int u16; u8 First_Int = 0; #define Buf2_Max 64 xdata u8 buffer[Buf2_Max];每次TI或者RI檢測(cè)到1,并且串口中斷ES打開,就進(jìn)入中斷,進(jìn)入中斷以后判斷是收到信息還是發(fā)送信息,收到信息則將信息存入buffer數(shù)組,用來存儲(chǔ)數(shù)據(jù)的數(shù)組最好用xdata加快速度,當(dāng)數(shù)組滿了就退出,發(fā)出信息則直接把發(fā)送信息位清0,最后再打開中斷。
中斷的開關(guān)速度是非??斓?#xff0c;每次一串信息8位過來,都會(huì)立刻觸發(fā)8次中斷,每次中斷存一位數(shù)據(jù)。
全局變量First_Int是用于檢測(cè)buffer是否滿了,滿了就清0,初始化為0即可。
以上內(nèi)容實(shí)際上只有接收部分,數(shù)據(jù)存到buffer以后還有很多事情要做,字符串的處理(這才是核心),數(shù)據(jù)到達(dá)以后怎么存儲(chǔ),怎么判斷邏輯,怎么發(fā)送等
發(fā)送字符串函數(shù)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函數(shù)是發(fā)送每一位字符的函數(shù),當(dāng)發(fā)送一串字符串時(shí),調(diào)用很多次這個(gè)函數(shù)。
以下是一個(gè)比較簡(jiǎn)單的發(fā)送AT指令并請(qǐng)求返回值的函數(shù),是從泥人模塊上扣下來的代碼,其實(shí)上面的很多代碼都是扣泥人的,畢竟人家比較專業(yè),廢話不多說,這個(gè)函數(shù)可以幫助深刻理解上面的內(nèi)容,比如
Second_AT_Command(”AT”,”O(jiān)K”,3);
就是向模塊發(fā)送AT,然后查詢模塊是否返回包含“OK”這個(gè)字符,等待時(shí)間為3s。
上面的代碼比較簡(jiǎn)單,代碼量很少,基本邏輯就是循環(huán)中不斷使用UART1_SendData發(fā)送AT,然后檢查buffer中是否有OK,最精彩的地方在于代碼控制部分,也是串口收發(fā)的核心之一,著重觀察Timer0_start值的變化
相關(guān)全局變量和函數(shù)的定義
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)總結(jié)一下串口使用,先用keil新建一個(gè)工程,然后到STC-ISP中獲取頭文件,再用ISP生成初始化串口函數(shù),寫中斷用來存數(shù)據(jù),寫發(fā)送函數(shù)。之后就根據(jù)自己需求定制了,基本上最難的就是這部分,代碼控制和邏輯,比如我使用TLSR8266時(shí),由于要求比較簡(jiǎn)單,基本上只有一個(gè)功能,所以只寫了一點(diǎn)點(diǎn)
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定位之類比較大型的代碼,則需要更多對(duì)字符串操作函數(shù)的掌握和使用,如strtok分割字符串,strcmp字符串匹配函數(shù),strcat字符串追加函數(shù),以及最重要的代碼控制,說白了串口使用還是對(duì)C的學(xué)習(xí)。
總結(jié)
以上是生活随笔為你收集整理的【STC15】串口使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一个js内存泄露的好例子
- 下一篇: new关键字对类成员的阻断