程式設計目標及程式運行效果說明
程式設計目標:通過本例程理解RS485通信方式,實作雙機通信,
程式運行效果:將兩塊帶有485模塊的51單片機通過485外接引腳A、B連接起來,單片機上電燒寫程式后485模塊的D/R引腳所對應的二極管均點亮,然后通過按鍵KEY3、KEY2控制數碼管上的數值進行加減處理,兩塊單片機起始都默認為接收狀態,最后按下KEY1發送鍵,將資料傳送給另一塊單片機,而此時接收方數碼管上的數值發生相應的改變,與發送方數碼管上的數值一致,
程式相關電路及作業原理說明
1.RS485通信原理
RS232介面是1970年由美國電子工業協會(EIA)聯合貝爾系統、 調制解調器廠家及計算機終端生產廠家共同制定的用于串行通訊的標準,針對RS232的不足,于是不斷出現了新的介面標準,RS485就是其中的一種, RS485介面的最大傳輸距離標準值為4000英尺,實際上可達 3000米,另外RS232介面在總線上只允許連接1個收發器, 即單站能力,而RS485介面在總線上是允許連接多達128個收發器,即具有多站能力,這樣用戶可以利用單一的RS485介面方便地建立起設備網路,
RS485屬于半雙工通信,資料可以在一個信號載體的兩個方向上傳輸,但是不能同時進行傳輸,電平轉換采用差分電路方式,A、B兩線的電壓差大于0.2認為是邏輯“1”,小于-0.2認為是邏輯“0”,方便與TTL電路連接,使用RS485進行通信與RS232通信的邏輯是一致的,但RS485抗干擾性更強,傳輸距離更遠,RS485廣泛運用在工業自動化控制、視頻監控、門禁對講以及樓宇報警等各個領域,
MAX485芯片的功能是將TTL電平轉換為RS485電平,引腳功能如下:
(1)485 D/R輸出、接收信號控制引腳:當該引腳為低電平時,485為接收態,MAX485通過485_RXD把來自u總線的信號輸出給單片機;當該引腳為高電平時,485為發送態,來自485_TXD的輸出信號通過A、B引腳加載到總線上,
(2)485_RXD引腳接收資料,RX1 LED點亮時表示正在接收資料,
(3)485_TXD引腳發送資料,TX1 LED點亮時表示正在發送資料,
(4)A、B埠與另一個開發板上的MAX485的A、B連接實作雙機通信,
使用RS485進行通信的大致步驟為:
(1)初始化波特率,設定好串口通信模式;
(2)發送資料時將資料放入S2BUF,并軟體清零S2RI;
(3)接收資料時從S2BUF讀取資料,并軟體清零S2TI,
2.數碼管顯示原理
通過LED_SEL控制74HC138的使能信號E3,并結合A0、A1、A2三個位選控制信號確定八個數碼管中的哪一個數碼管被點亮;該模塊采用八段共陰極數碼管,P0口的八個段選控制信號確定任意一個數碼管八段中的哪一段被點亮,
3.按鍵控制原理
本案例中,按鍵1引腳對應觸發外部中斷0,通過設定暫存器設定按鍵1下降沿觸發外部中斷,當按鍵1被按下時啟動資料發送;按鍵2和按鍵3實作數碼管上的數值加減,當單片機檢測到引腳為低電平時,對數碼管數值進行操作,按鍵部分需要考慮按鍵的消抖問題,本程式采用延時消抖,另外在本案例中使用按鍵中斷服務程式實作資料發送的,因此串口中斷的優先級高于按鍵中斷,
測驗方法
- 將兩塊帶485模塊的板子通過485外接引腳連接起來;注意不要交叉連接(資料傳輸錯誤)
- 按照“工程建立及下載到開發板整個流程指導.doc”檔案將當前目錄的Hex檔案下載到兩塊開發版上,兩塊開發板默認最右邊數碼管均顯示0;485模塊的D/R對應二極管均點亮;
- 通過key2或者key3調整數值(數碼管會顯示出來)如“c”,按下key1,完成一塊單片機向另一塊單片機發送資料,
雙機通信流程圖
相關暫存器配置
1.選擇485芯片引腳
P_SW2:外圍設備功能切換控制暫存器2(不可位尋址)
串口2可在2個地方切換,由S2_S控制位來選擇
該開發板485芯片使用串口2的第2組引腳:
P_SW2 |= 0x01 ;
2.設定串口2的作業模式
S2CON:串行口2的控制暫存器
S2SM0指定串行口2的作業方式
設定串行口2為:8位UART,波特率可變;允許串行口2接收
S2CON = 0x10 ;
3.選擇定時器作業模式
AUCR:輔助暫存器(不可位尋址)
T2R:定時器2運行控制位
T2_C/T:控制定時器2用作定時器或計數器;
T2x12:定時器2速度控制位,
設定定時器2為1T模式,并啟動定時器2
AUXR |= 0x14 ;
4.串行口2中斷允許
IE2:中斷允許暫存器2(不可位尋址)
ES2為串行口2中斷允許位
IE:中斷允許暫存器(可位尋址)中的EA為CPU的總中斷允許控制位,
允許串行口2中斷:
IE2 |= 0x01 ;
EA = 1 ;
代碼如下:
#include<STC15F2K60S2.H>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
#define cstUart2Ri 0x01 //接收中斷請求標志位
#define cstUart2Ti 0x02 //發送中斷請求標志位
#define cstNoneParity 0 //無校驗
#define PARITYBIT cstNoneParity //定義校驗位
/*串口波特率相關*/
#define cstFosc 11059200L //系統時鐘頻率
#define cstBaud2 9600 //串口波特率
#define cstT2HL (65536-(cstFosc/4/cstBaud2)) //定時器初始時間
sbit sbtKey1=P3^2; //啟動發送
sbit sbtKey2=P3^3; //數字減少
sbit sbtKey3=P1^7; //數字增加
sbit sbtSel0=P2^0;
sbit sbtSel1=P2^1;
sbit sbtSel2=P2^2;
sbit sbtLedSel=P2^3;
sbit sbtM485_TRN=P3^7 ; //定義MAX485使能引腳,為1時發送,為0時接收
bit btSendBusy; //為1時忙(發送資料),為0時閑
uchar ucGetDataTmp; //接收資料暫存
uchar ucPutDataTmp; //發送資料暫存
uchar arrSegSelect[]={0x3f, 0x06, 0x5b, 0x4f, 0x66,
0x6d, 0x7d, 0x07, 0x7f, 0x6f,
0x77, 0x7c, 0x39, 0x5e, 0x79,
0x71, 0x40, 0x00
};//段選,顯示0-f
//串口2初始化及波特率發生函式
void Uart2Init()
{
S2CON=0x10; //定義無校驗位,允許串行口2接收
T2L=cstT2HL; //設定波特率重裝值
T2H=cstT2HL>>8;
AUXR|=0x14; //T2為1T模式,并啟動定時器2
}
//系統硬體、變數初始化函式
void Init()
{
P0M0=0xff; //P0口推挽(放大電流)
P0M1=0x00;
P2M0=0x0f; //P2.0—~P2.3口推挽
P2M1=0x00;
P3M0=0x00;
P3M1=0x00;
P1M0=0x00;
P1M1=0x00; //P1、P3準雙向口
//外部中斷0
IT0=1; //下降沿觸發中斷(為0則下降沿和上升沿均會觸發中斷)
EX0=1; //允許外部中斷0
PX0=0; //外部中斷:低優先級
//485初始化 波特率生成
sbtM485_TRN=0; //初始為接收狀態
P_SW2|=0x01; //切換串口2的管腳到P4.6,P4.7
Uart2Init();
btSendBusy=1;
IE2|=0x01; //開串行口2中斷
IP2|=0x01; //設定串行口中斷:高優先級
EA=1; //開總中斷
//數碼管選擇
sbtLedSel=0; //開啟數碼管顯示
sbtSel0=1;
sbtSel1=1;
sbtSel2=1; //選擇第八位數碼管顯示
ucPutDataTmp=0;
}
void delay()
{
uchar i,j;
for(i=0;i<255;i++)
for(j=0;j<255;j++);
}
//串口2中斷處理程式
void Uart2_Process()interrupt 8 using 1
{
if(S2CON&cstUart2Ri)
{
ucGetDataTmp=S2BUF ;
ucPutDataTmp=ucGetDataTmp ;
S2CON&=~cstUart2Ri; //接收中斷標志位清0
}
if(S2CON&cstUart2Ti)
{
btSendBusy=0; //清除忙信號
S2CON&=~cstUart2Ti ; //發送中斷標志位清0
}
}
//外部中斷0處理程式
void ExInt0_Process()interrupt 0
{
sbtM485_TRN=1;
S2BUF=ucPutDataTmp;
while(btSendBusy);
btSendBusy=1;
sbtM485_TRN=0;
}
void main()
{
Init();
while(1)
{
ucPutDataTmp%=16;
P0=arrSegSelect[ucPutDataTmp];
if(sbtKey3==0)
{
delay();
if(sbtKey3==0)
{
while(!sbtKey3);
ucPutDataTmp++;
}
}
if(sbtKey2==0)
{
delay();
if(sbtKey2==0)
{
while(!sbtKey2);
ucPutDataTmp--;
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/295743.html
標籤:其他
上一篇:物聯網-電力監控平臺(二)
下一篇:Unity之預制體和克隆體