⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 基于嵌入式web服务器的web应用层代码
💻 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 + -