硬件環境:STC89C52
軟件環境:IDE Keil uVision V4.10
編譯器 C51 V9.0
代碼如下:
/**********************************************
方法3:中斷法
硬件:11.0592MHz晶振,STC89C52,RXD P1.0 TXD P1.1
波特率:9600
描述:所謂中斷法是指根據模擬出的波特率,每1位持續的時間的長短是通過定時器計數
溢出產生中斷來延時的。
測試1:上電發送1個0x03的字符
測試2:上電先發送1個0x03的字符,然后等待接收,將收到的字符再發送出去(分別一個一個發送0x01,0x02,0x03,0x04,0x05)
測試3:上電等待接收,將收到的字符再發送出去(分別一個一個發送0x01,0x02,0x03,0x04,0x05)
結果:
測試1:錯誤!上電發送0x03,接到到0xE0
測試1:錯誤!上電發送0x00,接到到0x80
測試1:錯誤!上電發送0x01,接到到0xC0
測試1:錯誤!上電發送0x02,接到到0x81
測試2:錯誤!上電接收到錯誤字符0xE0,此后分別接收到0x01,0x02,0x03,0x04,0x05,均正確
測試3:錯誤!接收到第1個字符錯誤0x82,此后分別接收到0x02,0x03,0x04,0x05,均正確。第1個錯誤的字符有時會是0x81
注意:初始化時,要將定時器T0的溢出標志位清0
時間:2012.07.25 于單位
**********************************************/
#include "reg52.h"
#define uchar unsigned char
sbit P1_0 = 0x90;
sbit P1_1 = 0x91;
sbit P1_2 = 0x92;
#define RXD P1_0
#define TXD P1_1
#define WRDYN 44 //寫延時
#define RDDYN 43 //讀延時
void Delay2cp(unsigned char i);
void WaitTF0( void );
#define TM0_FLAG P1_2 //設傳輸標志位
//計數器及中斷初始化
void S2INI(void)
{
TMOD |=0x02; //計數器0,方式2
TH0=0xA0; //預值為256-96=140,十六進制A0
TL0=TH0;
TR0=0; //在發送或接收才開始使用
TF0=0;
ET0=1; //允許定時器0中斷
EA=1; //中斷允許總開關
}
//發送一個字符
void WByte(uchar input)
{
//發送啟始位
uchar i=8;
TR0=1;
TXD=(bit)0;
WaitTF0();
//發送8位數據位
while(i--)
{
TXD=(bit)(input&0x01); //先傳低位
WaitTF0();
input=input>>1;
}
//發送校驗位(無)
//發送結束位
TXD=(bit)1;
WaitTF0();
TR0=0;
}
//接收一個字符
uchar RByte()
{
uchar Output=0;
uchar i=8;
TR0=1; //啟動Timer0
TL0=TH0;
WaitTF0(); //等過起始位
//發送8位數據位
while(i--)
{
Output >>=1;
if(RXD)
Output |=0x80; //先收低位
WaitTF0(); //位間延時
}
while(!TM0_FLAG) if(RXD) break;
TR0=0; //停止Timer0
return Output;
}
//中斷1處理程序
void IntTimer0() interrupt 1
{
TM0_FLAG=1; //設置標志位。
}
//查詢傳輸標志位
void WaitTF0( void )
{
while(!TM0_FLAG);
TM0_FLAG=0; //清標志
}
//檢查是不是有起始位
bit StartBitOn()
{
return (RXD==0);
}
void main()
{
uchar ccc;
S2INI();
//2012.07. 25 李響添加
//計時器T0啟用之前要把溢出標志清0,計時滿TF0=1
//缺少如下的語句,將發生描述中的錯誤
TM0_FLAG=0;
//測試1
/*
WByte(0x03);
WByte(0x01);
WByte(0x02);
WByte(0x03);
WByte(0x04);
WByte(0x05);
while(1){;}
*/
//測試2
WByte(0x03);
while(1)
{
if(StartBitOn())
{
ccc=RByte();
WByte(ccc);
}
}
//測試3
/*
while(1)
{
if(StartBitOn())
{
ccc=RByte();
WByte(ccc);
}
}
*/
}
附解決問題過程中所抓的波形:
測試1:錯誤!上電發送0x00時的波形。
測試1:錯誤!上電發送0x00時接收到的數據。
分析:上電發送0x00,理應也收到數據0x00,波形的形狀也應該如上圖所示,但接收到的數據為0x80則顯示這波形是錯誤的。且往下看。
----------------------------------------------------------------------------------------------------------------------------------------
測試1:錯誤!上電發送0x01時的波形。
測試1:錯誤!上電發送0x01時接收到的數據。
分析:波形錯誤,接收到的數據也錯誤。起始位為低電平,理應持續1位的時間,但可以看出,起始位保持很短的時間就跳為高電平了。說明起始位到來以后,相應的延時時間那里出了問題。
正確的0x01的波形如下圖所示:
----------------------------------------------------------------------------------------------------------------------------------------
測試1:錯誤!上電發送0x02時的波形。
測試1:錯誤!上電發送0x02時接收到的數據。
正確的0x02的波形如下圖所示:
----------------------------------------------------------------------------------------------------------------------------------------
測試1:錯誤!上電發送0x03時的TXD的波形。
上電發送0x03時接收到的數據。
正確的0x03的波形如下:
----------------------------------------------------------------------------------------------------------------------------------------
測試2:錯誤!上電本應先接到一個0x03的字符,但實際接收到的為0xE0,此后收發均正確。
測試2:錯誤!上電本應先接到一個0x03的字符,但實際接收到的為0xE0,此后收發均正確。
此圖僅用于證明除第一個字符錯誤外,此后其它接收到的字符均正確。
----------------------------------------------------------------------------------------------------------------------------------------
測試3:錯誤!先手動發送第1個字符0x01,此時接收到的錯誤數據81,此時的波形
接收到的錯誤數據0x81
上電后,依次發送0x01,0x02,0x03,0x04,0x05,接收到第1個字符0x81錯誤,后4個字符正確
上邊的那個實驗,有的時候偶爾會出現第1個字符是0x82的錯誤數據。
----------------------------------------------------------------------------------------------------------------------------------------
以下兩圖為0x04和0x05的正確的波形
0x04時的波形
0x05時的波形
----------------------------------------------------------------------------------------------------------------------------------------
分析:可以看出,起始位持續的時間不正確。
原因為:中斷標志位上電后默認為1,高電平,需要手動將其清0。本程序利用了P1^2做為中斷標志位,P1^2上電后為高電平。在程序中,S2INI();之后,添加TM0_FLAG=0;解決此問題。
上一篇:51單片機IO口模擬串口通訊4
下一篇:51單片機IO口模擬串口通訊2-計數法
推薦閱讀
史海拾趣
隨著公司規模的擴大和市場份額的增加,DECON公司開始積極拓展國際市場。公司成立了專門的海外市場部,積極參加國際電子展會和論壇,與全球各地的客戶建立了緊密的合作關系。同時,DECON還與國際知名電子企業展開合作,共同開發新產品,推動了公司的國際化進程。
隨著技術的不斷進步和市場的日益成熟,E-T-A公司的產品線也逐漸擴展。公司不僅繼續深耕斷路器領域,還推出了包括保護控制器、流量和液位傳感器等一系列新產品。同時,公司也開始積極拓展全球市場,通過設立分支機構和辦事處,為全球客戶提供更便捷的服務和支持。
進入1950年代,E-T-A公司開始關注固態遠程電源控制器(SSRPCs)的研發。這一創新技術為電氣系統提供了更加可靠和高效的電源管理方案。公司投入大量資源進行研發,成功推出了多款固態遠程電源控制器產品,這些產品在市場上獲得了廣泛認可,并為公司帶來了可觀的收益。
隨著技術的不斷進步和市場的日益成熟,E-T-A公司的產品線也逐漸擴展。公司不僅繼續深耕斷路器領域,還推出了包括保護控制器、流量和液位傳感器等一系列新產品。同時,公司也開始積極拓展全球市場,通過設立分支機構和辦事處,為全球客戶提供更便捷的服務和支持。
Antenna Factor公司始終注重產品質量和客戶體驗。他們建立了嚴格的質量管理體系,從原材料采購到產品生產的每一個環節都進行嚴格的把控。同時,公司還加強了對售后服務的管理和改進,確保客戶在使用過程中能夠得到及時、有效的支持。這些舉措使得Antenna Factor公司的產品質量和品牌形象得到了顯著提升。
隨著艾為電子在技術和產品方面的不斷突破,公司開始積極拓展市場。艾為電子的產品不僅覆蓋了華為、小米等知名手機廠商,還廣泛應用于可穿戴設備、智能便攜設備等領域。同時,公司還加大了品牌建設的力度,通過參加行業展會、舉辦技術研討會等方式,提高了品牌知名度和影響力。
我們經常會從工程文件創建makefile文件,但也會遇到這樣的需求,得到的第三方源代碼(正版)只有makefile文件,而沒有對應平臺的工程文件。 這里有幾種情況: 第一:單個工程的轉換,可以找一個現成的wpj文件,對照著去修改,試試也就差不多了。 ...… 查看全部問答∨ |
最近做wavecom模塊連單片機的項目,要做來電自動回復短信的模塊,可是用at+clip=1的at命令后,打電話返回的是這樣的字符串 +CLIP: \"618935\",129,,,\"8090B866535CF00032FFFF\" 這個是wavecom返回的數據,18935是我的號碼的一部分,其他的就不 ...… 查看全部問答∨ |
HANDLE hevt = OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT(\"SYSTEM/ShellAPIReady\")); ASSERT(NULL != hevt); & ...… 查看全部問答∨ |
我是一個新手, 按照這個文章配置 的 , 但是 只成功了一次, 以后就一直說 Active Sync 沒有安裝, 但是這個文章的說法是不使用 Active Sync 的., 不知道是不是有什么關鍵或者比較怪的地方,我沒有注意到, 請各位大蝦賜教. http ...… 查看全部問答∨ |
請教版主,STM8L152R6 SWIM與BEEP共用,使用BEEP功能后調試會不會不方便?還有,LCD SEG腳位不連續使用可以不?因 ...… 查看全部問答∨ |
|
我在用NRF905做一個無線通信的模塊時,但是始終收不到信號。我身邊只有萬用表,沒有頻譜儀之類的,大伙覺得用萬用表可以測量天線上面是否有信號嗎 … 查看全部問答∨ |
|
前段時間做了1塊DSP28335的板卡。基本功能都已經實現,程序在內部FLASH運行正常。 目前遇到新的問題: 后期有可能程序比較大,內部FLASH存放不下,于是通過XZCS7外擴了1片FLASH(SST39VF1602B-70) 目前想測試將程 ...… 查看全部問答∨ |
為什么在程序中加了math頭文件后,程序還是識別不了里面的庫函數,例如sinf。急急.... 本人是新手,接觸VxWorks時間不長。本人在Tornado的開發環境中編譯沒有任何問題。單下載到DSP上就報錯 說無法識別math里面的庫函數。程序中也加了頭文件,不知問題出在哪里,還請各位大神幫幫忙。很急很急。… 查看全部問答∨ |