C51串口通信实验
本文最后更新于20 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

串口通信

STC89C52(下面简称C51)系列单片机内部集成了一个功能很强的全双工串行通信口,与传统8051单片机的串口完全兼容。设有两个互相独立的接收、发送缓存器,可以同时发送和接收数据。发送缓存器只能写入不能读出,接收缓存器只能读出不能写入,两个缓存器共用一个地址吗(99H)。

串行通信外设有4种工作方式,其中两种方式的波特率是可变的,另两种是固定的,以供不同应用场合选用。波特率由内部定时器/计数器产生,用软件设置不同的波特率和选择不同的工作方式。

C51系列单片机串行口对应的引脚是P3.0(RxD)和P3.1(TxD)。

串行口控制寄存器

C51系列单片机的串行口设有两个控制寄存器:SCON(串行控制寄存器)和PCON(波特率选择特殊功能寄存器)

SCON

SM0和SM1共同确定串行的工作方式:

SM2:允许方式2或方式3多机通信控制位 REN:允许/禁止串口接收控制位,REN=1为允许接收 TB8: 在方式2或方式3,为要发送的第九位数据,按需要由软件置位或清0 RB8: 在方式2或方式3,是接收到的第九位数据 TI: 发送中断请求标志位 RI: 接收中断请求标志位

串行通信的中断请求:当一帧发送完成,内部硬件自动置位TI,即TI=1,请求中断处理;当接收完一帧信息时,内部硬件自动置位RI,即RI=1,请求中断处理

PCON

PCON只有高2位(B6、B7)是属于串口的

SMOD: 波特率选择位 SNOD0: 帧错误检测有效控制位

串行口工作模式1:8位UART,波特率可变

实验

  • P32和P33各接一个按键S3、S4。按下S3发送字符“1”到PC机,按下S4发送字符“2”到PC机的按键。-
  • PC机用串口助手软件将接收数据显示。
  • 晶振11.0592MHz,串行口用方式1,波特率9600bps
  • 接收PC发来的数据,在P1口上显示
  • 用LCD1602液晶屏显示接收到的数据

代码

 #include <reg52.h>
 ​
 ​
 sbit E   = P2^6;
 sbit RS = P2^4;
 sbit RW = P2^5;
 ​
 sbit S1 = P3^0;
 sbit S3 = P3^2;
 sbit S4 = P3^3;
 ​
 #define      LCD_Data           P0
 ​
 ​
 unsigned char flag1 = 1;
 unsigned int time0 = 0;
 unsigned int time1 = 0;
 ​
 unsigned char S1_flag0 = 1;
 unsigned char S1_flag1 = 1;
 ​
 unsigned char S3_flag0 = 1;
 unsigned char S3_flag1 = 1;
 ​
 unsigned char S4_flag0 = 1;
 unsigned char S4_flag1 = 1;
 ​
 unsigned char clean_flag0 = 0;
 unsigned char usart_send_flag1 = 0;
 unsigned char usart_send_flag2 = 0;
 ​
 unsigned char Addr = 1;
 ​
 unsigned char LCD_flag0 = 0;
 ​
 unsigned char Num = 1;
 ​
 ​
 ​
 void LCD_Delay(unsigned char time)
 {       
         while(time--)
         {
             unsigned char i = 0;
             for(i = 0; i<123;i++);
         }
 }
 ​
 void LCD_WriteCom(unsigned char com)
 {       
 ​
         RS = 0;
         RW = 0;
         LCD_Data = com;
         E = 1;
         LCD_Delay(1);
         E = 0;
         LCD_Delay(1);
 }
 ​
 ​
 void LCD_WriteData(unsigned char Data)
 {   
         RS = 1;
         RW = 0;
         LCD_Data = Data;
         E = 1;
         LCD_Delay(1);
         E = 0;
         LCD_Delay(1);
 }
 ​
 void LCD_Init(void)
 {
         LCD_WriteCom(0x38); //设置16x2显示,5x7点阵,8位数据接口
         LCD_WriteCom(0x0C); // 0000 1100
         LCD_WriteCom(0x06); //0000  0110
         LCD_WriteCom(0x01); //清除 复位
 ​
 }
 ​
 void LCD_SetCursor(unsigned Line, unsigned char Column)
 {
         if(Line == 1)
         {
             LCD_WriteCom(0x80|(Column - 1));
         }
         else
         {
             LCD_WriteCom(0x80|(Column) + 0x40);
         }
         
     
 }
 ​
 ​
 ​
 void LCD_ShowNum(unsigned char Line, unsigned char Column, unsigned char Num)
 {
         LCD_SetCursor(Line, Column);
         LCD_WriteData('0' + Num);
 ​
 }
 ​
 void Uart_SendByte(unsigned char Byte)
 {
         SBUF = Byte;
         while(TI == 0);
         TI = 1;
 ​
 }
 //11.0592Mhz
 void Uart_Init(void)
 {
         SCON = 0x50;        //8位数据,可变波特率   
         PCON &= 0x7F;   //不使能波特率倍速位
         TMOD &= 0x0F;   //清除定时器1模式
         TMOD |= 0x20; //设定定时器1为8位自动重装
         
         TL1 = 0xFD;     //设定定时初值
         TH1 = 0xFD;     //设定定时器重装值
         ET1 = 0;    //不需要进中断
         TR1 = 1;  //启动定时器1
     
         ES = 1; //串口中断
     
 }
 ​
 ​
 ​
             
 ​
 ​
 ​
 void Time_Init(void)
 {
         EA = 1;
         TMOD = 0x01;
         ET0 = 1;
         TR0 = 1;
         
         TH0 = 64535 / 256;
         TL0 = 64535 % 256;
 ​
 }
 ​
 ​
 ​
 void main(void)
  {
 ​
         LCD_Init();
         Time_Init();
         Uart_Init();
         
      
 ​
 ​
         while(1)
         {
             if(Addr == 17)
             {
                 
                 Addr = 0x41;                
             }
             
             if(usart_send_flag1 == 1)
             {
                     Uart_SendByte('1');
                     LCD_ShowNum(1, Addr++, 1);
                     usart_send_flag1 = 0;
             }
             
             if(usart_send_flag2 == 1)
             {
                     Uart_SendByte('2');
                     LCD_ShowNum(1, Addr++, 2);
                     usart_send_flag2 = 0;
             }
             
             if(LCD_flag0 == 1)
             {       
                     LCD_ShowNum(1, Addr++, Num - '0');
                     LCD_flag0 = 0;
             }
             
             if(clean_flag0 == 1)
             {       
                     Addr = 1;
                     LCD_WriteCom(0x01);
                     clean_flag0 = 0;
             }
     
         }
 ​
 ​
     
 }   
  
 ​
 ​
  
 void Time0_IT(void) interrupt 1
 {
     time0 ++;
     time1 ++;
     TH0 = 45535/256;
     TL0 = 45535%256;
     
     if(time0 == 25)
     {   
         if(flag1 == 0)
         {
             flag1 = 1;
         }
         else if(flag1 == 1)
         {
             flag1 = 0;
         }
         
         time0 =0;
     }
     
     if(time1 == 1)  //非阻塞按键扫描
     {
             S1_flag1 = S1_flag0;    //保存上一次的值
             S1_flag0 = S1;              //获取新的值
         
             S3_flag1 = S3_flag0;    //保存上一次的值
             S3_flag0 = S3;              //获取新的值
         
             S4_flag1 = S4_flag0;    //保存上一次的值
             S4_flag0 = S4;              //获取新的值
         
             if(S1_flag1 == 1 && S1_flag0 == 0)
             {
                     clean_flag0 = 1;
             }
             
             if(S3_flag1 == 1 && S3_flag0 == 0)
             {
                     usart_send_flag1 = 1;
             }
             
             if(S4_flag1 == 1 && S4_flag0 == 0)
             {
                     
                     usart_send_flag2 = 1;
             }
             
             time1 = 0;
     
     }
 ​
 ​
 }
 ​
 ​
 void Uart_Read() interrupt 4
 {
         if(RI == 1)
         {
 ​
                 Num = SBUF;
                 LCD_flag0 = 1;
                 RI = 0;
         }
 ​
 }
 ​

现象

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇