vbairbus 发表于 2011-6-23 22:22:02

单片机与家用电脑的串行通讯 (BASIC语言)

下面是我编在单片机上的串行通讯接收部分的编码(BASIC语言)
$regfile = "m16def.dat"
$crystal = 8000000
$baud = 9600
Config Lcdpin = Pin , Rs = Porta.0 , E = Porta.1 , Db4 = Porta.2 , Db5 = Porta.3 , Db6 = Porta.4 , Db7 = Porta.5
Config Lcd = 16 * 2
Config Portb = Output
Portb.0 = 1
Portb.1 = 1
Portb.2 = 0
Dim B As String * 1
Dim W As String * 20
W = ""
On Urxc Isr
Enable Urxc
Enable Interrupts
Do
Idle
Loop
Isr:
B = Inkey()
If B = Chr(13) Then
Portb.0 = 0
Cls
Lcd W
Else
Cls
Lcd 2
W = W + B
Portb.1 = 0
End If
Return
Portb.1接LED灯
在家用电脑上用VB2005编写,发送部分语句是
RS232.Write(TextBox1.Text & vbCr)
我在TextBox1输入A,点击发送按钮,单片机这边,Lcd显示2,接Portb.1的LED灯亮。
单片机编码部分,把Lcd 2改位Lcd B(让单片机显示接收的字符),同样在TextBox1输入A,点击发送按钮,单片机这边,Lcd显示怪码,接Portb.1的LED灯亮。从以上现象看,1、单片机与家用电脑能够串行通讯,因为中断发生了。2、单片机接收的是怪码。为什么?单片机和电脑的波特率9600,无校验,数据位8,停止位1.   如果要在单片机上设定用ASCII码传输,是不是只要数据位8就可以了?

machao 发表于 2011-6-24 01:01:48

单片机接收的不是怪码,是你自己的基础概念掌握的不好。

1。PC发送“A”,知道具体发送的8位二进制数是什么吗?

2。如果你知道到,“A”的ASCII码为65(0x41h)
   那么你测试下面2句的输出有什么不同?
   LCD 65
   LCD "A"

3.如果不同,思考明白为什么,这样才能正确理解LCD是如何显示的,以及你如何正确使用LCD语句显示你所需要的东西(提示:使用一个转换函数就能正确显示A了)

===============================
我写一个正确的LCD语句不难,但这样你以后碰到问题还是不知道为什么。

vbairbus 发表于 2011-6-24 10:35:07

马老师: LCD "A"显示字符A ,LCD 65显示65 ,LCD Chr(65) ,也显示字符A ,
我在家用电脑上发送部分语句是:
RS232.Write(TextBox1.Text & vbCr)   
每次都发送vbCr,就是回车换行符,也就是Chr(13),单片机中断发生后,就是没有收到Chr(13),因为我在中断部分写有语句
If B = Chr(13) Then
Portb.0 = 0
我在Portb.0接有一个LED灯,没亮。这说明接收不正常。
我在电脑上有 RS232.Encoding = Encoding.ASCII 语句,发的是ASCII码。

machao 发表于 2011-6-24 11:45:25

这是另外的问题了

1。回车换行是2个字符:chr(13)是回车,chr(10)是换行
2。你PC一次下发不是一个字符,而是连续3个:“A”,0x0d,0x0a。而你的AVR没有采用BUFF方式接收,只是采用简单中断的方式。那么当AVR收到第1个A后,中断处理去显示了,如果这个时间长的话,AVR收到的第2个字符来不及处理就被后面又到的字符冲掉了。

建议你AVR采用BUFF方式接收。

如果你真想学好AVR,建议你先在本拦下载我编写的教程参考学习。另外还必须有好的基础。

vbairbus 发表于 2011-6-24 15:02:27

回复【3楼】machao
-----------------------------------------------------------------------

不对,我中断一次只接收一个字符,请仔细看看我的编码
Isr:
B = Inkey()
If B = Chr(13) Then
Portb.0 = 0
Cls
Lcd W
Else
Cls
Lcd 2
W = W + B
Portb.1 = 0
End If
Return
因为有W = W + B 语句,字符不会被冲掉,还有接Portb.0的LED灯不亮,程序一直没走到这If B = Chr(13) Then
Portb.0 = 0也就是没收到Chr(13)。

machao 发表于 2011-6-24 15:40:06

你做个简单测试吧,AVR程序不动,修改PC的代码:

RS232.Write(TextBox1.Text)   ;送1个“A”
延时10ms
RS232.Write(TextBox1.Text)   ;送1个“B”
延时10ms
RS232.Write(TextBox1.Text)   ;送1个“C”
......

看AVR能否正确接收和显示

然后是:
RS232.Write(TextBox1.Text)   ;送“ABC”3个字符,看AVR能否正确接收

vbairbus 发表于 2011-6-25 08:47:05

马老师:我在AVR程序里把Lcd 2改为Lcd B(显示接收的字符),在电脑里把发送部分RS232.Write(TextBox1.Text & vbCr)改为RS232.Write(TextBox1.Text),测试结果是:送1个“A”,Lcd显示一个黑小方格(就是Lcd刚开机时显示的一行黑小方格里的一个),
送1个“B”和送1个“C”结果都一样都是黑小方格,送“AB”也是一个黑小方格,送“ABC”Lcd显示怪码,我不做延时了,这样看更清楚。

machao 发表于 2011-6-25 11:13:22

回复【2楼】vbairbus
马老师: lcd "a"显示字符a ,lcd 65显示65 ,lcd chr(65) ,也显示字符a ,
我在家用电脑上发送部分语句是:   
rs232.write(textbox1.text & vbcr)   
每次都发送vbcr,就是回车换行符,也就是chr(13),单片机中断发生后,就是没有收到chr(13),因为我在中断部分写有语句
if b = chr(13) then   
portb.0 = 0
我在portb.0接有一个led灯,没亮。这说明接收不正常。
我在电脑上有 rs232.encoding = encoding.ascii 语句,发的是ascii码。

-----------------------------------------------------------------------

你在二楼的回答,看似明白了,其实还是没有真正的理解。

LCD chr(B)

vbairbus 发表于 2011-6-26 06:50:49

回复【7楼】machao
-----------------------------------------------------------------------

这是什么意思?我的B是字符,不能这么写,请你说明白点,不要去猜。我在二楼的回答应把a改为A.

machao 发表于 2011-6-26 14:39:28

“马老师: LCD "A"显示字符A ,LCD 65显示65 ,LCD Chr(65) ,也显示字符A”

1。以上是你测试的,结果是对的,我以为你明白了,但看到后面你的贴子,知道你没有真正理解ASCII码的概念。

2。你把4楼的代码改成如下,然后测试,看是否能显示出PC送出的字符

Isr:   
B = Inkey()   
If B = Chr(13) Then   
   Portb.0 = 0   
Else   
   Lcd chr(B)   
   Portb.1 = 0   
End If   
Return   

3。再看1楼我说的问题。我已经说的很明白了,不是让谁去猜,这个是学习的过程。

vbairbus 发表于 2011-6-27 08:19:03

马老师:你把B = Chr(13)代到Lcd chr(B)里 ,就变成Lcd chr(Chr(13)),这里有两个Chr,显然是错的。

machao 发表于 2011-6-27 10:25:04

死脑筋,就是不开窍。

PC上下发回车   B=13          LCD chr(B) = lcd chr(13) --> 显示“回车”,光标返回坐端   
PC上下发“A”    B=65          LCD chr(B) = lcd chr(65) --> 显示A字符

静下心,先把基础的东西学好。

vbairbus 发表于 2011-6-27 10:56:40

我说的是
Lcd chr(B)
你的代码有错。【9楼】的代码有错。

vbairbus 发表于 2011-6-27 11:03:18

回复【11楼】machao
死脑筋,就是不开窍。
pc上下发回车   B=13          lcd chr(b) = lcd chr(13) --> 显示“回车”,光标返回坐端   
pc上下发“A”    B=65          lcd chr(b) = lcd chr(65) --> 显示a字符
静下心,先把基础的东西学好。

-----------------------------------------------------------------------
pc上下发回车   B=chr(13),不是B=13

vbairbus 发表于 2011-6-27 11:13:41

我引用你的话“如果你看的书是《AVR单片机BASIC语言编程及开发》的话,我就是这本书的第二作者。”
你在该书169页第14行写有   If B = Chr(13) Then    这样的语句,如果你9楼说的对,那你编的书就是错的,如果你编的书是对的,那你9楼说的就是错的。

vbairbus 发表于 2011-6-27 12:32:38

接14楼
该书169页第1行写有   Dim B As String * 1 ,已经把B定义为字符,后面的B怎么会等于13、65呢?

machao 发表于 2011-6-27 20:17:55

那你用下面的代码能正确显示出下发的“A”“B”“C”吗?

Isr:   
B = Inkey()   
If (B = Chr(13) or B = chr(10)) Then   
   Portb.0 = 0   
Else   
   Lcd B   
   Portb.1 = 0   
End If   
Return

vbairbus 发表于 2011-6-27 22:36:41

代码是这样的:
$regfile = "m16def.dat"
$crystal = 8000000
$baud = 9600
Config Lcdpin = Pin , Rs = Porta.0 , E = Porta.1 , Db4 = Porta.2 , Db5 = Porta.3 , Db6 = Porta.4 , Db7 = Porta.5
Config Lcd = 16 * 2
Config Portb = Output
Portb.0 = 1
Portb.1 = 1
Portb.2 = 0
Dim B As String * 1
Dim W As String * 20
W = ""
On Urxc Isr
Enable Urxc
Enable Interrupts
Do
Idle
Loop
Isr:
B = Inkey()
If B = Chr(13) Then
Portb.0 = 0
Cls
Lcd W
Else
Cls
Lcd B
W = W + B
Portb.1 = 0
End If
Return
结果是6楼那样。即
在AVR程序里把Lcd 2改为Lcd B(显示接收的字符),在电脑里把发送部分RS232.Write(TextBox1.Text & vbCr)改为RS232.Write(TextBox1.Text),测试结果是:送1个“A”,Lcd显示一个黑小方格(就是Lcd刚开机时显示的一行黑小方格里的一个),
送1个“B”和送1个“C”结果都一样都是一个黑小方格,送“AB”也是一个黑小方格,送“ABC”Lcd显示怪码。
另外我再问一个问题,你与《AVR单片机BASIC语言编程及开发》书的第一作者周建新有联系吗,如果有,请把我的帖子给他看一下。

vbairbus 发表于 2011-7-27 23:22:46

原来USB转串口质量有问题(在淘宝网忠昌店里买的,价格9.9元),我是怎么发现的呢?我想把串口的4、7脚电压升高,在电脑里用VB2005编个小程序,用万用表测量一下,串口的4、7脚电压没升高,而2、8脚电压却升高了,厂家把脚接错了。
页: [1]
查看完整版本: 单片机与家用电脑的串行通讯 (BASIC语言)