一、使用proteus繪制簡單的電路圖,用于后續仿真
二、編寫程序
/********************************************************************************************************************
---- @Project: USART
---- @File: main.c
---- @Edit: ZHQ
---- @Version: V1.0
---- @CreationTime: 20200720
---- @ModifiedTime: 20200720
---- @Description: 實現功能:
---- 顯示和獨立按鍵部分根據數碼管顯示的程序來改編,用S1,S5,S9,S13作為獨立按鍵。
---- 一共有4個窗口。每個窗口顯示一個參數。有兩種更改參數的方式:
---- 第一種:按鍵更改參數:
---- 第8,7,6,5位數碼管顯示當前窗口,P-1代表第1個窗口,P-2代表第2個窗口,P-3代表第3個窗口,P-4代表第1個窗口。
---- 第4,3,2,1位數碼管顯示當前窗口被設置的參數。范圍是從0到9999。S1是加按鍵,按下此按鍵會依次增加當前窗口的參數。S5是減按鍵,按下此按鍵會依次減少當前窗口的參數。S9是切換窗口按鍵,按下此按鍵會依次循環切換不同的窗口。S13是啟動發送數據和復位按鍵,當系統處于待機狀態時,按下此按鍵會啟動發送數據;當通訊超時蜂鳴器報警時,可以按下此鍵清除報警,返回到待機的狀態。
----
---- 第二:通過串口把更改的參數發送給從機。
---- 波特率是:9600.
---- 通訊協議:EB 00 55 GG 00 02 XX XX CY
---- 其中第1,2,3位EB 00 55就是數據頭
---- 其中第4位GG就是數據類型。01代表更改參數1,02代表更改參數2,03代表更改參數3,04代表更改參數4,
---- 其中第5,6位00 02就是有效數據長度。高位在左,低位在右。
---- 其中從第7,8位XX XX是被更改的參數。高位在左,低位在右。
---- 第9位CY是累加和,前面所有字節的累加。
---- 一個完整的通訊必須發送完4串數據,每串數據之間的間隔時間不能超過10秒鐘,否則認為通訊超時主機會重發數據,如果連續三次都沒有返回,則引發蜂鳴器報警。如果接收到得數據校驗正確,主機繼續發送新的一串數據,直到把4串數據發送完畢為止。
----
---- 系統處于待機狀態時,LED燈一直亮,
---- 系統處于非待機狀態時,LED燈閃爍,
---- 系統處于出錯狀態時,LED燈閃爍,并且蜂鳴器間歇鳴叫報警。
----
---- 通過電腦的串口助手來模擬從機,返回不同的應答
---- 從機返回校驗正確應答:eb 00 55 f5 00 00 35
---- 從機返回校驗出錯應答:eb 00 55 fa 00 00 3a
---- 單片機:AT89C52
********************************************************************************************************************/
#include "reg52.h"
/*——————宏定義——————*/
#define FOSC 11059200L
#define BAUD 9600
#define T1MS (65536-FOSC/12/500) /*0.5ms timer calculation method in 12Tmode*/
#define const_key_time1 9 /*按鍵去抖動延時的時間*/
#define const_key_time2 9 /*按鍵去抖動延時的時間*/
#define const_key_time3 9 /*按鍵去抖動延時的時間*/
#define const_key_time4 9 /*按鍵去抖動延時的時間*/
#define const_led_0_5s 32 /*大概0.5秒的時間*/
#define const_led_1s 64 /*大概1秒的時間*/
#define const_send_time_out 640 /*通訊超時出錯的時間 大概10秒*/
#define const_rc_size 20 /*接收串口中斷數據的緩沖區數組大小*/
#define const_receive_time 5 /*如果超過這個時間沒有串口數據過來,就認為一串數據已經全部接收完,這個時間根據實際情況來調整大小*/
#define const_send_size 10 /*串口發送數據的緩沖區數組大小*/
#define const_voice_short 20 /*蜂鳴器短叫的持續時間*/
/*——————變量函數定義及聲明——————*/
/*蜂鳴器的驅動IO口*/
sbit BEEP = P2^7;
/*LED*/
sbit LED = P3^5;
/*按鍵*/
sbit Key_S1 = P0^0; /*對應S1鍵,加鍵*/
sbit Key_S2 = P0^1; /*對應S5鍵,減鍵*/
sbit Key_S3 = P0^2; /*對應S9鍵,切換窗口*/
sbit Key_S4 = P0^3; /*對應S13鍵,復位*/
sbit Key_Gnd = P0^4;
/*數碼管*/
sbit Dig_Hc595_Sh = P2^0;
sbit Dig_Hc595_St = P2^1;
sbit Dig_Hc595_Ds = P2^2;
unsigned char ucSendregBuf[const_send_size]; /*發送的緩沖區數組*/
unsigned int uiSendCnt = 0; /*用來識別串口是否接收完一串數據的計時器*/
unsigned char ucSendLock = 1; /*串口服務程序的自鎖變量,每次接收完一串數據只處理一次*/
unsigned int uiRcregTotal = 0; /*代表當前緩沖區已經接收了多少個數據*/
unsigned char ucRcregBuf[const_rc_size]; /*接收串口中斷數據的緩沖區數組*/
unsigned int uiRcMoveIndex = 0; /*用來解析數據協議的中間變量*/
unsigned char ucSendCntLock = 0; /*串口計時器的原子鎖*/
unsigned char ucRcType = 0; /*數據類型*/
unsigned int uiRcSize = 0; /*數據長度*/
unsigned char ucRcCy = 0; /*校驗累加和*/
unsigned char ucLedLock = 0; /*原子鎖*/
unsigned int uiLedCnt = 0; /*控制Led閃爍的延時計時器*/
unsigned int uiSendTimeOutCnt = 0; /*用來識別接收數據超時的計時器*/
unsigned char ucSendTimeOutLock = 0; /*原子鎖*/
unsigned char ucStatus = 0; /*當前狀態變量 0代表待機 1代表正在通訊過程 2代表發送出錯*/
unsigned char ucSendStep = 0; /*發送數據的過程步驟*/
unsigned char ucErrorCnt = 0; /*累計錯誤總數*/
unsigned char ucSendTotal = 0; /*記錄當前已經發送了多少串數據*/
unsigned char ucReceiveStatus = 0; /*返回的數據狀態 0代表待機 1代表校驗正確 2代表校驗出錯*/
unsigned char ucKeySec = 0; /*被觸發的按鍵編號*/
unsigned int uiKeyTimeCnt1 = 0; /*按鍵去抖動延時計數器*/
unsigned char ucKeyLock1 = 0; /*按鍵觸發后自鎖的變量標志*/
unsigned int uiKeyTimeCnt2 = 0; /*按鍵去抖動延時計數器*/
unsigned char ucKeyLock2 = 0; /*按鍵觸發后自鎖的變量標志*/
unsigned int uiKeyTimeCnt3 = 0; /*按鍵去抖動延時計數器*/
unsigned char ucKeyLock3 = 0; /*按鍵觸發后自鎖的變量標志*/
unsigned int uiKeyTimeCnt4 = 0; /*按鍵去抖動延時計數器*/
unsigned char ucKeyLock4 = 0; /*按鍵觸發后自鎖的變量標志*/
unsigned int uiVoiceCnt = 0; /*蜂鳴器鳴叫的持續時間計數器*/
unsigned char ucVoiceLock = 0; /*蜂鳴器鳴叫的原子鎖*/
unsigned char ucDigShow8; /*第8位數碼管要顯示的內容*/
unsigned char ucDigShow7; /*第7位數碼管要顯示的內容*/
unsigned char ucDigShow6; /*第6位數碼管要顯示的內容*/
unsigned char ucDigShow5; /*第5位數碼管要顯示的內容*/
unsigned char ucDigShow4; /*第4位數碼管要顯示的內容*/
unsigned char ucDigShow3; /*第3位數碼管要顯示的內容*/
unsigned char ucDigShow2; /*第2位數碼管要顯示的內容*/
unsigned char ucDigShow1; /*第1位數碼管要顯示的內容*/
unsigned char ucDigDot8; /*數碼管8的小數點是否顯示的標志*/
unsigned char ucDigDot7; /*數碼管7的小數點是否顯示的標志*/
unsigned char ucDigDot6; /*數碼管6的小數點是否顯示的標志*/
unsigned char ucDigDot5; /*數碼管5的小數點是否顯示的標志*/
unsigned char ucDigDot4; /*數碼管4的小數點是否顯示的標志*/
unsigned char ucDigDot3; /*數碼管3的小數點是否顯示的標志*/
unsigned char ucDigDot2; /*數碼管2的小數點是否顯示的標志*/
unsigned char ucDigDot1; /*數碼管1的小數點是否顯示的標志*/
unsigned char ucDigShowTemp = 0; /*臨時中間變量*/
unsigned char ucDisplayDriveStep = 1; /*動態掃描數碼管的步驟變量*/
unsigned char ucWd1Update = 1; /*窗口1更新顯示標志*/
unsigned char ucWd2Update = 0; /*窗口2更新顯示標志*/
unsigned char ucWd3Update = 0; /*窗口3更新顯示標志*/
unsigned char ucWd4Update = 0; /*窗口4更新顯示標志*/
unsigned char ucWd = 1; /*本程序的核心變量,窗口顯示變量。類似于一級菜單的變量。代表顯示不同的窗口。*/
unsigned int uiSetData1 = 0; /*本程序中需要被設置的參數1*/
unsigned int uiSetData2 = 0; /*本程序中需要被設置的參數2*/
unsigned int uiSetData3 = 0; /*本程序中需要被設置的參數3*/
unsigned int uiSetData4 = 0; /*本程序中需要被設置的參數4*/
unsigned char ucTemp1 = 0; /*中間過渡變量*/
unsigned char ucTemp2 = 0; /*中間過渡變量*/
unsigned char ucTemp3 = 0; /*中間過渡變量*/
unsigned char ucTemp4 = 0; /*中間過渡變量*/
void Dig_Hc595_Drive(unsigned char, unsigned char);
/*根據原理圖得出的共陰數碼管字模表*/
code unsigned char Dig_Table[] =
{
0x3f, /*0 序號0*/
0x06, /*1 序號1*/
0x5b, /*2 序號2*/
0x4f, /*3 序號3*/
0x66, /*4 序號4*/
0x6d, /*5 序號5*/
0x7d, /*6 序號6*/
0x07, /*7 序號7*/
0x7f, /*8 序號8*/
0x6f, /*9 序號9*/
0x00, /*不顯示 序號10*/
0x40, /*- 序號11*/
0x73, /*P 序號12*/
};
/**
* @brief 定時器0初始化函數
* @param 無
* @retval 初始化T0
**/
void Init_T0(void)
{
TMOD = 0x01; /*set timer0 as mode1 (16-bit)*/
TL0 = T1MS; /*initial timer0 low byte*/
TH0 = T1MS >> 8; /*initial timer0 high byte*/
}
/**
* @brief 串口初始化函數
* @param 無
* @retval 初始化T0
**/
void Init_USART(void)
{
SCON = 0x50;
TMOD = 0x21;
TH1=TL1=-(FOSC/12/32/BAUD);
}
/**
* @brief 外圍初始化函數
* @param 無
* @retval 初始化外圍
* 讓數碼管顯示的內容轉移到以下幾個變量接口上,方便以后編寫更上一層的窗口程序。
* 只要更改以下對應變量的內容,就可以顯示你想顯示的數字。
**/
void Init_Peripheral(void)
{
ucDigDot8 = 0;
ucDigDot7 = 0;
ucDigDot6 = 0;
ucDigDot5 = 0;
ucDigDot4 = 0;
ucDigDot3 = 0;
ucDigDot2 = 0;
ucDigDot1 = 0;
ET0 = 1;/*允許定時中斷*/
TR0 = 1;/*啟動定時中斷*/
TR1 = 1;
ES = 1; /*允許串口中斷*/
EA = 1;/*開總中斷*/
}
/**
* @brief 初始化函數
* @param 無
* @retval 初始化單片機
**/
void Init(void)
{
LED = 0;
BEEP = 1;
Key_Gnd = 0;
Dig_Hc595_Drive(0x00, 0x00); /*關閉所有經過另外兩個74HC595驅動的LED燈*/
Init_T0();
Init_USART();
/*
* 為了保證串口中斷接收的數據不丟失,必須設置IP = 0x10,相當于把串口中斷設置為最高優先級,
* 這個時候,串口中斷可以打斷任何其他的中斷服務函數實現嵌套,
*/
IP = 0x10; /*把串口中斷設置為最高優先級,必須的。*/
}
/**
* @brief 延時函數
* @param 無
* @retval 無
**/
void Delay_Long(unsigned int uiDelayLong)
{
unsigned int i;
unsigned int j;
for(i=0;i for(j=0;j<500;j++) /*內嵌循環的空指令數量*/ { ; /*一個分號相當于執行一條空語句*/ } } } /** * @brief 延時函數 * @param 無 * @retval 無 **/ void Delay_Short(unsigned int uiDelayShort) { unsigned int i; for(i=0;i ; /*一個分號相當于執行一條空語句*/ } } /** * @brief 串口發送函數 * @param ucSendData * @retval 在發送一串數據中,每個字節之間必須添加一個延時,用來等待串口發送完成。 * 不增加延時,單單靠發送完成標志位來判斷還是容易出錯,在51,PIC單片機中都是這么做。 * 在stm32單片機中,可以不增加延時,直接靠單片機自帶的標志位來判斷就很可靠。 **/ void eusart_send(unsigned char ucSendData) { ES = 0; /*關串口中斷*/ TI = 0; /*清零串口發送完成中斷請求標志*/ SBUF = ucSendData; /*發送一個字節*/ Delay_Short(400); /*每個字節之間的延時,這里非常關鍵,也是最容易出錯的地方。延時的大小請根據實際項目來調整*/ TI = 0; /*清零串口發送完成中斷請求標志*/ ES = 1; /*允許串口中斷*/ } /** * @brief 一發一收的通訊服務程序 * @param 無 * @retval 無 **/ void communication_service(void) { unsigned int i; if(ucStatus == 1) /*處于正在通訊的過程中*/ { switch(ucSendStep) { case 0: /*通訊過程0 發送一串數據*/ switch(ucSendTotal) /*根據當前已經發送到第幾條數據來決定發送哪些參數*/ { case 0: /*發送參數1*/ ucSendregBuf[0] = 0xeb; ucSendregBuf[1] = 0x00; ucSendregBuf[2] = 0x55; ucSendregBuf[3] = 0x01; ucSendregBuf[4] = 0x00; ucSendregBuf[5] = 0x02; ucSendregBuf[6] = uiSetData1 >> 8; /*把int類型的參數分解成兩個字節的數據*/ ucSendregBuf[7] = uiSetData1; break; case 1: /*發送參數2*/ ucSendregBuf[0] = 0xeb; ucSendregBuf[1] = 0x00; ucSendregBuf[2] = 0x55; ucSendregBuf[3] = 0x02; ucSendregBuf[4] = 0x00; ucSendregBuf[5] = 0x02; ucSendregBuf[6] = uiSetData2 >> 8; /*把int類型的參數分解成兩個字節的數據*/ ucSendregBuf[7] = uiSetData2; break; case 2: /*發送參數3*/ ucSendregBuf[0] = 0xeb; ucSendregBuf[1] = 0x00; ucSendregBuf[2] = 0x55; ucSendregBuf[3] = 0x03; ucSendregBuf[4] = 0x00; ucSendregBuf[5] = 0x02; ucSendregBuf[6] = uiSetData3 >> 8; /*把int類型的參數分解成兩個字節的數據*/ ucSendregBuf[7] = uiSetData3;
上一篇:51單片機實現利用AT24C02進行掉電后的數據保存
下一篇:51單片機實現從機的串口收發
推薦閱讀
史海拾趣
如今,Fagor Electrónica已經成為電子和數字領域的領軍企業之一。展望未來,公司將繼續秉承創新驅動的發展理念,加大在人工智能、物聯網等新興領域的投入。同時,Fagor Electrónica還將積極參與全球市場競爭,拓展更廣闊的市場空間。相信在不久的將來,Fagor Electrónica將會創造更加輝煌的業績。
在電子組裝行業,品質是企業的生命線。一家名為“品質電子組裝”的公司,從創立之初就堅持以品質為核心競爭力。公司引進了國際先進的生產設備和管理體系,建立了嚴格的質量控制體系,確保每一件產品都符合高標準、嚴要求。正是憑借著對品質的堅守和追求,品質電子組裝贏得了客戶的廣泛贊譽和信賴,逐漸在行業中樹立了良好的口碑。
隨著技術的不斷進步和市場需求的增長,ET Enterprises Ltd公司開始推出多種類型的光電倍增管產品,包括普通可見光型、紫外靈敏型、日盲型等。同時,公司也積極拓展國際市場,與全球各地的客戶建立合作關系,進一步鞏固了其在光電倍增管領域的領先地位。
隨著技術的不斷進步和市場需求的增長,ET Enterprises Ltd公司開始推出多種類型的光電倍增管產品,包括普通可見光型、紫外靈敏型、日盲型等。同時,公司也積極拓展國際市場,與全球各地的客戶建立合作關系,進一步鞏固了其在光電倍增管領域的領先地位。
碩頡科技不斷推出創新產品,主打系列包括逆變器、LED驅動器、線性穩壓器、AC/DC驅動器、MOSFET、視頻編碼器和解碼器以及圖像處理器等。這些產品廣泛應用于消費電子領域,滿足了市場對高質量電子產品的需求。同時,公司積極拓展銷售網絡,以臺灣、韓國、中國大陸和日本等地區為主,逐步向全球市場擴張。
Adam Tech公司成立于1987年,總部位于美國新澤西州。創業初期,公司面臨著資金短缺、市場競爭激烈等諸多困難。然而,創始人憑借對電子連接器行業的深刻理解和執著追求,帶領團隊克服重重困難,逐漸在市場上站穩腳跟。公司最初的產品線相對單一,但憑借著高品質和可靠的性能,逐漸贏得了客戶的信任。
altium designer我使用的是6.6版本,這個新軟件比protel DXP有了質的飛躍,而且帶來了很多的便利,比起官方網站上的列表的哪么多新特性,我覺得一下的新特性很方便,其他的特性還沒有用武之地。 PCB 新的信號完整性范例 信號完整性的可 ...… 查看全部問答∨ |
|
我這臺電腦有點郁悶,安裝EVC只有 每次啟動很久才進入桌面, 右下角,老是有個什么visual emulator 阻止系統加載的汽包提示。 EVC倒是能正常使用,我把EVC卸載了,這個東西還是會彈出來,啟動還是很慢,請問有什么辦法,徹底刪除這個東西?… 查看全部問答∨ |
|
全國賽快到了,實驗室老師讓我畫一批板子培訓用,我果斷用了811,曬圖啊。。。有不足的地方歡迎大家提意見啊。就是下載器比較頭疼啊,Jlink80一個,11個下載器就得九百啊。。。。soso姐送塊811板子吧,我們山寨一下Mlink吧再附上LCD液晶屏的電路 [ ...… 查看全部問答∨ |
2530 + 2591,最大電流是多大? 看資料2530的輸出電流是30mA,2591是100mA,而我測的只有30mA。 這是怎么一回事呢… 查看全部問答∨ |
深圳揚創科技的WinCE工業平板電腦操作GPIO函數如下: IO輸入輸出功能(此功能為選配)總共有16路IO口,默認配置為8路輸入和8路輸出。 (1)8路輸出 BOOL SetIO (byte level,byte idNum); 參數說明: byte level: 0:低電平1:高電平 byte idN ...… 查看全部問答∨ |
設計資源 培訓 開發板 精華推薦
- 高通攜手中國“汽車朋友圈”亮相2025上海車展: 加速駕駛輔助普惠,推動艙駕創新升級
- 工業市場正在快速回暖,德州儀器如何重塑電力電子市場?
- 特斯拉:美國交付的Model Y/3電池包已實現100%美國生產
- 地平線與博世深化合作,攜手為多家車企提供輔助駕駛產品
- 強化中國市場戰略布局,德州儀器正靈活應對全球關稅挑戰
- Molex莫仕通過本地合作和創新加強支持中國汽車行業
- 貿澤開售Texas Instruments適用于高分辨率AR HUD的 全新DLP4620S-Q1 0.46"汽車數字微鏡器件
- ROHM推出高功率密度的新型SiC模塊,將實現車載充電器小型化!
- 用上車規級UFS 4.0,讓出行變得高效且可靠
- 車載測試技術解析:聚焦高帶寬、多通道同步采集與協議分析