利用串口实现单片机与PC超级终端通信
#include"SST89x5x4.H"unsignedcharByte;//接收到字节bitread_flag=0;//接收完毕标志位voidUART_Init(){...
#include "SST89x5x4.H"
unsigned char Byte; //接收到字节
bit read_flag= 0 ; //接收完毕标志位
void UART_Init()
{
char temp=0;
EA=0; //全局中断禁止
SCON = 0x50; //S0MODE=1 工作方式1 波特率可编程的8位UART
//(SCON第4位)REN =1 UART0 接收允许
temp=TMOD;
TMOD=temp|0x20; //定时器1工作方式2
PCON = 0x80;
TL1=0xfa; //计数初值 256-2*1*11059200/(9600*64*12)=0xfd
TH1=0xfa; //保存计数初值 256-2*1*11059200/(9600*64*12)=0xfd
TR1=1; //开始计数
ES=1; //串行中断允许
EA=1; //全局中断开启
}
void sendbyte(unsigned char sendByte)
{
SBUF=sendByte;
ES=0; //禁止串行中断
while(TI==0); //等待发送完毕
TI=0; //清发送中断标志TI0
ES=1; //允许串行中断
}
void UART0_Interrupt (void) interrupt 4
{
if (RI==1)
{
RI=0; // 清接收中断标志RI0
Byte=SBUF; // 从串口接收一个字符
read_flag=1; // 接收完毕标志位
}
}
函数名称:主函数
函数功能:串口接收字符,回显
void main()
{
UART_Init();//串口初始化
while(1)
{
if(read_flag==1)
{
read_flag=0; //清零接受标志
sendbyte(Byte);
}
}
}
通信是可以 但是在回显示的时候会出错 最终目的是实现字符串的通信与识别 就是 PC传一个字符串命令给单片机 单片机可以识别 并回应 字符串 最好有现成的程序 我现在这个只能穿一个字节 而且还出错 谢谢大家了 展开
unsigned char Byte; //接收到字节
bit read_flag= 0 ; //接收完毕标志位
void UART_Init()
{
char temp=0;
EA=0; //全局中断禁止
SCON = 0x50; //S0MODE=1 工作方式1 波特率可编程的8位UART
//(SCON第4位)REN =1 UART0 接收允许
temp=TMOD;
TMOD=temp|0x20; //定时器1工作方式2
PCON = 0x80;
TL1=0xfa; //计数初值 256-2*1*11059200/(9600*64*12)=0xfd
TH1=0xfa; //保存计数初值 256-2*1*11059200/(9600*64*12)=0xfd
TR1=1; //开始计数
ES=1; //串行中断允许
EA=1; //全局中断开启
}
void sendbyte(unsigned char sendByte)
{
SBUF=sendByte;
ES=0; //禁止串行中断
while(TI==0); //等待发送完毕
TI=0; //清发送中断标志TI0
ES=1; //允许串行中断
}
void UART0_Interrupt (void) interrupt 4
{
if (RI==1)
{
RI=0; // 清接收中断标志RI0
Byte=SBUF; // 从串口接收一个字符
read_flag=1; // 接收完毕标志位
}
}
函数名称:主函数
函数功能:串口接收字符,回显
void main()
{
UART_Init();//串口初始化
while(1)
{
if(read_flag==1)
{
read_flag=0; //清零接受标志
sendbyte(Byte);
}
}
}
通信是可以 但是在回显示的时候会出错 最终目的是实现字符串的通信与识别 就是 PC传一个字符串命令给单片机 单片机可以识别 并回应 字符串 最好有现成的程序 我现在这个只能穿一个字节 而且还出错 谢谢大家了 展开
4个回答
展开全部
标准串口参考程序如下:(来源周立功单片机公司)具有一般参考意义。
#include<reg51.h>
unsigned char UART_RX; //定义串口接收数据变量
unsigned char RX_flag; //定义穿行接收标记
/*********************************************************************************************
函数名:UART串口初始化函数
调 用:UART_init();
参 数:无
返回值:无
结 果:启动UART串口接收中断,允许串口接收,启动T/C1产生波特率(占用)
备 注:振荡晶体为12MHz,PC串口端设置 [ 4800,8,无,1,无 ]
/**********************************************************************************************/
void UART_init (void){
EA = 1; //允许总中断(如不使用中断,可用//屏蔽)
ES = 1; //允许UART串口的中断
TMOD = 0x20; //定时器T/C1工作方式2
SCON = 0x50; //串口工作方式1,允许串口接收(SCON = 0x40 时禁止串口接收)
TH1 = 0xF3; //定时器初值高8位设置
TL1 = 0xF3; //定时器初值低8位设置
PCON = 0x80; //波特率倍频(屏蔽本句波特率为2400)
TR1 = 1; //定时器启动
}
/**********************************************************************************************/
/*********************************************************************************************
函数名:UART串口接收中断处理函数
调 用:[SBUF收到数据后中断处理]
参 数:无
返回值:无
结 果:UART串口接收到数据时产生中断,用户对数据进行处理(并发送回去)
备 注:过长的处理程序会影响后面数据的接收
/**********************************************************************************************/
void UART_R (void) interrupt 4 using 1{ //切换寄存器组到1
RI = 0; //令接收中断标志位为0(软件清零)
UART_RX = SBUF; //将接收到的数据送入变量 UART_data
RX_flag=1; //标记接收
//用户函数内容(用户可使用UART_data做数据处理)
//SBUF = UART_data; //将接收的数据发送回去(删除//即生效)
//while(TI == 0); //检查发送中断标志位
//TI = 0; //令发送中断标志位为0(软件清零)
}
/**********************************************************************************************/
/*********************************************************************************************
函数名:UART串口发送函数
调 用:UART_T (?);
参 数:需要UART串口发送的数据(8位/1字节)
返回值:无
结 果:将参数中的数据发送给UART串口,确认发送完成后退出,采用非中断方式
备 注:
/**********************************************************************************************/
void UART_T (unsigned char UART_data){ //定义串口发送数据变量
ES=0; //禁止穿行中断
SBUF = UART_data; //将接收的数据发送回去
while(TI == 0); //检查发送中断标志位
TI = 0; //令发送中断标志位为0(软件清零)
ES=1; //打开穿行中断
}
/*********************************************************************************************
函数名:UART串口发送字符串函数
调 用:UART_S (?);
参 数:需要UART串口发送的数据(8位/1字节)
返回值:无
结 果:将参数中的数据发送给UART串口,确认发送完成后退出,采用非中断方式
备 注:
/**********************************************************************************************/
void UART_S(unsigned char *str)
{
while(1)
{
if(*str=='\0') break;
UART_T(*str++);
}
}
/*********************************************************************************************
函数名:主函数
调 用:main();
参 数:
返回值:无
结 果:
备 注:
/**********************************************************************************************/
void main()
{
unsigned char Buf_data[]={" welcome to MCU world. \n\r"};
UART_init();
UART_S(Buf_data);
while(1){
if(RX_flag==1)
{
UART_T(UART_RX);
RX_flag=0;
}
}
}
///////////////////////////////////////////////////////////////////
个人认为普通单片机在通信频率上及不上AVR单片机,更可能使用USB转串口工具进行开发,所以串口波特率不能过高,最好是2400或4800。过高只会导致乱码或丢失。而楼主的中断服务程序也不正确,设计缺乏经验,所以需要继续努力。
#include<reg51.h>
unsigned char UART_RX; //定义串口接收数据变量
unsigned char RX_flag; //定义穿行接收标记
/*********************************************************************************************
函数名:UART串口初始化函数
调 用:UART_init();
参 数:无
返回值:无
结 果:启动UART串口接收中断,允许串口接收,启动T/C1产生波特率(占用)
备 注:振荡晶体为12MHz,PC串口端设置 [ 4800,8,无,1,无 ]
/**********************************************************************************************/
void UART_init (void){
EA = 1; //允许总中断(如不使用中断,可用//屏蔽)
ES = 1; //允许UART串口的中断
TMOD = 0x20; //定时器T/C1工作方式2
SCON = 0x50; //串口工作方式1,允许串口接收(SCON = 0x40 时禁止串口接收)
TH1 = 0xF3; //定时器初值高8位设置
TL1 = 0xF3; //定时器初值低8位设置
PCON = 0x80; //波特率倍频(屏蔽本句波特率为2400)
TR1 = 1; //定时器启动
}
/**********************************************************************************************/
/*********************************************************************************************
函数名:UART串口接收中断处理函数
调 用:[SBUF收到数据后中断处理]
参 数:无
返回值:无
结 果:UART串口接收到数据时产生中断,用户对数据进行处理(并发送回去)
备 注:过长的处理程序会影响后面数据的接收
/**********************************************************************************************/
void UART_R (void) interrupt 4 using 1{ //切换寄存器组到1
RI = 0; //令接收中断标志位为0(软件清零)
UART_RX = SBUF; //将接收到的数据送入变量 UART_data
RX_flag=1; //标记接收
//用户函数内容(用户可使用UART_data做数据处理)
//SBUF = UART_data; //将接收的数据发送回去(删除//即生效)
//while(TI == 0); //检查发送中断标志位
//TI = 0; //令发送中断标志位为0(软件清零)
}
/**********************************************************************************************/
/*********************************************************************************************
函数名:UART串口发送函数
调 用:UART_T (?);
参 数:需要UART串口发送的数据(8位/1字节)
返回值:无
结 果:将参数中的数据发送给UART串口,确认发送完成后退出,采用非中断方式
备 注:
/**********************************************************************************************/
void UART_T (unsigned char UART_data){ //定义串口发送数据变量
ES=0; //禁止穿行中断
SBUF = UART_data; //将接收的数据发送回去
while(TI == 0); //检查发送中断标志位
TI = 0; //令发送中断标志位为0(软件清零)
ES=1; //打开穿行中断
}
/*********************************************************************************************
函数名:UART串口发送字符串函数
调 用:UART_S (?);
参 数:需要UART串口发送的数据(8位/1字节)
返回值:无
结 果:将参数中的数据发送给UART串口,确认发送完成后退出,采用非中断方式
备 注:
/**********************************************************************************************/
void UART_S(unsigned char *str)
{
while(1)
{
if(*str=='\0') break;
UART_T(*str++);
}
}
/*********************************************************************************************
函数名:主函数
调 用:main();
参 数:
返回值:无
结 果:
备 注:
/**********************************************************************************************/
void main()
{
unsigned char Buf_data[]={" welcome to MCU world. \n\r"};
UART_init();
UART_S(Buf_data);
while(1){
if(RX_flag==1)
{
UART_T(UART_RX);
RX_flag=0;
}
}
}
///////////////////////////////////////////////////////////////////
个人认为普通单片机在通信频率上及不上AVR单片机,更可能使用USB转串口工具进行开发,所以串口波特率不能过高,最好是2400或4800。过高只会导致乱码或丢失。而楼主的中断服务程序也不正确,设计缺乏经验,所以需要继续努力。
展开全部
你的SMOD位是为1的,也就是你设置的波特率是9600,但是你串口调试助手的波特率设置为4800的,这个可能是问题之一,修改方法,改串口的波特率,或者将定时器的初值设为0xF4,两者择一,如果再不行那就不知问题的原因了
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
考虑到上位发送字符是连续的,在发送时要打开中断,
防止在发送数据时造成接收错位或掉位,需要在中断函数内增加发送中断。
如:
void UART0_Interrupt (void) interrupt 4
{
if (RI==1)
{
RI=0; // 清接收中断标志RI0
Byte=SBUF; // 从串口接收一个字符
SBUF=Byte;//增加
read_flag=1; // 接收完毕标志位
}
else
TI=0;//清发送完成标志
}
防止在发送数据时造成接收错位或掉位,需要在中断函数内增加发送中断。
如:
void UART0_Interrupt (void) interrupt 4
{
if (RI==1)
{
RI=0; // 清接收中断标志RI0
Byte=SBUF; // 从串口接收一个字符
SBUF=Byte;//增加
read_flag=1; // 接收完毕标志位
}
else
TI=0;//清发送完成标志
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
波特率????
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询