日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【STC15】串口使用

發(fā)布時(shí)間:2023/12/9 编程问答 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【STC15】串口使用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一般我們玩單片機(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。

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循環(huán)中每次發(fā)送一次數(shù)據(jù),回到這尋找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 }

上面的代碼比較簡(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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。