51 单片机串口通信
11.0592MHz
96009600
1.1.1.1./*/*/*/*打开串口调试程序,将波特率设置为 9600
11.0592MHz
9600,无奇偶校验晶振 11.0592MHz
11.0592MHz,发送和接收使用的格式相同,如都使
用字符型格式,在发送框输入 hellohellohellohello,IIII LoveLoveLoveLove MCUMCUMCUMCU ,在接收框中同样可以看到相同字符,说明设置和通信正确*/*/*/*/
#include
/*主程序*/
void main (void)
{
SCON = 0x50; /* SCON: 模式 1, 8-bit UART, 使能接收*/
TMOD = 0x20; /* TMOD: timer 1, mode 2,
8-bit reload*/
reload value for 9600 baud @ 11.0592MHz
*/
TH1 = 0xFD; /* TH1:
TL1=0XFD;
TR1 = 1; /* TR1:
EA = 1;
ES = 1;
while (1)
{
}
/*打开总中断*/
/*打开串口中断*/
timer 1 run
*/
/*主循环不做任何动作*/
}
void UART_SER (void) interrupt 4 //串行中断服务程序
{
unsigned char Temp;
//定义临时变量
if(RI)
{
RI=0;
Temp=SBUF;
P1=Temp;
SBUF=Temp;
//判断是接收中断产生
//标志位清零
//读入缓冲区的值
//把值输出到 P1 口,用于观察
//把接收到的值再发回电脑端
}
if(TI)
TI=0;
}
//如果是发送标志位,清零
2.2.2.2.51515151 单片机与电脑串口通信的 CCCC 程序,,,,最好是中断方式的
#include
#include
unsigned char ch;
bit read_flag= 0 ;
void init_serialcom( void ) //串口通信初始设定
{
SCON = 0x50 ; //UART 为模式 1,8 位数据,
允许接收
TMOD = 0x20 ; //定时器 1 为模式 2,8 位自动重装
PCON = 0x80 ; //SMOD=1;
TH1 = 0xFD ; //Baud:19200 fosc="11".0592MHz
TL1=0XFD;
IE = 0x90 ; //Enable Serial Interrupt
TR1 = 1 ; // timer 1 run
TI=1;
}
//向串口发送一个字符
void send_char_com( unsigned char ch)
{
}
SBUF=ch;
while (TI== 0);
TI= 0 ;
void serial () interrupt 4 using 3 //串口接收中断函数
{
RI = 0 ;
ch=SBUF;
read_flag= 1 ; //就置位取数标志
if (RI)
{
}
}
main()
{
init_serialcom(); //初始化串口
while ( 1 )
{
if (read_flag) //如果取数标志已置位,就将读到的数从串口发出
{
}
read_flag= 0 ; //取数标志清 0
send_char_com(ch);
}
}
3.3.3.3.//////// 单片机串行口发送////接收程序,每接收到字节即发送出去
//////// 和微机相接后键入的字符回显示在屏幕上
//////// 可用此程序测试
#include
#define XTAL 11059200
#define baudrate 9600
void main(void)
{
// CUP 晶振频率
// 通信波特率
unsigned char c;
TMOD = 0x20; // 定时器 1 工作于 8 位自动重载模式, 用于产生波特率
TH1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate)));
// 定时器 0 赋初值
TL1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate)));
SCON = 0x50;
PCON = 0x00;
TR1 = 1;
IE = 0x00; // 禁止任何中断
while(1)
{
while(RI == 0);
RI = 0;
c = SBUF;
SBUF = c;
while(TI == 0);
TI = 0;
// 从缓冲区中把接收的字符放入 c 中
// 要发送的字符放入缓冲区
}
}
////////////////
4.4.4.4.////////////////
/////////////////////////////////////////////////////////
////////////////
/////////////////////////////////////////////////////////
//////////////// /////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
//E51Pro.c
//E51Pro.c
//E51Pro.c
//E51Pro.c
51Pro
//Easy
//Easy
51Pro
//Easy 51Pro
//Easy
51Pro 编程器主程序,负责通讯,管理编程操作
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
#include
BYTE ComBuf[18];//串口通讯数据缓存,发送和接收都使用
UINT nAddress;//ROM 中地址计数
UINT nTimeOut;//超时计数
ProWork pw;//编程器一般操作
void Delay_us(BYTE nUs)//微秒级延时<255us
{
TH0=0;
TL0=0;
TR0=1;
while(TL0}
n++;
}
TR0=0;
}
{
BOOL WaitComm()//等待上位机的命令,18 字节
BYTE n=0;
RI=0;
while(!RI){}//等待第一个字节
ComBuf[n]=SBUF;
RI=0;
n++;
for(n;n<=17;n++)
{
nTimeOut=0;
while(!RI)
{
nTimeOut++;
if(nTimeOut>10000)//后 17 个字节都有超时限制
return 0;
}
ComBuf[n]=SBUF;
RI=0;
}
return 1;
}
BOOL WaitResp()//等待上位机回应,1 字节,有超时限制
{
nTimeOut=0;
RI=0;
while(!RI)
{
nTimeOut++;
if(nTimeOut>50000)
{
return 0;
}
}
RI=0;
ComBuf[0]=SBUF;
return 1;
}
BOOL WaitData()//写器件时等待上位机数据,18 字节,有超时限制
{
BYTE n;
RI=0;
for(n=0;n<=17;n++)
{
nTimeOut=0;
while(!RI)
{
nTimeOut++;
if(nTimeOut>10000)
{
return 0;
}
}
RI=0;
ComBuf[n]=SBUF;
}
return 1;
}
void SendData()//发送数据或回应操作完成,18 字节
{
BYTE n=0;
for(n;n<=17;n++)
{
TI=0;
SBUF=ComBuf[n];
while(!TI){}
TI=0;
}
}
void SendResp()//回应上位机 1 个字节,在写器件函数中使用
{
TI=0;
SBUF=ComBuf[0];
while(!TI){}
TI=0;
}
void SetVpp5V()//设置 Vpp 为 5v
{
P3_4=0;
P3_3=0;
}
void SetVpp0V()//设置 Vpp 为 0v
{
P3_3=0;
P3_4=1;
}
void SetVpp12V()//设置 Vpp 为 12v
{
P3_4=0;
P3_3=1;
}
void RstPro()//编程器复位
{
pw.fpProOver();//直接编程结束
SendData();//通知上位机,表示编程器就绪,可以直接用此函数因为协议号(ComBuf[0])还没被修改,下同
}
void ReadSign()//读特征字
{
pw.fpReadSign();
SendData();//通知上位机,送出读出器件特征字
}
void Erase()//擦除器件
{
pw.fpErase();
SendData();//通知上位机,擦除了器件
}
void Write()//写器件
{
BYTE n;
pw.fpInitPro();//编程前的准备工作
SendData();//回应上位机表示进入写器件状态,
可以发来数据
while(1)
{
if(WaitData())//如果等待数据成功
{
if(ComBuf[0]==0x07)//判断是否继续写
{
for(n=2;n<=17;n++)//ComBuf[2~17]为待写入数据块
{
if(!pw.fpWrite(ComBuf[n]))//<<< <<<<<<调用写该器件一个单元的函数
{
pw.fpProOver();//出错了就结束编程
ComBuf[0]=0xff;
SendResp();//回应上位机一个字节,
表示写数据出错了
WaitData();//等待上位机的回应后就结束
return;
}
nAddress++;//下一个单元
}
ComBuf[0]=1;//回应上位机一个字节,表示数据块顺利完成,请求继续
SendResp();
}
else if(ComBuf[0]==0x00)//写器件结束
break;
else//可能是通讯出错了
{
pw.fpProOver();
return;
}
}
else//等待数据失败
{
pw.fpProOver();
return;
}
}
pw.fpProOver();//编程结束后的工作
Delay_ms(50);//延时等待上位机写线程结束
ComBuf[0]=0;//通知上位机编程器进入就绪状态
SendData();
}
void Read()//读器件
{
BYTE n;
pw.fpInitPro();//先设置成编程状态
SendData();//回应上位机表示进入读状态
while(1)
{
if(WaitResp())//等待上位机回应 1 个字节
{
if(ComBuf[0]==0)//ComBuf[0]==0 表示读结束
{
break;
}
else if(ComBuf[0]==0xff)//0xff 表示重发
{
nAddress=nAddress-0x0010;
}
for(n=2;n<=17;n++)//ComBuf[2~17]保存读出的数据块
{
ComBuf[n]=pw.fpRead();//<<<<<<<<<<调用写该器件一个单元的函数
nAddress++;//下一个单元
}
ComBuf[0]=6;//向上位机发送读出的数据块
SendData();
}
else
break;//等待回应失败
}
pw.fpProOver();//操作结束设置为运行状态
ComBuf[0]=0;//通知上位机编程器进入就绪状态
SendData();
}
void Lock()//写锁定位
{
pw.fpLock();
SendData();
}
/////////////////////////////////////////////////////////////////////////////////
//所支持的 FID,请在这里继续添加
/////////////////////////////////////////////////////////////////////////////
extern void PreparePro00();//FID=00:AT89C51 编程器
extern void PreparePro01();//FID=01:AT89C2051 编程器
extern void PreparePro02();//FID=02:AT89S51 编程器
void main()
{
SP=0x60;
SetVpp5V();//先初始化 Vpp 为 5v
SCON=0x00;
TCON=0x00;
//PCON=0x00;//波特率*2
IE=0x00;
//TMOD: GATE|C/!T|M1|M0|GATE|C/!T|M1|M0
//
0
TMOD=0x21;//T0 用于延时程序
TH1=0xff;
TL1=0xff;//波特率 28800*2,注意 PCON
//SCON: SM0|SM1|SM2|REN|TB8|RB8|TI|RI
0 0 0
1 0
0 1
1
0
0
0
0
//
0
1
0
SCON=0x50;
TR1=1;
Delay_ms(1000);//延时 1 秒后编程器自举
ComBuf[0]=0;
SendData();
while(1)//串口通讯采用查询方式
{
if(!WaitComm())//如果超时,通讯出错
{
Delay_ms(500);