?? mcs51-項(xiàng)目開發(fā)經(jīng)典.c
字號(hào):
//=================================================================================================
// 項(xiàng)目名:MCS51-項(xiàng)目開發(fā)經(jīng)典
// 硬件文件名:51Studay.DDB
// 程序組目錄名:MCS51-項(xiàng)目開發(fā)經(jīng)典
// 開始時(shí)間:2007年5月21日
// 完成時(shí)間:2007年6月10日
//-------------------------------------------------------------------------------------------------
// 程序中用到哪些C51標(biāo)準(zhǔn)函數(shù),就需要把該函數(shù)對(duì)應(yīng)的頭文件包含進(jìn)來
//-------------------------------------------------------------------------------------------------
#include <intrins.h>
#include <string.h>
#include <absacc.h>
#include <reg52.h>
//-------------------------------------------------------------------------------------------------
// 為提高書寫效率做以下宏定義
//-------------------------------------------------------------------------------------------------
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define CLOSE 1
#define OPEN 0
//-------------------------------------------------------------------------------------------------
// HD7279操控位及指令宏定義
//-------------------------------------------------------------------------------------------------
sbit CS_7279 = P1^0;
sbit CLK_7279 = P1^1;
sbit DATA_7279= P1^2;
sbit KEY_7279 = P1^3;
// HD7279指令宏定義:不帶數(shù)據(jù)的純指令
#define HD7279_RESET 0xa4 //復(fù)位,相當(dāng)于重新上電
#define HD7279_TEST 0xbf //測(cè)試,點(diǎn)亮全部LED并閃爍
#define HD7279_RL 0xa1 //左移1位
#define HD7279_RR 0xa0 //右移1位
#define HD7279_RLC 0xa3 //循環(huán)左移
#define HD7279_RRC 0xa2 //循環(huán)右移
// HD7279指令宏定義:帶有數(shù)據(jù)的指令
#define HD7279_DECODE0 0x80 //譯碼方式0
#define HD7279_DECODE1 0xc8 //譯碼方式1
#define HD7279_UNDECODE 0x90 //譯碼方式2: 不譯碼
#define HD7279_FLASH 0x88 //閃爍指令,后跟8位數(shù)據(jù) D8|D7|D6|D5|D4|D3|D2|D1,某位置0則該位閃爍
#define HD7279_HIDE 0x98 //消隱指令,后跟8位數(shù)據(jù) D8|D7|D6|D5|D4|D3|D2|D1,某位置0則該位消隱
#define HD7279_SEGON 0xe0 //單段亮
#define HD7279_SEGOFF 0xc0 //單段滅
#define HD7279_READ_KEY 0x15 //讀按鍵代碼,讀出的數(shù)值對(duì)應(yīng)按下的鍵,無鍵按下時(shí)數(shù)值為0xff.
//=================================================================================================
#define TEST_74HC595 1
#define TEST_24C02 2
#define TEST_93C46 3
#define SET_SD2000 4
#define READ_SD2000 5
#define TEST_18B20 6
#define TEST_HD7279 7
#define TEST_BIT_IO 8
#define TEST_TLC2543 9
#define TEST_TLC5617 10
#define TEST_PWM_DA 11
#define TEST_L297 12
#define TEST_DC_MOTOR 13
#define TEST_LCM 14
//-------------------------------------------------------------------------------------------------
// 操作UART串口相關(guān)的全局變量
//-------------------------------------------------------------------------------------------------
uchar idata uart_buffer[40];//串口接收緩沖區(qū),可接收字符串的最大長(zhǎng)度為40
uchar uart_buffer_address;//串口接收緩沖區(qū)地址計(jì)數(shù)器
bit uart_receive_start; //串口接收啟動(dòng)
bit uart_receive_ok; //串口接收(UART0)中斷里已接收完整消息標(biāo)志
bit kaiguan;
//-------------------------------------------------------------------------------------------------
// 鍵盤掃描相關(guān)的全局變量
//-------------------------------------------------------------------------------------------------
uchar key_value_previous;
uchar key_press_counter;
uchar key_value_main;
uchar key_press_timer;
//-------------------------------------------------------------------------------------------------
uchar t1_delay_time;//50毫秒計(jì)數(shù)器累加變量,在T2中斷里累加
bit i2c_response_signal;//I2C總線應(yīng)答信號(hào)
uint idata temporary_data[10];//臨時(shí)數(shù)據(jù)
uchar idata test_command;//存儲(chǔ)串口接收的測(cè)試命令
uchar idata weizhi;
uint motor_speed_delay;
//-------------------------------------------------------------------------------------------------
// 函數(shù)聲明
//-------------------------------------------------------------------------------------------------
void init_cpu(void);
void ctrl_74hc595(uchar led_display_data);
void HD7279_LongDelay(void);
void HD7279_ShortDelay(void);
void HD7279_SendByte(uchar out_byte);
uchar HD7279_ReceiveByte(void);
uchar HD7279_GetKey(void);
void HD7279_ShowData(uchar Position,uchar ShowData,bit Have_DP);
void HD7279_Showflash(uchar Position_flash);
void HD7279_Initial(void);
void uart_byte_out(uchar uart_data_out);
void uart_string_out(char * char_array);
void uart_data_decimalist_out(uint data_to_out);
void uart_newline(uchar newline_number);
void uart_space(uchar space_number);
uchar change_bcd_to_hex(uchar shu);
uchar change_hex_to_bcd(uchar shu);
uchar change_askii_to_hex(uchar askii);
uchar change_hex_to_askii(uchar data_hex);
void get_data(uchar * how_much_data);
char * strstr(char * haystack, char * needle);
//=================================================================================================
//===================== ================================================
//===================== 主程序 ================================================
//===================== ================================================
//=================================================================================================
void main (void)
{ uchar i;
init_cpu();
HD7279_Initial();
key_value_main=0xff;
HD7279_SendByte( HD7279_RESET );//復(fù)位
wqyloop:
for(i=0;i<10;i++) //數(shù)碼管測(cè)試
{ HD7279_ShowData(1,i,1);
HD7279_ShowData(2,i,1);
HD7279_ShowData(3,i,1);
HD7279_ShowData(4,i,1);
HD7279_ShowData(5,i,1);
HD7279_ShowData(6,i,1);
HD7279_ShowData(7,i,1);
HD7279_ShowData(8,i,1);
for(t1_delay_time=0;t1_delay_time<10;);//延時(shí)500毫秒
}
HD7279_ShowData(1,1,1);
for(t1_delay_time=0;t1_delay_time<10;);//延時(shí)500毫秒
HD7279_ShowData(2,2,1);
for(t1_delay_time=0;t1_delay_time<10;);//延時(shí)500毫秒
HD7279_ShowData(3,3,1);
for(t1_delay_time=0;t1_delay_time<10;);//延時(shí)500毫秒
HD7279_ShowData(4,4,1);
for(t1_delay_time=0;t1_delay_time<10;);//延時(shí)500毫秒
HD7279_ShowData(5,5,1);
for(t1_delay_time=0;t1_delay_time<10;);//延時(shí)500毫秒
HD7279_Showflash(3);
for(t1_delay_time=0;t1_delay_time<10;);//延時(shí)500毫秒
if(key_value_main!=0xff)//如果有按鍵觸發(fā)則如下
{uart_string_out("You have pushed the button S");
uart_byte_out(change_hex_to_askii(key_value_main));
uart_newline(1);
key_value_main=0xff;//使用完本次觸發(fā)的鍵值后必須清空鍵值,否則主程序認(rèn)為在連續(xù)觸發(fā)該鍵
}
goto wqyloop;
}//The end of main()
//########################## 主程序結(jié)束 #########################################################
//########################## 子程序開始 #########################################################
//=================================================================================================
// 函數(shù)功能:CPU初始化函數(shù)
// 串口波特率可以由T1或T2產(chǎn)生,本例中用T1產(chǎn)生波特率
// T2用于50毫秒精確定時(shí)
// T0用于PWM控制中頻率的時(shí)基
//=================================================================================================
void init_cpu(void)
{
TMOD=0x12;//T1為16位計(jì)數(shù)器,T0為8位自動(dòng)重裝載計(jì)數(shù)器
ET1=1;
TH1=0x4c;//11.0592M晶振時(shí)T1定時(shí)時(shí)間長(zhǎng)度為50毫秒
TL1=0x00;
TR1=1;//T1開始定時(shí)
T2CON=0x30;//定時(shí)器T2工作于波特率發(fā)生器方式
RCAP2H=0xff;//11.0592M晶振,9600bps初值
RCAP2L=0xdc;
TH2=0xff;
TL2=0xdc;
//RCAP2H=0xfe;//11.0592M晶振,1200bps初值
//RCAP2L=0xe0;
//TH2=0xfe;
//TL2=0xe0;
TR2=1;//允許T2中斷
ES=1; //串口中斷允許
PS=1; //串口中斷優(yōu)先級(jí)設(shè)為高,因?yàn)橐ㄟ^串口干預(yù)程序流程,為保證可靠接收所以有此設(shè)置
SCON=0x50;//串口工作于方式1,啟動(dòng)串口接收
EA=1;//CPU中斷開放
//以下是程序中軟件邏輯需要的變量初值設(shè)置和硬件初始狀態(tài)設(shè)置
key_value_main=0xff;
}
//=================================================================================================
// 以下是HD7279驅(qū)動(dòng)程序
// 操作HD7279的關(guān)鍵是如何保證手冊(cè)中給定的T1到T8這8個(gè)時(shí)間間隔
// 并且只有當(dāng)HD7279的27腳外接R=1。5K、C=15P時(shí),T1到T8才是手冊(cè)中給的數(shù)值,建議不要隨意改變R、C的值
// 弄清楚這個(gè)問題,則你對(duì)器件時(shí)序圖的理解將上升到一個(gè)新的高度。任何器件的驅(qū)動(dòng)程序只要看懂時(shí)序圖就OK!
//=================================================================================================
// 函數(shù)功能:長(zhǎng)延時(shí),保證延時(shí)時(shí)間在50~250uS之間
void HD7279_LongDelay(void)
{ uchar i;
for (i=0;i<30;i++);
}
//-------------------------------------------------------------------------------------------------
// 函數(shù)功能:短延時(shí),保證延時(shí)時(shí)間在8~250uS之間
void HD7279_ShortDelay(void)
{ uchar i;
for (i=0;i<8;i++);
}
//-------------------------------------------------------------------------------------------------
//函數(shù)功能:向HD7279寫字節(jié)
void HD7279_SendByte(uchar out_byte)
{ uchar i;
CLK_7279=0;//準(zhǔn)備CLK腳狀態(tài)
CS_7279=0; //準(zhǔn)備CS腳狀態(tài),置0允許操作7279
HD7279_LongDelay();//延時(shí)T1,在帶數(shù)據(jù)的命令中此延時(shí)相當(dāng)于送數(shù)據(jù)之前的T4延時(shí)
for(i=0;i<8;i++)
{if(out_byte&0x80) DATA_7279=1;//準(zhǔn)備數(shù)據(jù),高位MSB先入
else DATA_7279=0;
CLK_7279=1;//CLK_7279下降沿時(shí)DATA_7279數(shù)據(jù)寫入
HD7279_ShortDelay();//延時(shí)T2
CLK_7279=0;
HD7279_ShortDelay();//延時(shí)T3
out_byte<<=1;//準(zhǔn)備要寫入數(shù)據(jù)的次高位
}
}
//-------------------------------------------------------------------------------------------------
//函數(shù)功能:從HD7279讀字節(jié),只在讀鍵值時(shí)用到
uchar HD7279_ReceiveByte(void)
{ uchar i;
uchar in_byte;
DATA_7279=1;//置單片機(jī)DATA_7279端為輸入狀態(tài)
HD7279_LongDelay();//延時(shí)T5
for(i=0;i<8;i++)
{CLK_7279=1;
HD7279_ShortDelay();//延時(shí)T7(因?yàn)門7=T6),此延時(shí)結(jié)束后HD7279_DATA數(shù)據(jù)才有效,
in_byte=in_byte<<1;//鍵值的高位MSB先出,因?yàn)樽畹臀籐SB取出后不需要左移,所以有此操作
if(DATA_7279) in_byte=in_byte|0x01;//取HD7279_DATA的數(shù)據(jù)狀態(tài),放入in_byte最低位LSB
CLK_7279=0;
HD7279_ShortDelay();//延時(shí)T3,這個(gè)延時(shí)手冊(cè)中沒有標(biāo)出(因?yàn)門3>T8,所以最后1位取出后此T3相當(dāng)于T8)
}
return (in_byte);
}
//----------------------------------------------------------------------------------------------
//函數(shù)功能:獲得按鍵代碼
uchar HD7279_GetKey(void)
{ uchar key;
HD7279_SendByte(HD7279_READ_KEY);
key=HD7279_ReceiveByte();
return(key);
}
//-------------------------------------------------------------------------------------------------
// 函數(shù)功能:按方式0譯碼,在指定的1到8位置顯示數(shù)據(jù)
// 通常情況下我們都使用方式0譯碼,方式1譯碼與之大同小異
// 形參:Position 顯示位置(1-8),ShowData 數(shù)據(jù)(0-15),Have_DP 是否顯示小數(shù)點(diǎn)(1顯示,0不顯示)
void HD7279_ShowData(uchar Position,uchar ShowData,bit Have_DP)
{ uchar Decode0_data;
if(Have_DP) ShowData = ShowData|0x80;//處理小數(shù)點(diǎn)的顯示與否
Decode0_data=(Position-1)|HD7279_DECODE0;//將譯碼方式0和要顯示的位置合并
HD7279_SendByte(Decode0_data);//送命令
HD7279_SendByte(ShowData);//送數(shù)據(jù)
CS_7279=1;
}
//-------------------------------------------------------------------------------------------------
// 函數(shù)功能:按方式0譯碼,在指定的1到8位置閃爍數(shù)據(jù)
// 通常情況下我們都使用方式0譯碼,方式1譯碼與之大同小異
// 形參:Position_flash 顯示位置(1-8)
void HD7279_Showflash(uchar Position_flash)
{ uchar FlashDate=0xff;
FlashDate=FlashDate&(~(0x01<<(Position_flash-1)));
HD7279_SendByte(HD7279_FLASH);//送命令
HD7279_SendByte(FlashDate);//送數(shù)據(jù)
CS_7279=1;
}
//-------------------------------------------------------------------------------------------------
//函數(shù)功能:HD7279初始化,建議在工業(yè)現(xiàn)場(chǎng)干擾嚴(yán)重情況下,刷新顯示時(shí)先執(zhí)行此命令
void HD7279_Initial(void)
{
HD7279_SendByte( HD7279_RESET );//復(fù)位
}
//=================================================================================================
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -