一个项目的一部分内容,让初学者模拟着做一下,还是很有用处的。
这样的程序可以实现一个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--);
- };
- }
复制代码
|