PC与51单片机串口通信Word格式.docx
《PC与51单片机串口通信Word格式.docx》由会员分享,可在线阅读,更多相关《PC与51单片机串口通信Word格式.docx(11页珍藏版)》请在冰豆网上搜索。
串行口工作方式为方式1(10位异步收发),波特率为9600bps,用定时器1作波特率发生器,选用定时器模式2,其它详见程序及说明。
(3)程序功能说明
通过串口调试助手,向单片机发送字符,发送字符的末尾需加“!
”,让单片机识别数据接收完毕,返回“Waitcommand!
”字符串。
当单片机接收一个字符时,发光二极管端引脚取反一次,所以其亮、灭的状态改变一次。
例如:
初始状态为灭。
当发送“12!
”时,取反三次,发光二极管变亮,返回“Waitcommand!
”字符串(如图
(1)所示);
当发送“123!
”时,取反四次,发光二极管状态不变,但返回“Waitcommand!
”字符串(如图
(2)所示)。
图
(1)a图
(1)b
图
(2)a图
(2)
b
(4)单片机内运行的程序
#includereg51.h
sbitP1_2=P1^2;
//接发光二极管
bitflag;
//单片机数据发送标志位bitflag_inter;
//单片机数据接收完标志位unsignedchara;
voidSendData(chardat);
//发送字符voidSendString(char*s);
//发送字符串
voidmain(){
SCON=0x50;
//串行通信方式1,接收允许PCON=0x00;
//单倍频
TMOD=0x20;
//设置定时器T1为模式2,定时方式TH1=TL1=0xFD;
//波特率为9600,晶振11.0594MHzTR1=1;
//定时器T1开始计数EA=1;
//中断允许
ES=1;
//串行口中断开放
while
(1){if(flag_inter==1){flag_inter=0;
//标志位清0SendString(“Waitcommand!
\n"
);
}}}
//串口接收发送中断
voidUart_Isr()interrupt4using1{
if(RI){
RI=0;
//接收中断标志a=SBUF;
P1_2=!
P1_2;
//数据送到P0口if(a=='
!
'
){
flag_inter=1;
//数据接收完毕,置1}}if(TI){
TI=0;
//发送中断标志flag=0;
//标志位清0}}
//向串口发送字符
voidSendData(chardat){
while(flag);
ACC=dat;
flag=1;
SBUF=ACC;
}
//向串口发送字符串voidSendString(char*s){
while(*s){
SendData(*s++);
}}//等待数据发送//标志位置1//数据装入SBUF//字符串发送完否//发送字符,并指针指向下一字符
2、利用串口调试助手实现串行口数据收发
本程序可以实现PC机与单片机之间数据双向传输、互发
(注:
由*****1电路板原理图可知CH452数码管驱动及键盘控制芯片为四线接口,CH452_DCLK=P1^7,CH452_DIN=P1^6,CH452_LOAD=P1^5,CH452_DOUT=P3^3。
)
*****2RC
MCUFirmwareVersion:
24.0*****M.外部时钟频率:
24.0*****M.
串行口工作方式为方式1(10位异步收发),波特率为4800bps,用定时器1作波特率发生器,选用定时器模式2,其它详见程序及说明。
”,让单片机识别数据接收完毕。
当单片机接收到PC机发来的数据时,先存入数组,当检测到结束标志“!
”时,调用显示函数,从左至右,两个LED数码管表示一位字符的ASCII码(注:
为了显示出特殊字符,所以用ASCII码表示)。
一次最多只能表示四个字符,当超过四个时,延时一段时间,再显示下面的字符。
数码管显示结束后,返回“Waitcommand!
当按下按键时,将按键对应的键值返回给PC机。
当在串口调试助手中发送“a=1,b=3,ba!
”时,数码管将依次显示对应的十六进制ASCII码如下:
61H(a)、3dH(=)、31H
(1)、2cH(,)、62H(b)、3dH(=)、33H(3)、2cH(,)、62H(b)、3EH()、61H(a)、21H(!
),具体见图(3)。
当从左至右,从上到下依次按下键盘上的三行按键时,返回键值到PC机,具体见图(4)。
图(3)a图(3)b
图(3)c图(3)d
图(4)a图(4)b
主程序如下:
#includereg51.h#includeintrins.h
#include*****D.h#includepin.h
//标志位
bitflag_inter;
//PC机发送信息结束标志位
unsignedcharm=0;
//数组testdata[a]
unsignedchartestdata={0};
//存放PC机发送到单片机的信息
//输出命令子程序,定义一无符号整型变量存储12字节的命令字。
voidCH452_Write(unsignedintcmd){unsignedchari;
#ifdefUSE_KEY*****_*****PT;
//禁止键盘中断,防止传输过程中被CH452中断
//进入中断服务程序中再次传输
#endifCH452_LOAD_CLR;
//命令开始,LOAD=0for(i=0;
i!
=12;
i++)//送入12位数据,低位在前{if(cmd1){CH452_DIN_SET;
}else{CH452_DIN_CLR;
}//输出位数据CH452_DCLK_CLR;
cmd=1;
CH452_DCLK_SET;
//上升沿有效}
CH452_LOAD_SET;
//加载数据,LOAD上升沿DELAY_1US;
//命令数据加载周期不小于6USDELAY_1US;
DELAY_1US;
#ifdefUSE_KEY
ENABLE_*****PT;
#endif}
//输入命令子程序,MCU从CH452读一个字节unsignedcharCH452_Read(){unsignedchari;
unsignedcharcmd,keycode;
//定义命令字,和数据存储器#ifdefUSE_KEY
*****_*****PT;
#endif
cmd=0x07;
//输入读451命令字CH452_LOAD_CLR;
for(i=0;
=4;
i++){if(cmd1){CH452_DIN_SET;
//往右移一位CH452_DCLK_SET;
//产生时钟上升沿锁通知CH451输入位数据}
//产生加载上升沿通知CH451处理命令数据keycode=0;
//清除keycodefor(i=0;
=7;
i++){keycode=1;
//数据移入keycode,高位在前,低位在后keycode|=CH452_DOUT;
//从高到低读入451的数据CH452_DCLK_CLR;
//产生时钟下升沿通知CH451输出下一位CH452_DCLK_SET;
CLEAR_INTER_FLAG;
//清中断标志#ifdefUSE_KEY
return(keycode);
//反回键值}
//延时函数
voiddelayms(unsignedchari){unsignedintj;
do{for(j=0;
j!
=1000;
j++){;
}}while(--i);
//串行通信初始设置子函数voidinit(void){
//设置定时器T1为模式2,定时方式TH1=TL1=0xf3;
//波特率为4800,晶振24MHzTR1=1;
//串行口中断开放}
//LED显示函数voidDisplay(void){
unsignedcharn=0;
unsignedcharp;
unsignedchartestdata1;
unsignedchartestdata2;
unsignedchartestdata3;
unsignedchartestdata4;
unsignedchartestdata5;
unsignedchartestdata6;
unsignedchartestdata7;
unsignedchartestdata8;
CH452_Write(CH452_SYSON2);
//两线制方式,如果SDA用做按键中断输出,
//那么命令应该为(0x04,0x23)
CH452_Write(CH452_BCD);
//BCD译码,8个数码管
while((4*n)(m+1)){testdata1=testdata[0+4*n]%16;
testdata2=testdata[0+4*n]/16;
testdata3=testdata[1+4*n]%16;
testdata4=testdata[1+4*n]/16;
testdata5=testdata[2+4*n]%16;
testdata6=testdata[2+4*n]/16;
testdata7=testdata[3+4*n]%16;
testdata8=testdata[3+4*n]/16;
CH452_Write(CH452_DIG0|testdata7);
//显示接收字符的ASCII码CH452_Write(CH452_DIG1|testdata8);
CH452_Write(CH452_DIG2|testdata5);
CH452_Write(CH452_DIG3|testdata6);
CH452_Write(CH452_DIG4|testdata3);
CH452_Write(CH452_DIG5|testdata4);
CH452_Write(CH452_DIG6|testdata1);
CH452_Write(CH452_DIG7|testdata2);
delayms(1000);
n++;
for(p=0;
pp++){testdata[p]=0;
}m=0;
if(RI){RI=0;
testdata[m]=SBUF;
if(testdata[m]=='
){Display();
}else{m++;
}}if(TI)
//延时//数组清零//接收中断标志
{
//标志位清零}}
voidSendData(chardata0){
ACC=data0;
}}
//INT1中断服务程序
voidint1()interrupt2//using1{
SBUF=CH452_Read();
while(!
TI);
voidmain(){delayms(10);
init();
//等待数据发送//标志位置1//数据装入SBUF//字符串发送完否//发送字符,并指针指向下一字符//将按键值通过串口发给PC机检查//延时//串口初始化函数
//设置CH452按键中断
IE1=0;
//外部中断1中断请求标志EX1=1;
//外部中断1中断允许while
(1){if(flag_inter==1){flag_inter=0;
SendString("
Waitcommand!
附外加头文件:
(1)*****D.h
#defineCH452_NOP0x0000#defineCH452_RESET0x0201#defineCH452_LEVEL0x0100#defineCH452_CLR_BIT0x0180#defineCH452_SET_BIT0x01C0#defineCH452_SLEEP0x0202#defineCH452_*****0x0300#defineCH452_*****0x0301#defineCH452_*****V0x0302#defineCH452_*****C0x0303#defineCH452_SELF_BCD0x0380#defineCH452_SYSOFF0x0400#defineCH452_SYSON10x0401#defineCH452_SYSON20x0403#defineCH452_*****0x0423#defineCH452_DSP0x0500#defineCH452_BCD0x0580#defineCH452_*****0x0600#defineCH452_GET_KEY0x0700#defineCH452_DIG00x0800#defineCH452_DIG10x0900#defineCH452_DIG20x0a00#defineCH452_DIG30x0b00#defineCH452_DIG40x0c00#defineCH452_DIG50x0d00#defineCH452_DIG60x0e00#defineCH452_DIG70x0f00
//空操作//复位//加载光柱值//段位清0//段位置1//进入睡眠状态//设置移动方式-左移//设置移动方式-左循//设置移动方式-右移//设置移动方式-右循//自定义BCD码//关显示、键盘//开显示//开显示、键盘//开显示、键盘,真正2线接口//设置默认显示方式//设置BCD译码方式//设置闪烁控制//获取按键//数码管位0显示//数码管位1显示//数码管位2显示//数码管位3显示//数码管位4显示//数码管位5显示//数码管位6显示//数码管位7显示
(2)pin.h
/*延时1uS子程序,主要用于2线接口,与单片机速度有关*/#defineDELAY_1US{_nop_();
_nop_();
}//MCS51=30MHz
/*4线接口的连接,与实际电路有关*/
sbitCH452_DCLK=P1^7;
//串行数据时钟上升延激活sbitCH452_DIN=P1^6;
//串行数据输出,接CH452的数据输入sbitCH452_LOAD=P1^5;
//串行命令加载,上升延激活
sbitCH452_DOUT=P3^3;
//INT1,键盘中断和键值输入,接CH452的数据输出
/*4线接口的位操作,与单片机有关*/#defineCH452_DCLK_SET{CH452_DCLK=1;
}#defineCH452_DCLK_CLR{CH452_DCLK=0;
}#defineCH452_DIN_SET{CH452_DIN=1;
}#defineCH452_DIN_CLR{CH452_DIN=0;
}#defineCH452_LOAD_SET{CH452_LOAD=1;
}#defineCH452_LOAD_CLR{CH452_LOAD=0;
}
/*与单片机有关,与中断连接方式有关*/#define*****_*****PT{EX1=0;
}#defineENABLE_*****PT{EX1=1;
}#defineCLEAR_INTER_FLAG{IE1=0;
3、MATLAB控制数据收发
(1)利用STC提供STC-ISP-V4.83软件检查MCU选项(同2)
(2)串行口初始参数设定(同2)(3)单片机内运行的程序(同2)
以上部分皆与“2、利用串口调试助手实现串行口数据收发”内容相同只是用MATLAB替代串口调试助手的功能。
(4)MATLAB数据收发功能实现简述
先用MATLABGUI画出所需窗口(如图(5)所示),并在系统生成的程序中设置串口通信参数及相关函数。
由于刚学MATLAB没几天,窗口设置较简单。
接收数据窗口,只能显示接收到字符的ASCII码;
发送数据窗口会在数据前自动加控制字符“LF,”ASCII码为0AH。
这些不足都有待于进一步学习。
图(5)
当要发送数据时,在数据发送窗口输入所要发送的数据,点击发送。
同样,需在所要发送数据末尾加上“!
”,让单片机识别数据接收完,调用LED数码管显示程序,显示发送数据的ASCII码,然后返回“Waitcommand!
”字符串(PC机数据接收窗口显示其ASCII码),表示数据已接收且显示。
当单片机按下按键时,返回键值(PC机数据接收窗口显示键值的ASCII码)。
点击MATLAB
收发窗口的
关闭按钮,可以关闭此窗口。
MATLAB数据发送窗口输入“6789ABCD!
”,LED数码管依次显示0AH(LF控制符)、36H(6)、37H(7)、38H(8)、39H(9)、20H(空格)、41H(A)、42H(B)、43H(C)、44H(D)、21H(!
),详见图(6)。
当按下最左侧的三个键@、H、x时,数据接收窗口依次显示40H(@)、48H(H)、78H(x),详见图(7)。
图(6)a图(6)b
图(6)c图(6)d
图(7)a图(7)b
图(7)c图(7)d
(5)MATLAB相关程序
functionvarargout=chuankoutongxingmatlab(varargin)gui_Singleton=1;
gui_State=struct('
gui_Name'
mfilename,...