-
serial
2012-05-18 10:13:411.Device Drivers ---> Character devices ---> Serial drivers ---> Samsung Soc Serial support obj-$(CONFIG_SERIAL_CORE) += serial_core.o 是串口核心 obj-$(CONFIG_SERIAL_SAMSUNG)make menuconfig:
1.Device Drivers ---> Character devices ---> Serial drivers ---> <*> Samsung Soc Serial support
obj-$(CONFIG_SERIAL_CORE) += serial_core.o 是串口核心
obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o 是串口具体实现
2.控制台终端
计算机显示器通常被称为控制台终端(console)。必须有一个(些)特殊文件与console相关联,比如虚拟终端tty1 tty2 串口ttySAC0 ttySAC1等。系统所发出的信息会发送到console对应的文件上。
如果不选此项,在启动kernel后就不输出了。
- Starting kernel ...
- Uncompressing Linux......................................................................................................................................
- ................... done, booting the kernel.
在samsung.c中实现console。
- /* s3c24xx_serial_initconsole
- *
- * initialise the console from one of the uart drivers
- */
- static struct console s3c24xx_serial_console = {
- .name = S3C24XX_SERIAL_NAME,
- .device = uart_console_device,
- .flags = CON_PRINTBUFFER,
- .index = -1,
- .write = s3c24xx_serial_console_write,
- .setup = s3c24xx_serial_console_setup
- };
- int s3c24xx_serial_initconsole(struct platform_driver *drv,
- struct s3c24xx_uart_info *info)
- {
- struct platform_device *dev = s3c24xx_uart_devs[0];
- dbg("s3c24xx_serial_initconsole\n");
- /* select driver based on the cpu */
- if (dev == NULL) {
- printk(KERN_ERR "s3c24xx: no devices for console init\n");
- return 0;
- }
- if (strcmp(dev->name, drv->driver.name) != 0)
- return 0;
- s3c24xx_serial_console.data = &s3c24xx_uart_drv;
- s3c24xx_serial_init_ports(info);
- register_console(&s3c24xx_serial_console);
- return 0;
- }
3.<*> Samsung S3C2440/S3C2442 Serial port support
普通串口 /dev/ttySAC*
obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o- </pre><span style="font-family:SimSun;">1.串口的平台设备分散在mach-mini2440.c,arch/arm/plat-s3c/init.c等,在系统启动时注册。比如<span style="font-family:SimSun;">mach-mini2440.c</span></span><pre name="code" class="cpp">static struct s3c2410_uartcfg mini2440_uartcfgs[] __initdata = {
- [0] = {//串口0
- .hwport = 0,
- .flags = 0,
- .ucon = 0x3c5,
- .ulcon = 0x03,
- .ufcon = 0x51,
- },
- [1] = {//串口1
- .hwport = 1,
- .flags = 0,
- .ucon = 0x3c5,
- .ulcon = 0x03,
- .ufcon = 0x51,
- },
- [2] = {//串口2
- .hwport = 2,
- .flags = 0,
- .ucon = 0x3c5,
- .ulcon = 0x03,
- .ufcon = 0x51,
- }
- };
void __init s3c24xx_init_uartdevs(char *name,
struct s3c24xx_uart_resources *res,
struct s3c2410_uartcfg *cfg, int no)
{
struct platform_device *platdev;
struct s3c2410_uartcfg *cfgptr = uart_cfgs;
struct s3c24xx_uart_resources *resp;
int uart;
memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
platdev = s3c24xx_uart_src[cfgptr->hwport];
resp = res + cfgptr->hwport;
s3c24xx_uart_devs[uart] = platdev;
platdev->name = name;
platdev->resource = resp->resources;
platdev->num_resources = resp->nr_resources;
platdev->dev.platform_data = cfgptr;
}
nr_uarts = no;
}
2.串口的平台驱动在
arch/arm/mach-s3c2440/s3c2440.c和samsung.c
初始化:
s3c2440.c初始化时注册了平台驱动
- static int __init s3c2440_serial_init(void)
- {
- return s3c24xx_serial_init(&s3c2440_serial_driver, &s3c2440_uart_inf);//见下面
- }
- static void __exit s3c2440_serial_exit(void)
- {
- platform_driver_unregister(&s3c2440_serial_driver);
- }
- module_init(s3c2440_serial_init);
- module_exit(s3c2440_serial_exit);
- //samsung.c
- int s3c24xx_serial_init(struct platform_driver *drv,
- struct s3c24xx_uart_info *info)
- {
- dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);
- #ifdef CONFIG_PM
- drv->suspend = s3c24xx_serial_suspend;
- drv->resume = s3c24xx_serial_resume;
- #endif
- return platform_driver_register(drv);
- }
samsung.c在初始化时就注册了串口驱动- static int __init s3c24xx_serial_modinit(void)
- {
- int ret;
- ret = uart_register_driver(&s3c24xx_uart_drv);
- if (ret < 0) {
- printk(KERN_ERR "failed to register UART driver\n");
- return -1;
- }
- return 0;
- }
- static void __exit s3c24xx_serial_modexit(void)
- {
- uart_unregister_driver(&s3c24xx_uart_drv);
- }
- module_init(s3c24xx_serial_modinit);
- module_exit(s3c24xx_serial_modexit);
看一下平台驱动的probe,可知是在probe函数里面添加串口
s3c2440.c- static struct s3c24xx_uart_info s3c2440_uart_inf = {
- .name = "Samsung S3C2440 UART",
- .type = PORT_S3C2440,
- .fifosize = 64,
- .rx_fifomask = S3C2440_UFSTAT_RXMASK,
- .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
- .rx_fifofull = S3C2440_UFSTAT_RXFULL,
- .tx_fifofull = S3C2440_UFSTAT_TXFULL,
- .tx_fifomask = S3C2440_UFSTAT_TXMASK,
- .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
- .get_clksrc = s3c2440_serial_getsource,
- .set_clksrc = s3c2440_serial_setsource,
- .reset_port = s3c2440_serial_resetport,
- };
- /* device management */
- static int s3c2440_serial_probe(struct platform_device *dev)
- {
- dbg("s3c2440_serial_probe: dev=%p\n", dev);
- return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);//见下面
- }
- //samsung.c
- static int probe_index;
- int s3c24xx_serial_probe(struct platform_device *dev,
- struct s3c24xx_uart_info *info)
- {
- struct s3c24xx_uart_port *ourport;
- int ret;
- dbg("s3c24xx_serial_probe(%p, %p) %d\n", dev, info, probe_index);
- ourport = &s3c24xx_serial_ports[probe_index];
- probe_index++;
- dbg("%s: initialising port %p...\n", __func__, ourport);
- ret = s3c24xx_serial_init_port(ourport, info, dev);
- if (ret < 0)
- goto probe_err;
- dbg("%s: adding port\n", __func__);
- uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
- platform_set_drvdata(dev, &ourport->port);
- ret = device_create_file(&dev->dev, &dev_attr_clock_source);
- if (ret < 0)
- printk(KERN_ERR "%s: failed to add clksrc attr.\n", __func__);
- ret = s3c24xx_serial_cpufreq_register(ourport);
- if (ret < 0)
- dev_err(&dev->dev, "failed to add cpufreq notifier\n");
- return 0;
- probe_err:
- return ret;
- }
几个重要的结构体- //uart_ops
- static struct uart_ops s3c24xx_serial_ops = {
- .pm = s3c24xx_serial_pm,
- .tx_empty = s3c24xx_serial_tx_empty,
- .get_mctrl = s3c24xx_serial_get_mctrl,
- .set_mctrl = s3c24xx_serial_set_mctrl,
- .stop_tx = s3c24xx_serial_stop_tx,
- .start_tx = s3c24xx_serial_start_tx,
- .stop_rx = s3c24xx_serial_stop_rx,
- .enable_ms = s3c24xx_serial_enable_ms,
- .break_ctl = s3c24xx_serial_break_ctl,
- .startup = s3c24xx_serial_startup,
- .shutdown = s3c24xx_serial_shutdown,
- .set_termios = s3c24xx_serial_set_termios,
- .type = s3c24xx_serial_type,
- .release_port = s3c24xx_serial_release_port,
- .request_port = s3c24xx_serial_request_port,
- .config_port = s3c24xx_serial_config_port,
- .verify_port = s3c24xx_serial_verify_port,
- };
- //uart_driver
- static struct uart_driver s3c24xx_uart_drv = {
- .owner = THIS_MODULE,
- .dev_name = "s3c2410_serial",
- .nr = CONFIG_SERIAL_SAMSUNG_UARTS,
- .cons = S3C24XX_SERIAL_CONSOLE,
- .driver_name = S3C24XX_SERIAL_NAME,
- .major = S3C24XX_SERIAL_MAJOR,
- .minor = S3C24XX_SERIAL_MINOR,
- };
- //s3c24xx_uart_port
- static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = {
- [0] = {
- .port = {
- .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),
- .iotype = UPIO_MEM,
- .irq = IRQ_S3CUART_RX0,
- .uartclk = 0,
- .fifosize = 16,
- .ops = &s3c24xx_serial_ops,
- .flags = UPF_BOOT_AUTOCONF,
- .line = 0,
- }
- },
- [1] = {
- .port = {
- .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock),
- .iotype = UPIO_MEM,
- .irq = IRQ_S3CUART_RX1,
- .uartclk = 0,
- .fifosize = 16,
- .ops = &s3c24xx_serial_ops,
- .flags = UPF_BOOT_AUTOCONF,
- .line = 1,
- }
- },
- #if CONFIG_SERIAL_SAMSUNG_UARTS > 2
- [2] = {
- .port = {
- .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock),
- .iotype = UPIO_MEM,
- .irq = IRQ_S3CUART_RX2,
- .uartclk = 0,
- .fifosize = 16,
- .ops = &s3c24xx_serial_ops,
- .flags = UPF_BOOT_AUTOCONF,
- .line = 2,
- }
- },
- #endif
- #if CONFIG_SERIAL_SAMSUNG_UARTS > 3
- [3] = {
- .port = {
- .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[3].port.lock),
- .iotype = UPIO_MEM,
- .irq = IRQ_S3CUART_RX3,
- .uartclk = 0,
- .fifosize = 16,
- .ops = &s3c24xx_serial_ops,
- .flags = UPF_BOOT_AUTOCONF,
- .line = 3,
- }
- }
- #endif
- };
- //serial_core.h
- struct uart_port {
- spinlock_t lock; /* port lock */
- unsigned long iobase; /* in/out[bwl] */
- unsigned char __iomem *membase; /* read/write[bwl] */
- unsigned int (*serial_in)(struct uart_port *, int);
- void (*serial_out)(struct uart_port *, int, int);
- unsigned int irq; /* irq number */
- unsigned long irqflags; /* irq flags */
- unsigned int uartclk; /* base uart clock */
- unsigned int fifosize; /* tx fifo size */
- unsigned char x_char; /* xon/xoff char */
- unsigned char regshift; /* reg offset shift */
- unsigned char iotype; /* io access style */
- unsigned char unused1;
- #define UPIO_PORT (0)
- #define UPIO_HUB6 (1)
- #define UPIO_MEM (2)
- #define UPIO_MEM32 (3)
- #define UPIO_AU (4) /* Au1x00 type IO */
- #define UPIO_TSI (5) /* Tsi108/109 type IO */
- #define UPIO_DWAPB (6) /* DesignWare APB UART */
- #define UPIO_RM9000 (7) /* RM9000 type IO */
- unsigned int read_status_mask; /* driver specific */
- unsigned int ignore_status_mask; /* driver specific */
- struct uart_state *state; /* pointer to parent state */
- struct uart_icount icount; /* statistics */
- struct console *cons; /* struct console, if any */
- #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(SUPPORT_SYSRQ)
- unsigned long sysrq; /* sysrq timeout */
- #endif
- upf_t flags;
- #define UPF_FOURPORT ((__force upf_t) (1 << 1))
- #define UPF_SAK ((__force upf_t) (1 << 2))
- #define UPF_SPD_MASK ((__force upf_t) (0x1030))
- #define UPF_SPD_HI ((__force upf_t) (0x0010))
- #define UPF_SPD_VHI ((__force upf_t) (0x0020))
- #define UPF_SPD_CUST ((__force upf_t) (0x0030))
- #define UPF_SPD_SHI ((__force upf_t) (0x1000))
- #define UPF_SPD_WARP ((__force upf_t) (0x1010))
- #define UPF_SKIP_TEST ((__force upf_t) (1 << 6))
- #define UPF_AUTO_IRQ ((__force upf_t) (1 << 7))
- #define UPF_HARDPPS_CD ((__force upf_t) (1 << 11))
- #define UPF_LOW_LATENCY ((__force upf_t) (1 << 13))
- #define UPF_BUGGY_UART ((__force upf_t) (1 << 14))
- #define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15))
- #define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16))
- #define UPF_CONS_FLOW ((__force upf_t) (1 << 23))
- #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24))
- /* The exact UART type is known and should not be probed. */
- #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27))
- #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28))
- #define UPF_FIXED_PORT ((__force upf_t) (1 << 29))
- #define UPF_DEAD ((__force upf_t) (1 << 30))
- #define UPF_IOREMAP ((__force upf_t) (1 << 31))
- #define UPF_CHANGE_MASK ((__force upf_t) (0x17fff))
- #define UPF_USR_MASK ((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY))
- unsigned int mctrl; /* current modem ctrl settings */
- unsigned int timeout; /* character-based timeout */
- unsigned int type; /* port type */
- const struct uart_ops *ops;
- unsigned int custom_divisor;
- unsigned int line; /* port index */
- resource_size_t mapbase; /* for ioremap */
- struct device *dev; /* parent device */
- unsigned char hub6; /* this should be in the 8250 driver */
- unsigned char suspended;
- unsigned char unused[2];
- void *private_data; /* generic platform data pointer */
- };
在probe中(s3c24xx_serial_probe(),samsung.c)用uart_add_one_port()将uart_port加入uart_driver
每一uart_port对应一个uart_ops,主要工作就是实现这些函数指针。 -
Python 之 Serial串口通信
2019-06-07 09:36:13确定串口名称 WINDOWS #!/usr/bin/env python #-*- coding: utf-8 -* import serial ...import serial.tools.list_ports ...plist = list(serial.tools.list_ports.comports()) ... print ("The Serial...0 Serial方法
1、导入pyserial模块
import serial
2、打开串行口
// 打开串口0, 9600,8N1,连接超时0.5秒
import serial
ser=serial.Serial("/dev/ttyUSB0",9600,timeout=0.5) #使用USB连接串行口
ser=serial.Serial("/dev/ttyAMA0",9600,timeout=0.5) #使用树莓派的GPIO口连接串行口
ser=serial.Serial(1,9600,timeout=0.5)#winsows系统使用com1口连接串行口
ser=serial.Serial(“com1”,9600,timeout=0.5)#winsows系统使用com1口连接串行口
ser=serial.Serial("/dev/ttyS1",9600,timeout=0.5)#Linux系统使用com1口连接串行口
print ser.name#打印设备名称
print ser.port#打印设备名
ser.open() #打开端口
s = ser.read(10)#从端口读10个字节
ser.write(“hello”)#向端口些数据
ser.close()#关闭端口
data = ser.read(20) #是读20个字符
data = ser.readline() #是读一行,以/n结束,要是没有/n就一直读,阻塞。
data = ser.readlines()和ser.xreadlines()#都需要设置超时时间
ser.baudrate = 9600 #设置波特率
ser.isOpen() #看看这个串口是否已经被打开3、获得串行口状态
串行口的属性:
name:设备名字
portstr:已废弃,用name代替
port:读或者写端口
baudrate:波特率
bytesize:字节大小
parity:校验位
stopbits:停止位
timeout:读超时设置
writeTimeout:写超时
xonxoff:软件流控
rtscts:硬件流控
dsrdtr:硬件流控
interCharTimeout:字符间隔超时属性的使用方法:
ser=serial.Serial("/dev/ttyAMA0",9600,timeout=0.5)
ser.open()print ser.name
print ser.port
print ser.baudrate#波特率
print ser.bytesize#字节大小
print ser.parity#校验位N-无校验,E-偶校验,O-奇校验
print ser.stopbits#停止位
print ser.timeout#读超时设置
print ser.writeTimeout#写超时
print ser.xonxoff#软件流控
print ser.rtscts#硬件流控
print ser.dsrdtr#硬件流控
print ser.interCharTimeout#字符间隔超时ser.close()
4、设置串行口状态
需要用的常量
bytesize:FIVE BITS、SIXBITS、SEVENBITS、EIGHTBITS
parity: PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE
stopbits: STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO
异常:
ValueError:参数错误
SerialException:找不到设备或不能配置ser.baudrate=9600#设置波特率
ser.bytesize=8#字节大小
ser.bytesize=serial.EiGHTBITS#8位数据位ser.parity=serial.PARITY_EVEN#偶校验
ser.parity=serial.PARITY_NONE#无校验
ser.parity=serial.PARITY_ODD#奇校验ser.stopbits=1#停止位
ser.timeout=0.5#读超时设置
ser.writeTimeout=0.5#写超时
ser.xonxoff#软件流控
ser.rtscts#硬件流控
ser.dsrdtr#硬件流控
ser.interCharTimeout#字符间隔超时5、Readline方法的使用
是读一行,以/n结束,要是没有/n就一直读,阻塞。
使用readline()时应该注意:打开串口时应该指定超时,否则如果串口没有收到新行,则会一直等待。如果没有超时,readline会报异常。
6、serial.Serial类——原生端口
class serial.Serial
{
init(port=None, baudrate=9600, bytesize=EIGHTBITS,parity=PARITY_NONE, stopbits=STOPBITS_ONE, timeout=None, xonxoff=False, rtscts=False, writeTimeout=None, dsrdtr=False, interCharTimeout=None)#其中:
# bytesize:FIVEBITS、SIXBITS、SEVENBITS、EIGHTBITS
# parity: PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE
# stopbits: STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO
#异常:
#ValueError:参数错误
#SerialException:找不到设备或不能配置open():打开串口
close():立即关闭串口
del():析构函数
read(size=1):从串口读size个字节。如果指定超时,则可能在超时后返回较少的字节;如果没有指定超时,则会一直等到收完指定的字节数。
write(data):发送data,并返回发送字节数。如果bytes和bytearray可用(python 2.6以上),则接受其作为参数;否则接受str作为参数。
#异常:SerialTimeoutException——配置了写超时并发生超时时发生此异常。inWaiting():返回接收缓存中的字节数
flush():等待所有数据写出。
flushInput():丢弃接收缓存中的所有数据
flushOutput():终止当前写操作,并丢弃发送缓存中的数据。
sendBreadk(duration=0.25):发送BREAK条件,并于duration时间之后返回IDLE
setBreak(level=True):根据level设置break条件。
setRTS(level=True)
setDTR(level=True)
getCTS()
getDSR()
getRI()
getCD()
#只读属性:
name:设备名字
portstr:已废弃,用name代替
port:读或者写端口
baudrate:波特率
bytesize:字节大小
parity:校验位
stopbits:停止位
timeout:读超时设置
writeTimeout:写超时
xonxoff:软件流控
rtscts:硬件流控
dsrdtr:硬件流控
interCharTimeout:字符间隔超时#端口设置可以被读入字典,也可从字典加载设置:
getSettingDict():返回当前串口设置的字典
applySettingDict(d):应用字典到串口设置#对提供io库的系统(python 2.6或以上),Serial从io.RawIOBase派生。对其它系统,从FileLike派生。
#异常:
exception serial.SerialException
exception serial.SerialTimeoutException#常量:
serial.VERSION:pyserial版本#模块函数和属性:
serial.device(number)serial.serial_for_url(url, *args, **kwargs)
serial.protocol_handler_packages()
serial.to_bytes(sequence):接收一个字符串或整数列表sequence,返回bytes实例
1 确定串口名称
1.1 WINDOWS
获取可用串口列表
#!/usr/bin/env python #-*- coding: utf-8 -* import serial import serial.tools.list_ports plist = list(serial.tools.list_ports.comports()) if len(plist) <= 0: print ("The Serial port can't find!") else: plist_0 =list(plist[0]) serialName = plist_0[0] serialFd = serial.Serial(serialName,9600,timeout = 60) print ("check which port was really used >",serialFd.name)
import serial #导入模块 import serial.tools.list_ports port_list = list(serial.tools.list_ports.comports()) print(port_list) if len(port_list) == 0: print('无可用串口') else: for i in range(0,len(port_list)): print(port_list[i])
1.2 LINUX
查询从系统启动到现在串口插拔的信息,显示串口Ubuntu连接的端口号:
在终端输入:
dmesg | grep ttyS*
在Ubuntu下装了CuteCom,但当打开 /dev/ttyUSB0 时,总提示错误,打开失败时:
用 Minicom 可以正常读取 ttyUSB0。
sudo chmod 666 /dev/ttyUSB0
这样修改后, CuteCom 就可以正常打开 USB 串口了
1,pycharm程序端代码。
#usr/bin/python3 # -*- coding: utf-8 -*- import serial from time import sleep ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=0.5) def recv(serial): global data while True: data = serial.read(30) if data == '': continue else: break sleep(0.02) return data while True: data = recv(ser) ser.write(data)
在pycharm上的程序:
程序效果为: 运行后,在CuteCom发生的代码, 程序这边会原文返回发给CuteCom。
1.3 Python(Linux下)获取串口的idv和idp以及serial序列号
串口端口的获取脚本
# coding=utf-8 # __author__ = 'Haleydu' __editTime__ = '2018.12.7' import serial.tools.list_ports import serial import os import re class AutoMatchSerialPort: #一.获取串口 or 判断是否存在该串口 def getSerial(self,needdev=''): needSerial='' port_list = list(serial.tools.list_ports.comports()) if len(port_list) <= 0: print ("The Serial port can't find!") else: #1.过滤,获取需要的串口 for i in list(port_list): if i.name==needdev: needSerial=i.name print(i.name,end=',') print('\n') #2.返回获取的目的串口为了绑定 return needSerial # 二.根据端口号返回ID号和硬件号 def getSerialIDAndSer(self,dev): cmd = "udevadm info --attribute-walk --name=" + dev result = self.execCmd(cmd) pat1 = "ATTRS{idVendor}==.?(\d\d\d\d).?" pat2 = "ATTRS{idProduct}==.?(\d\d\d\d).?" pat3 = 'ATTRS{serial}==.([A-Za-z0-9]+).' ret1 = re.search(pat1,result) ret2 = re.search(pat2,result) ret3 = re.search(pat3,result) idv = ret1.group(1) idp = ret2.group(1) ser = ret3.group(1) return idv,idp,ser # 三.根据ID号或者序列号返回串口的端口号,也可以用别名直接调用该串口(运行后需要拔插目的串口后生效) def getSerialPort(self,idv='',idp='',ser='',alias='ttyUSB_test'): if idv==''or idp=='': contentID = 'ATTRS{serial}=="'+ser+', MODE:="0777", SYMLINK+="'+ alias +'" \n' elif ser=='': contentID = '", ATTRS{idVendor}=="'+idv+'", ATTRS{idProduct}=="'+idp+'", MODE:="0777", SYMLINK+="'+ alias +'" \n' else: contentID = 'ATTRS{serial}=="'+ser+'", ATTRS{idVendor}=="'+idv+'", ATTRS{idProduct}=="'+idp+'", MODE:="0777", SYMLINK+="'+ alias +'" \n' path='/etc/udev/rules.d/getSerialPort_'+alias+'.rules' if os.path.exists(path): #print('存在文件') f = open(path,"w") f.write(contentID) f.flush() f.close() #print('创建成功') #print('重新拔插串口后生效') else: #print('不存在文件,开始创建getSerialPort_'+alias+'.rules的udev规则文件') f = open(path,"w") f.write(contentID) f.flush() f.close() #print('创建成功') #print('重新拔插串口后生效') #重启udev规则 #sudo /etc/init.d/udev restart #根据ID获得端口号 cmd = "udevadm info --attribute-walk --name=" + alias result = self.execCmd(cmd) pat = '(ttyUSB.)' ret = re.search(pat,result) dev='' try: dev = ret.group(1) except AttributeError: if dev=='': print('重新拔插串口后生效') return dev #调用终端,获取终端输出 def execCmd(self,cmd): r = os.popen(cmd) result = r.read() r.close() return result if __name__ == '__main__': am=AutoMatchSerialPort() am.getSerial() print('ttyUSB0:' + str(am.getSerialIDAndSer("ttyUSB0"))) print('ttyUSB1:' + str(am.getSerialIDAndSer("ttyUSB1"))) print('0403:6002,FT2NPXY4,ttyUSB_1:' + am.getSerialPort('0403','6002','FT2NPXY4','ttyUSB_1')) print('0403:6001,FTSYWCXZ,ttyUSB_2:' + am.getSerialPort('0403','6001','FTSYWCXZ','ttyUSB_2'))
2 SERIAL 串口操作
参考文档:
https://blog.csdn.net/qq_14997473/article/details/80875722:Python学习笔记——串口配置以及发送数据https://blog.csdn.net/ubuntu14/article/details/75335106:python实现串口自动触发工作
(1) 安装pyserial库
pip install pyserial
serial = serial.Serial(‘COM1’, 115200) 打开COM1并设置波特率为115200,COM1只适用于Windows
serial = serial.Serial(‘/dev/ttyS0’, 115200) 打开/dev/ttyS0并设置波特率为115200, 只适用于Linux(2) pyserial库常用函数介绍
serial = serial.Serial(‘COM1’, 115200) 打开COM1并设置波特率为115200,COM1只适用于Windows serial = serial.Serial(‘/dev/ttyS0’, 115200) 打开/dev/ttyS0并设置波特率为115200, 只适用于Linux print serial .portstr 能看到第一个串口的标识 serial .write(“hello”) 往串口里面写数据 serial .close() 关闭serial 表示的串口 serial .open() 打开串口 data = serial .read(num) 读num个字符 data = serial .readline() 读一行数据,以/n结束,要是没有/n就一直读,阻塞。 serial .baudrate = 9600 设置波特率 print serial 可查看当前串口的状态信息 serial .isOpen() 当前串口是否已经打开 serial.inWaiting() 判断当前接收的数据 serial.flushInput() 清除输入缓冲区数据 serial.flushOutput() 中止当前输出并清除输出缓冲区数据
(3) 实例: 获取从其他串口发送来的数据并回显
#!/usr/bin/python # coding=UTF-8 import serial ################################################### # # 功 能: 将接收到的数据已hex显示 # 参 数: 串口接受到的数据 # 返 回: 转换后的数据 # ################################################### def hexshow(data): hex_data = '' hLen = len(data) for i in xrange(hLen): hvol = ord(data[i]) hhex = '%02x' % hvol hex_data += hhex+' ' print 'hexshow:', hex_data ################################################### # # 功 能: 将需要发送的字符串以hex形式发送 # 参 数: 待发送的数据 # 返 回: 转换后的数据 # ################################################### def hexsend(string_data=''): hex_data = string_data.decode("hex") return hex_data if __name__ == '__main__': serial = serial.Serial('/dev/ttyS0', 115200) print serial if serial.isOpen(): print("open success") else: print("open failed") try: while True: count = serial.inWaiting() if count > 0: data = serial.read(count) if data != b'': print("receive:", data) serial.write(data) else: serial.write(hexsend(data)) except KeyboardInterrupt: if serial != None: serial.close()
16进制处理
import serial #导入模块 try: portx="COM3" bps=115200 #超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒) timex=None ser=serial.Serial(portx,bps,timeout=timex) print("串口详情参数:", ser) #十六进制的发送 result=ser.write(chr(0x06).encode("utf-8"))#写数据 print("写总字节数:",result) #十六进制的读取 print(ser.read().hex())#读一个字节 print("---------------") ser.close()#关闭串口 except Exception as e: print("---异常---:",e)
其他
import serial #导入模块 try: #端口,GNU / Linux上的/ dev / ttyUSB0 等 或 Windows上的 COM3 等 portx="COM3" #波特率,标准值之一:50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200 bps=115200 #超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒) timex=5 # 打开串口,并得到串口对象 ser=serial.Serial(portx,bps,timeout=timex) print("串口详情参数:", ser) print(ser.port)#获取到当前打开的串口名 print(ser.baudrate)#获取波特率 result=ser.write("我是东小东".encode("gbk"))#写数据 print("写总字节数:",result) #print(ser.read())#读一个字节 # print(ser.read(10).decode("gbk"))#读十个字节 #print(ser.readline().decode("gbk"))#读一行 #print(ser.readlines())#读取多行,返回列表,必须匹配超时(timeout)使用 #print(ser.in_waiting)#获取输入缓冲区的剩余字节数 #print(ser.out_waiting)#获取输出缓冲区的字节数 #循环接收数据,此为死循环,可用线程实现 while True: if ser.in_waiting: str=ser.read(ser.in_waiting ).decode("gbk") if(str=="exit"):#退出标志 break else: print("收到数据:",str) print("---------------") ser.close()#关闭串口 except Exception as e: print("---异常---:",e)
3 解决 ImportError: No module named ‘serial’ 问题
在pycharm里编写Python串口程序的时候,编译时提示 ImportError: No module named ‘serial’
解决办法:
安装 serial module
这里区分python2和 python3:首先需要在终端输入:
sudo apt install python-pip //python2 sudo apt install python3-pip //python3
安装python3的 pip3的时候,如果时国内的软件源可能安装不上,(当时用中国科学技术大学的软件源,python3-pip下载有问题),换成ubuntu官网成功下载。如果系统已经安装过了pip,就不需要这一步了。
然后通过:pip install pyserial //python2 pip3 install pyserial //python3
可以从pyserial下载这里去获取源码进行熟悉和学习。
4 PYCHARM 里面的no module name serial错误
错误原因在于:==interpreter的选择==
安装目录下的python,其模块只有一个setuptools,所以找不到serial
ANACONDA下的python.exe里面包含了多个模块,所以应该将interpreter改为该目录下的python.exe5 TypeError: ‘bool’ object is not callable
因为 isOpen是属性所以有如下做法
def isOpen(self): return True def is_active(self): return True def is_anonymous(self): return False
不是方法,将sOpen()括号去掉,完美解决!
-
解决ModuleNotFoundError: No module named ‘serial.tools‘问题
2020-07-31 14:41:25pycharm 中已经安装了serial,在调用 port_list = list(serial.tools.list_ports.comports()) 的时候报错: ModuleNotFoundError: No module named 'serial.tools' 这时我们不能直接pip install serial.tools,...pycharm 中已经安装了serial,在调用
port_list = list(serial.tools.list_ports.comports())
的时候报错:
ModuleNotFoundError: No module named 'serial.tools'
这时我们不能直接
pip install serial.tools
,而是应该安装pip install pyserial
即可 -
Timeout on Serial connect
2020-12-01 12:36:21Unable to open port: [Errno 2] could not open port /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0: [Errno 2] No such file or directory: '/dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0... -
serial安装
2019-07-13 17:40:34apt-cache search serial http://packages.ros.org/ros/ubuntu/pool/main/r/ros-kinetic-serial/ sudo dpkg -i /home/××××××××/下载/ros-kinetic-serial_1.2.1-0xenial-20190607-172310-0800_amd64.deb .....手动装包,不通过终端
apt-cache search serial
http://packages.ros.org/ros/ubuntu/pool/main/r/ros-kinetic-serial/
sudo dpkg -i /home/××××××××/下载/ros-kinetic-serial_1.2.1-0xenial-20190607-172310-0800_amd64.deb
-
module ‘serial’ has no attribute ‘Serial’
2020-07-02 16:56:43module ‘serial’ has no attribute ‘Serial’ 问题代码: import serial # 导入pyserial com = serial.Serial('com3', 115200) # 实例化串口,com3,波特率115200 报错:module ‘serial’ has no attribute ... -
Serial Programming/Serial Java
2014-07-09 10:09:04http://en.wikibooks.org/wiki/Serial_Programming/Serial_Java -
Arduino编程之Serial.println()和Serial.print()
2018-04-22 19:59:51Arduino编程之Serial.println()和Serial.print()Arduino 的输出基本就用两个函数 print 和 println,区别在于后者比前者多了回车换行Serial.println(data)从串行端口输出数据,跟随一个回车(ASCII 13, 或 'r')和一... -
Arduino之坑(一)——serial.println 、serial.write、Serial.print()
2019-11-20 10:22:210.serial.println 与Serial.print() Arduino 的输出基本就用两个函数 print 和 println,区别在于后者比前者多了回车换行 Serial.println(data) 从串行端口输出数据,跟随一个回车(ASCII 13, 或 'r')和一个换行... -
Serial.begin
2019-08-02 17:53:00串口波特率的设置:通常我们使用Serial.begin(speed)来完成串口的初始化,这种方式,只能配置串口的波特率。 使用Serial.begin(speed, config)可以配置数据位、校验位、停止位等。例如Serial.begin(9600,... -
MTK cdc serial 驱动
2014-10-25 16:33:09MTK cdc serial 驱动,找了很久才找到,这个能用,对于MTK ATA测试中 -
Serial.print()函数与Serial.write()函数的区别
2019-03-31 11:29:33Arduino 的Serial.print()函数与Serial.write()函数的区别 1. 在发送数值类型数据时的区别 首先你需要理解这两句话: Serial.print() 发送的是字符, Serial.write() 发送的字节. 例 1.发送十进制的数据 int i=97;... -
AttributeError: module ‘serial‘ has no attribute ‘Serial
2020-07-30 11:05:54AttributeError: module ‘serial’ has no attribute ‘Serial’ AttributeError: module ‘serial’ has no attribute ‘Serial’ 运行python的时候出现AttributeError: module ‘serial’ has no attribute ... -
usb-to-serial-win10
2016-11-27 22:59:58PL2303芯片Prolific USB-to-Serial Comm Port,在WIN10下可用的驱动。也有win7和XP的。 -
USB-serial controller驱动
2009-09-22 10:09:47USB-serial controller驱动 usb到console口的转接器驱动,连接路由器交换机时可能需要转接 -
Serial Drivers
2013-11-25 16:42:38http://www.linux.it/~rubini/docs/serial/serial.html ...This article is meant to show the internal structure of device drivers for serial ports, and how they can be perform a variety of services includin -
Serial Flash
2013-02-04 11:20:00Serial flash is NOR flash memory incorporating a serial interface, specifically, aserial peripheral interface (SPI) bus Serial flash是一种集成了SPI的NOR Flash。 转载于:... -
python 安装serial及No module named ‘serial.tools‘等问题解决方案
2020-12-26 14:07:42安装serial pip命令安装 pip install serial 测试安装 import serial 按照惯例,Python 引入 serial 不报错即为安装成功 问题汇总 关于serial安装使用相关的问题之后会在这里补充维护 import serial.... -
pgSQL serial IDENTITY
2019-05-28 13:31:46在pgSQL中 主键生成策略可以用: serial ,IDENTITY 需要注意的是 IDENTITY是 pgSQL 10 版本才有的新特性, 如果使用的是 pgSQL 9版本以及以下版本,在 生成主键的时请选择 serial ... -
AttributeError: module 'serial' has no attribute 'Serial'
2019-04-21 16:21:36(1)你的文件名serial.py和引入的第三方库名字重复了,解决方法:重命名文件名 (2)你没有安装第三方库文件,解决方法,pip3 install serial 之后 pip3 install pyserial (3)可能由于网络原因没有安装好,解决... -
arduino 的 serial.println 与serial.write区别
2018-06-10 09:50:19Serial.print 发送的是字符,如果你发送97,发过去的其实是9的ascii码(00111001)和7的ascii码(00110111)。Serial.write 发送的字节,是一个0-255的数字,如果你发97, 发过去的其实是97的二进制(01100001),对应... -
python 使用serial
2018-02-07 11:20:05##模块为PyserialCode:import serial import serial.tools.list_ports import time #####list serial ports####port_list = list(serial.tools.list_ports.comports()) for port in port_list: print port[0]#... -
Virtual Serial Port Driver 8
2017-10-24 13:25:28最低2积分? Virtual Serial Port Driver 8下载 -
import serial 使用方法
2019-02-15 17:14:34import serial python中的串口模块 serial 中常用方法 ser = serial.Serial(0) 是打开第一个串口(实例化一个串口) print ser.portstr 能看到第一个串口的标识,windows下是COM1 ser.baudrate = 9600 设置... -
PYTHON3 AttributeError: module ‘serial‘ has no attribute ‘Serial
2020-08-15 08:03:00print(serial.Serial()) 执行上述代码的时候报错(如题) 多方找寻答案未果,后来发现,因为我安装了两个库一个“serial”,另一个“pyserial”。第一个库因该不是针对串口的。应该用第二个“pyserial”。 所以... -
PostgreSQL SERIAL创建自增列
2019-06-22 21:44:08PostgreSQL SERIAL创建自增列 本文我们介绍PostgreSQL SERIAL,并展示如何使用serial类型创建表自增列。 PostgreSQL SERIAL伪类型 PostgreSQL序列是一种特殊的用于生产整数序列数据库对象。序列通常用于主键列,与... -
serial setting
2013-05-13 14:12:25Serial port From Wikipedia, the free encyclopedia Jump to: navigation, search A male DE-9 connector used for a serial port on an IBM PC compatible computer along with the se -
HSM USB SERIAL DRIVER
2014-04-05 20:56:25HSM USB SERIAL DRIVER HSM 系统驱动程序
-
小红书图片去水印(免费版).rar
-
一天学完MySQL数据库
-
图像分类预习知识笔记
-
应广105G雾化片驱动.rar
-
NFS 网络文件系统
-
基于Qt的LibVLC开发教程
-
股票投资了解
-
MySQL 高可用(DRBD + heartbeat)
-
MySQL 备份与恢复详解(高低版本 迁移;不同字符集 相互转换;表
-
2021年 系统分析师 系列课
-
马士兵老师HashMap学习笔记
-
基于Hypervisor虚拟化技术的Hadoop云平台管理方案的研究.docx
-
request+response学习笔记
-
【Zookeeper】集群模式:架构设计猜想
-
从Docker到Kubernetes之技术实战.pdf
-
FFmpeg4.3系列之16:WebRTC之小白入门与视频聊天的实战
-
DHCP 动态主机配置服务(在Linux环境下,配置单网段或跨网段提)
-
SaaS产品项目实施流程
-
Galera 高可用 MySQL 集群(PXC v5.6 + Ngin
-
Hdu自动健康打卡系统