我们采用串行口1编程,主要用到的特殊功能寄存器有:数据缓冲寄存器SBUF、串行口1方式控制寄存器SCON、辅助寄存器AUXR等
两个补充链接;
C51中的介绍/qq_34629988/article/details/53225293.
51单片机 XBYTE说明/shenhuxi_yu/article/details/54344362.
/*******************************************************************************
- 文件名称:串口通讯实验
- 实验目的:
- 1.掌握51单片机串口工作模式及相关寄存器配置方法
2.了解51单片机波特率的计算方法 - 程序说明:
1.通过USB连接线连接PC机,在计算机硬件管理器中查看串口号
2.打开串口调试工具软件,并将串口通讯波特率设定为2400 - 硬件说明:IAP15F2K61S2@11.0592MHz
- 日期版本:2019-2-12/qingyu
说明因为延时程序有_nop_();函数,代表一个机器周期,所以用到了定时器,需要进行相关的配置,同时用到了串行口1的中断标志位TI,注意辅助特殊功能寄存器AUXR,能够选择定时器的工作模式(1T和12T,这是和普通八位的区别,复位及默认情况下为12T模式,与普通相同),SBUF为串口的发送与接收数据缓冲器。
*******************************************************************************/
#include ""
#include ""
#include ""
#define BAUD 2400 //波特率
#define SYSTEMCLOCK 11059200L //系统时钟频率
sfr AUXR = 0x8e;
void uart_sendstring(unsigned char *str);
void delay() //延时函数
{
unsigned char i, j, k;
_nop_();//代表一个机器周期
_nop_();
i = 43;
j = 6;
k = 203;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
//主函数
void main(void)
{
SCON = 0x50; // 串行口1的方式控制寄存器sm0,SM1为工作方式选择位,先择了方式1REN允许接收位,为1有效 ;
AUXR = 0x40; //1T选择定时器1的1T模式
TMOD = 0x00; // 采用系统时钟作为计数脉冲
TL1 = (65536 - (SYSTEMCLOCK/4/BAUD)); //设置定时初值与终值,为固定模板
TH1 = (65536 - (SYSTEMCLOCK/4/BAUD))>>8;
TR1 = 1; //运行控制位 启动定时器1
while(1){
uart_sendstring("hello,world.\r\n"); //串口发送函数
delay();
}
}
//通过串口发送字符串
void uart_sendstring(unsigned char *str) //指针变量
{
unsigned char *p;
p = str;
while(*p != '\0')
{
SBUF = *p; //用作串口1的发送和接受数据缓存器
while(TI == 0); //等待发送标志位置位,TI为串口1的中断标志
TI = 0;
p++;
}
}
/*******************************************************************************
- 文件名称:串口通讯实验
- 实验目的:
- 1.掌握51单片机串口工作模式及相关寄存器配置方法
2.了解51单片机波特率的计算方法
3.掌握单片机串口接收中断服务函数的设计方法
程序说明:
1.通过USB连接线连接PC机,在计算机硬件管理器中查看串口号
2.打开串口调试工具软件,并将串口通讯波特率设定为2400
3.将跳线J13配置为IO模式
4.输入1-8字符,控制8个LED指示灯状态 - 硬件说明:IAP15F2K61S2 @11.0592MHz
- 日期版本:2019-2-12/qingyu
进行串行口1的相关寄存器配置,定时器1的配置,打开串行口中断和总中断 。我们需要定义一个串口的终端服务函数,若PC向单片机发送其他数据时,我们需要它进行向我们发送一段数据表示它受到,因此我们需要定义一个串行口发送数据的函数。最后是构建PC发送不同的数据,单片机会接受并执行对应操作的函数
*******************************************************************************/
#include "" //定义51单片机特殊功能寄存器
#include ""
#define BAUD 2400 //波特率
#define SYSTEMCLOCK 11059200L //系统时钟频率
sfr AUXR = 0x8e;
bit rxc = 0;
char rx = '1';
void uart_sendstring(unsigned char *str);
void interrupt_scan();
//主函数
void main(void)
{
SCON = 0x50; //串行口1选取工作方式1
AUXR = 0x40; //特殊功能寄存器配置成1T模式
TMOD = 0x00; //采用系统时钟作为计数脉冲
TL1 = (65536 - (SYSTEMCLOCK/4/BAUD)); //
TH1 = (65536 - (SYSTEMCLOCK/4/BAUD))>>8;
TR1 = 1; //TMOD中的GATE位为0时,打开TR1即可采用定时器1 计数
ES = 1;//打开串行口1 的中断允许位
EA = 1; //打开总中断
while(1)
{
interrupt_scan();
}
}
//构建PC发送不同的数据,单片机会接受并执行对应操作的函数
void interrupt_scan()
{
if(rxc == 1)
{
rxc = 0;
switch(rx)
{
case '1':
P2=0X80;P0=0XFE;
break;
case '2':
P2=0X80;P0=0xFD;
break;
case '3':
P2=0X80;P0=0xFB;
break;
case '4':
P2=0X80;P0=0xF7;
break;
case '5':
P2=0X80;P0=0xEF;
break;
case '6':
P2=0X80;P0=0xDF;
break;
case '7':
P2=0X80;P0=0xBF;
break;
case '8':
P2=0X80;P0=0x7F;
break;
default:
uart_sendstring("error\r\n"); //输入其他数据返回error
break;
}
ES = 1;//再次打开串行口1的中断允许位
}
}
//串口中断服务函数
void isr_uart(void) interrupt 4
{
if(RI)
{
RI = 0; //清除接收中断标志位 除方式0的其他方式下(本程序在SCON中设置SM0,SM1为01,为方式1)
//接受到停止位置1,向CPU发起中断,中断结束后必须由软件置0!!)
rx = SBUF;//将数据缓存器的数据给rx
ES = 0;//关闭串行口1的中断允许位
rxc = 1;
}
}
//通过串口发送字符串
void uart_sendstring(unsigned char *str)
{
unsigned char *p;
p = str;
while(*p != '\0')
{
SBUF = *p;
while(TI == 0); //等待发送标志位置位
TI = 0;
p++;
}
}
也可采用寄存器编程,将void interrupt_scan()函数修改,同时将开发板的J13接到MM即可
void interrupt_scan()
{
if(rxc == 1)
{
rxc = 0;
switch(rx)
{
case '1':
XBYTE[0x8000] = 0xFE;
break;
case '2':
XBYTE[0x8000] = 0xFD;
break;
case '3':
XBYTE[0x8000] = 0xFB;
break;
case '4':
XBYTE[0x8000] = 0xF7;
break;
case '5':
XBYTE[0x8000] = 0xEF;
break;
case '6':
XBYTE[0x8000] = 0xDF;
break;
case '7':
XBYTE[0x8000] = 0xBF;
break;
case '8':
XBYTE[0x8000] = 0x7F;
break;
default:
uart_sendstring("error\r\n"); //输入其他数据返回error
break;
}
ES = 1;//再次打开串行口1的中断允许位
}
}