日本高清不卡中文字幕-一起草草视频在线观看-亚洲精品一区二区三区色-国产亚洲精品免费视频

你好!歡迎來(lái)到深圳市穎特新科技有限公司!
語(yǔ)言
當(dāng)前位置:首頁(yè) >> 技術(shù)中心 >> 單片機(jī)入門 >> 字符和數(shù)據(jù)之間的轉(zhuǎn)換

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

作者:admin 來(lái)源:不詳 發(fā)布時(shí)間:2018-05-08  瀏覽:25

  我們學(xué)串口通信的應(yīng)用主要是實(shí)現(xiàn)單片機(jī)和電腦之間的信息互發(fā),可以用電腦控制單片機(jī)的一些信息,可以把單片機(jī)的一些信息狀況發(fā)給電腦上的軟件。下面我們就做一個(gè)簡(jiǎn)單的例程,實(shí)現(xiàn)單片機(jī)串口調(diào)試助手發(fā)送的數(shù)據(jù),在我們開(kāi)發(fā)板上的數(shù)碼管上顯示出來(lái)。

 

#include <reg52.h>

 

sbit ADDR3 = P1^3;      //LED選擇地址線3

sbit ENLED = P1^4;      //LED總使能引腳

 

unsigned char code LedChar[] = {  //數(shù)碼管顯示字符轉(zhuǎn)換表

    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,

    0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E

};

unsigned char LedBuff[6] = {  //數(shù)碼管

    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF

};

unsigned char T0RH = 0;  //T0重載值的高字節(jié)

unsigned char T0RL = 0;  //T0重載值的低字節(jié)

unsigned char RxdByte = 0;  //串口接收到的字節(jié)

 

void ConfigTimer0(unsigned int ms);

void ConfigUART(unsigned int baud);

 

void main ()

{

    P0 = 0xFF;  //P0口初始化

    ADDR3 = 1;  //選擇數(shù)碼管

    ENLED = 0;  //LED總使能

    EA = 1;     //開(kāi)總中斷

    ConfigTimer0(1);   //配置T0定時(shí)1ms

    ConfigUART(9600);  //配置波特率為9600

    

    while(1)

    {   //將接收字節(jié)在數(shù)碼管上以十六進(jìn)制形式顯示出來(lái)

        LedBuff[0] = LedChar[RxdByte & 0x0F];

        LedBuff[1] = LedChar[RxdByte >> 4];

    }

}

 

void ConfigTimer0(unsigned int ms)  //T0配置函數(shù)

{

    unsigned long tmp;

    

    tmp = 11059200 / 12;      //定時(shí)器計(jì)數(shù)頻率

    tmp = (tmp * ms) / 1000;  //計(jì)算所需的計(jì)數(shù)值

    tmp = 65536 - tmp;        //計(jì)算定時(shí)器重載值

    tmp = tmp + 31;           //修正中斷響應(yīng)延時(shí)造成的誤差

    

    T0RH = (unsigned char)(tmp >> 8);  //定時(shí)器重載值拆分為高低字節(jié)

    T0RL = (unsigned char)tmp;

    TMOD &= 0xF0;   //清零T0的控制位

    TMOD |= 0x01;   //配置T0為模式1

    TH0 = T0RH;     //加載T0重載值

    TL0 = T0RL;

    ET0 = 1;        //使能T0中斷

    TR0 = 1;        //啟動(dòng)T0

}

 

void ConfigUART(unsigned int baud)  //串口配置函數(shù),baud為波特率

{

    SCON = 0x50;   //配置串口為模式1

    TMOD &= 0x0F;  //清零T1的控制位

    TMOD |= 0x20;  //配置T1為模式2

    TH1 = 256 - (11059200/12/32) / baud;  //計(jì)算T1重載值

    TL1 = TH1;     //初值等于重載值

    ET1 = 0;       //禁止T1中斷

    ES  = 1;       //使能串口中斷

    TR1 = 1;       //啟動(dòng)T1

}

 

void LedScan()  //LED顯示掃描函數(shù)

{

    static unsigned char index = 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個(gè)數(shù)碼管

        index++;

    else

        index = 0;

}

 

void InterruptTimer0() interrupt 1  //T0中斷服務(wù)函數(shù)

{

    TH0 = T0RH;  //定時(shí)器重新加載重載值

    TL0 = T0RL;

    LedScan();   //LED掃描顯示

}

 

void InterruptUART() interrupt 4

{

    if (RI)  //接收到字節(jié)

    {

        RI = 0;  //手動(dòng)清零接收中斷標(biāo)志位

        RxdByte = SBUF;  //接收到的數(shù)據(jù)保存到接收字節(jié)變量中

        SBUF = RxdByte;  //接收到的數(shù)據(jù)又直接發(fā)回,這叫回顯-"echo",以提示用戶輸入的信息是否已正確接收

    }

    if (TI)  //字節(jié)發(fā)送完畢

    {

        TI = 0;  //手動(dòng)清零發(fā)送中斷標(biāo)志位

    }

}

  大家在做這個(gè)實(shí)驗(yàn)的時(shí)候,有個(gè)小問(wèn)題要注意一下。因?yàn)槲覀僑TC89C52RC下載程序是使用了UART串口下載,下載完程序后,程序運(yùn)行起來(lái)了,可是下載軟件最后還會(huì)通過(guò)串口發(fā)送一些額外的數(shù)據(jù),所以程序剛下載進(jìn)去不是顯示00,而可能是其他數(shù)據(jù)。大家只要把開(kāi)關(guān)關(guān)閉,重新打開(kāi)一次就好了。

  細(xì)心的同學(xué)可能會(huì)發(fā)現(xiàn),在串口調(diào)試助手發(fā)送選項(xiàng)和接收選項(xiàng)處,還有個(gè)“字符格式發(fā)送”和“字符格式顯示”,這是什么意思呢?

  先拋開(kāi)我們使用的漢字不談,那么我們常用的字符就包含了0~9的數(shù)字、A~Z/a~z的字母、還有各種標(biāo)點(diǎn)符號(hào)等。那么在單片機(jī)系統(tǒng)里面我們?cè)趺磥?lái)表示它們呢?ASCII碼(American Standard Code for Information Interchange,即美國(guó)信息互換標(biāo)準(zhǔn)代碼)可以完成這個(gè)使命:我們知道,在單片機(jī)中一個(gè)字節(jié)的數(shù)據(jù)可以有0~255共256個(gè)值,我們?nèi)∑渲械?~127共128個(gè)值賦予了它另外一層涵義,即讓它們分別來(lái)代表一個(gè)常用字符,其具體的對(duì)應(yīng)關(guān)系如下表。

  表1 ASCII表

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ù)之間建立了一一對(duì)應(yīng)的關(guān)系,那么現(xiàn)在一個(gè)字節(jié)就既可以代表一個(gè)整數(shù)又可以代表一個(gè)字符了,但它本質(zhì)上只是一個(gè)字節(jié)的數(shù)據(jù),而我們賦予了它不同的涵義,什么時(shí)候賦予它那種涵義就看編程者的意圖了。ASCII碼在單片機(jī)系統(tǒng)中應(yīng)用非常廣泛,我們后續(xù)的課程也會(huì)經(jīng)常使用到它,下面我們來(lái)對(duì)它做一個(gè)直觀的認(rèn)識(shí),同學(xué)們一定要深刻理解其本質(zhì)。

  對(duì)照上述表格,我們就可以實(shí)現(xiàn)字符和數(shù)字之間的轉(zhuǎn)換了,比如還是這個(gè)程序,我們發(fā)送的時(shí)候改成字符格式發(fā)送,接收還是用十六進(jìn)制接收,這樣接收和數(shù)碼管好做一下對(duì)比。

  我們用字符格式發(fā)送一個(gè)小寫(xiě)的a,返回一個(gè)十六進(jìn)制的0x61,數(shù)碼管上顯示的也是61,ASCII碼表里字符a對(duì)應(yīng)十進(jìn)制是97,等于十六進(jìn)制的0x61;我們?cè)儆米址袷桨l(fā)送一個(gè)數(shù)字1,返回一個(gè)十六進(jìn)制的0x31,數(shù)碼管上顯示的也是31,ASCII表里字符1對(duì)應(yīng)的十進(jìn)制是49,等于十六進(jìn)制的0x31。這下大家就該清楚了:所謂的十六進(jìn)制發(fā)送和十六進(jìn)制接收,都是按字節(jié)數(shù)據(jù)的真實(shí)值進(jìn)行的;而字符格式發(fā)送和字符格式接收,是按ASCII碼表中字符形式進(jìn)行的,但它實(shí)際上最終傳輸?shù)倪是一個(gè)字節(jié)數(shù)據(jù)。這個(gè)表格,當(dāng)然不需要大家去記住,理解它,用的時(shí)候過(guò)來(lái)查就行了。

  通信的學(xué)習(xí),不像前邊控制部分那么直觀了,通信部分我們的程序只能獲得一個(gè)結(jié)果,而其過(guò)程我們卻無(wú)法直接看到,所以慢慢的可能大家就會(huì)知道有示波器和邏輯分析儀這類測(cè)量?jī)x器。如果學(xué)校實(shí)驗(yàn)室或者公司里有示波器或者邏輯分析儀這類儀器,可以拿過(guò)來(lái)抓一下串口波形,直觀的了解一下。如果暫時(shí)還沒(méi)有這些儀器,先知道這么回事,有條件再說(shuō)。因?yàn)楣ぞ哳惖臇|西有的比較昂貴,有條件可以盡量使用學(xué);蛘吖镜。在這里我用一款簡(jiǎn)易的邏輯分析儀把串口通信的波形抓出來(lái)給大家看一下,大家了解一下即可,如圖1所示。

邏輯分析儀串口數(shù)據(jù)示意圖

邏輯分析儀串口數(shù)據(jù)示意圖

圖1 邏輯分析儀串口數(shù)據(jù)示意圖

  分析儀和示波器的作用,就是把通信過(guò)程的波形抓出來(lái)進(jìn)行分析。先大概說(shuō)一下波形的意思。波形左邊是低位,右邊是高位,上邊這個(gè)波形是電腦發(fā)送給單片機(jī)的,下邊這個(gè)波形是單片機(jī)回發(fā)給電腦的。以上邊的波形為例,左邊第一位是起始位0,從低位到高位依次是10001100,順序倒一下,就是數(shù)據(jù)0x31,也就是ASCII碼表里的‘1’。大家可以注意到分析儀在每個(gè)數(shù)據(jù)位都給標(biāo)了一個(gè)白色的點(diǎn),表示是數(shù)據(jù),起始位和無(wú)數(shù)據(jù)的時(shí)候都沒(méi)有這個(gè)白點(diǎn)。時(shí)間標(biāo)T1和T2的差值在右邊顯示出來(lái)是0.102ms,大概是9600分之一,稍微有點(diǎn)偏差,在容許范圍內(nèi)即可。通過(guò)圖11-7,我們可以清晰的了解了串口通信的收發(fā)的詳細(xì)過(guò)程。

  那我們這里再來(lái)了解一下,如果我們使用串口調(diào)試助手,用字符格式直接發(fā)送一個(gè)“12”,我們?cè)谖覀兊臄?shù)碼管上應(yīng)該顯示什么呢?串口調(diào)試助手應(yīng)該返回什么呢?經(jīng)過(guò)試驗(yàn)發(fā)現(xiàn),我們數(shù)碼管顯示的是32,而串口調(diào)試助手返回十六進(jìn)制顯示的是31、32兩個(gè)數(shù)據(jù),如圖2所示。

 串口調(diào)試助手?jǐn)?shù)據(jù)顯示

圖2 串口調(diào)試助手?jǐn)?shù)據(jù)顯示

  我們用邏輯分析儀把這個(gè)數(shù)據(jù)抓出來(lái)看一下,如圖3所示。

邏輯分析儀抓取數(shù)據(jù)

圖3 邏輯分析儀抓取數(shù)據(jù)

  對(duì)于ASCII碼表來(lái)說(shuō),數(shù)字本身是字符而非數(shù)據(jù),所以如果發(fā)送“12”的話,實(shí)際上是是分別發(fā)送了“1”和“2”兩個(gè)字符,單片機(jī)呢,先收到第一個(gè)字符“1”,在數(shù)碼管上會(huì)顯示出31這個(gè)對(duì)應(yīng)數(shù)字,但是瞬間馬上就又收到了“2”這個(gè)字符,數(shù)碼管瞬間從31變成了32,而我們視覺(jué)上呢,根本是沒(méi)有辦法發(fā)現(xiàn)這種快速變化的,所以我們感覺(jué)數(shù)碼管直接顯示的是32。

編輯:admin  最后修改時(shí)間:2018-05-08

聯(lián)系方式

0755-82591179

傳真:0755-82591176

郵箱:vicky@yingtexin.net

地址:深圳市龍華區(qū)民治街道民治大道973萬(wàn)眾潤(rùn)豐創(chuàng)業(yè)園A棟2樓A08

Copyright © 2014-2023 穎特新科技有限公司 All Rights Reserved.  粵ICP備14043402號(hào)-4

龙泉市| 昆明市| 涞源县| 曲麻莱县| 天台县| 无为县| 盐边县| 庄浪县| 富平县| 庄浪县| 十堰市| 甘泉县| 沾化县| 霍城县| 怀集县| 左云县| 平江县| 疏勒县| 湖北省| 定襄县| 鄂州市| 林芝县| 永年县| 高淳县| 铜鼓县| 儋州市| 庆城县| 东乡族自治县| 保靖县| 丹江口市| 新津县| 廉江市| 鄱阳县| 泽库县| 岳普湖县| 保定市| 九龙城区| 宾川县| 新泰市| 临漳县| 台山市|