|
电脑串行端口(serial port) 和单晶片通讯
[复制链接]
|
|
楼主 |
发表于 5-3-2010 04:39 PM
|
显示全部楼层
回复 18# xin777_88
当然是可以的, visual basic里面把它拆成character,然后再writebyte出去。
不过请问你的目的是什么呢?
如果是send "testing123"为什么要拆成 't', 'e', 's', 't', 'i', 'n', 'g', '1', '2', '3',才send呢? |
|
|
|
|
|
|
|
楼主 |
发表于 6-3-2010 02:14 PM
|
显示全部楼层
电脑串行端口(serial port) 和单晶片通讯
终于进入正题。 电脑串行端口(serial port) 和单晶片通讯.
之前是loopback testing,send什么, 收到什么。
这次是send 'A'给microcontroller, microcontroller 会回复 "yo, i got A"
这次是send 'B'给microcontroller, microcontroller 会回复 "yo, i got B"
其实很简单。不难。
电脑<->microcontroller..
这里, 电脑什么都可以, 有serial port/usb to serial port 都可以。
microcontroller用有uart的就可以了。 这里, 我用pic18f4620.
电路图如下。 电脑和microcontroller 串行端口(serial port)的通讯需要max232,这是因为电平(voltage level)不一样。pic18f4620是5V, max232是5v device. 没问题。 如果用3.3v device,就要用max3232. max232 & max3232都一样, 只是max3232 是wide operating range. 可以支援3.3v/5v而max232只能4.5v-5v而已。
不一样的mcu可能有不一样的I/O 电平。
首先, 来看看mcu的coding. 很简单罢了。
- #include <p18cxxx.h>
- #include <usart.h>
- #include <stdio.h>
- #pragma config OSC = HSPLL //hspll osc
- #pragma config BOREN = OFF //no brownout reset
- #pragma config WDT = OFF //no watchdog
- #pragma config MCLRE = OFF //no mclr
- #define BAUDRATE 9600
- #define BAUD_VAL 40000000/BAUDRATE/64 -1
- void main (void)
- {
- unsigned char receivedData;
- OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_BRGH_LOW & USART_EIGHT_BIT, BAUD_VAL);
- while (1){
- if (DataRdyUSART()){ //if data available
- receivedData = ReadUSART();
- printf ("yo, i got %c\r\n", receivedData);
- }
- }
- }
- int putc (char c, FILE *stream)
- {
- while (BusyUSART());
- WriteUSART(c);
- return c;
- }
复制代码
我只解释main program loop,其他的如#define, #include, #config bit setting,有兴趣者可以到
http://cforum1.cari.com.my/viewthread.php?tid=1655673&extra=page%3D1&page=2
看看, 第二十八楼, 不明白再发问。
- unsigned char receivedData;
- OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_BRGH_LOW & USART_EIGHT_BIT, BAUD_VAL);
复制代码
receivedData用来接收serial port data.
openusart是用来做port setting, 一般操作模式我用, 9600,8,N,1,也就代表 baudrate = 9600, databits = 8, no parity bits 和1 stop bits.
- while (1){
- if (DataRdyUSART()){ //if data available
- receivedData = ReadUSART();
- printf ("yo, i got %c\r\n", receivedData);
- }
- }
复制代码
这个只是一直在等电脑发过来的data,收到过后就用printf 回复电脑。
比如收到'A', 就会reply, "yo, i got A"
比如收到'-', 就会reply, "yo, i got -"
比如收到'?', 就会reply, "yo, i got ?"
至于\r\n是newline + carriage return,也就是vb里的vbCrLf.一般来讲就是enter key.这个是需要的。 等一下vb program我用readline来接受,如果没有\r\n,vb program就会一直在等newline.
mcu 部分到此为止。
接下来是vb部分。
interface,我有两个button,
按第一个会send 'A',第二个会send 'B'.
还有一个textbox,是用来收mcu reply的。
先看看interface.
- Public Class Form1
- Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
- SerialPort1.Open()
- End Sub
- Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
- SerialPort1.Write("A")
- TextBox1.Text = SerialPort1.ReadLine
- End Sub
- Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
- SerialPort1.Write("B")
- TextBox1.Text = SerialPort1.ReadLine
- End Sub
- End Class
复制代码
code方面不难, form load只是open port.当然serialport properties,你要做setting.详情请看这贴第二楼。
接下来只有两个sub, 一个给handle button1.click也就是click send 'A'时候的action.
第二个是handle button2.click,也就是click Send 'B' 的时候的action
两个sub都是一样的,只是send出去的东西不一样。
SerialPort1.Write("A"),只是send 一个character 'A'出去,
TextBox1.Text = SerialPort1.ReadLine 接下来就等mcu reply,等到newline character为止。
如果没有newline character,program就会一直等, 等到有为止。收到过后, 就display 在textbox里面。
当然这不是一个好的program,好的program应该要有exception handling, 有空再讲简单的exception handling.
看看result:
下一堂,讲关于runtime serial port setting.
现在是通过program set comport, baudrate等。
接下来会教如何runtime set port, baudrate, list comport等。。。 |
|
|
|
|
|
|
|
发表于 8-3-2010 11:58 PM
|
显示全部楼层
这教学真是太好了,网上太缺乏 vb2008 教学
请问 readexisting 于 readline 有什么差别?
MOV TMOD,#20H
MOV TH1,#-3 ;9600 baud rate
MOV SCON,#50H ;8 bit, 1 stop, receiver enable
SETB TR1
AGAIN: MOV SBUF,#"A"
HERE: JNB TI, HERE
CLR TI
SJMP AGAIN
我send character "A" continuously 但 vb 就是receive 不到
Serialport1.open()
TextBox1.Text = serialport1.ReadLine |
|
|
|
|
|
|
|
发表于 9-3-2010 12:01 AM
|
显示全部楼层
应该是所讲的 readline / newline 问题吧。这方面不是很明白 |
|
|
|
|
|
|
|
楼主 |
发表于 9-3-2010 08:46 AM
|
显示全部楼层
回复 23# xkore
readexisting会把现在你serial port buffer里所有的咚咚丢给你。
readline会read serial port直到newline character或者发生timeout exception为止。
你的8051 program一直send A 给电脑, vb则用readline来read data.这样program就会hang 在readline那边。 因为你的mcu没有send newline char给你的电脑。
如果你用readexisting,相信也是没有东西。 因为你的program只是read一次。也就是serial port open过后,马上read.这个时候很有可能电脑还没收到就readexisting,然后就exit sub.
你要试试看电脑,mcu connection.首先你的8051 程序需要改改下。
一直loop的话,没有几秒你的buffer就full了。你需要加入button, 按的话才send.这样你就可以控制你要send几多。
vb方面你也加入一个button,按的话就read existing,然后show在你的textbox. |
|
|
|
|
|
|
|
发表于 9-3-2010 04:58 PM
|
显示全部楼层
用 readline program 会 hang..加入 button 也是得不到output.今晚再改过 controller 的 program
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
SerialPort1.Open()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TextBox1.Text = SerialPort1.ReadExisting()
End Sub |
|
|
|
|
|
|
|
发表于 13-3-2010 01:21 PM
|
显示全部楼层
fritlizt 版主 。。有什么网站有 vb express 2008 serial communication 教学的吗 ? google search 到的不多 |
|
|
|
|
|
|
|
发表于 21-3-2010 07:31 AM
|
显示全部楼层
本帖最后由 whkang07 于 21-3-2010 07:34 AM 编辑
如果我要用progress bar 在visual basic 里。。。用MCU signal来停止的,该整麽做呢?
1. button pressed
2. VB 和 mcu沟通(send A),mcu开始做工(收到A后,会做pre-programmed task)
3。progress bar 开始跑
4。 mcu做完工,和vb沟通(send B)
5。(vb收到B后)progress bar 停止
- Public Class Form1
- Dim result As String
- Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
- SerialPort1.Write("A")
- Timer1.Start()
- Do While result <> "B"
- result = SerialPort1.ReadExisting
- Loop
- Timer1.Stop()
- ProgressBar1.Value = 0
- result = ""
- End Sub
- Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
- ProgressBar1.Increment(1)
- If ProgressBar1.Value = ProgressBar1.Maximum Then
- ProgressBar1.Value = 0
- End If
- End Sub
- Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
- SerialPort1.Open()
- End Sub
- End Class
复制代码
如果我拿掉- Do While result <> "B"
- result = SerialPort1.ReadExisting
- Loop
复制代码 , progress bar是会loading的。。
如果没拿掉的话,program 会hang..
我不知道要怎样接受MCU的data来中断progress bar loading.. |
|
|
|
|
|
|
|
楼主 |
发表于 22-3-2010 08:47 PM
|
显示全部楼层
回复 28# whkang07
这个你可以用background worker来做。 详情我也不是很清楚。 我也是正在学习。
一开始, 先用简单的。 就是用label/textbox来显示现在状况。这是我现在的做法。 |
|
|
|
|
|
|
|
发表于 24-3-2010 12:30 AM
|
显示全部楼层
回复 28# whkang07
以下代码必须根据条件如下:
1.MCU 收到 “A” 后,回传一次“B”。
Public Class Form1
Dim result As String
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ProgressBar1.Value = 0
SerialPort1.Write("A")
Timer1.Interval=50
Timer1.Enabled=True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
ProgressBar1.Increment(1)
dim result as string = SerialPort1.ReadExisting
if result="B" then
Timer1.Enabled=False
else
If ProgressBar1.Value = ProgressBar1.Maximum Then ProgressBar1.Value = 0
End If
End if
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
SerialPort1.Open()
End Sub
End Class
注意:progressbar1.value 的数值变化取决于MCU 回传“B”的速度
-- MCU 回传“B”速度小于50ms,progressbar1.value=1
-- MCU 回传“B”速度50ms<ms<1000ms,progressbar1.value=20 |
评分
-
查看全部评分
|
|
|
|
|
|
|
发表于 25-3-2010 10:43 AM
|
显示全部楼层
请问microcontroller 的 sbuf register 可以 transmit binary code 吗?
example: MOV SBUF,#00010100
或许只可以 transmit ASCII character code?
那我是不是该写program convert binary 去 ASCII ?
知道的请告诉我。谢谢 |
|
|
|
|
|
|
|
楼主 |
发表于 25-3-2010 11:29 AM
|
显示全部楼层
回复 30# wkloh
热心回答。 加分奖励奖励。 |
|
|
|
|
|
|
|
发表于 25-3-2010 04:27 PM
|
显示全部楼层
回复 31# xkore
请问microcontroller 的 sbuf register 可以 transmit binary code 吗?
是可以的.
二进制吗如下:
example: MOV SBUF,#00010100B
十进制吗如下:
example: MOV SBUF,#20
十六进制吗如下:
example: MOV SBUF,#14H
多年没8051写组合语言了,快忘光了!
加油。。。 |
|
|
|
|
|
|
|
发表于 25-3-2010 06:42 PM
|
显示全部楼层
谢谢你。。如果 Vb 能读binary 那就没问题了 =) |
|
|
|
|
|
|
|
发表于 25-3-2010 06:48 PM
|
显示全部楼层
那位高手可以帮我看看吗?
vb/hyperterminal 就是 receive 不到 “A”
以下simple program 应该不会有错
MOV TMOD,#20H
MOV TH1,#-3 ;9600 baud rate
MOV SCON,#50H ;8 bit, 1 stop, receiver enable
SETB TR1 ;start timer
AGAIN: MOV SBUF,#"A" ; send character A to SBUF
HERE: JNB TI, HERE
CLR TI
SJMP AGAIN |
|
|
|
|
|
|
|
楼主 |
发表于 25-3-2010 08:45 PM
|
显示全部楼层
回复 34# xkore
你还是get不到wkloh的意思啊。。。。
binary 01000001 = hexadecimel 0x41 = decimel 65 = ASCII 'A'。根本是一样的东西。
不是vb read到binary还是没有。。 只是表达方式不一样。
你send 'A'给电脑。 你可以讲电脑收到'A',也可以讲电脑收到 hex 0x41,也可以讲电脑收到 binary 01000001.。。。。。。。。。。 |
|
|
|
|
|
|
|
楼主 |
发表于 25-3-2010 08:47 PM
|
显示全部楼层
回复 33# wkloh
没错是这样。 8051kaki吗?
你好, 我也是。
我也是几年没用asm了。 |
|
|
|
|
|
|
|
发表于 25-3-2010 10:07 PM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 25-3-2010 10:27 PM
|
显示全部楼层
回复 35# xkore
1.请检查vb/hyperterminal port setting是否如下:
BaudRate = 9600
DataBits = 8
Parity =None
StopBits = 1
flow control = None
请参考 4楼的帖。
2.可疑:
AGAIN: MOV SBUF,#"A" ; send character A to SBUF
HERE: JNB TI, HERE
CLR TI
3.led闪烁代码在“SJMP AGAIN”之前,确保代码是有执行发送资料出去的。 |
|
|
|
|
|
|
|
发表于 25-3-2010 10:33 PM
|
显示全部楼层
回复 37# fritlizt
你好!
前两年还有写8051 C 代码,近年迷恋上ARM cortex-M3(32bit)芯片,8051都荒废掉了。 |
|
|
|
|
|
|
| |
本周最热论坛帖子
|