一個項目的一部分內容,讓初學者模擬著做一下,還是很有用處的。
這樣的程序可以實現一個51單片機有兩個串口- #include<regx52.h>
- sbit BT_SND =P1^1;
- sbit BT_REC =P1^0;
- //1602部分引腳定義
- sbit LCM_RW =P2^1 ;//定義引腳
- sbit LCM_RS =P2^0;
- sbit LCM_E =P2^2;
- #define LCM_Data P0
- #define Busy 0x80 //用于檢測LCM狀態字中的Busy標識
- #define F_TM F0
- #define TIMER0_ENABLE TL0=TH0; TR0=1;
- #define TIMER0_DISABLE TR0=0;
- void WriteDataLCM(unsigned char WDLCM);
- void WriteCommandLCM(unsigned char WCLCM,BuysC);
- unsigned char ReadDataLCM(void);
- unsigned char ReadStatusLCM(void);
- void LCMInit(void);
- void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
- void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
- void Delay5Ms(void);
- void Delay400Ms(void);
- unsigned char code qq[] = {"Receive_Data"};
- //unsigned char code tel[] = {"Command:"};
- sbit ACC0= ACC^0;
- sbit ACC1= ACC^1;
- sbit ACC2= ACC^2;
- sbit ACC3= ACC^3;
- sbit ACC4= ACC^4;
- sbit ACC5= ACC^5;
- sbit ACC6= ACC^6;
- sbit ACC7= ACC^7;
- void IntTimer0() interrupt 1
- {
- F_TM=1;
- }
- //發送一個字符
- void PSendChar(unsigned char inch)
- {
- ACC=inch;
- F_TM=0;
- BT_SND=0; //start bit
- TIMER0_ENABLE; //啟動
- while(!F_TM);
- BT_SND=ACC0; //先送出低位
- F_TM=0;
- while(!F_TM);
- BT_SND=ACC1;
- F_TM=0;
- while(!F_TM);
- BT_SND=ACC2;
- F_TM=0;
- while(!F_TM);
- BT_SND=ACC3;
- F_TM=0;
- while(!F_TM);
- BT_SND=ACC4;
- F_TM=0;
- while(!F_TM);
- BT_SND=ACC5;
- F_TM=0;
- while(!F_TM);
- BT_SND=ACC6;
- F_TM=0;
- while(!F_TM);
- BT_SND=ACC7;
- F_TM=0;
- while(!F_TM);
- BT_SND=1;
- F_TM=0;
- while(!F_TM);
- TIMER0_DISABLE; //停止timer
- }
- //接收一個字符
- unsigned char PGetChar()
- {
- TIMER0_ENABLE;
- F_TM=0;
- while(!F_TM); //等過起始位
- ACC0=BT_REC;
- TL0=TH0;
- F_TM=0;
- while(!F_TM);
- ACC1=BT_REC;
- F_TM=0;
- while(!F_TM);
- ACC2=BT_REC;
- F_TM=0;
- while(!F_TM);
- ACC3=BT_REC;
- F_TM=0;
- while(!F_TM);
- ACC4=BT_REC;
- F_TM=0;
- while(!F_TM);
- ACC5=BT_REC;
- F_TM=0;
- while(!F_TM);
- ACC6=BT_REC;
- F_TM=0;
- while(!F_TM);
- ACC7=BT_REC;
- F_TM=0;
- while(!F_TM)
- {
- if(BT_REC)
- {
- break;
- }
- }
- TIMER0_DISABLE; //停止timer
- return ACC;
- }
- //檢查是不是有起始位
- bit StartBitOn()
- {
- return(BT_REC==0);
- }
- void main()
- {
- unsigned char gch,i;
- TMOD=0x22; /*定時器1為工作模式2(8位自動重裝),0為模式2(8位自動重裝) */
- PCON=00;
- TR0=0; //在發送或接收才開始使用
- TF0=0;
- TH0=(256-96); //9600bps 就是 1000000/9600=104.167微秒 執行的timer是104.167*11.0592/12= 96
- //
- TL0=TH0;
- ET0=1;
- EA=1;
- Delay400Ms(); //啟動等待,等LCM講入工作狀態
- LCMInit(); //LCM初始化
- Delay5Ms(); //延時片刻(可不要)
- DisplayListChar(2, 0, qq);
- // DisplayListChar(0, 1, tel);
- // ReadDataLCM();//測試用句無意義
- PSendChar(0x55);
- PSendChar(0xaa);
- PSendChar(0x00);
- PSendChar(0xff);
- while(1)
- {
- if(StartBitOn())
- {
- gch=PGetChar();
- PSendChar(gch);
- for(i=0;i<8;i++)
- DisplayOneChar(7-i,1, ((gch>>i)&0x01)+48);
-
- }
- }
- }
- //寫數據
- void WriteDataLCM(unsigned char WDLCM)
- {
- ReadStatusLCM(); //檢測忙
- LCM_Data = WDLCM;
- LCM_RS = 1;
- LCM_RW = 0;
- LCM_E = 0; //若晶振速度太高可以在這后加小的延時
- LCM_E = 0; //延時
- LCM_E = 1;
- }
- //寫指令
- void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC為0時忽略忙檢測
- {
- if (BuysC) ReadStatusLCM(); //根據需要檢測忙
- LCM_Data = WCLCM;
- LCM_RS = 0;
- LCM_RW = 0;
- LCM_E = 0;
- LCM_E = 0;
- LCM_E = 1;
- }
- /*/讀數據
- unsigned char ReadDataLCM(void)
- {
- LCM_RS = 1;
- LCM_RW = 1;
- LCM_E = 0;
- LCM_E = 0;
- LCM_E = 1;
- return(LCM_Data);
- }
- */
- //讀狀態
- unsigned char ReadStatusLCM(void)
- {
- LCM_Data = 0xFF;
- LCM_RS = 0;
- LCM_RW = 1;
- LCM_E = 0;
- LCM_E = 0;
- LCM_E = 1;
- while (LCM_Data & Busy); //檢測忙信號
- return(LCM_Data);
- }
- void LCMInit(void) //LCM初始化
- {
- LCM_Data = 0;
- WriteCommandLCM(0x38,0); //三次顯示模式設置,不檢測忙信號
- Delay5Ms();
- WriteCommandLCM(0x38,0);
- Delay5Ms();
- WriteCommandLCM(0x38,0);
- Delay5Ms();
- WriteCommandLCM(0x38,1); //顯示模式設置,開始要求每次檢測忙信號
- WriteCommandLCM(0x08,1); //關閉顯示
- WriteCommandLCM(0x01,1); //顯示清屏
- WriteCommandLCM(0x06,1); // 顯示光標移動設置
- WriteCommandLCM(0x0C,1); // 顯示開及光標設置
- }
- //按指定位置顯示一個字符
- void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
- {
- Y &= 0x1;
- X &= 0xF; //限制X不能大于15,Y不能大于1
- if (Y) X |= 0x40; //當要顯示第二行時地址碼+0x40;
- X |= 0x80; //算出指令碼
- WriteCommandLCM(X, 0); //這里不檢測忙信號,發送地址碼
- WriteDataLCM(DData);
- }
- //按指定位置顯示一串字符
- void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
- {
- unsigned char ListLength;
- ListLength = 0;
- Y &= 0x1;
- X &= 0xF; //限制X不能大于15,Y不能大于1
- while (DData[ListLength]>0x20) //若到達字串尾則退出
- {
- if (X <= 0xF) //X坐標應小于0xF
- {
- DisplayOneChar(X, Y, DData[ListLength]); //顯示單個字符
- ListLength++;
- X++;
- }
- }
- }
- //5ms延時
- void Delay5Ms(void)
- {
- unsigned int TempCyc = 5552;
- while(TempCyc--);
- }
- //400ms延時
- void Delay400Ms(void)
- {
- unsigned char TempCycA = 5;
- unsigned int TempCycB;
- while(TempCycA--)
- {
- TempCycB=7269;
- while(TempCycB--);
- };
- }
復制代碼
|