3

我在 python 中编写了一个程序,它通过 USART 从 Atmega32(微控制器)接收二进制数并将其打印在输出中。

另一方面,我的 Atmega32 在中断触发时读取其 PINA,并使用 USART 将其值发送到计算机。

这是我的python程序:

>>> import serial
>>> ser=serial.Serial ('COM3')
>>> ser.open()
>>> while(1):
    ser.read()

当我以使00000111(等于7)的方式连接 PINA 引脚时,我在 python 中看到以下输出:

'7'
'7'
'7'
'7'
'7'
'7'
.
.
.

但是当我以使10000111(等于135)的方式连接 PINA 引脚时,我在 python 中看到以下输出:

'1'
'3'
'5'
'1'
'3'
'5'
'1'
'3'
'5'
'1'
'3'
'5'
'1'
'3'
'5'
'1'
'3'
'5'
.
.
.

如上所示,它在三行中打印135 !为什么?


仅供参考:这是我在 CodeVision 中为Atmega32编写程序:

interrupt [EXT_INT0] void ext_int0_isr(void)
{
printf("%d",PINA);
}

更新:我按照答案中的建议更改了 ATMEGA 端和 Python 端中的程序:

我的 AVR 中断程序:

interrupt [EXT_INT0] void ext_int0_isr(void)
{
printf("%d",PINA);
printf("%d\n",0);
}

这是我在 python 中的输出:

>>> while(1):
    ser.readline()


'35\n'
'135\n'
'135\n'
'135\n'
'135\n'
'135\n'
'135\n'
'agi\x16agi\x16\xff135255\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'1350\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'1350\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'1350\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'
'135255\n'
'1350\n'
'135255\n'

如您所见,AVR 代码和 Python 代码的输出不是我们所期望的!

4

2 回答 2

4

ser.read()一次只会返回 1 个字节。指定读取多个字节的计数。

>>> x = ser.read()          # reads one byte
>>> x = ser.read(10)        # reads up to ten bytes 

你也可以试试ser.readline()

编辑:

您可以尝试在您为 Atmega32 编写的程序中插入换行符吗:

interrupt [EXT_INT0] void ext_int0_isr(void)
{
printf("%d\n",PINA);
}

然后在打印前寻找换行符:

mylist=[]
while True:
    char = ser.read()
    if char == '\n':
        print(mylist)
        mylist = []
        continue
    mylist.append(char)

ser.readline()按照@hyades 在评论中的建议使用。

于 2014-12-27T08:55:34.697 回答
2

我将尝试解释会发生什么:

在 µC 端,您通过串行线路传输一个值。您必须决定以哪种格式发生这种情况并使接收器使用相同的格式。

您已决定使用 ASCII。因此,设备将每个值转换为其数字并通过线路发送它们。这里的第一个问题是你没有分隔符。如果你有 5 倍的值 77,它会发送7777777777. 但是你怎么知道它不是 7 的 10 倍呢?因此,您必须添加行分隔符。

其他选项可能是发送数据二进制(就像它们一样)或作为所有 2 个字节长的十六进制数据(带有printf("%02x", PINA))。那么你就不需要分隔符了。

您选择哪种方式,您必须使接收器与发送器兼容。

  • 如果您保持原样(但使用\n),则可以使用.readline().
  • 如果您以二进制形式发送它,您可以保持接收器不变。
  • 如果要使用十六进制格式,则必须读取 2 个字节并根据需要进行转换。
于 2014-12-27T09:50:42.220 回答