Raspberry Pi Resources-Using the UART
本文来自:http://www.raspberry-projects.com/pi/programming-in-c/uart-serial-port/using-the-uart
Using the UART
If you are running Raspbian or similar then the UART will be used as a serial console. Using a suitable cable, such as the TTL-232R-3V3-WE, you can connect it to your PC and using some simple terminal software set to 115200-8-N-1 use the command line interface to the Raspberry Pi in the same way as if you we're using a keyboard and screen connected to it. However that's no use if you want to use the UART interface for your own application running on the RPi.
Turning off the UART functioning as a serial console
See here.
Using The UART In Your C Code
(This is based on the example code given here).
Headers required
#include <stdio.h>
#include <unistd.h> //Used for UART
#include <fcntl.h> //Used for UART
#include <termios.h> //Used for UART
Setting Up The UART
//-------------------------
//----- SETUP USART 0 -----
//-------------------------
//At bootup, pins 8 and 10 are already set to UART0_TXD, UART0_RXD (ie the alt0 function) respectively
int uart0_filestream = -1;
//OPEN THE UART
//The flags (defined in fcntl.h):
// Access modes (use 1 of these):
// O_RDONLY - Open for reading only.
// O_RDWR - Open for reading and writing.
// O_WRONLY - Open for writing only.
//
// O_NDELAY / O_NONBLOCK (same function) - Enables nonblocking mode. When set read requests on the file can return immediately with a failure status
// if there is no input immediately available (instead of blocking). Likewise, write requests can also return
// immediately with a failure status if the output can't be written immediately.
//
// O_NOCTTY - When set and path identifies a terminal device, open() shall not cause the terminal device to become the controlling terminal for the process.
uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY); //Open in non blocking read/write mode
if (uart0_filestream == -1)
{
//ERROR - CAN'T OPEN SERIAL PORT
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
}
//CONFIGURE THE UART
//The flags (defined in /usr/include/termios.h - see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html):
// Baud rate:- B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B500000, B576000, B921600, B1000000, B1152000, B1500000, B2000000, B2500000, B3000000, B3500000, B4000000
// CSIZE:- CS5, CS6, CS7, CS8
// CLOCAL - Ignore modem status lines
// CREAD - Enable receiver
// IGNPAR = Ignore characters with parity errors
// ICRNL - Map CR to NL on input (Use for ASCII comms where you want to auto correct end of line characters - don't use for bianry comms!)
// PARENB - Parity enable
// PARODD - Odd parity (else even)
struct termios options;
tcgetattr(uart0_filestream, &options);
options.c_cflag = B9600 | CS8 | CLOCAL | CREAD; //<Set baud rate
options.c_iflag = IGNPAR;
options.c_oflag = 0;
options.c_lflag = 0;
tcflush(uart0_filestream, TCIFLUSH);
tcsetattr(uart0_filestream, TCSANOW, &options);
Transmitting Bytes
//----- TX BYTES -----
unsigned char tx_buffer[20];
unsigned char *p_tx_buffer;
p_tx_buffer = &tx_buffer[0];
*p_tx_buffer++ = 'H';
*p_tx_buffer++ = 'e';
*p_tx_buffer++ = 'l';
*p_tx_buffer++ = 'l';
*p_tx_buffer++ = 'o';
if (uart0_filestream != -1)
{
int count = write(uart0_filestream, &tx_buffer[0], (p_tx_buffer - &tx_buffer[0])); //Filestream, bytes to write, number of bytes to write
if (count < 0)
{
printf("UART TX error\n");
}
}
Receiving Bytes
Because O_NDELAY has been used this will exit if there are no receive bytes waiting (non blocking read), so if you want to hold waiting for input simply put this in a while loop
//----- CHECK FOR ANY RX BYTES -----
if (uart0_filestream != -1)
{
// Read up to 255 characters from the port if they are there
unsigned char rx_buffer[256];
int rx_length = read(uart0_filestream, (void*)rx_buffer, 255); //Filestream, buffer to store in, number of bytes to read (max)
if (rx_length < 0)
{
//An error occured (will occur if there are no bytes)
}
else if (rx_length == 0)
{
//No data waiting
}
else
{
//Bytes received
rx_buffer[rx_length] = '\0';
printf("%i bytes read : %s\n", rx_length, rx_buffer);
}
}
Closing the UART if no longer needed
//----- CLOSE THE UART -----
close(uart0_filestream);
Using minicom on the UART
Install minicom:
sudo apt-get install minicom
Running minicom:
minicom -b 115200 -o -D /dev/ttyAMA0
To test the UART is working you can simply link the TX and RX pins to each other and verify minicom receives what you type.
Troubleshooting UART Problems
The above code works (we've used it for TX and RX). If you can't get to to work for you and you've been through the steps to release the UART from being used for the console try the following:
Permissions
This command will set read and write access permissions for all users on the UART – it shouldn't be needed but can be used just to be sure there is not a permissions problem:
sudo chmod a+rw /dev/ttyAMA0
Baud Rate Error
Try using a slower BAUD rate (or a single 0xFF byte which only has the start bit low) and see if it works. We had a problem using 115k2 baud rate where our microcontroller communicating with the RPi could hit 113636baud or 119047baud. 113636baud had the lowest error margin so we used it and TX from the RPi being received by the microcontroller worked fine. However when transmitting to the RPi nothing was ever received. Changing the microcontroller to use 119047baud caused RX to work. We then tested the RPi transmitting a byte of 0×00 and measured the low state on a scope we got 78uS, showing an actual baud rate of 115384 from the RPi (8bits + the start bit all low). This was odd as 113636baud still had to lower error margin but that was the finding.
Are you over or under clocking the RPi? If so do you need to adjust the baud rate to compensate for this?
General UART Programming Resources
Raspberry Pi Resources-Using the UART的更多相关文章
- Raspberry Pi UART with PySerial
参考:http://programmingadvent.blogspot.hk/2012/12/raspberry-pi-uart-with-pyserial.html Raspberry Pi UA ...
- A new comer playing with Raspberry Pi 3B
there are some things to do for raspberry pi 3b for the first time: 1, connect pi with monitor/KB/mo ...
- RASPBERRY PI 外设学习资源
参考: http://www.siongboon.com/projects/2013-07-08_raspberry_pi/index.html Raspberry Pi Get st ...
- Raspberry Pi上手
2013-05-21 买的树莓派终于到手了,嘿嘿.我在官方代理ICKEY买的,是英国版,B型. 上手教程可以根据Getting Started with Raspberry Pi(网上有电子版免费下载 ...
- Adding an On/Off switch to your Raspberry Pi
http://www.raspberry-pi-geek.com/Archive/2013/01/Adding-an-On-Off-switch-to-your-Raspberry-Pi#articl ...
- Raspberry Pi GPIO Protection
After damaging the GPIO port on our raspberry pi while designing a new solar monitoring system we de ...
- Device trees, Overlays and Parameters of Raspberry Pi
Raspberry Pi's latest kernels and firmware, including Raspbian and NOOBS releases, now by default us ...
- Raspberry Pi - Huawei HiLink E3256 3G modem to ethernet adapter
Raspberry Pi - Huawei HiLink E3256 3G modem to ethernet adapter This page documents how to configure ...
- 【树莓派】【转载】Raspberry Pi (树莓派)折腾记
在网上看到一篇对树莓派折腾记录比较详细的文章,时间比较早,但是有些东西没变. 对于新手而言,还是有点参考价值.文章参见:http://skypegnu1.blog.51cto.com/8991766/ ...
随机推荐
- JS中函数声明与函数表达式的不同
Js中的函数声明是指下面的形式: function functionName(){ } 这样的方式来声明一个函数,而函数表达式则是类似表达式那样来声明一个函数,如 var functionName ...
- iOS - iOS 应用
1.Xcode 项目属性 Product Name 软件名称.产品名称.项目名称 Organization Name 公司名称.组织名称 Organization Identifier 公司的唯一标识 ...
- Node 编程规范
空格, 2个, 因为有多层函数嵌套 行宽, 80个字符 语句分隔, 一律用; 并且占一行 变量定义, 每一个都要用 var, 并且不要定义全局变量 变量名和属性名, 小驼峰, yourName 函数, ...
- 浅谈 原生javaScript&&react 实现全局触摸按钮(附带对addeventlistener的了解)
1.采用原生javaACript 实现全局触摸按钮 首先在控制台输出,观察事件有哪些关于触摸的字段可以使用,然后拿这些字段的数据开始来写方法. 因为要做的是全局触摸按钮,我需要拿到的是按钮时时的坐标位 ...
- js_多个引号的用法
str += "<input id='sel_DayB' width='120' onfocus=\"WdatePicker({skin:'whyGreen',dateFmt ...
- JS在window和document的应用
页面跳转: window.location.href('地址') window.open('地址', '_self') 打开新窗口: window.open('地址', '_blank') 只显示地址 ...
- 分组找ID
select t.name1,t.name2,t.zx from (select row_number()over(partition by name1 order by zx desc)rn, te ...
- linux笔记:shell编程-文本处理命令
cut(字段提取命令,也叫列提取命令): printf(格式化输出命令): awk(awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理): sed(sed是一个很好 ...
- 十天精通CSS3学习笔记 part3
第8章 CSS3中的变形与动画(上) 变形--旋转 rotate() 旋转rotate()函数通过指定的角度参数使元素相对原点进行旋转.它主要在二维空间内进行操作,设置一个角度值,用来指定旋转的幅度. ...
- JavaWeb 自定义404页面
本来,Tomcat中自定义404页面不过是在web.xml文件中写4行代码的事情. 直接引用 Tomcat官方FAQ 怎样自定义404页面? 编辑web.xml <error-page> ...