uart c example code
更新記錄
item | note |
---|---|
20161020 | 第一版 |
目錄
ch341
使用示波器查看,當按下時KB-100有立即送出資料
使用ubuntu測試,發現在取得uart時,需要等到buffer到一定量才會在read讀到
但了解原因
test data
1 | 第一次設定CH3,,無輸出 |
test code
1 | $ cat ex-1.c |
log
log1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94$ lsusb -t
/: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/3p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/8p, 480M
|__ Port 5: Dev 3, If 0, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 5: Dev 3, If 1, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 6: Dev 4, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
|__ Port 6: Dev 4, If 1, Class=Human Interface Device, Driver=usbhid, 1.5M
/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/3p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/6p, 480M
|__ Port 1: Dev 3, If 0, Class=Vendor Specific Class, Driver=ftdi_sio, 12M
|__ Port 5: Dev 8, If 0, Class=Chip/SmartCard, Driver=, 480M
|__ Port 5: Dev 8, If 1, Class=Mass Storage, Driver=usb-storage, 480M
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
|__ Port 2: Dev 5, If 0, Class=Vendor Specific Class, Driver=ftdi_sio, 12M
|__ Port 3: Dev 4, If 0, Class=Communications, Driver=cdc_ether, 480M
|__ Port 3: Dev 4, If 1, Class=CDC Data, Driver=cdc_ether, 480M
|__ Port 4: Dev 6, If 0, Class=Vendor Specific Class, Driver=ch341, 12M
$ sudo lsusb -v -d 1a86:5523
[sudo] password for erwin:
Bus 001 Device 006: ID 1a86:5523 QinHeng Electronics CH341 in serial mode, usb to serial port converter
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 255 Vendor Specific Class
bDeviceSubClass 0
bDeviceProtocol 2
bMaxPacketSize0 8
idVendor 0x1a86 QinHeng Electronics
idProduct 0x5523 CH341 in serial mode, usb to serial port converter
bcdDevice 3.04
iManufacturer 0
iProduct 0
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 39
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 96mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 1
bInterfaceProtocol 2
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0020 1x 32 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0020 1x 32 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 1
Device Status: 0x0000
(Bus Powered)log2
1
2
3
4
5$ sudo cat driver/usbserial
usbserinfo:1.0 driver:2.0
0: module:ftdi_sio name:"FTDI USB Serial Device" vendor:0403 product:6001 num_ports:1 port:0 path:usb-0000:00:14.0-2
1: module:ftdi_sio name:"FTDI USB Serial Device" vendor:0403 product:6001 num_ports:1 port:0 path:usb-0000:00:1a.0-1.1
2: module:ch341 name:"ch341-uart" vendor:1a86 product:5523 num_ports:1 port:0 path:usb-0000:00:14.0-4Retrieving buffer/packet/payload sizes for USB serial write transfer in userspace Linux C code
說明
名稱定義
數傳機(DCE)
DCE(Data Communication Equipment)
是指Modem,母接頭資料終端(DTE)
DTE(Data Terminal equipment)
是指電腦,公接頭TX
output data (DTE -> DCE)RX
input data (DCE -> DTE)
Pins Configuration
- Pins Configuration
PIN (9-pin) | Signal | Source | Type | Description |
---|---|---|---|---|
1 | CD | DCE | Control | Carrier detect |
2 | RX | DCE | Data | Receive data |
3 | TX | DTE | Data | Transmit data |
4 | DTR | DTE | Control | Data terminal ready |
5 | SG | - | - | Signal ground |
6 | DSR | DCE | Control | Data set ready |
7 | RTS | DTE | Control | Request to send |
8 | CTS | DCE | Control | Clear to send |
9 | RI | DCE | control | Ring indicator |
遠距離通信
RTS (request to send) 請求發送
可用CTS/RTS或Xon/Xoff流量控制(Flow control)
- DTE與DCE速度之間存在很大差異,這樣在資料的傳送與接收過程當中很可能出現收方來不及接收的情況,
這時就需要對發方進行控制,以免資料丟失,這個過程就是所謂的流量控制 - CTS(clear to send)/RTS(request to send)則是通過電腦與Modem之間的信號線傳送控制信號來實現流量控制的,即硬體方式
- 請求發送信號(RTS)由電腦產生,通知Modem可以發送資料
- 清除發送信號(CTS)由Modem產生,通知電腦可以傳送資料
- DTE與DCE速度之間存在很大差異,這樣在資料的傳送與接收過程當中很可能出現收方來不及接收的情況,
DSR, DTR
- DSR: 表示 數傳機(DCE)準備好, 只表示設備本身可用
- DTR: 表示 資料終端(DTE)準備好, 只表示設備本身可用
近距離通信
零Modem 的最簡連線(3線制)
在通信中根本不需要RS-232C的控制聯絡信號,只需三根線(發送線、接收線、信號地線)便可實現全雙工非同步串列通信
程式流程
終端機介面
- 正規模式
這種模式中,終端設備會處理特殊字元 - 非正規模式 (non-canonical)
稱為raw模式。在這種模式中,終端設備不會處理特殊字元
- 正規模式
open dev (/dev/ttyUSBx)
1
2//fd = open((const char *)USB_UART, O_RDWR | O_NOCTTY | O_NDELAY );
fd = open((const char *)USB_UART, O_RDWR );設定uart
1
2
3
4
5
6
7
8
9newtio.c_cflag = B2400 | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
// set input mode (non-canonical)
newtio.c_oflag = 0;
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 1;
tcflush(fd,TCIFLUSH);
tcsetattr(fd, TCSANOW, &newtio)-
1
2
3
4
5
6struct termios{
tcflag_t c_iflag; //輸入模式
tcflag_t c_oflag; //輸出模式
tcflag_t c_cflag; //控制模式
tcflag_t c_lflag; //局部模式
cc_t c_cc[NCCS]; //特殊控制字元} 非正規模式的特殊字元TIME和MIN對於輸入字元的處理非常重要,有下列4種組合:
由於在read之後都會return, 因為若為while(1),記得加入sleep(若newtio.c_cc[VTIME]設定為0,不然會吃cpu)1
2
3
4
5組合 說明
MIN=0, TIME = 0 以read()函數讀取串列埠後立即返回,若讀取到字元則傳回字元,否則傳回0。
MIN=0, TIME > 0 以read()函數讀取串列埠後,會在TIME時間內等待第一個字元。若有字元傳入或時間到,立即返回。若讀取到字元則傳回字元,否則傳回0。
MIN > 0, TIME = 0 以read()函數讀取串列埠後會等待資料傳入,若有MIN個字元可讀取,傳回讀取的字元數。
MIN > 0, TIME > 0 以read()函數讀取串列埠後,會等待資料的傳入。若有MIN個字元可讀取時,傳回讀取到的字元數。若TIME的時間到,則read()傳回0。Serial Port Programming in Linux
1
2
3
4
5
6
7
8
9
10// Set the timeouts
// VMIN is the minimum amount
// of characters to read.
options.c_cc[VMIN] = 0;
// The amount of time to wait
// for the amount of data
// specified by VMIN in tenths
// of a second.
optiont.c_cc[VTIME] = 1;