首先我們先來了解一下51單片機與計算機進行通信的實現方法。先來看一個實現這個功能的基本電路。
圖中的P1就是仿真用的一個串口接口,這個仿真電路要實現與計算機通信功能需要用到其他兩個軟件,一個是虛擬串口驅動軟件,另外一個是串口助手軟件,這兩個軟件在網上都很容易找到。我使用的是Virtual Serial Port Driver和丁丁串口助手,你也可以使用自己熟悉的軟件,如果找不到或使用,安裝這兩個軟件有問題可以私信。
虛擬串口驅動軟件安裝后配置兩個成對的虛擬串口一個對應仿真電路中的串口接口,一個對應在串口助手軟件上,這樣就相當于將兩個軟件通過虛擬串口連接在一起了,將他們配置成相同的串口參數之后,這時就可以實現相互發送信息了。
這里需要注意的一個問題,上一篇文章中最后部分列舉了一個關于使用12MHz和11.0592MHz兩種晶振配置特定波特率對應定時器數據寄存器的數據對應的表格,里面還包含各配置值對應的波特率精度,從圖中可以看出使用12MHz晶振時誤差率普遍比較大,而使用11.0592MHz時幾乎沒有誤差,所以現在知道為啥你手上的單片機使用的晶振都是11.0592MHz的了吧!雖然使用12MHz的晶振進行通信計算機也能捕獲到數據,但為了保險起見,若日后你使用51單片機開發項目需要使用到串口時要注意晶振的選擇,當然如果使用其他單片機就要另說了,最簡單的比如STC生產的1T型的51單片機(即一個機器周期等于一個時鐘周期,它的執行效率理論上是傳統單片機的12倍,實際因程序復雜程度不一會低一點),就需要參考對應說明了。
接下來我們要怎么驗證單片機與計算機進行通信了呢?我們現在就編程實現計算機串口助手發送數據,單片機收到數據就做出回應將數據回傳給計算機。
現在我們先來看看程序的具體實現過程。
/*
*這是一個串口通信應用程序
*目的是將串口助手發送過來的數據回傳
*/
#include
#include
typedef unsigned char u8;
typedef unsigned int u16;
u8 data_L,data_H;
u8 T0_cnt = 0;
u8 T0_s = 0;
u8 T1_cnt = 0;
u8 crol = 0xfe;
u8 temp = 0;
u8 code num_codelist[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay(u8 ms);
void data_init(void);
//void Timer_init(void);
void display(void);
void uart_init(void);
void main(void)
{
// Timer_init();
uart_init();
while(1)
{
data_init();
display();
}
}
void delay(u8 ms)
{
u8 i,j;
for(i=0; i
}
void data_init(void)
{
data_L = T0_s%10;
data_H = T0_s/10;
}
void display(void)
{
P2 = 0xfe;
P0 = num_codelist[data_H];
delay(1);
P2 = 0xfd;
P0 = num_codelist[data_L];
delay(1);
}
void uart_init(void) //串口初始化
{
TMOD = 0x20;
SCON = 0x50;
TH1 = 0xFD; //9600
TL1 = TH1;
PCON = 0x00;
EA = 1;
ES = 1;
TR1 = 1;
}
void uart() interrupt 4 //串口中斷
{
if(RI)
{
RI = 0;
temp=SBUF;
SBUF=temp;
while(TI==0);
TI=0;
}
}
現在來看一下程序的仿真效果:
可以看到串口助手發送的數據馬上又被單片機傳回來了。這個程序沒有多少新的代碼,主要就是void uart_init(void)和void uart() interrupt 4這兩個函數,其中一個串口初始化函數,另一個是串口中斷函數。void uart_init(void)這個函數里面設置串口模式,定時器計數值以及串口中斷設置。void uart() interrupt 4串口中斷函數里面非常簡單,就是獲取收到的數據然后將數據發送出去。
程序實現過程是非常簡單吧,看到這里趕緊去試試看吧。
接下來
51單片機雙機通信
在項目開發時我們用到串口更多是和其他芯片進行通信,所以這里我們再來實現一個單片機雙機通信的例子,先來看看這個電路圖。
現在來看看我們要實現雙機通信的代碼:
/*
*這是一個串口通信應用程序
*目的是實現單片機的雙機通信
*/
#include
#include
typedef unsigned char u8;
typedef unsigned int u16;
sbit key1 = P3^0;
sbit key2 = P3^1;
sbit key3 = P3^2;
sbit key4 = P3^3;
u8 data_L,data_H;
u8 T0_cnt = 0;
u8 T0_s = 0;
u8 T1_cnt = 0;
u8 crol = 0xfe;
u8 temp = 0;
u8 temp_key = 0; //定義一個變量用來存放臨時按鍵值
u8 key_num = 0;//定義一個數字,用來顯示
u8 code num_codelist[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay(u8 ms);
void data_init(void);
//void Timer_init(void);
void display(void);
void key_init(void);
void uart_init(void);
void main(void)
{
// Timer_init();
key_init();
uart_init();
while(1)
{
data_init();
display();
}
}
void delay(u8 ms)
{
u8 i,j;
for(i=0; i
}
void data_init(void)
{
data_L = key_num%10;
data_H = key_num/10;
}
void display(void)
{
P2 = 0xfe;
P0 = num_codelist[data_H];
delay(1);
P2 = 0xfd;
P0 = num_codelist[data_L];
delay(1);
P1 = key_num; //P1端口LED顯示
}
void key_init(void) //按鍵初始化
{
IT0=1; //外部中斷0為下降沿觸發
IT1=1; //外部中斷1為下降沿觸發
EX0=1; //開EX0中斷
EX1=1; //開EX1中斷
EA=1; //開總中斷
}
void uart_init(void) //串口初始化
{
TMOD = 0x20;
SCON = 0x50;
TH1 = 0xFD; //9600
TL1 = TH1;
PCON = 0x00;
EA = 1;
ES = 1;
TR1 = 1;
}
//外部中斷0服務例程
void P3_2_key_func(void) interrupt 0
{
//將外部中斷0對應的按鍵K3設置為按鍵加功能
if(0 == key3)
{
delay(15);
if(0 == key3)
{
if(key_num < 100)
{
key_num++;
}
else
{
key_num = 0;
}
}
SBUF = key_num; //串口發送
while(TI==0);
TI=0;
}
}
//外部中斷1服務例程
void P3_3_key_func(void) interrupt 2
{
//將外部中斷0對應的按鍵K4設置為按鍵減功能
if(0 == key4)
{
delay(15);
if(0 == key4)
{
if(key_num > 0)
{
key_num--;
}
else
{
key_num = 100;
}
}
SBUF=key_num; //串口發送
while(TI==0);
TI=0;
}
}
void uart() interrupt 4
{
if(RI)
{
RI = 0;
key_num = SBUF; //串口接收
}
}
將這段代碼同時下載到兩個單片機中就實現兩個單片機同步了,現在看看仿真結果:
這個程序中的大多數代碼都是前面的文章中類似的,只做簡單修改就可以,接下來的時間自己看這代碼理一理邏輯,如果有理解不了的地方再留言或私信吧。
評論
查看更多