佳礼资讯网

 找回密码
 注册

ADVERTISEMENT

楼主: fritlizt

电脑串行端口(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呢?
回复

使用道具 举报


ADVERTISEMENT

 楼主| 发表于 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. 很简单罢了。
  1. #include <p18cxxx.h>
  2. #include <usart.h>
  3. #include <stdio.h>

  4. #pragma config OSC = HSPLL            //hspll osc
  5. #pragma config BOREN = OFF            //no brownout reset
  6. #pragma config WDT = OFF            //no watchdog
  7. #pragma config MCLRE = OFF            //no mclr

  8. #define BAUDRATE 9600
  9. #define BAUD_VAL 40000000/BAUDRATE/64 -1

  10. void main (void)
  11. {
  12.         unsigned char receivedData;
  13.         OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_BRGH_LOW & USART_EIGHT_BIT, BAUD_VAL);
  14.         while (1){
  15.                 if (DataRdyUSART()){        //if data available
  16.                         receivedData = ReadUSART();
  17.                         printf ("yo, i got %c\r\n", receivedData);
  18.                 }
  19.         }
  20. }

  21. int putc (char c, FILE *stream)
  22. {
  23.         while (BusyUSART());
  24.         WriteUSART(c);
  25.         return c;
  26. }
复制代码

我只解释main program loop,其他的如#define, #include, #config bit setting,有兴趣者可以到
http://cforum1.cari.com.my/viewthread.php?tid=1655673&extra=page%3D1&page=2
看看, 第二十八楼, 不明白再发问。

  1. unsigned char receivedData;
  2. 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.

  1.         while (1){
  2.                 if (DataRdyUSART()){        //if data available
  3.                         receivedData = ReadUSART();
  4.                         printf ("yo, i got %c\r\n", receivedData);
  5.                 }
  6.         }
复制代码

这个只是一直在等电脑发过来的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.


  1. Public Class Form1

  2.     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  3.         SerialPort1.Open()
  4.     End Sub

  5.     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  6.         SerialPort1.Write("A")
  7.         TextBox1.Text = SerialPort1.ReadLine
  8.     End Sub

  9.     Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
  10.         SerialPort1.Write("B")
  11.         TextBox1.Text = SerialPort1.ReadLine
  12.     End Sub
  13. 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
回复

使用道具 举报

Follow Us
发表于 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 停止

  1. Public Class Form1
  2.     Dim result As String

  3.     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  4.         SerialPort1.Write("A")

  5.         Timer1.Start()


  6.         Do While result <> "B"
  7.             result = SerialPort1.ReadExisting
  8.         Loop


  9.         Timer1.Stop()
  10.         ProgressBar1.Value = 0
  11.         result = ""



  12.     End Sub

  13.     Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
  14.         ProgressBar1.Increment(1)
  15.         If ProgressBar1.Value = ProgressBar1.Maximum Then
  16.             ProgressBar1.Value = 0
  17.         End If
  18.     End Sub

  19.     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load


  20.         SerialPort1.Open()

  21.     End Sub
  22. End Class
复制代码




如果我拿掉
  1. Do While result <> "B"
  2.             result = SerialPort1.ReadExisting
  3.         Loop
复制代码
, progress bar是会loading的。。
如果没拿掉的话,program 会hang..

我不知道要怎样接受MCU的data来中断progress bar loading..
回复

使用道具 举报


ADVERTISEMENT

 楼主| 发表于 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

评分

参与人数 1积分 +10 收起 理由
fritlizt + 10

查看全部评分

回复

使用道具 举报

发表于 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.。。。。。。。。。。
回复

使用道具 举报


ADVERTISEMENT

 楼主| 发表于 25-3-2010 08:47 PM | 显示全部楼层
回复 33# wkloh


   

没错是这样。 8051kaki吗?
你好, 我也是。
我也是几年没用asm了。
回复

使用道具 举报

发表于 25-3-2010 10:07 PM | 显示全部楼层
回复 34# xkore

VB.net 的serialport 元件绝对支持读写二进制码,只所采用指令不同而已。

有一点要提醒你的是,思路要清晰,目标要规划清楚!

比如:
  目标一:MCU负责的工作范围()。
  目标二:定义PC串口连接MCU传输/接收资料形态(ASCII或非ASCII)。
  目标二:PC该如何处理接受到MCU发来的资料。

如果以你现在的进度,同时兼顾 software 和firmware 的开发,花费时间。。。。
学到的知识可能不足以应付在商用project上。

公布谜团了!!!!!

Dim readBuffer(serialport 1.ReadBufferSize + 1) As Byte
先建立阵列参数长度。

serialport 1.Read(readBuffer, 0, serialport 1.ReadBufferSize)
把seriaport1内的接受暂存请资料导入阵列长度参数

有了readBuffer,接下来就可任意发挥了(做报表。。。)。

不过先声明,readBuffer内全部是二进制码,做报表。。。。。。

所以我不建议使用二进制码读写指令,需要处理的东东太多了(资料接受长度、丢失等问题)。。。。
回复

使用道具 举报

发表于 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都荒废掉了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

 

ADVERTISEMENT



ADVERTISEMENT



ADVERTISEMENT

ADVERTISEMENT


版权所有 © 1996-2023 Cari Internet Sdn Bhd (483575-W)|IPSERVERONE 提供云主机|广告刊登|关于我们|私隐权|免控|投诉|联络|脸书|佳礼资讯网

GMT+8, 25-4-2024 09:12 PM , Processed in 0.078749 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表