字符和數(shù)據(jù)之間的轉(zhuǎn)換

發(fā)布時間:2024-03-17
我們學(xué)串口通信的應(yīng)用主要是實現(xiàn)單片機和電腦之間的信息互發(fā),可以用電腦控制單片機的一些信息,可以把單片機的一些信息狀況發(fā)給電腦上的軟件。下面我們就做一個簡單的例程,實現(xiàn)單片機串口調(diào)試助手發(fā)送的數(shù)據(jù),在我們開發(fā)板上的數(shù)碼管上顯示出來。
#include<reg52.h>
sbitaddr3=p1^3;//led選擇地址線3
sbitenled=p1^4;//led總使能引腳
unsignedcharcodeledchar[]={//數(shù)碼管顯示字符轉(zhuǎn)換表
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e
};
unsignedcharledbuff[6]={//數(shù)碼管
0xff,0xff,0xff,0xff,0xff,0xff
};
unsignedchart0rh=0;//t0重載值的高字節(jié)
unsignedchart0rl=0;//t0重載值的低字節(jié)
unsignedcharrxdbyte=0;//串口接收到的字節(jié)
voidconfigtimer0(unsignedintms);
voidconfiguart(unsignedintbaud);
voidmain()
{
p0=0xff;//p0口初始化
addr3=1;//選擇數(shù)碼管
enled=0;//led總使能
ea=1;//開總中斷
configtimer0(1);//配置t0定時1ms
configuart(9600);//配置波特率為9600
while(1)
{//將接收字節(jié)在數(shù)碼管上以十六進制形式顯示出來
ledbuff[0]=ledchar[rxdbyte&0x0f];
ledbuff[1]=ledchar[rxdbyte>>4];
}
}
voidconfigtimer0(unsignedintms)//t0配置函數(shù)
{
unsignedlongtmp;
tmp=11059200/12;//定時器計數(shù)頻率
tmp=(tmp*ms)/1000;//計算所需的計數(shù)值
tmp=65536-tmp;//計算定時器重載值
tmp=tmp+31;//修正中斷響應(yīng)延時造成的誤差
t0rh=(unsignedchar)(tmp>>8);//定時器重載值拆分為高低字節(jié)
t0rl=(unsignedchar)tmp;
tmod&=0xf0;//清零t0的控制位
tmod|=0x01;//配置t0為模式1
th0=t0rh;//加載t0重載值
tl0=t0rl;
et0=1;//使能t0中斷
tr0=1;//啟動t0
}
voidconfiguart(unsignedintbaud)//串口配置函數(shù),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顯示掃描函數(shù)
{
staticunsignedcharindex=0;
p0=0xff;//關(guān)閉所有段選位,顯示消隱
p1=(p1&0xf8)|index;//位選索引值賦值到p1口低3位
p0=ledbuff[index];//相應(yīng)顯示緩沖區(qū)的值賦值到p0口
if(index<5)//位選索引0-5循環(huán),因有6個數(shù)碼管
index++;
else
index=0;
}
voidinterrupttimer0()interrupt1//t0中斷服務(wù)函數(shù)
{
th0=t0rh;//定時器重新加載重載值
tl0=t0rl;
ledscan();//led掃描顯示
}
voidinterruptuart()interrupt4
{
if(ri)//接收到字節(jié)
{
ri=0;//手動清零接收中斷標(biāo)志位
rxdbyte=sbuf;//接收到的數(shù)據(jù)保存到接收字節(jié)變量中
sbuf=rxdbyte;//接收到的數(shù)據(jù)又直接發(fā)回,這叫回顯-echo,以提示用戶輸入的信息是否已正確接收
}
if(ti)//字節(jié)發(fā)送完畢
{
ti=0;//手動清零發(fā)送中斷標(biāo)志位
}
}
大家在做這個實驗的時候,有個小問題要注意一下。因為我們stc89c52rc下載程序是使用了uart串口下載,下載完程序后,程序運行起來了,可是下載軟件最后還會通過串口發(fā)送一些額外的數(shù)據(jù),所以程序剛下載進去不是顯示00,而可能是其他數(shù)據(jù)。大家只要把開關(guān)關(guān)閉,重新打開一次就好了。
細(xì)心的同學(xué)可能會發(fā)現(xiàn),在串口調(diào)試助手發(fā)送選項和接收選項處,還有個“字符格式發(fā)送”和“字符格式顯示”,這是什么意思呢?
先拋開我們使用的漢字不談,那么我們常用的字符就包含了0~9的數(shù)字、a~z/a~z的字母、還有各種標(biāo)點符號等。那么在單片機系統(tǒng)里面我們怎么來表示它們呢?ascii碼(americanstandardcodeforinformationinterchange,即美國信息互換標(biāo)準(zhǔn)代碼)可以完成這個使命:我們知道,在單片機中一個字節(jié)的數(shù)據(jù)可以有0~255共256個值,我們?nèi)∑渲械?~127共128個值賦予了它另外一層涵義,即讓它們分別來代表一個常用字符,其具體的對應(yīng)關(guān)系如下表。
表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
這樣我們就在常用字符和字節(jié)數(shù)據(jù)之間建立了一一對應(yīng)的關(guān)系,那么現(xiàn)在一個字節(jié)就既可以代表一個整數(shù)又可以代表一個字符了,但它本質(zhì)上只是一個字節(jié)的數(shù)據(jù),而我們賦予了它不同的涵義,什么時候賦予它那種涵義就看編程者的意圖了。ascii碼在單片機系統(tǒng)中應(yīng)用非常廣泛,我們后續(xù)的課程也會經(jīng)常使用到它,下面我們來對它做一個直觀的認(rèn)識,同學(xué)們一定要深刻理解其本質(zhì)。
對照上述表格,我們就可以實現(xiàn)字符和數(shù)字之間的轉(zhuǎn)換了,比如還是這個程序,我們發(fā)送的時候改成字符格式發(fā)送,接收還是用十六進制接收,這樣接收和數(shù)碼管好做一下對比。
我們用字符格式發(fā)送一個小寫的a,返回一個十六進制的0x61,數(shù)碼管上顯示的也是61,ascii碼表里字符a對應(yīng)十進制是97,等于十六進制的0x61;我們再用字符格式發(fā)送一個數(shù)字1,返回一個十六進制的0x31,數(shù)碼管上顯示的也是31,ascii表里字符1對應(yīng)的十進制是49,等于十六進制的0x31。這下大家就該清楚了:所謂的十六進制發(fā)送和十六進制接收,都是按字節(jié)數(shù)據(jù)的真實值進行的;而字符格式發(fā)送和字符格式接收,是按ascii碼表中字符形式進行的,但它實際上最終傳輸?shù)倪€是一個字節(jié)數(shù)據(jù)。這個表格,當(dāng)然不需要大家去記住,理解它,用的時候過來查就行了。
通信的學(xué)習(xí),不像前邊控制部分那么直觀了,通信部分我們的程序只能獲得一個結(jié)果,而其過程我們卻無法直接看到,所以慢慢的可能大家就會知道有示波器和邏輯分析儀這類測量儀器。如果學(xué)校實驗室或者公司里有示波器或者邏輯分析儀這類儀器,可以拿過來抓一下串口波形,直觀的了解一下。如果暫時還沒有這些儀器,先知道這么回事,有條件再說。因為工具類的東西有的比較昂貴,有條件可以盡量使用學(xué)?;蛘吖镜?。在這里我用一款簡易的邏輯分析儀把串口通信的波形抓出來給大家看一下,大家了解一下即可,如圖1所示。
圖1邏輯分析儀串口數(shù)據(jù)示意圖
分析儀和示波器的作用,就是把通信過程的波形抓出來進行分析。先大概說一下波形的意思。波形左邊是低位,右邊是高位,上邊這個波形是電腦發(fā)送給單片機的,下邊這個波形是單片機回發(fā)給電腦的。以上邊的波形為例,左邊第一位是起始位0,從低位到高位依次是10001100,順序倒一下,就是數(shù)據(jù)0x31,也就是ascii碼表里的‘1’。大家可以注意到分析儀在每個數(shù)據(jù)位都給標(biāo)了一個白色的點,表示是數(shù)據(jù),起始位和無數(shù)據(jù)的時候都沒有這個白點。時間標(biāo)t1和t2的差值在右邊顯示出來是0.102ms,大概是9600分之一,稍微有點偏差,在容許范圍內(nèi)即可。通過圖11-7,我們可以清晰的了解了串口通信的收發(fā)的詳細(xì)過程。
那我們這里再來了解一下,如果我們使用串口調(diào)試助手,用字符格式直接發(fā)送一個“12”,我們在我們的數(shù)碼管上應(yīng)該顯示什么呢?串口調(diào)試助手應(yīng)該返回什么呢?經(jīng)過試驗發(fā)現(xiàn),我們數(shù)碼管顯示的是32,而串口調(diào)試助手返回十六進制顯示的是31、32兩個數(shù)據(jù),如圖2所示。
圖2串口調(diào)試助手?jǐn)?shù)據(jù)顯示
我們用邏輯分析儀把這個數(shù)據(jù)抓出來看一下,如圖3所示。
圖3邏輯分析儀抓取數(shù)據(jù)
對于ascii碼表來說,數(shù)字本身是字符而非數(shù)據(jù),所以如果發(fā)送“12”的話,實際上是是分別發(fā)送了“1”和“2”兩個字符,單片機呢,先收到第一個字符“1”,在數(shù)碼管上會顯示出31這個對應(yīng)數(shù)字,但是瞬間馬上就又收到了“2”這個字符,數(shù)碼管瞬間從31變成了32,而我們視覺上呢,根本是沒有辦法發(fā)現(xiàn)這種快速變化的,所以我們感覺數(shù)碼管直接顯示的是32。
上一個:windows10無法安裝gpt分區(qū)怎么辦(windows無法安裝gpt分區(qū))
下一個:熔融指數(shù)儀塑料測試

解決牽引力穩(wěn)定FESTO有桿氣缸纜線纏繞裝置的說明
51單片機指令快速記憶方法總結(jié)
wifi密碼忘了,怎么重置(wifi密碼忘記了怎么重新設(shè)置wifi密碼)
機械硬盤的常用接口,硬盤用的SCSI接口一般是多少針的
office2016激活工具百度網(wǎng)盤(office2016激活工具下載百度云)
域名 空間 服務(wù)器三者的關(guān)系是什么?域名空間由什么構(gòu)成?
千兆網(wǎng)線水晶頭接幾根線(網(wǎng)絡(luò)千兆水晶頭接法)
怎樣科學(xué)培養(yǎng)好花毛茛
win10快速訪問文件夾刪不掉(windows10快速訪問內(nèi)容如何刪除)
口腔醫(yī)院污水處理設(shè)備處理要求
十八禁 网站在线观看免费视频_2020av天堂网_一 级 黄 色 片免费网站_绝顶高潮合集Videos