STC89C52单片机 串口通信
生活随笔
收集整理的這篇文章主要介紹了
STC89C52单片机 串口通信
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
串口初始化
void UARTInit() {EA = 1; //打開總中斷ES = 1; //打開串口中斷SM0 = 0; SM1 = 1;//串口工作方式1,8位UART波特率可變REN = 1;//串口允許接收TR1 = 1;//啟動定時器1TMOD |= 0x20;//定時器1,工作模式2 8位自動重裝TH1 = 0xfd; // 根據下面的公式計算得到TL1 = 0xfd; //設置比特率9600 }
例如:計算9600的波特率
SMOD在沒有設置的情況下,默認為0.
SMOD = 0
所以2的0次方為1
2^0 = 1
晶震頻率計算:fosc = 11.0592 兆赫茲 = 11.0592 x 1000000 = 11059200赫茲
11059200 ÷ 9600 = 1152 得到波特率公式的被除數
根據公式
1152 ÷ 32 = 36
36 ÷ 12 = 3
256 - T初 = 256 - 3 = 253
將 253 轉換為16進制得到 0xFD
TH1 = 0xFD;
TL1 = 0xFD; 設置波特率9600
串口中斷
void UART() interrupt 4 {if(RI)//判斷接收是否完成{num = SBUF;//讀SBUF,讀出串口接收到的數據RI = 0;//軟件清零接收標志位 }if(TI)//判斷是否發送完成TI = 0;//清零發送完成標志位 }串口工作方式1,8位UART比特率9600
#include <reg52.h> #include <intrins.h>#define uint unsigned int #define uchar unsigned charsbit DU = P2^6;//數碼管段選 sbit WE = P2^7;//數碼管段選 uchar num;//數碼管顯示的值//共陰數碼管段選表0-9 uchar code SMGduan[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,}; //數碼管位選碼 uchar code SMGwei[] = {0xfe, 0xfd, 0xfb};/*==================================== 函數 :display(uchar i) 參數 :i 顯示數值,取值范圍0-255 返回值 :無 描述 :三位共陰數碼管動態顯示 ====================================*/ void display(uchar i) {static uchar wei; P0 = 0XFF;//清除斷碼WE = 1;//打開位選鎖存器P0 = SMGwei[wei];WE = 0;//鎖存位選數據switch(wei){case 0: DU = 1; P0 = SMGduan[i / 100]; DU = 0; break;case 1: DU = 1; P0 = SMGduan[i % 100 / 10]; DU = 0; break; case 2: DU = 1; P0 = SMGduan[i % 10]; DU = 0; break; }wei++;if(wei == 3)wei = 0; } //定時器0初始化 void timer0Init() {EA = 1; //打開總中斷ET0 = 1;//打開定時器0中斷TR0 = 1; //啟動定時器0REN = 1;//允許串口接收TMOD |= 0X01; //定時器工作模式1,16位定時模式TH0 = 0xED;TL0 = 0xFF; //定時5ms } //串口初始化 void UARTInit() {EA = 1; //打開總中斷ES = 1; //打開串口中斷SM0 = 0; SM1 = 1;//串口工作方式1,8位UART波特率可變REN = 1;//串口允許接收TR1 = 1;//啟動定時器1TMOD |= 0x20;//定時器1,工作模式2 8位自動重裝TH1 = 0xfd;TL1 = 0xfd;//設置比特率9600 } void main()//main函數自身會循環 { timer0Init();//定時器0初始化UARTInit();//串口初始化while(1); } //定時器0中斷函數 void timer0() interrupt 1 {TH0 = 0xED;TL0 = 0xFF; //定時5msdisplay(num); //數碼管顯示函數 } //串口中斷函數 void UART() interrupt 4 {if(RI)//判斷接收是否完成{num = SBUF;//讀SBUF,讀出串口接收到的數據RI = 0;//軟件清零接收標志位 }if(TI)//判斷是否發送完成TI = 0;//清零發送完成標志位 }通過串口發送數據前需要進行的設置
在右邊的菜單欄找到串口助手然后
- 第一步讓COM號保持一致
- 第二步波特率設置為9600
- 第三步打開串口
- 第四步發送和接收格式選擇HEX格式
修改串口中斷中的函數,實現接收緩沖區數據
//串口中斷函數 void UART() interrupt 4 {uchar temp;if(RI)//判斷接收是否完成{num = SBUF;//讀SBUF,讀出串口接收到的數據RI = 0;//軟件清零接收標志位 temp = num;//SBUF = temp;//寫SBUF,把要發送的數據送給發送緩存器}if(TI)//判斷是否發送完成TI = 0;//清零發送完成標志位 }對代碼修改后可以通過
串口助手選擇文本模式接收和發送數據
ASCII碼規定了不同字符是用哪個整數去表示,所以其它字母或數字對應的值可以通過ASCII表查看。
通過串口發送字符串
puts()函數和printf()函數
void main() {UARTInit(); //串口初始化while(1){TI = 1;puts("Hello Wolrd!"); // 使用puts函數while(!TI);TI = 0;delay(1000);} } void main() {UARTInit(); //串口初始化while(1){TI = 1;printf("Hello Wolrd!"); // 使用printf函數while(!TI);TI = 0;delay(1000);} }注:puts()函數和printf()函數區別是
- puts函數會執行換行操作
- printf函數不會執行換行操作
打開串口助手選擇對應COM號,設置波特率9600接收格式選擇【文本格式】。
#include <reg52.h> #include <stdio.h> // 打印字符串需要調用 stdio.h 庫#define uint unsigned int #define uchar unsigned char//毫秒級延時函數定義 void delay(uint z) {uint x,y;for(x = z; x > 0; x--)for(y = 114; y > 0 ; y--); } //串口初始化 void UARTInit() {SM0 = 0; SM1 = 1;//串口工作方式1,8位UART波特率可變TR1 = 1;//啟動定時器1TMOD |= 0x20;//定時器1,工作模式2 8位自動重裝TH1 = 0xfd;TL1 = 0xfd;//設置比特率9600 }void main() {UARTInit(); //串口初始化while(1){TI = 1;puts("Hello Wolrd!"); // 每次打印都會換行 支持中文打印 while(!TI);TI = 0;delay(1000);} }注:
- 使用printf()函數或puts()函數需要引入頭文件#include <stdio.h>
- 使用printf()函數或puts()函數前都應軟件置位TI = 1;
如果沒有軟件置位TI = 1,則會一直處于等待狀態,while(!TI)一直在循環中。
總結
以上是生活随笔為你收集整理的STC89C52单片机 串口通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++ 指向常量的指针与指针类型的常量
- 下一篇: STC89C52单片机 LCD1602液