Error[8]: Undefined offset: 539, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

串口通信协议

串口通信协议 ——多机通信

串口通信属于全双工

软件和硬件我们都是模块化的思想

串口通信协议

全双工和半双工的区别:

全双工:好比 男和女的在互骂,两个声音都听的到。


半双工:好比 男和女的在吵架 ,男的先骂,女的再骂,一个一个骂(一个能讲话时候,另一个闭嘴)。

两个人吵架,语言要互通,语速要正常
串口里呢就是:数据格式(语言要互通) 波特率(语速)

数据格式:

  1. 数据位
  2. 奇偶校验
  3. 停止位

接下来我们来用串口 实现树莓派和 win 的通信

关于串口库

串口通信,使用时需要包含头文件:#include

int serialOpen (char *device, int baud)
功能:打开并初始串口
参数:
	device:串口的地址,在Linux中就是设备所在的目录。

默认一般是"/dev/ttyAMA0",我的是这样的。

baud:波特率 返回: 正常返回文件描述符,否则返回-1失败。

void serialClose (int fd) 功能: 关闭fd关联的串口 参数: fd:文件描述符 void serialPutchar (int fd, unsigned char c) 功能: 发送一个字节的数据到串口 参数: fd:文件描述符 c:要发送的数据 void serialPuts (int fd, char *s) 功能: 发送一个字符串到串口 参数: fd:文件描述符 s:发送的字符串,字符串要以'void'结尾 serialPrintf ( int, fdchar * ,message)int 功能: 像使用C语言中的printf一样发送数据到串口 参数: fd:文件描述符 message:格式化的字符串 serialDataAvail ( int) fd- 功能: 获取串口缓存中可用的字节数。

参数: fd:文件描述符 返回: 串口缓存中已经接收的,可读取的字节数,1int代表错误 serialGetchar ( int) fd10 功能: 从串口读取一个字节数据返回。

如果串口缓存中没有可用的数据,则会等待10秒,如果-后还有没,返回1void 所以,在读取前,做好通过serialDataAvail判断下。

参数: fd:文件描述符 返回: 读取到的字符 serialFlush ( int) fd* 功能: 刷新,清空串口缓冲中的所有可用的数据。

参数: fd:文件描述符 size_twrite ( int, fdconstvoid * , bufsize_t) count< 功能: 这个是Linux下的标准IO库函数,需要包含头文件#include .unistd*h> 当要发送到的数据量过大时,wiringPi建议使用这个函数。

size_tread (int, fdvoid* , buf size_t) count;< 功能: 这个是Linux下的标准IO库函数,需要包含头文件#include .unistd:h> 当要接收的数据量过大时,wiringPi建议使用这个函数。

参数: fd:文件描述符 buf:接受的数据缓存的数组 count.接收的字节数/* 修改 cmdline.txt文件 */ 返回: 实际读取的字符数。

初次使用树莓派串口编程,需要配置。

/
cd /boot.
sudo vim cmdline.txt
删除【】之间的部分
dwc_otg=lpm_enable0= 【console,ttyAMA0115200=】 kgdboc,ttyAMA0115200= console=tty1 root//dev=mmcblk0p2 rootfstype=ext4 elevator/*修改 inittab文件 */deadline rootwait

/
cd /etc:
sudo vim inittab
注释掉最后一行内容#,在前面加上 # 号
:T023::respawn//sbin-getty 115200L ttyAMA0 # vt100
sudo reboot 重启
串口通信编程

串口通信代码

include#
include#
includeint

main ()int
{
    ; fdif
    
    ((wiringPiSetup())<0)//初始化树莓派引脚  return
    {
         1 ;}
    if

    ((=fdserialOpen("/dev/ttyAMA0",115200))<0)//打开并初始串口   return
        ///dev/ttyAMA0 串口的地址,在Linux中就是设备所在的目录。

{ 1 ;} while (1)serialPutchar{ (,fd'c');//发送一个字节的数据到串口 delayMicroseconds (1000000);// 延时1秒 微秒数(1000微秒 = 1毫秒 = 0.001秒) } serialClose ( )fd;return 0 ;} gcc demo1.c -lwiringPi -o demo1

编译 : sudo ./demo1
运行:#

连接usb模块到win

usb模块(ch340)和树莓派连接图

在win端 用串口助手接收树莓派发送的串口信息

串口通信获取数据

include#
include#
includeint

main ()int
{
    ; fdint
    ; cmdif
    
    ((wiringPiSetup())<0)//初始化树莓派引脚  return
    {
         1 ;}
    if

    ((=fdserialOpen("/dev/ttyAMA0",115200))<0)//打开并初始串口   return
        ///dev/ttyAMA0 串口的地址,在Linux中就是设备所在的目录。

{ 1 ;} while (1)while{ (serialDataAvail( )fd!= - 1)={ //获取串口缓存中可用的字节数。

串口缓存中已经接收的,可读取的字节数,-1代表错误 cmd serialGetchar ( )fd;printf //从串口读取一个字节数据返回。

如果串口缓存中没有可用的数据,则会等待10秒,如果10后还有没,返回-1,所以,在读取前,做好通过serialDataAvail判断下。

("get data:cmd=%d\n",)cmd;} } serialClose ( )fd;return 0 ;} #

接下来我们简单使用一下语音模块

使用树莓派和语音模块实现语音识别功能

树莓派和语音模块接线图

树莓派串口接收语音模块信息代码

include#
include#
include#
include#
includeint

main ()int
{
  ; fdchar
  [ cmd128]='}'{;int; 
  if n_read(

  wiringPiSetup()<0)return1{
       ; }if
  (
  
  (=serialOpenfd ( "/dev/ttyAMA0",9600))<0)return1{
       ; }while
  (
  1)=read{
       n_read(,,fdsizeofcmd ())cmd;if(
       strlen()==cmd0) printf({   //收到的字符长度=0 ,就打印超时,并且等待。

"chaoshi\n");continue; }printf ( "getData: %d byte ,context:%s\n",,)n_read;cmdmemset( ,','cmdsizeof()/sizeofcmd(char));}return0 ; } #include #

语音模块部分代码

对语音模块说话:极cc 它会反馈读到6个字节,内容不显示

对语音模块说话:极cc 打开灯 /关闭灯

结果把12字节拆分成了两次,我们本想它读128个字节,结果显示只要超过8个字节,就拆分。

我们来改变一下代码

include#
include#
include#
includeint
main(

) int;char
{
  [ fd128
  ] cmd='}';int{;if( 
  wiringPiSetup n_read(

  )<0)return1;}{
       if ((
  =
  
  serialOpen("/dev/ttyAMA0"fd , 9600))<0)return1;}{
       while (1
  )
  =read(,{
       n_read,sizeof(fd)cmd );ifcmd(strlen(
       )==0)cmdprintf( "chaoshi\n"){   //收到的字符长度=0 ,就打印超时,并且等待。

;continue;}if (strstr ( ,"open"!=NULLcmd)) printf ("open light\n"){ ;}if(strstr ( ,"close"!=NULLcmd)) printf ("close light\n"){ ;}memset(, ',' sizeof(cmd)/sizeof(charcmd));}return0;} [+++] [+++] [+++][+++] [+++]

对语音模块说话:极cc 打开灯 /关闭灯
这样就实现了全部字符串显示

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 540, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

串口通信协议

串口通信协议 ——多机通信

串口通信属于全双工

软件和硬件我们都是模块化的思想

串口通信协议

全双工和半双工的区别:

全双工:好比 男和女的在互骂,两个声音都听的到。


半双工:好比 男和女的在吵架 ,男的先骂,女的再骂,一个一个骂(一个能讲话时候,另一个闭嘴)。

两个人吵架,语言要互通,语速要正常
串口里呢就是:数据格式(语言要互通) 波特率(语速)

数据格式:

  1. 数据位
  2. 奇偶校验
  3. 停止位

接下来我们来用串口 实现树莓派和 win 的通信

关于串口库

串口通信,使用时需要包含头文件:#include

int serialOpen (char *device, int baud)
功能:打开并初始串口
参数:
	device:串口的地址,在Linux中就是设备所在的目录。

默认一般是"/dev/ttyAMA0",我的是这样的。

baud:波特率 返回: 正常返回文件描述符,否则返回-1失败。

void serialClose (int fd) 功能: 关闭fd关联的串口 参数: fd:文件描述符 void serialPutchar (int fd, unsigned char c) 功能: 发送一个字节的数据到串口 参数: fd:文件描述符 c:要发送的数据 void serialPuts (int fd, char *s) 功能: 发送一个字符串到串口 参数: fd:文件描述符 s:发送的字符串,字符串要以'void'结尾 serialPrintf ( int, fdchar * ,message)int 功能: 像使用C语言中的printf一样发送数据到串口 参数: fd:文件描述符 message:格式化的字符串 serialDataAvail ( int) fd- 功能: 获取串口缓存中可用的字节数。

参数: fd:文件描述符 返回: 串口缓存中已经接收的,可读取的字节数,1int代表错误 serialGetchar ( int) fd10 功能: 从串口读取一个字节数据返回。

如果串口缓存中没有可用的数据,则会等待10秒,如果-后还有没,返回1void 所以,在读取前,做好通过serialDataAvail判断下。

参数: fd:文件描述符 返回: 读取到的字符 serialFlush ( int) fd* 功能: 刷新,清空串口缓冲中的所有可用的数据。

参数: fd:文件描述符 size_twrite ( int, fdconstvoid * , bufsize_t) count< 功能: 这个是Linux下的标准IO库函数,需要包含头文件#include .unistd*h> 当要发送到的数据量过大时,wiringPi建议使用这个函数。

size_tread (int, fdvoid* , buf size_t) count;< 功能: 这个是Linux下的标准IO库函数,需要包含头文件#include .unistd:h> 当要接收的数据量过大时,wiringPi建议使用这个函数。

参数: fd:文件描述符 buf:接受的数据缓存的数组 count.接收的字节数/* 修改 cmdline.txt文件 */ 返回: 实际读取的字符数。

初次使用树莓派串口编程,需要配置。

/
cd /boot.
sudo vim cmdline.txt
删除【】之间的部分
dwc_otg=lpm_enable0= 【console,ttyAMA0115200=】 kgdboc,ttyAMA0115200= console=tty1 root//dev=mmcblk0p2 rootfstype=ext4 elevator/*修改 inittab文件 */deadline rootwait

/
cd /etc:
sudo vim inittab
注释掉最后一行内容#,在前面加上 # 号
:T023::respawn//sbin-getty 115200L ttyAMA0 # vt100
sudo reboot 重启
串口通信编程

串口通信代码

include#
include#
includeint

main ()int
{
    ; fdif
    
    ((wiringPiSetup())<0)//初始化树莓派引脚  return
    {
         1 ;}
    if

    ((=fdserialOpen("/dev/ttyAMA0",115200))<0)//打开并初始串口   return
        ///dev/ttyAMA0 串口的地址,在Linux中就是设备所在的目录。

{ 1 ;} while (1)serialPutchar{ (,fd'c');//发送一个字节的数据到串口 delayMicroseconds (1000000);// 延时1秒 微秒数(1000微秒 = 1毫秒 = 0.001秒) } serialClose ( )fd;return 0 ;} gcc demo1.c -lwiringPi -o demo1

编译 : sudo ./demo1
运行:#

连接usb模块到win

usb模块(ch340)和树莓派连接图

在win端 用串口助手接收树莓派发送的串口信息

串口通信获取数据

include#
include#
includeint

main ()int
{
    ; fdint
    ; cmdif
    
    ((wiringPiSetup())<0)//初始化树莓派引脚  return
    {
         1 ;}
    if

    ((=fdserialOpen("/dev/ttyAMA0",115200))<0)//打开并初始串口   return
        ///dev/ttyAMA0 串口的地址,在Linux中就是设备所在的目录。

{ 1 ;} while (1)while{ (serialDataAvail( )fd!= - 1)={ //获取串口缓存中可用的字节数。

串口缓存中已经接收的,可读取的字节数,-1代表错误 cmd serialGetchar ( )fd;printf //从串口读取一个字节数据返回。

如果串口缓存中没有可用的数据,则会等待10秒,如果10后还有没,返回-1,所以,在读取前,做好通过serialDataAvail判断下。

("get data:cmd=%d\n",)cmd;} } serialClose ( )fd;return 0 ;} #

接下来我们简单使用一下语音模块

使用树莓派和语音模块实现语音识别功能

树莓派和语音模块接线图

树莓派串口接收语音模块信息代码

include#
include#
include#
include#
includeint

main ()int
{
  ; fdchar
  [ cmd128]='}'{;int; 
  if n_read(

  wiringPiSetup()<0)return1{
       ; }if
  (
  
  (=serialOpenfd ( "/dev/ttyAMA0",9600))<0)return1{
       ; }while
  (
  1)=read{
       n_read(,,fdsizeofcmd ())cmd;if(
       strlen()==cmd0) printf({   //收到的字符长度=0 ,就打印超时,并且等待。

"chaoshi\n");continue; }printf ( "getData: %d byte ,context:%s\n",,)n_read;cmdmemset( ,','cmdsizeof()/sizeofcmd(char));}return0 ; } #include #

语音模块部分代码

对语音模块说话:极cc 它会反馈读到6个字节,内容不显示

对语音模块说话:极cc 打开灯 /关闭灯

结果把12字节拆分成了两次,我们本想它读128个字节,结果显示只要超过8个字节,就拆分。

我们来改变一下代码

include#
include#
include#
includeint
main(

) int;char
{
  [ fd128
  ] cmd='}';int{;if( 
  wiringPiSetup n_read(

  )<0)return1;}{
       if ((
  =
  
  serialOpen("/dev/ttyAMA0"fd , 9600))<0)return1;}{
       while (1
  )
  =read(,{
       n_read,sizeof(fd)cmd );ifcmd(strlen(
       )==0)cmdprintf( "chaoshi\n"){   //收到的字符长度=0 ,就打印超时,并且等待。

;continue;}if (strstr ( ,"open"!=NULLcmd)) printf ("open light\n"){ ;}if(strstr ( ,"close"!=NULLcmd)) printf ("close light\n"){ ;}memset(, ',' sizeof(cmd)/sizeof(charcmd));}return0;} [+++] [+++][+++] [+++]

对语音模块说话:极cc 打开灯 /关闭灯
这样就实现了全部字符串显示

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 541, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

串口通信协议

串口通信协议 ——多机通信

串口通信属于全双工

软件和硬件我们都是模块化的思想

串口通信协议

全双工和半双工的区别:

全双工:好比 男和女的在互骂,两个声音都听的到。


半双工:好比 男和女的在吵架 ,男的先骂,女的再骂,一个一个骂(一个能讲话时候,另一个闭嘴)。

两个人吵架,语言要互通,语速要正常
串口里呢就是:数据格式(语言要互通) 波特率(语速)

数据格式:

  1. 数据位
  2. 奇偶校验
  3. 停止位

接下来我们来用串口 实现树莓派和 win 的通信

关于串口库

串口通信,使用时需要包含头文件:#include

int serialOpen (char *device, int baud)
功能:打开并初始串口
参数:
	device:串口的地址,在Linux中就是设备所在的目录。

默认一般是"/dev/ttyAMA0",我的是这样的。

baud:波特率 返回: 正常返回文件描述符,否则返回-1失败。

void serialClose (int fd) 功能: 关闭fd关联的串口 参数: fd:文件描述符 void serialPutchar (int fd, unsigned char c) 功能: 发送一个字节的数据到串口 参数: fd:文件描述符 c:要发送的数据 void serialPuts (int fd, char *s) 功能: 发送一个字符串到串口 参数: fd:文件描述符 s:发送的字符串,字符串要以'void'结尾 serialPrintf ( int, fdchar * ,message)int 功能: 像使用C语言中的printf一样发送数据到串口 参数: fd:文件描述符 message:格式化的字符串 serialDataAvail ( int) fd- 功能: 获取串口缓存中可用的字节数。

参数: fd:文件描述符 返回: 串口缓存中已经接收的,可读取的字节数,1int代表错误 serialGetchar ( int) fd10 功能: 从串口读取一个字节数据返回。

如果串口缓存中没有可用的数据,则会等待10秒,如果-后还有没,返回1void 所以,在读取前,做好通过serialDataAvail判断下。

参数: fd:文件描述符 返回: 读取到的字符 serialFlush ( int) fd* 功能: 刷新,清空串口缓冲中的所有可用的数据。

参数: fd:文件描述符 size_twrite ( int, fdconstvoid * , bufsize_t) count< 功能: 这个是Linux下的标准IO库函数,需要包含头文件#include .unistd*h> 当要发送到的数据量过大时,wiringPi建议使用这个函数。

size_tread (int, fdvoid* , buf size_t) count;< 功能: 这个是Linux下的标准IO库函数,需要包含头文件#include .unistd:h> 当要接收的数据量过大时,wiringPi建议使用这个函数。

参数: fd:文件描述符 buf:接受的数据缓存的数组 count.接收的字节数/* 修改 cmdline.txt文件 */ 返回: 实际读取的字符数。

初次使用树莓派串口编程,需要配置。

/
cd /boot.
sudo vim cmdline.txt
删除【】之间的部分
dwc_otg=lpm_enable0= 【console,ttyAMA0115200=】 kgdboc,ttyAMA0115200= console=tty1 root//dev=mmcblk0p2 rootfstype=ext4 elevator/*修改 inittab文件 */deadline rootwait

/
cd /etc:
sudo vim inittab
注释掉最后一行内容#,在前面加上 # 号
:T023::respawn//sbin-getty 115200L ttyAMA0 # vt100
sudo reboot 重启
串口通信编程

串口通信代码

include#
include#
includeint

main ()int
{
    ; fdif
    
    ((wiringPiSetup())<0)//初始化树莓派引脚  return
    {
         1 ;}
    if

    ((=fdserialOpen("/dev/ttyAMA0",115200))<0)//打开并初始串口   return
        ///dev/ttyAMA0 串口的地址,在Linux中就是设备所在的目录。

{ 1 ;} while (1)serialPutchar{ (,fd'c');//发送一个字节的数据到串口 delayMicroseconds (1000000);// 延时1秒 微秒数(1000微秒 = 1毫秒 = 0.001秒) } serialClose ( )fd;return 0 ;} gcc demo1.c -lwiringPi -o demo1

编译 : sudo ./demo1
运行:#

连接usb模块到win

usb模块(ch340)和树莓派连接图

在win端 用串口助手接收树莓派发送的串口信息

串口通信获取数据

include#
include#
includeint

main ()int
{
    ; fdint
    ; cmdif
    
    ((wiringPiSetup())<0)//初始化树莓派引脚  return
    {
         1 ;}
    if

    ((=fdserialOpen("/dev/ttyAMA0",115200))<0)//打开并初始串口   return
        ///dev/ttyAMA0 串口的地址,在Linux中就是设备所在的目录。

{ 1 ;} while (1)while{ (serialDataAvail( )fd!= - 1)={ //获取串口缓存中可用的字节数。

串口缓存中已经接收的,可读取的字节数,-1代表错误 cmd serialGetchar ( )fd;printf //从串口读取一个字节数据返回。

如果串口缓存中没有可用的数据,则会等待10秒,如果10后还有没,返回-1,所以,在读取前,做好通过serialDataAvail判断下。

("get data:cmd=%d\n",)cmd;} } serialClose ( )fd;return 0 ;} #

接下来我们简单使用一下语音模块

使用树莓派和语音模块实现语音识别功能

树莓派和语音模块接线图

树莓派串口接收语音模块信息代码

include#
include#
include#
include#
includeint

main ()int
{
  ; fdchar
  [ cmd128]='}'{;int; 
  if n_read(

  wiringPiSetup()<0)return1{
       ; }if
  (
  
  (=serialOpenfd ( "/dev/ttyAMA0",9600))<0)return1{
       ; }while
  (
  1)=read{
       n_read(,,fdsizeofcmd ())cmd;if(
       strlen()==cmd0) printf({   //收到的字符长度=0 ,就打印超时,并且等待。

"chaoshi\n");continue; }printf ( "getData: %d byte ,context:%s\n",,)n_read;cmdmemset( ,','cmdsizeof()/sizeofcmd(char));}return0 ; } #include #

语音模块部分代码

对语音模块说话:极cc 它会反馈读到6个字节,内容不显示

对语音模块说话:极cc 打开灯 /关闭灯

结果把12字节拆分成了两次,我们本想它读128个字节,结果显示只要超过8个字节,就拆分。

我们来改变一下代码

include#
include#
include#
includeint
main(

) int;char
{
  [ fd128
  ] cmd='}';int{;if( 
  wiringPiSetup n_read(

  )<0)return1;}{
       if ((
  =
  
  serialOpen("/dev/ttyAMA0"fd , 9600))<0)return1;}{
       while (1
  )
  =read(,{
       n_read,sizeof(fd)cmd );ifcmd(strlen(
       )==0)cmdprintf( "chaoshi\n"){   //收到的字符长度=0 ,就打印超时,并且等待。

;continue;}if (strstr ( ,"open"!=NULLcmd)) printf ("open light\n"){ ;}if(strstr ( ,"close"!=NULLcmd)) printf ("close light\n"){ ;}memset(, ',' sizeof(cmd)/sizeof(charcmd));}return0;} [+++][+++] [+++]

对语音模块说话:极cc 打开灯 /关闭灯
这样就实现了全部字符串显示

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 542, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

串口通信协议

串口通信协议 ——多机通信

串口通信属于全双工

软件和硬件我们都是模块化的思想

串口通信协议

全双工和半双工的区别:

全双工:好比 男和女的在互骂,两个声音都听的到。


半双工:好比 男和女的在吵架 ,男的先骂,女的再骂,一个一个骂(一个能讲话时候,另一个闭嘴)。

两个人吵架,语言要互通,语速要正常
串口里呢就是:数据格式(语言要互通) 波特率(语速)

数据格式:

  1. 数据位
  2. 奇偶校验
  3. 停止位

接下来我们来用串口 实现树莓派和 win 的通信

关于串口库

串口通信,使用时需要包含头文件:#include

int serialOpen (char *device, int baud)
功能:打开并初始串口
参数:
	device:串口的地址,在Linux中就是设备所在的目录。

默认一般是"/dev/ttyAMA0",我的是这样的。

baud:波特率 返回: 正常返回文件描述符,否则返回-1失败。

void serialClose (int fd) 功能: 关闭fd关联的串口 参数: fd:文件描述符 void serialPutchar (int fd, unsigned char c) 功能: 发送一个字节的数据到串口 参数: fd:文件描述符 c:要发送的数据 void serialPuts (int fd, char *s) 功能: 发送一个字符串到串口 参数: fd:文件描述符 s:发送的字符串,字符串要以'void'结尾 serialPrintf ( int, fdchar * ,message)int 功能: 像使用C语言中的printf一样发送数据到串口 参数: fd:文件描述符 message:格式化的字符串 serialDataAvail ( int) fd- 功能: 获取串口缓存中可用的字节数。

参数: fd:文件描述符 返回: 串口缓存中已经接收的,可读取的字节数,1int代表错误 serialGetchar ( int) fd10 功能: 从串口读取一个字节数据返回。

如果串口缓存中没有可用的数据,则会等待10秒,如果-后还有没,返回1void 所以,在读取前,做好通过serialDataAvail判断下。

参数: fd:文件描述符 返回: 读取到的字符 serialFlush ( int) fd* 功能: 刷新,清空串口缓冲中的所有可用的数据。

参数: fd:文件描述符 size_twrite ( int, fdconstvoid * , bufsize_t) count< 功能: 这个是Linux下的标准IO库函数,需要包含头文件#include .unistd*h> 当要发送到的数据量过大时,wiringPi建议使用这个函数。

size_tread (int, fdvoid* , buf size_t) count;< 功能: 这个是Linux下的标准IO库函数,需要包含头文件#include .unistd:h> 当要接收的数据量过大时,wiringPi建议使用这个函数。

参数: fd:文件描述符 buf:接受的数据缓存的数组 count.接收的字节数/* 修改 cmdline.txt文件 */ 返回: 实际读取的字符数。

初次使用树莓派串口编程,需要配置。

/
cd /boot.
sudo vim cmdline.txt
删除【】之间的部分
dwc_otg=lpm_enable0= 【console,ttyAMA0115200=】 kgdboc,ttyAMA0115200= console=tty1 root//dev=mmcblk0p2 rootfstype=ext4 elevator/*修改 inittab文件 */deadline rootwait

/
cd /etc:
sudo vim inittab
注释掉最后一行内容#,在前面加上 # 号
:T023::respawn//sbin-getty 115200L ttyAMA0 # vt100
sudo reboot 重启
串口通信编程

串口通信代码

include#
include#
includeint

main ()int
{
    ; fdif
    
    ((wiringPiSetup())<0)//初始化树莓派引脚  return
    {
         1 ;}
    if

    ((=fdserialOpen("/dev/ttyAMA0",115200))<0)//打开并初始串口   return
        ///dev/ttyAMA0 串口的地址,在Linux中就是设备所在的目录。

{ 1 ;} while (1)serialPutchar{ (,fd'c');//发送一个字节的数据到串口 delayMicroseconds (1000000);// 延时1秒 微秒数(1000微秒 = 1毫秒 = 0.001秒) } serialClose ( )fd;return 0 ;} gcc demo1.c -lwiringPi -o demo1

编译 : sudo ./demo1
运行:#

连接usb模块到win

usb模块(ch340)和树莓派连接图

在win端 用串口助手接收树莓派发送的串口信息

串口通信获取数据

include#
include#
includeint

main ()int
{
    ; fdint
    ; cmdif
    
    ((wiringPiSetup())<0)//初始化树莓派引脚  return
    {
         1 ;}
    if

    ((=fdserialOpen("/dev/ttyAMA0",115200))<0)//打开并初始串口   return
        ///dev/ttyAMA0 串口的地址,在Linux中就是设备所在的目录。

{ 1 ;} while (1)while{ (serialDataAvail( )fd!= - 1)={ //获取串口缓存中可用的字节数。

串口缓存中已经接收的,可读取的字节数,-1代表错误 cmd serialGetchar ( )fd;printf //从串口读取一个字节数据返回。

如果串口缓存中没有可用的数据,则会等待10秒,如果10后还有没,返回-1,所以,在读取前,做好通过serialDataAvail判断下。

("get data:cmd=%d\n",)cmd;} } serialClose ( )fd;return 0 ;} #

接下来我们简单使用一下语音模块

使用树莓派和语音模块实现语音识别功能

树莓派和语音模块接线图

树莓派串口接收语音模块信息代码

include#
include#
include#
include#
includeint

main ()int
{
  ; fdchar
  [ cmd128]='}'{;int; 
  if n_read(

  wiringPiSetup()<0)return1{
       ; }if
  (
  
  (=serialOpenfd ( "/dev/ttyAMA0",9600))<0)return1{
       ; }while
  (
  1)=read{
       n_read(,,fdsizeofcmd ())cmd;if(
       strlen()==cmd0) printf({   //收到的字符长度=0 ,就打印超时,并且等待。

"chaoshi\n");continue; }printf ( "getData: %d byte ,context:%s\n",,)n_read;cmdmemset( ,','cmdsizeof()/sizeofcmd(char));}return0 ; } #include #

语音模块部分代码

对语音模块说话:极cc 它会反馈读到6个字节,内容不显示

对语音模块说话:极cc 打开灯 /关闭灯

结果把12字节拆分成了两次,我们本想它读128个字节,结果显示只要超过8个字节,就拆分。

我们来改变一下代码

include#
include#
include#
includeint
main(

) int;char
{
  [ fd128
  ] cmd='}';int{;if( 
  wiringPiSetup n_read(

  )<0)return1;}{
       if ((
  =
  
  serialOpen("/dev/ttyAMA0"fd , 9600))<0)return1;}{
       while (1
  )
  =read(,{
       n_read,sizeof(fd)cmd );ifcmd(strlen(
       )==0)cmdprintf( "chaoshi\n"){   //收到的字符长度=0 ,就打印超时,并且等待。

;continue;}if (strstr ( ,"open"!=NULLcmd)) printf ("open light\n"){ ;}if(strstr ( ,"close"!=NULLcmd)) printf ("close light\n"){ ;}memset(, ',' sizeof(cmd)/sizeof(charcmd));}return0;} [+++] [+++]

对语音模块说话:极cc 打开灯 /关闭灯
这样就实现了全部字符串显示

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 543, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

串口通信协议

串口通信协议 ——多机通信

串口通信属于全双工

软件和硬件我们都是模块化的思想

串口通信协议

全双工和半双工的区别:

全双工:好比 男和女的在互骂,两个声音都听的到。


半双工:好比 男和女的在吵架 ,男的先骂,女的再骂,一个一个骂(一个能讲话时候,另一个闭嘴)。

两个人吵架,语言要互通,语速要正常
串口里呢就是:数据格式(语言要互通) 波特率(语速)

数据格式:

  1. 数据位
  2. 奇偶校验
  3. 停止位

接下来我们来用串口 实现树莓派和 win 的通信

关于串口库

串口通信,使用时需要包含头文件:#include

int serialOpen (char *device, int baud)
功能:打开并初始串口
参数:
	device:串口的地址,在Linux中就是设备所在的目录。

默认一般是"/dev/ttyAMA0",我的是这样的。

baud:波特率 返回: 正常返回文件描述符,否则返回-1失败。

void serialClose (int fd) 功能: 关闭fd关联的串口 参数: fd:文件描述符 void serialPutchar (int fd, unsigned char c) 功能: 发送一个字节的数据到串口 参数: fd:文件描述符 c:要发送的数据 void serialPuts (int fd, char *s) 功能: 发送一个字符串到串口 参数: fd:文件描述符 s:发送的字符串,字符串要以'void'结尾 serialPrintf ( int, fdchar * ,message)int 功能: 像使用C语言中的printf一样发送数据到串口 参数: fd:文件描述符 message:格式化的字符串 serialDataAvail ( int) fd- 功能: 获取串口缓存中可用的字节数。

参数: fd:文件描述符 返回: 串口缓存中已经接收的,可读取的字节数,1int代表错误 serialGetchar ( int) fd10 功能: 从串口读取一个字节数据返回。

如果串口缓存中没有可用的数据,则会等待10秒,如果-后还有没,返回1void 所以,在读取前,做好通过serialDataAvail判断下。

参数: fd:文件描述符 返回: 读取到的字符 serialFlush ( int) fd* 功能: 刷新,清空串口缓冲中的所有可用的数据。

参数: fd:文件描述符 size_twrite ( int, fdconstvoid * , bufsize_t) count< 功能: 这个是Linux下的标准IO库函数,需要包含头文件#include .unistd*h> 当要发送到的数据量过大时,wiringPi建议使用这个函数。

size_tread (int, fdvoid* , buf size_t) count;< 功能: 这个是Linux下的标准IO库函数,需要包含头文件#include .unistd:h> 当要接收的数据量过大时,wiringPi建议使用这个函数。

参数: fd:文件描述符 buf:接受的数据缓存的数组 count.接收的字节数/* 修改 cmdline.txt文件 */ 返回: 实际读取的字符数。

初次使用树莓派串口编程,需要配置。

/
cd /boot.
sudo vim cmdline.txt
删除【】之间的部分
dwc_otg=lpm_enable0= 【console,ttyAMA0115200=】 kgdboc,ttyAMA0115200= console=tty1 root//dev=mmcblk0p2 rootfstype=ext4 elevator/*修改 inittab文件 */deadline rootwait

/
cd /etc:
sudo vim inittab
注释掉最后一行内容#,在前面加上 # 号
:T023::respawn//sbin-getty 115200L ttyAMA0 # vt100
sudo reboot 重启
串口通信编程

串口通信代码

include#
include#
includeint

main ()int
{
    ; fdif
    
    ((wiringPiSetup())<0)//初始化树莓派引脚  return
    {
         1 ;}
    if

    ((=fdserialOpen("/dev/ttyAMA0",115200))<0)//打开并初始串口   return
        ///dev/ttyAMA0 串口的地址,在Linux中就是设备所在的目录。

{ 1 ;} while (1)serialPutchar{ (,fd'c');//发送一个字节的数据到串口 delayMicroseconds (1000000);// 延时1秒 微秒数(1000微秒 = 1毫秒 = 0.001秒) } serialClose ( )fd;return 0 ;} gcc demo1.c -lwiringPi -o demo1

编译 : sudo ./demo1
运行:#

连接usb模块到win

usb模块(ch340)和树莓派连接图

在win端 用串口助手接收树莓派发送的串口信息

串口通信获取数据

include#
include#
includeint

main ()int
{
    ; fdint
    ; cmdif
    
    ((wiringPiSetup())<0)//初始化树莓派引脚  return
    {
         1 ;}
    if

    ((=fdserialOpen("/dev/ttyAMA0",115200))<0)//打开并初始串口   return
        ///dev/ttyAMA0 串口的地址,在Linux中就是设备所在的目录。

{ 1 ;} while (1)while{ (serialDataAvail( )fd!= - 1)={ //获取串口缓存中可用的字节数。

串口缓存中已经接收的,可读取的字节数,-1代表错误 cmd serialGetchar ( )fd;printf //从串口读取一个字节数据返回。

如果串口缓存中没有可用的数据,则会等待10秒,如果10后还有没,返回-1,所以,在读取前,做好通过serialDataAvail判断下。

("get data:cmd=%d\n",)cmd;} } serialClose ( )fd;return 0 ;} #

接下来我们简单使用一下语音模块

使用树莓派和语音模块实现语音识别功能

树莓派和语音模块接线图

树莓派串口接收语音模块信息代码

include#
include#
include#
include#
includeint

main ()int
{
  ; fdchar
  [ cmd128]='}'{;int; 
  if n_read(

  wiringPiSetup()<0)return1{
       ; }if
  (
  
  (=serialOpenfd ( "/dev/ttyAMA0",9600))<0)return1{
       ; }while
  (
  1)=read{
       n_read(,,fdsizeofcmd ())cmd;if(
       strlen()==cmd0) printf({   //收到的字符长度=0 ,就打印超时,并且等待。

"chaoshi\n");continue; }printf ( "getData: %d byte ,context:%s\n",,)n_read;cmdmemset( ,','cmdsizeof()/sizeofcmd(char));}return0 ; } #include #

语音模块部分代码

对语音模块说话:极cc 它会反馈读到6个字节,内容不显示

对语音模块说话:极cc 打开灯 /关闭灯

结果把12字节拆分成了两次,我们本想它读128个字节,结果显示只要超过8个字节,就拆分。

我们来改变一下代码

include#
include#
include#
includeint
main(

) int;char
{
  [ fd128
  ] cmd='}';int{;if( 
  wiringPiSetup n_read(

  )<0)return1;}{
       if ((
  =
  
  serialOpen("/dev/ttyAMA0"fd , 9600))<0)return1;}{
       while (1
  )
  =read(,{
       n_read,sizeof(fd)cmd );ifcmd(strlen(
       )==0)cmdprintf( "chaoshi\n"){   //收到的字符长度=0 ,就打印超时,并且等待。

;continue;}if (strstr ( ,"open"!=NULLcmd)) printf ("open light\n"){ ;}if(strstr ( ,"close"!=NULLcmd)) printf ("close light\n"){ ;}memset(, ',' sizeof(cmd)/sizeof(charcmd));}return0;} [+++]

对语音模块说话:极cc 打开灯 /关闭灯
这样就实现了全部字符串显示

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
树莓派开发——“串口通信协议” 解决针对串口通信的面试利器_C_内存溢出

树莓派开发——“串口通信协议” 解决针对串口通信的面试利器

树莓派开发——“串口通信协议” 解决针对串口通信的面试利器,第1张

串口通信协议

串口通信协议 ——多机通信

串口通信属于全双工

软件和硬件我们都是模块化的思想

串口通信协议

全双工和半双工的区别:

全双工:好比 男和女的在互骂,两个声音都听的到。


半双工:好比 男和女的在吵架 ,男的先骂,女的再骂,一个一个骂(一个能讲话时候,另一个闭嘴)。

两个人吵架,语言要互通,语速要正常
串口里呢就是:数据格式(语言要互通) 波特率(语速)

数据格式:

  1. 数据位
  2. 奇偶校验
  3. 停止位

接下来我们来用串口 实现树莓派和 win 的通信

关于串口库

串口通信,使用时需要包含头文件:#include

int serialOpen (char *device, int baud)
功能:打开并初始串口
参数:
	device:串口的地址,在Linux中就是设备所在的目录。

默认一般是"/dev/ttyAMA0",我的是这样的。

baud:波特率 返回: 正常返回文件描述符,否则返回-1失败。

void serialClose (int fd) 功能: 关闭fd关联的串口 参数: fd:文件描述符 void serialPutchar (int fd, unsigned char c) 功能: 发送一个字节的数据到串口 参数: fd:文件描述符 c:要发送的数据 void serialPuts (int fd, char *s) 功能: 发送一个字符串到串口 参数: fd:文件描述符 s:发送的字符串,字符串要以'void'结尾 serialPrintf ( int, fdchar * ,message)int 功能: 像使用C语言中的printf一样发送数据到串口 参数: fd:文件描述符 message:格式化的字符串 serialDataAvail ( int) fd- 功能: 获取串口缓存中可用的字节数。

参数: fd:文件描述符 返回: 串口缓存中已经接收的,可读取的字节数,1int代表错误 serialGetchar ( int) fd10 功能: 从串口读取一个字节数据返回。

如果串口缓存中没有可用的数据,则会等待10秒,如果-后还有没,返回1void 所以,在读取前,做好通过serialDataAvail判断下。

参数: fd:文件描述符 返回: 读取到的字符 serialFlush ( int) fd* 功能: 刷新,清空串口缓冲中的所有可用的数据。

参数: fd:文件描述符 size_twrite ( int, fdconstvoid * , bufsize_t) count< 功能: 这个是Linux下的标准IO库函数,需要包含头文件#include .unistd*h> 当要发送到的数据量过大时,wiringPi建议使用这个函数。

size_tread (int, fdvoid* , buf size_t) count;< 功能: 这个是Linux下的标准IO库函数,需要包含头文件#include .unistd:h> 当要接收的数据量过大时,wiringPi建议使用这个函数。

参数: fd:文件描述符 buf:接受的数据缓存的数组 count.接收的字节数/* 修改 cmdline.txt文件 */ 返回: 实际读取的字符数。

初次使用树莓派串口编程,需要配置。

/
cd /boot.
sudo vim cmdline.txt
删除【】之间的部分
dwc_otg=lpm_enable0= 【console,ttyAMA0115200=】 kgdboc,ttyAMA0115200= console=tty1 root//dev=mmcblk0p2 rootfstype=ext4 elevator/*修改 inittab文件 */deadline rootwait

/
cd /etc:
sudo vim inittab
注释掉最后一行内容#,在前面加上 # 号
:T023::respawn//sbin-getty 115200L ttyAMA0 # vt100
sudo reboot 重启
串口通信编程

串口通信代码

include#
include#
includeint

main ()int
{
    ; fdif
    
    ((wiringPiSetup())<0)//初始化树莓派引脚  return
    {
         1 ;}
    if

    ((=fdserialOpen("/dev/ttyAMA0",115200))<0)//打开并初始串口   return
        ///dev/ttyAMA0 串口的地址,在Linux中就是设备所在的目录。

{ 1 ;} while (1)serialPutchar{ (,fd'c');//发送一个字节的数据到串口 delayMicroseconds (1000000);// 延时1秒 微秒数(1000微秒 = 1毫秒 = 0.001秒) } serialClose ( )fd;return 0 ;} gcc demo1.c -lwiringPi -o demo1

编译 : sudo ./demo1
运行:#

连接usb模块到win

usb模块(ch340)和树莓派连接图

在win端 用串口助手接收树莓派发送的串口信息

串口通信获取数据

include#
include#
includeint

main ()int
{
    ; fdint
    ; cmdif
    
    ((wiringPiSetup())<0)//初始化树莓派引脚  return
    {
         1 ;}
    if

    ((=fdserialOpen("/dev/ttyAMA0",115200))<0)//打开并初始串口   return
        ///dev/ttyAMA0 串口的地址,在Linux中就是设备所在的目录。

{ 1 ;} while (1)while{ (serialDataAvail( )fd!= - 1)={ //获取串口缓存中可用的字节数。

串口缓存中已经接收的,可读取的字节数,-1代表错误 cmd serialGetchar ( )fd;printf //从串口读取一个字节数据返回。

如果串口缓存中没有可用的数据,则会等待10秒,如果10后还有没,返回-1,所以,在读取前,做好通过serialDataAvail判断下。

("get data:cmd=%d\n",)cmd;} } serialClose ( )fd;return 0 ;} #

接下来我们简单使用一下语音模块

使用树莓派和语音模块实现语音识别功能

树莓派和语音模块接线图

树莓派串口接收语音模块信息代码

include#
include#
include#
include#
includeint

main ()int
{
  ; fdchar
  [ cmd128]='}'{;int; 
  if n_read(

  wiringPiSetup()<0)return1{
       ; }if
  (
  
  (=serialOpenfd ( "/dev/ttyAMA0",9600))<0)return1{
       ; }while
  (
  1)=read{
       n_read(,,fdsizeofcmd ())cmd;if(
       strlen()==cmd0) printf({   //收到的字符长度=0 ,就打印超时,并且等待。

"chaoshi\n");continue; }printf ( "getData: %d byte ,context:%s\n",,)n_read;cmdmemset( ,','cmdsizeof()/sizeofcmd(char));}return0 ; } #include #

语音模块部分代码

对语音模块说话:极cc 它会反馈读到6个字节,内容不显示

对语音模块说话:极cc 打开灯 /关闭灯

结果把12字节拆分成了两次,我们本想它读128个字节,结果显示只要超过8个字节,就拆分。

我们来改变一下代码

include#
include#
include#
includeint
main(

) int;char
{
  [ fd128
  ] cmd='}';int{;if( 
  wiringPiSetup n_read(

  )<0)return1;}{
       if ((
  =
  
  serialOpen("/dev/ttyAMA0"fd , 9600))<0)return1;}{
       while (1
  )
  =read(,{
       n_read,sizeof(fd)cmd );ifcmd(strlen(
       )==0)cmdprintf( "chaoshi\n"){   //收到的字符长度=0 ,就打印超时,并且等待。

;continue;}if (strstr ( ,"open"!=NULLcmd)) printf ("open light\n"){ ;}if(strstr ( ,"close"!=NULLcmd)) printf ("close light\n"){ ;}memset(, ',' sizeof(cmd)/sizeof(charcmd));}return0;}

对语音模块说话:极cc 打开灯 /关闭灯
这样就实现了全部字符串显示

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/674463.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-19
下一篇 2022-04-19

发表评论

登录后才能评论

评论列表(0条)

保存