字符和数据之间的改换
咱们学串口通讯的运用首要是结束单片机和电脑之间的信息互发,能够用电脑操控单片机的一些信息,能够把单片机的一些信息状况发给电脑上的软件。下面咱们就做一个简略的例程,结束单片机串口调试帮手发送的数据,在咱们开发板上的数码管上闪现出来。
#include<reg52.h>
sbitADDR3=P1^3;//LED挑选地址线3
sbitENLED=P1^4;//LED总使能引脚
unsignedcharcodeLedChar[]={//数码管闪现字符改换表
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E
};
unsignedcharLedBuff[6]={//数码管
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
};
unsignedcharT0RH=0;//T0重载值的高字节
unsignedcharT0RL=0;//T0重载值的低字节
unsignedcharRxdByte=0;//串口接纳到的字节
voidConfigTimer0(unsignedintms);
voidConfigUART(unsignedintbaud);
voidmain()
{
P0=0xFF;//P0口初始化
ADDR3=1;//挑选数码管
ENLED=0;//LED总使能
EA=1;//开总接连
ConfigTimer0(1);//配备T0守时1ms
ConfigUART(9600);//配备波特率为9600
while(1)
{//将接纳字节在数码管上以十六进制办法闪现出来
LedBuff[0]=LedChar[RxdByte&0x0F];
LedBuff[1]=LedChar[RxdByte>>4];
}
}
voidConfigTimer0(unsignedintms)//T0配备函数
{
unsignedlongtmp;
tmp=11059200/12;//守时器计数频率
tmp=(tmp*ms)/1000;//核算所需的计数值
tmp=65536-tmp;//核算守时器重载值
tmp=tmp+31;//批改接连照应延时构成的差错
T0RH=(unsignedchar)(tmp>>8);//守时器重载值拆分为凹凸字节
T0RL=(unsignedchar)tmp;
TMOD&=0xF0;//清零T0的操控位
TMOD|=0x01;//配备T0为办法1
TH0=T0RH;//加载T0重载值
TL0=T0RL;
ET0=1;//使能T0接连
TR0=1;//主张T0
}
voidConfigUART(unsignedintbaud)//串口配备函数,baud为波特率
{
SCON=0x50;//配备串口为办法1
TMOD&=0x0F;//清零T1的操控位
TMOD|=0x20;//配备T1为办法2
TH1=256-(11059200/12/32)/baud;//核算T1重载值
TL1=TH1;//初值等于重载值
ET1=0;//阻遏T1接连
ES=1;//使能串口接连
TR1=1;//主张T1
}
voidLedScan()//LED闪现扫描函数
{
staticunsignedcharindex=0;
P0=0xFF;//封闭悉数段选位,闪现消隐
P1=(P1&0xF8)|index;//位选索引值赋值到P1口低3位
P0=LedBuff[index];//相应闪现缓冲区的值赋值到P0口
if(index<5)//位选索引0-5循环,因有6个数码管
index++;
else
index=0;
}
voidInterruptTimer0()interrupt1//T0接连效劳函数
{
TH0=T0RH;//守时器从头加载重载值
TL0=T0RL;
LedScan();//LED扫描闪现
}
voidInterruptUART()interrupt4
{
if(RI)//接纳到字节
{
RI=0;//手动清零接纳接连象征位
RxdByte=SBUF;//接纳到的数据保留到接纳字节变量中
SBUF=RxdByte;//接纳到的数据又直接发回,这叫回显-"echo",以提示用户输入的信息是不是已精确接纳
}
if(TI)//字节发送结束
{
TI=0;//手动清零发送接连象征位
}
}
咱们在做这个实验的时分,有个小疑问要留心一下。因为咱们STC89C52RC下载程序是运用了UART串口下载,下载完程序后,程序作业起来了,可是下载软件终究还会经过串口发送一些额定的数据,所以程序刚下载进入不是闪现00,而或许是别的数据。咱们只需把开关封闭,从头翻开一次就好了。
仔细的同学或许会发现,在串口调试帮手发送选项和接纳选项处,还有个“字符格局发送”和“字符格局闪现”,这是啥意思呢?
先抛开咱们运用的汉字不谈,那么咱们常用的字符就包含了0~9的数字、A~Z/a~z的字母、还有各种标点符号等。那么在单片机系统里边咱们怎么来标明它们呢?ASCII码(AmericanStandardCodeforInformationInterchange,即美国信息沟通规范代码)能够结束这个使命:咱们知道,在单片机中一个字节的数据能够有0~255共256个值,咱们取其间的0~127共128个值赋予了它别的一层寓意,即让它们别离来代表一个常用字符,其详细的对应联络如下表。
表1ASCII表
ASCII值 | 操控字符 | ASCII值 | 字符 | ASCII值 | 字符 | ASCII值 | 字符 |
000 | NUL | 032 | (space) | 064 | @ | 096 | ’ |
001 | SOH | 033 | ! | 065 | A | 097 | a |
002 | STX | 034 | " | 066 | B | 098 | b |
003 | ETX | 035 | # | 067 | C | 099 | c |
004 | EOT | 036 | $ | 068 | D | 100 | d |
005 | END | 037 | % | 069 | E | 101 | e |
006 | ACK | 038 | & | 070 | F | 102 | f |
007 | BEL | 039 | ' | 071 | G | 103 | g |
008 | BS | 040 | ( | 072 | H | 104 | h |
009 | HT | 041 | ) | 073 | I | 105 | i |
010 | LF | 042 | * | 074 | J | 106 | j |
011 | VT | 043 | + | 075 | K | 107 | k |
012 | FF | 044 | , | 076 | L | 108 | l |
013 | CR | 045 | - | 077 | M | 109 | m |
014 | SO | 046 | . | 078 | N | 110 | n |
015 | SI | 047 | / | 079 | O | 111 | o |
016 | DLE | 048 | 0 | 080 | P | 112 | p |
017 | DC1 | 049 | 1 | 081 | Q | 113 | q |
018 | DC2 | 050 | 2 | 082 | R | 114 | r |
019 | DC3 | 051 | 3 | 083 | S | 115 | s |
020 | DC4 | 052 | 4 | 084 | T | 116 | t |
021 | NAK | 053 | 5 | 085 | U | 117 | u |
022 | SYN | 054 | 6 | 086 | V | 118 | v |
023 | ETB | 055 | 7 | 087 | W | 119 | w |
024 | CAN | 056 | 8 | 088 | X | 120 | x |
025 | EM | 057 | 9 | 089 | Y | 121 | y |
026 | SUB | 058 | : | 090 | Z | 122 | z |
027 | ESC | 059 | ; | 091 | [ | 123 | { |
028 | FS | 060 | < | 092 | \ | 124 | | |
029 | GS | 061 | = | 093 | ] | 125 | } |
030 | RS | 062 | > | 094 | ^ | 126 | ~ |
031 | US | 063 | 095 | _ | 127 | DEL |
这么咱们就在常用字符和字节数据之间建立了逐个对应的联络,那么现在一个字节就既能够代表一个整数又能够代表一个字符了,但它实质上仅仅一个字节的数据,而咱们赋予了它纷歧样的寓意,啥时分赋予它那种寓意就看编程者的目的了。ASCII码在单片机系统中运用十分广泛,咱们后续的课程也会常常运用到它,下面咱们来对它做一个直观的知道,同学们必定要深化了解正实质。
对照上述表格,咱们就能够结束字符和数字之间的改换了,比方仍是这个程序,咱们发送的时分改成字符格局发送,接纳仍是用十六进制接纳,这么接纳和数码管好做一下比照。
咱们用字符格局发送一个小写的a,回来一个十六进制的0x61,数码管上闪现的也是61,ASCII码表里字符a对应十进制是97,等于十六进制的0x61;咱们再用字符格局发送一个数字1,回来一个十六进制的0x31,数码管上闪现的也是31,ASCII表里字符1对应的十进制是49,等于十六进制的0x31。这下咱们就该了解了:所谓的十六进制发送和十六进制接纳,都是按字节数据的实在值进行的;而字符格局发送和字符格局接纳,是按ASCII码表中字符办法进行的,但它实习上终究传输的仍是一个字节数据。这个表格,当然不需求咱们去记住,了解它,用的时分过来查就行了。
通讯的学习,不像前边操控有些那么直观了,通讯有些咱们的程序只能取得一个作用,而其进程咱们却无法直接看到,所以逐步的或许咱们就会知道有示波器和逻辑剖析仪这类测量仪器。假定校园实验室或许公司里有示波器或许逻辑剖析仪这类仪器,能够拿过来抓一下串口波形,直观的了解一下。假定暂时还没有这些仪器,先知道这么回事,有条件再说。因为东西类的东西有的比照贵重,有条件能够尽量运用校园或许公司的。在这儿我用一款简练的逻辑剖析仪把串口通讯的波形抓出来给咱们看一下,咱们了解一下即可,如图1所示。
图1逻辑剖析仪串口数据暗示图
剖析仪和示波器的作用,便是把通讯进程的波形抓出来进行剖析。先大约说一下波形的意思。波形左面是低位,右边是高位,上边这个波形是电脑发送给单片机的,下边这个波形是单片机回发给电脑的。以上边的波形为例,左面榜首位是开端位0,从低位到高位顺次是10001100,次第倒一下,便是数据0x31,也便是ASCII码表里的‘1’。咱们能够留心到剖析仪在每个数据位都给标了一个白色的点,标明是数据,开端位和很多据的时分都没有这个白点。时刻标T1和T2的差值在右边闪现出来是0.102ms,大约是9600分之一,略微有点差错,在容许方案内即可。经过图11-7,咱们能够明晰的了解了串口通讯的收发的详细进程。
那咱们这儿再来了解一下,假定咱们运用串口调试帮手,用字符格局直接发送一个“12”,咱们在咱们的数码管上应当闪现啥呢?串口调试帮手应当回来啥呢?经过实验发现,咱们数码管闪现的是32,而串口调试帮手回来十六进制闪现的是31、32两个数据,如图2所示。
图2串口调试帮手数据闪现
咱们用逻辑剖析仪把这个数据抓出来看一下,如图3所示。
图3逻辑剖析仪抓取数据
对于ASCII码表来说,数字本身是字符而非数据,所以假定发送“12”的话,实习上是是别离发送了“1”和“2”两个字符,单片机呢,先收到榜首个字符“1”,在数码管上会闪现出31这个对应数字,可是霎时刻立刻就又收到了“2”这个字符,数码管霎时刻从31变成了32,而咱们视觉上呢,底子是没有办法发现这种活络改动的,所以咱们感触数码管直接闪现的是32。