PC机与单片机串行通讯时出错了

PC机与单片机串行通讯时 我单片机采集的室内温度 单片机显示的温度是正确的 但是和电脑通讯时 电脑接收到的温度字节确实错误的 到底是哪里的问题 是不是我硬件的问题啊 程序保证都对 因为用别人的板子就能正常显示 接收正确的温度字节 感谢万分

第1个回答  2012-06-05
程序发出来看看,一下是我得汇编,向电脑发送02 符号 温度百位 温度十位 温度个位 温度小数位 03 结束 符号为+时接受到的是空格asc2码,符号为-时接受到-的asic2码

TEMPERATURE_L EQU 30H
TEMPERATURE_H EQU 31H
TEMPERATURE_FH EQU 32H ;温度符号位
TEMPERATURE_INT EQU 33H ;转换后的温度十六进制整数部分
TEMPERATURE_FLT EQU 34H ;转换后的温度十六进制小数部分
TEMPERATURE_B EQU 35H ;转换后的温度十进制百位
TEMPERATURE_S EQU 36H ;转换后的温度十进制十位
TEMPERATURE_G EQU 37H ;转换后的温度十进制个位
TEMPERATURE_XS EQU 38H ;转换后的温度十进制小数位

DAT_LCD EQU P2
FLAG BIT 00H
DQ BIT P0.0

BL BIT P1.0
RS BIT P1.1
RW BIT P1.2
EN BIT P1.3

ORG 0000H
LJMP START
ORG 0030H
START:
MOV SP,#60H
MOV TMOD,#20H
MOV TH1,#0FDH
MOV TL1,#0FDH
MOV SCON,#50H
SETB TR1
CLR BL
LCALL INIT_1602
LCALL DISP_START

;------------------<<主程序>>--------------------
MAIN:
LCALL READ_TEMPERATURE
LCALL DISP_18B20
LCALL CHUANGE_TEMPERATURE
LCALL DISP_TEMPERATURE
LCALL SEND_TEMPERATURE
LJMP MAIN
;------------------------------------------------

;---------------<读出DS18B20温度数据>------------
READ_TEMPERATURE:
SETB DQ
LCALL INIT_18B20 ;先复位DS18B20
JB FLAG,OK_18B20 ;判断DS1820是否存在,若DS18B20不存在则返回
RET
OK_18B20:
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE_18B20
MOV A,#44H ;发出温度转换命令
LCALL WRITE_18B20
LCALL DELAY_18B20 ;等待AD转换结束,12位的话750毫秒
LCALL INIT_18B20 ;准备读温度前先复位
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE_18B20
MOV A,#0BEH ;发出读温度命令
LCALL WRITE_18B20
MOV R1,#30H
LCALL READ_18B20 ;将读出的温度数据保存到
MOV R1,#31H
LCALL READ_18B20
RET
;------------------------------------------------

;----------------<DS18B20复位程序>---------------
INIT_18B20:
SETB DQ
NOP
CLR DQ ;主机发出延时537微秒的复位低脉冲
MOV R7,#230
DJNZ R7,$
SETB DQ ;然后拉高数据线,释放总线进入接受状态
NOP
NOP
NOP
MOV R7,#110
TSR1:
JNB DQ,TSR2 ;等待DS18B20回应
DJNZ R7,TSR1
LJMP TSR3
TSR2:
SETB FLAG ;置标志位,表示DS1820存在
LJMP TSR4
TSR3:
CLR FLAG ;清标志位,表示DS1820不存在
LJMP TSR5
TSR4:
MOV R7,#103
DJNZ R7,$ ;时序要求延时一段时间
TSR5:
SETB DQ
RET
;------------------------------------------------

;----------------<数据写入DS18B20>---------------
WRITE_18B20:
MOV R2,#8 ;一共8位数据,串行通信
CLR C
WR1:
CLR DQ
MOV R0,#5
DJNZ R0,$
RRC A ;循环右移
MOV DQ,C
MOV R0,#25
DJNZ R0,$
SETB DQ
NOP
DJNZ R2,WR1 ;A里面一共是8位,所以要送8次
SETB DQ ;释放总线
RET
;------------------------------------------------

;---------------<读DS18B20数据>------------------
READ_18B20: ;将温度高位和低位从DS18B20中读出
MOV R2,#8 ;数据一共有8位
CLR C
RE8:
SETB DQ
NOP
NOP
CLR DQ
NOP
NOP
NOP
NOP
NOP
NOP
SETB DQ
NOP
NOP
NOP
NOP
MOV C,DQ
RRC A
MOV R7,#15
DJNZ R7,$
DJNZ R2,RE8
MOV @R1,A
RET
;------------------------------------------------

;-----------------<LCD1602初始化>----------------
INIT_1602:
MOV DAT_LCD,#01H ;清屏并光标复位
LCALL WRITCOM
MOV DAT_LCD,#38H ;设置显示模式:8位2行5x7点阵
LCALL WRITCOM
MOV DAT_LCD,#0CH ;显示器开、光标关、光标禁止闪烁
LCALL WRITCOM
MOV DAT_LCD,#06H ;文字不动,光标自动右移
LCALL WRITCOM
RET
;------------------------------------------------

;--------------<显示DS18B20是否存在>-------------
DISP_18B20:
JB FLAG,DISOK
MOV DAT_LCD,#0DH
ORL DAT_LCD,#80H
LCALL WRITCOM
MOV DAT_LCD,#'E'
LCALL WRITDATA
MOV DAT_LCD,#'R'
LCALL WRITDATA
MOV DAT_LCD,#'R'
LCALL WRITDATA
RET
DISOK:
MOV DAT_LCD,#0DH
ORL DAT_LCD,#80H
LCALL WRITCOM
MOV DAT_LCD,#' '
LCALL WRITDATA
MOV DAT_LCD,#'O'
LCALL WRITDATA
MOV DAT_LCD,#'K'
LCALL WRITDATA
RET
;------------------------------------------------

;--------------<LCD1602显示不变字符>-------------
DISP_START:
MOV DPTR,#TAB_START
MOV DAT_LCD,#03H ;写入显示起始地址
ORL DAT_LCD,#80H ;按模块要求写入的地址最高位必需为1
LCALL WRITCOM
MOV R7,#7
MOV R2,#0
DIS_N_BIT:
MOV A,R2
MOVC A,@A+DPTR
MOV DAT_LCD,A
LCALL WRITDATA
INC R2
DJNZ R7,DIS_N_BIT
MOV DAT_LCD,#4EH
ORL DAT_LCD,#80H
LCALL WRITCOM
MOV DAT_LCD,#0DFH
LCALL WRITDATA
MOV DAT_LCD,#43H
LCALL WRITDATA
RET
;------------------------------------------------

;----------------<LCD1602显示温度>---------------
DISP_TEMPERATURE:
MOV DPTR,#TAB_NUMBER_ASIC
MOV DAT_LCD,#48H
ORL DAT_LCD,#80H
LCALL WRITCOM
MOV A,#0
CJNE A,TEMPERATURE_B,DISP_B
MOV A,#0
CJNE A,TEMPERATURE_S,DISP_S
LJMP DISP_G

DISP_B:
MOV DAT_LCD,TEMPERATURE_FH
LCALL WRITDATA
MOV A,TEMPERATURE_B
MOVC A,@A+DPTR
MOV DAT_LCD,A
LCALL WRITDATA
LJMP LOOP_S
DISP_S:
MOV DAT_LCD,#' '
LCALL WRITDATA
MOV DAT_LCD,TEMPERATURE_FH
LCALL WRITDATA
LOOP_S:
MOV A,TEMPERATURE_S
MOVC A,@A+DPTR
MOV DAT_LCD,A
LCALL WRITDATA
LJMP LOOP_G
DISP_G:
MOV DAT_LCD,#' '
LCALL WRITDATA
MOV DAT_LCD,#' '
LCALL WRITDATA
MOV DAT_LCD,TEMPERATURE_FH
LCALL WRITDATA
LOOP_G:
MOV A,TEMPERATURE_G
MOVC A,@A+DPTR
MOV DAT_LCD,A
LCALL WRITDATA

MOV DAT_LCD,#'.'
LCALL WRITDATA
MOV A,TEMPERATURE_XS
MOVC A,@A+DPTR
MOV DAT_LCD,A
LCALL WRITDATA
RET
;------------------------------------------------

;----------------<温度转换>----------------------
CHUANGE_TEMPERATURE:
MOV A,TEMPERATURE_H
JB ACC.7,LOOP_FH
MOV TEMPERATURE_FH,#' '
TRAN:
MOV A,TEMPERATURE_H
ANL A,#07H
SWAP A
MOV TEMPERATURE_INT,A
MOV A,TEMPERATURE_L
ANL A,#0F0H
SWAP A
ADD A,TEMPERATURE_INT
MOV TEMPERATURE_INT,A
MOV A,TEMPERATURE_L
ANL A,#0FH
MOV TEMPERATURE_FLT,A
MOV A,TEMPERATURE_INT
MOV B,#100
DIV AB
MOV TEMPERATURE_B,A
MOV A,B
MOV B,#10
DIV AB
MOV TEMPERATURE_S,A
MOV TEMPERATURE_G,B
MOV DPTR,#TAB_XS
MOV A,TEMPERATURE_FLT
MOVC A,@A+DPTR
MOV TEMPERATURE_XS,A
RET
;-------------<负数取反加一>----------------
LOOP_FH:
MOV TEMPERATURE_FH,#'-'
CPL TEMPERATURE_L
CPL TEMPERATURE_H
CLR C
MOV A,#1
ADD A,TEMPERATURE_L
MOV TEMPERATURE_L,A
MOV A,#0
ADDC A,TEMPERATURE_H
MOV TEMPERATURE_H,A
LJMP TRAN
;------------------------------------------------

;--------------<LCD1602写入控制命令>-------------
WRITCOM:
CLR RS
CLR RW
CLR EN
LCALL BUSY_1602
SETB EN
RET
;------------------------------------------------

;--------------<LCD1602写入数据命令>-------------
WRITDATA:
SETB RS
CLR RW
CLR EN
LCALL BUSY_1602
SETB EN
RET
;------------------------------------------------

;----------------<LCD1602忙等待>-----------------
BUSY_1602:
CLR RS
SETB RW
CLR EN
SETB EN
JB DAT_LCD.7,BUSY_1602
RET
;------------------------------------------------

;---------------<等待温度转换完成>---------------
DELAY_18B20:
MOV R7,#255
DELAY_18B20_A:
MOV R6,#255
DJNZ R6,$
DJNZ R7,DELAY_18B20_A
RET
;------------------------------------------------

;----------------<RS232通讯>---------------------
SEND_TEMPERATURE:
MOV SBUF,#02H
JNB TI,$
CLR TI
MOV SBUF,TEMPERATURE_FH
JNB TI,$
CLR TI
MOV R1,#TEMPERATURE_B
MOV R7,#4
SEND4:
MOV A,@R1
ADD A,#30H
MOV SBUF,A
JNB TI,$
CLR TI
INC R1
DJNZ R7,SEND4
MOV SBUF,#03H
JNB TI,$
CLR TI
RET
;------------------------------------------------

TAB_START:
DB 'DS18B20'

TAB_NUMBER_ASIC:
DB '0123456789'

TAB_XS:
DB 00H,01H,01H,02H,03H,03H,04H,04H
DB 05H,06H,06H,07H,08H,08H,09H,09H

END追问

程序太长了 总是提示超字节了 发不过去

第2个回答  2012-06-05
你先用串口调试工具在你电脑上模拟上位机接收,看看能不能收到正确的字节。 通过此办法来检测通讯设置的正确性。追问

接收了 接收的字符不正确

追答

能不能附一张图

追问

我传不上呢 级别不够 我用的是DS18B20采集的温度 传的时候应该是两个字节 我的单片机的温度现在是26.6 单片机传送的字节应该是26.6*16=409 高字节是01低字节是99 但是现在串口助手上接收的字符 高字节是E0 低字节是D6

追答

是你的转换方法有问题,设温度为T,第一个字节为TH,第二个字节为TL,则TH=T/256,TL=T%256
例如:温度为173,则用两个字节表示为00 AD

追问

DS18B20在出厂时以配置为12位,读取温度时共读取16位,所以把后11位的2进制转化为10进制后在乘以0.0625便为所测的温度,还需要判断正负。前5个数字为符号位 所以你所说的173应该是转化后的十进制数吧,我认为是这样,实际温度应该是173*0.0625 但是为什么串行通讯时 单片机能正确显示温度 传到电脑后的字节为什么不对呢 是不是我的硬件哪里焊错了 程序在我同学的板子上能正确接收啊

追答

你和你同学使用的晶振一样吧

第3个回答  2012-06-05
波特率不准确追问

准确 对了好多遍了

追答

那就是你的板的问题了,看看你们的晶振是不是一模一样的,不能有偏差

第4个回答  2012-06-05
可能是波特率设置不一样追问

没有 都正确 是不是硬件的问题啊 同样的程序在我们同学的实物上就能正确接收

追答

晶振频率是11.0592M吗,会不会用12M的

相似回答