?? uart.c
字號:
/*********************************************************************
Filename: uart.c
Revised: $Date: 2007-12-13 10:01:47 -0800 $
Revision: $Revision: 10194 $
Description:
Notes:
*********************************************************************/
/*********************************************************************
* INCLUDES
*/
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>
/*
#include <semaphore.h>
#include <pthread.h>
*/
#include "uart.h"
#include "analyseframe.h"
/*********************************************************************
* LOCAL VARIABLES
*/
volatile int STOP=FALSE;
volatile int tty_fd;
semun_t port_sem;
int sem_id;
unsigned char rx_buf[RX_BUF_SIZE];
unsigned int rx_buf_pointer = 0;
unsigned int rx_buf_overflow = 0;
/*********************************************************************
* CONSTANTS
*/
/*********************************************************************
* FUNCTIONS
*/
//釋放信號量
int sem_up(int semid)
{
struct sembuf sops={0, +1, IPC_NOWAIT};
return (semop(semid, &sops, 1));
}
//獲取信號量
int sem_down(int semid)
{
struct sembuf sops={0, -1, IPC_NOWAIT};
return (semop(semid, &sops, 1));
}
int set_port(int fd, int nSpeed, int nBits, char nParity, int nStop)
{
struct termios newtio, oldtio;
/* 保存測試現有串口參數設置,在這里如果串口號等出錯,會有相關的出錯信息 */
if (tcgetattr(fd, &oldtio) != 0)
{
perror("SetupSerial 1");
//printf("<p>SetupSerial 1\n");
return -1;
}
bzero(&newtio, sizeof(newtio));
/* 步驟一,設置字符大小 */
newtio.c_cflag |= CLOCAL | CREAD;
newtio.c_cflag &= ~CSIZE;
newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
newtio.c_oflag &= ~OPOST; /*Output*/
switch (nBits)
{
case 7:
newtio.c_cflag |= CS7;
break;
case 8:
newtio.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
break;
}
/* 設置奇偶校驗位 */
switch (nParity)
{
case 'O': // 奇數
case 'o':
newtio.c_cflag |= PARENB;
newtio.c_cflag |= PARODD;
newtio.c_iflag |= (INPCK | ISTRIP);
break;
case 'E': // 偶數
case 'e':
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PARODD;
newtio.c_iflag |= (INPCK | ISTRIP);
break;
case 'N': // 無奇偶校驗位
case 'n':
newtio.c_cflag &= ~PARENB;
break;
}
/* 設置波特率 */
switch (nSpeed)
{
case 2400:
cfsetispeed(&newtio, B2400);
cfsetospeed(&newtio, B2400);
break;
case 4800:
cfsetispeed(&newtio, B4800);
cfsetospeed(&newtio, B4800);
break;
case 9600:
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
break;
case 19200:
cfsetispeed(&newtio, B19200);
cfsetospeed(&newtio, B19200);
break;
case 38400:
cfsetispeed(&newtio, B38400);
cfsetospeed(&newtio, B38400);
break;
case 115200:
cfsetispeed(&newtio, B115200);
cfsetospeed(&newtio, B115200);
break;
case 460800:
cfsetispeed(&newtio, B460800);
cfsetospeed(&newtio, B460800);
break;
default:
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
break;
}
/* 設置停止位 */
if (nStop == 1)
{
newtio.c_cflag &= ~CSTOPB;
}
else if (nStop == 2)
{
newtio.c_cflag |= CSTOPB;
}
/* 設置等待時間和最小接收字符 */
newtio.c_cc[VTIME] = 3; //300ms
newtio.c_cc[VMIN] = 0;
/* 處理未接收字符 */
tcflush(fd, TCIOFLUSH);
/* 激活新配置 */
if ((tcsetattr(fd, TCSANOW, &newtio)) != 0)
{
perror("com set error");
printf("<p>com set error!\n");
return -1;
}
//printf("set done!\n");
return 0;
}
int port_open(void)
{
int value;
if (sem_down(sem_id) == -1)
{
printf("can not get semaphore!\n");
exit(1);
}
#ifdef DEBUG_MODE
printf("<p>get semaphore success!\n");
value = semctl(sem_id, 0, GETVAL, 0);
printf("value of semaphore is: %d\n", value);
#endif
if ((tty_fd = open(COM, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) //非阻塞模式,忽略VMIN 和VTIME 的設置
{
perror("Can't Open Serial Port");
printf("<p>Can't Open Serial Port!\n");
port_close();
return -1;
}
if (set_port(tty_fd, BAUDRATE, 8, 'N', 1) < 0)
{
perror("set_opt error");
printf("<p>set_opt error!\n");
port_close();
return -1;
}
return (tty_fd);
}
void port_close(void)
{
int value;
close(tty_fd);
if (sem_up(sem_id) == -1)
{
printf("can not release semaphore!\n");
}
#ifdef DEBUG_MODE
printf("<p>release semaphore success!\n");
value = semctl(sem_id, 0, GETVAL, 0);
printf("value of semaphore is: %d\n", value);
#endif
}
void port_write(unsigned char *buffer, unsigned int length)
{
if (write(tty_fd, buffer, length) < 0)
perror("write error:");
}
unsigned int port_read(void)
{
int nread = 0;
unsigned char start_timer_flag = 0;
unsigned char read_timer_count = 0;
rx_buf_pointer = 0;
while (1)
{
if((nread = read(tty_fd, &rx_buf[rx_buf_pointer], RX_BUF_SIZE)) > 0)
{
start_timer_flag = 1; //接收到有效數據后開始計數
read_timer_count = 0;
rx_buf_pointer += nread; //接收指針累加
#ifdef DEBUG_MODE
printf("read length is: %d\n", nread);
printf("rx_buf_pointer is: %d\n", rx_buf_pointer);
printf("read data is: %s\n", rx_buf);
#endif
}
usleep(100000);
#ifdef DEBUG_MODE
if (nread <= 0)
printf("no data!\n");
//printf("read length is: %d\n", nread);
#endif
read_timer_count++; //進行計數
if (start_timer_flag)
{
if (read_timer_count >= 3) //超時退出
break;
}
else
{
if (read_timer_count >= 50) //超時退出
break;
}
}
return (rx_buf_pointer);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -