I.Mx6 使用串口连接PSAM卡的注意事项

{背景}

1. 使用模拟方式与PSAM卡进行通信,对时序的要求非常严格,在自己的代码中一定要做好相关延时尤其是每个etu的时间

    要测量准确。

2. 使用串口方式与PSAM卡直连,是硬件级的通信,写起来相对容易一些。

 

{遇到的问题}

1. 串口应用收不到PSAM卡的复位信息

2. 串口的TX 在RX 有数据时发出干扰数据

 

{解决方案}

1、问题一的解决方案

设置串口为8个数据位,2位停止位,偶校验位。

set_Parity(uart_fd, 8, 2, 'E')

设置串口参数为原始模式,这样才能正确收到PSAM复位信息

options.c_lflag &= ~(ICANON); // config as original mode. 

 

2. 问题二的解决方案

设置串口参数关闭回显,这样TX 就不会再出现干扰信息。

options.c_lflag &= ~(ECHO | ECHONL | ISIG); // disable echo

 

{参考代码}

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/time.h>#define TRUE 1
#define FALSE -1int speed_arr[] = { B230400, B115200, B38400, B19200, B9600, B4800, B2400,
B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = { 230400, 115200, 38400, 19200, 9600, 4800, 2400, 1200, 300,38400, 19200, 9600, 4800, 2400, 1200, 300, };void set_speed(int fd, int speed) 
{int i;int status;struct termios Opt;tcgetattr(fd, &Opt);for (i = 0; i < sizeof(speed_arr) / sizeof(int); i++) {if (speed == name_arr[i]) {tcflush(fd, TCIOFLUSH);// set baudratecfsetispeed(&Opt, speed_arr[i]);cfsetospeed(&Opt, speed_arr[i]);status = tcsetattr(fd, TCSANOW, &Opt);if (status != 0) {perror("tcsetattr fd1");}return;}tcflush(fd, TCIOFLUSH);}
}/***@brief  设置串口数据位,停止位和校验位*@param  fd     类型  int  打开的串口文件句柄*@param  databits 类型  int 数据位 取值为7或者8*@param  stopbits 类型  int 停止位 取值为1或者2*@param  parity  类型  int  奇偶校验位 取值 N, E, O, S*/
int set_Parity(int fd, int databits, int stopbits, int parity) 
{struct termios options;if (tcgetattr(fd, &options) != 0) {perror("SetupSerial 1");return (FALSE);}options.c_cflag &= ~CSIZE;switch (databits) {case 7:options.c_cflag |= CS7;break;case 8:options.c_cflag |= CS8;break;default:fprintf(stderr, "Unsupported data size\n");return FALSE;}switch (parity) {case 'n':case 'N':options.c_cflag &= ~PARENB; /* Clear parity enable */options.c_iflag &= ~INPCK; /* Enable parity checking */options.c_iflag &= ~(ICRNL | IGNCR);options.c_lflag &= ~(ICANON);break;case 'o':case 'O':options.c_cflag |= (PARODD | PARENB);  // 设置为奇校验位options.c_iflag |= INPCK; /* Disnable parity checking */break;case 'e':case 'E':options.c_cflag |= PARENB; // Enable parity checkoptions.c_cflag &= ~PARODD; // config as even parity checkoptions.c_iflag |= INPCK; // enable input parity checkoptions.c_oflag &= ~OPOST; // output for raw modeoptions.c_lflag &= ~(ICANON); // config as original mode. MUST be configured.options.c_lflag &= ~(ECHO | ECHONL | ISIG); // disable echo        break;case 'S':case 's': /*as no parity*/options.c_cflag &= ~PARENB;options.c_cflag &= ~CSTOPB;break;default:fprintf(stderr, "Unsupported parity\n");return FALSE;}// set stop bitsswitch (stopbits) {case 1:options.c_cflag &= ~CSTOPB;break;case 2:options.c_cflag |= CSTOPB;break;default:fprintf(stderr, "Unsupported stop bits\n");return FALSE;}/* Set input parity option */if (parity != 'n') {options.c_iflag |= INPCK;}//options.c_cc[VTIME] = 150; // 15 secondsoptions.c_cc[VTIME] = 50; // 5 secondsoptions.c_cc[VMIN] = 0;options.c_iflag &= ~(ICRNL | IXON);tcflush(fd, TCIFLUSH); /* Update the options and do it NOW */if (tcsetattr(fd, TCSANOW, &options) != 0) {perror("SetupSerial 3");return FALSE;}return TRUE;
}int OpenDev(char *Dev) 
{int fd = open(Dev, O_RDWR);if (-1 == fd) {perror("Can't Open Serial Port");return -1;} else {return fd;}
}int CloseDev(int Dev) 
{int fd = close(Dev);if (-1 == fd) {perror("Can't close Serial Port");return -1;} else {return fd;}
}//
// input: e.g. "/dev/ttymxc3"
// output: valid uart_fd or -1 for open error, -2 for set parity error
//
int uart_cfg(char *which_uart, int speed) 
{int uart_fd;if (which_uart == NULL) {perror("input parameter invalid.");}uart_fd = OpenDev(which_uart);if (uart_fd > 0) {set_speed(uart_fd, speed);printf("open success, 9600\n");} else {printf("Open Failure!\n");return -1;}if (set_Parity(uart_fd, 8, 2, 'E') == FALSE) {printf("Set Parity Error\n");return -2;} else {printf("parity set as 8,2,E\n");}return uart_fd;
}void psam_send_cmd(int fd, unsigned char *cmd_buf, unsigned int cmd_len) {if (cmd_buf == NULL || cmd_len == 0 || fd < 0) {perror("Invalid parameter.");}if (write(fd, cmd_buf, cmd_len) != cmd_len) {printf("send psam cmd failed!\n");}
}void psam_get_cmd_response(int fd, int res_len) {int i = 0;int read_byte = 0;unsigned char res = 0;for (i = 0; i < res_len; i++) {read_byte = read(fd, &res, 1);if (read_byte > 0) {printf("%2x ", res);} else {break;}}printf("\n");
}int main(int argc, char **argv) 
{int nread = 0;int uart_fd = 0;// open uart3int current_speed = 9600;char *dev = "/dev/ttymxc3";uart_fd = uart_cfg(dev, current_speed);if (uart_fd < 0) {perror("uart cfg error.");exit(1);}printf("\nWelcome to PSAM CARD tests\n\n");unsigned char cmd_pps[4] = { 0xFF, 0x10, 0x95, 0x7A };unsigned char cmd_get_rand[5] = { 0x00, 0x84, 0x00, 0x00, 0x08 };unsigned char cmd_select_3F00[7] = { 0x00, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00 };unsigned char cmd_select_0015[7] = { 0x00, 0xA4, 0x00, 0x00, 0x02, 0x00, 0x15 };unsigned char cmd_get_num[5] = { 0x00, 0xB0, 0x96, 0x00, 0x06 };unsigned char res = 0x00;int choice = 0;int speed_choice = 0;while (1) {if (choice != '\n') {printf("\n");printf("Input you select.\n");printf("\t=== Psam Test ===\n");printf("\t a. pps to 115200\n");printf("\t b. get_rand_number\n");printf("\t c. get_psam_number\n");printf("\t d. Test Rest ATR\n");printf("\t f. set baudrate\n");}choice = getchar();switch (choice) {case 'a': // pps cmdprintf("pps selected.\n");psam_send_cmd(uart_fd, cmd_pps, 4);psam_get_cmd_response(uart_fd, 19);set_speed(uart_fd, 115200);printf("*** Current speed is 115200\n");break;case 'b':printf("get_rand_number selected.\n");psam_send_cmd(uart_fd, cmd_get_rand, 5);psam_get_cmd_response(uart_fd, 11);break;case 'c': // attention: if cmd length larger than 5 bytes, send 5 bytes first, __FIXME__printf("get_psam_number selected.\n"); // // select 3F00printf("1) select 3F00\n");psam_send_cmd(uart_fd, cmd_select_3F00, 7);psam_get_cmd_response(uart_fd, 15);printf("\n");// select 0015printf("2) select 0015\n");psam_send_cmd(uart_fd, cmd_select_0015, 7);psam_get_cmd_response(uart_fd, 20);printf("\n");// read psam numberprintf("3) get psam number\n");psam_send_cmd(uart_fd, cmd_get_num, 5);psam_get_cmd_response(uart_fd, 20);printf("\n");break;case 'd':psam_get_cmd_response(uart_fd, 15);break;case 'f': {if (choice != '\n') {printf("\t current speed is %d\n", current_speed);printf("\n");printf("\t=== baudrate set ===\n");printf("\t 1. 115200\n");printf("\t 2. 38400\n");printf("\t 3. 9600\n");printf("\t 9. Exit\n");printf("\n");}scanf("%d", &speed_choice);switch (speed_choice) {case 1: // 115200current_speed = 115200;set_speed(uart_fd, 115200);printf("*** Current speed is 115200\n");break;case 2: // 38400current_speed = 38400;set_speed(uart_fd, 38400);printf("*** Current speed is 38400\n");break;case 3: // 9600current_speed = 9600;set_speed(uart_fd, 9600);printf("*** Current speed is 9600\n");break;case 9:break;}}break;default:break;}}
}

 

转载于:https://www.cnblogs.com/aqing1987/p/4329092.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/398410.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CentOS7.0 安装 tomcat-9.0

2019独角兽企业重金招聘Python工程师标准>>> 1、解压 # tar -zxvf apache-tomcat-9.0.0.M4.tar.gz -C /opt/usr/local 改个名字好以后操作&#xff1a; # mv apache-tomcat-9.0.0.M4.tar.gz tomcat 2、启动&停止 # /opt/usr/local/tomcat/bin/start…

SpringMVC转发和重定向

页面间的跳转分为转发和重定向 但是转发和重定向在springMVC里又分为转发到页面和重定向到页面&#xff0c;转发到处理器方法和重定向到处理器方法 下边是具体实现功能的代码&#xff1a; 转发到页面和重定向到页面 //转发到页面RequestMapping("/five")public Strin…

一幅长文细学华为MRS大数据开发(四)——HBase

4 HBase 摘要&#xff1a;HBase是一种非关系型数据库&#xff0c;它是基于谷歌BigTable的开源实现&#xff0c;和BigTable一样&#xff0c;支持大规模海量数据的存储&#xff0c;对于分布式并发数据处理的效率极高&#xff0c;易于扩展且支持动态伸缩&#xff0c;适用于廉价设备…

AOP技术基础

1、引言2、AOP技术基础 3、Java平台AOP技术研究4、.Net平台AOP技术研究2.1 AOP技术起源 AOP技术的诞生并不算晚&#xff0c;早在1990年开始&#xff0c;来自Xerox Palo Alto Research Lab&#xff08;即PARC&#xff09;的研究人员就对面向对象思想的局限性进行了分析。他们研…

Could not find a package,configuration file provided by G2O ,G2OConfig.cmake,g2o-config.cmake

因为项目需要使用到g2o&#xff0c;所以自己从git上面clone下来&#xff0c; git clone https://github.com/RainerKuemmerle/g2o.git 然后&#xff1a; cd g2o mkdir build cd build cmake .. make -j4 编译完成&#xff0c;并在CMakeLists.txt使用g2o&#xff1a; set(G2O_DI…

TCP 协议的三次握手、四次分手

详细描述了 TCP 协议的连接和关闭的整个过程。解释了为什么 TCP 协议是面向连接的、可靠的数据传输协议。 TCP 在互联网上之间的通信交流&#xff0c;一般是基于 TCP (Transmission Control Protocol&#xff0c;传输控制协议) 或者 UDP (User Datagram Protocol&#xff0c;用…

prefix.pch文件的一些简单使用

该文件可以引入一些全局通用的文件&#xff0c;这样就不用每次在文件中导入&#xff0c;也可以定义全局通用的变量或常量&#xff0c;如 //定义NSString常量 #define ServiceName "cn.zmfc" //定义颜色 #define BackgroudColor [UIColor colorWithRed:232/2…

[Bzoj4182]Shopping(点分治)(树上背包)(单调队列优化多重背包)

4182: Shopping Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 374 Solved: 130[Submit][Status][Discuss]Description 马上就是小苗的生日了&#xff0c;为了给小苗准备礼物&#xff0c;小葱兴冲冲地来到了商店街。商店街有n个商店&#xff0c;并且它们之间的道路构成了一…

您不能在64-位可执行文件上设置DEP属性?

我是为dllhost.exe设置DEP时遇到了同样的情况。你需要选择64位系统对应的程序。64位系统&#xff1a;C:\Windows\SysWOW64\dllhost.exe32位系统&#xff1a;C:\Windows\System32\dllhost.exe

应聘者提问环节

http://blog.csdn.net/jinhuiyu/article/details/4487058转载于:https://www.cnblogs.com/wuchanming/p/4333791.html

Tiny框架2.0版火热推出

方法论 方法论决定了可以达到的高度 方法论&#xff0c;就是人们认识世界、改造世界的根本方法。 它是人们用什么样的方式、方法来观察事物和处理问题。概括地说&#xff0c;世界观主要解决世界“是什么”的问题&#xff0c;方法论主要解决“怎么办”的问题。 方法论是一种以解…

Java--Socket通信

下面内容是Java开发内容的高级知识点&#xff0c;需要对Java中的面向对象、IO、多线程、以及网络相关知识有一定的基础。(知识永远都有深度&#xff0c;本章节长期更新内容) 1、网络基础知识 网络通信的条件&#xff1a;1、两个通信的端都要有各自的IP地址作为唯一标识&#xf…

一幅长文细学华为MRS大数据开发(五)——MapReduce和Yarn

5 MapReduce和Yarn 摘要&#xff1a;本文中主要讲述大数据领域中最著名的批处理和离线处理计算框架——MapReduce&#xff0c;包括MapReduce的原理、流程、使用场景&#xff0c;以及Hadoop集群中负责统一的资源管理和调度的组件——Yarn。 作者&#xff1a;来自ArimaMisaki创作…

数据:ContentResolver类

ContentResolver是通过URI来查询ContentProvider中提供的数据。除了URI以 外&#xff0c;还必须知道需要获取的数据段的名称&#xff0c;以及此数据段的数据类型。 如果你需要获取一个特定的记录&#xff0c;你就必须知道当前记录的ID。 简要介绍ContentResolver的主要接口&…

[MySQL 5.6] Performance Schema 之 PS配置项(1)

尽管Performance Schema&#xff08;以下简称PS&#xff09;在5.5中已经出现&#xff0c;但一直没有使用过&#xff0c;并且相比5.6&#xff0c;5.5的PS表要少很多。 以下从一个初学者的角度&#xff0c;阅读PS的官方文档&#xff0c;做一些简单的笔记官方文档见&#xff1a;ht…

Tensorflow从入门到精通之——Tensorflow基本操作

前边的章节介绍了什么是Tensorflow&#xff0c;本节将带大家真正走进Tensorflow的世界&#xff0c;学习Tensorflow一些基本的操作及使用方法。同时也欢迎大家关注我们的网站和系列教程&#xff1a;http://www.tensorflownews.com/&#xff0c;学习更多的机器学习、深度学习的知…

一幅长文细学Vue(七)——路由

7 路由 摘要&#xff1a;在本文中我们会谈及路由的知识点&#xff0c;了解前端路由工作的过程以及如何在Vue3中配置路由&#xff0c;知道怎么使用嵌套路由和实现动态路由匹配&#xff0c;以及使用编程式导航和导航守卫。 声明&#xff1a;为了文章的清爽性&#xff0c;在文章内…

[编程题] 按照左右半区的方式重新组合单链表

[编程题] 按照左右半区的方式重新组合单链表 给定一个单链表的头部节点head&#xff0c;链表长度为N。 如果N为偶数&#xff0c;那么前N/2个节点算作左半区&#xff0c;后N/2个节点算作右半区&#xff1b; 如果N为奇数&#xff0c;那么前N/2个节点算作左半区&#xff0c;后N/21…

iOS开发之单例模式

1、概述 单例模式是一种常用的软件设计模式&#xff0c;通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问&#xff0c;从而方便对实例个数的控制并节约系统资源。 如果希望系统中某个类的对象只能存在一个&#xff0c;单例模式是最好的解决方案&#xff0c…

Codeforces 913 二进制背包(柠檬水) 暴力贪心特殊背包(选题)

A B C 给你N(N<30)种水瓶每种水瓶有无限个 每个的体积是2^(i-1)价格是cost[i] 要求你花最少的钱弄出L体积的水 先从前到后扫一遍cost[i1]min(cost[i1],cost[i]*2) 再从后往前扫一遍cost[i]min(cost[i],cost[i1) 保证了价格的最优化 然后从0开始到30 如果二进制有当前体积的…