
c语言串口通讯过程
分接收端和发送端。
接收端:1·打开com1端口 fd=fopen(\\\/dev\\\/ttys0,方式);2·取得当前串口值,保存到结构体变量oldtio tcgetattr(fd,&oldtio);3·串口结构体变量newtio清0.bzero(&newtio,sizeof(newtio))4·设置串口参数 主要设置比特率、是否忽略奇偶校验错误,启用正规模式等等。
接收端1·打开com端口2·取得当前串口值3·串口结构体变量清04·设置串口参数。
求个mini2440的串口C程序
Mini2440有三个串口,USRT0,UART1,UART3。
对串口的操作有三种:串口初始化,串口接收,串口发送 1 串口初始化 1)串口初始化函数 void Uart_Init(int pclk,int baud) { int i; if(pclk == 0) pclk = PCLK; rUFCON0 = 0x0; \\\/\\\/UART channel 0 FIFO control register, FIFO disable rUFCON1 = 0x0; \\\/\\\/UART channel 1 FIFO control register, FIFO disable rUFCON2 = 0x0; \\\/\\\/UART channel 2 FIFO control register, FIFO disable rUMCON0 = 0x0; \\\/\\\/UART chaneel 0 MODEM control register, AFC disable rUMCON1 = 0x0; \\\/\\\/UART chaneel 1 MODEM control register, AFC disable \\\/\\\/UART0 rULCON0 = 0x3; \\\/\\\/Line control register : Normal,No parity,1 stop,8 bits \\\/\\\/ [10] [9] [8] [7] [6] [5] [4] [3:2] [1:0] \\\/\\\/ Clock Sel, Tx Int, Rx Int, Rx Time Out, Rx err, Loop-back, Send break, Transmit Mode, Receive Mode \\\/\\\/ 0 1 0 , 0 1 0 0 , 01 01 \\\/\\\/ PCLK Level Pulse Disable Generate Normal Normal Interrupt or Polling rUCON0 = 0x245; \\\/\\\/ Control register rUBRDIV0=( (int)(pclk\\\/16.\\\/baud+0.5) -1 ); \\\/\\\/Baud rate divisior register 0 \\\/\\\/UART1 rULCON1 = 0x3; rUCON1 = 0x245; rUBRDIV1=( (int)(pclk\\\/16.\\\/baud+0.5) -1 ); \\\/\\\/UART2 rULCON2 = 0x3; rUCON2 = 0x245; rUBRDIV2=( (int)(pclk\\\/16.\\\/baud+0.5) -1 ); for(i=0;i<100;i++); } l 串口时钟的设置 pclk = PCLK;使用PCLK作为串口的时钟。
l 寄存器进行了设置 主要是对三种寄存器进行了设置 rUFCONn (n=0,1,2) —— 串口FIFO控制寄存器 rUMCONn (n=0,1)——串口调制控制寄存器 rULCONn (n=0,1,2)——串口线性控制寄存器 rUCONn(n=0,1,2)——串口控制寄存器 rUBRDIVn(n=0,1,2)——串口Tx,Rx收发速率的设定 2)串口的选择 void Uart_Select(int ch) { whichUart = ch; } 2 串口发送 串口发送数据通过判断rUTRSTATn (n=0,1,2)的第2位是不是为1来判断发送缓存是否为空。
1) 串口发送字节 void Uart_SendByte(int data) { if(whichUart==0) { if(data=='\\\ ') { while(!(rUTRSTAT0 & 0x2)); \\\/\\\/ Delay(1); \\\/\\\/because the slow response of hyper_terminal WrUTXH0('\\\\r'); } while(!(rUTRSTAT0 & 0x2)); \\\/\\\/Wait until THR is empty. \\\/\\\/ Delay(1); WrUTXH0(data); } else if(whichUart==1) { if(data=='\\\ ') { while(!(rUTRSTAT1 & 0x2)); \\\/\\\/Delay(1); \\\/\\\/because the slow response of hyper_terminal rUTXH1 = '\\\\r'; } while(!(rUTRSTAT1 & 0x2)); \\\/\\\/Wait until THR is empty. \\\/\\\/Delay(1); rUTXH1 = data; } else if(whichUart==2) { if(data=='\\\ ') { while(!(rUTRSTAT2 & 0x2)); \\\/\\\/Delay(1); \\\/\\\/because the slow response of hyper_terminal rUTXH2 = '\\\\r'; } while(!(rUTRSTAT2 & 0x2)); \\\/\\\/Wait until THR is empty. \\\/\\\/Delay(1); rUTXH2 = data; } } 首先是串口通道的选择;然后判断THR是否为空,直到等到发送缓存为空,退出while循环;再要发送的字节data放到发送缓存中。
如果发送的数据是回车的话,直接发送转义字符\\\/r,当然也要等到THR为空才可以发送。
2) 串口发送字符串 void Uart_SendString(char *pt) { while(*pt) Uart_SendByte(*pt++); } 把字符串看作是字符数组,字符指针*pt来指代字符数组的首地址,读取指针指向的字符,这样就可以把发送的的字符串逐个进行字节发送了。
2 串口接收 串口接收通过判断rUTRSTATn (n=0,1,2)的第1位是不是为1来判断发送缓存是否为空。
1)串口等待接收状态 void Uart_TxEmpty(int ch) { if(ch==0) while(!(rUTRSTAT0 & 0x4)); \\\/\\\/Wait until tx shifter is empty. else if(ch==1) while(!(rUTRSTAT1 & 0x4)); \\\/\\\/Wait until tx shifter is empty. else if(ch==2) while(!(rUTRSTAT2 & 0x4)); \\\/\\\/Wait until tx shifter is empty. } 寄存器rUTRSTATn & 0x4 (n=0,1,2)来判断tx shifter是不是为空 3) 接收字符 char Uart_Getch(void) { if(whichUart==0) { while(!(rUTRSTAT0 & 0x1)); \\\/\\\/Receive data ready return RdURXH0(); } else if(whichUart==1) { while(!(rUTRSTAT1 & 0x1)); \\\/\\\/Receive data ready return RdURXH1(); } else if(whichUart==2) { while(!(rUTRSTAT2 & 0x1)); \\\/\\\/Receive data ready return RdURXH2(); } return 0 ; } 寄存器rUTRSTATn & 0x1 (n=0,1,2)来判断Receive data ready
并把接收到的数据写到接收缓存里面。
4) 接收字符串 void Uart_GetString(char *string) { char *string2 = string; char c; while((c = Uart_Getch())!='\\\\r') { if(c=='\\\\b') { if( (int)string2 < (int)string ) { Uart_Printf(\\\\b \\\\b); string--; } } else { *string++ = c; Uart_SendByte(c); } } *string='\\\\0'; Uart_SendByte('\\\ '); } char Uart_GetKey(void) { if(whichUart==0) { if(rUTRSTAT0 & 0x1) \\\/\\\/Receive data ready return RdURXH0(); else return 0; } else if(whichUart==1) { if(rUTRSTAT1 & 0x1) \\\/\\\/Receive data ready return RdURXH1(); else return 0; } else if(whichUart==2) { if(rUTRSTAT2 & 0x1) \\\/\\\/Receive data ready return RdURXH2(); else return 0; } return 0 ; } 寄存器rUTRSTATn & 0x1 (n=0,1,2) 来判断Receive data ready
并把接收到的数据写到接收缓存里面。
否则返回空。
与getchar类似,并且也是返回字符类型。
5) 接收整形数字 函数返回类型:整形 int Uart_GetIntNum(void) { char str[30]; char *string = str; int base = 10; int minus = 0; int result = 0; int lastIndex; int i; Uart_GetString(string); if(string[0]=='-') { minus = 1; string++; } if(string[0]=='0' && (string[1]=='x' || string[1]=='X')) { base = 16; string += 2; } lastIndex = strlen(string) - 1; if(lastIndex<0) return -1; if(string[lastIndex]=='h' || string[lastIndex]=='H' ) { base = 16; string[lastIndex] = 0; lastIndex--; } if(base==10) { result = atoi(string); result = minus ? (-1*result):result; } else { for(i=0;i<=lastIndex;i++) { if(isalpha(string)) { if(isupper(string)) result = (result<<4) + string - 'A' + 10; else result = (result<<4) + string - 'a' + 10; } else result = (result<<4) + string - '0'; } result = minus ? (-1*result):result; } return result; } 首先以字符串的形式接收数据Uart_GetString(string); 然后通过判断是不是以‘-’开头来确定是不是负数,是负数则minus=1;再通过以0x,oX开头或者以H,h结尾来判断是不是16进制,否则为10进制;如果是10进制,则通过atoi把字符串转化为数字,并加上正负,如果是16进制,判断是不是字母,再判断大小写字母分别进行转换。
16进制也支持正负号。
6) 接收10进制的数 int Uart_GetIntNum_GJ(void) { char string[16] ; char *p_string = string ; char c; int i = 0 ; int data = 0 ; while( ( c = Uart_Getch()) != '\\\\r' ) { if(c=='\\\\b') p_string--; else *p_string++=c; Uart_SendByte( c ) ; } *p_string = '\\\\0'; i = 0 ; while( string != '\\\\0' ) { data = data * 10 ; if( string<'0'||string>'9' ) return -1 ; data = data + ( string-'0' ) ; i++ ; } return data ; } 只转化10进制的数字。
首先用getchar接收单个字符存储在string中,然后把string转换为整型的data。
并返回整形的data。
3串口打印 \\\/\\\/If you don't use vsprintf(), the code size is reduced very much. void Uart_Printf(char *fmt,...) { va_list ap; char string[256]; va_start(ap,fmt); vsprintf(string,fmt,ap); Uart_SendString(string); va_end(ap); } va_list完成可变参数的操作 具体实现如下 n 由于无法列出传递函数的所有实参的类型和数目时,用省略号指定参数表 void Uart_Printf(char *fmt,...) n 函数参数的传递原理 函数参数是以数据结构:栈的形式存取,从右至左入栈. n 获取省略号指定的参数 在函数体中声明一个va_list,然后用va_start函数来获取参数列表中的参数,使用完毕后调用va_end()结束。
va_list ap; char string[256]; va_start(ap,fmt); vsprintf(string,fmt,ap); Uart_SendString(string); va_end(ap); va_start使ap指向第一个可选参数。
va_end把ap指针清为NULL。
函数体内可以多次遍历这些参数,但是都必须以va_start开始,并以va_end结尾。
vsprintf(string,fmt,ap);实现向字符数组中写指定格式的内容本文来自CSDN博客,转载请标明出处:
cfmakeraw函数有什么作用
就是设置串口属性对吧
我想问的是设置后是什么效果
cfmakeraw sets the terminal attributes as follows: termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP |INLCR|IGNCR|ICRNL|IXON); termios_p->c_oflag &= ~OPOST; termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); termios_p->c_cflag &= ~(CSIZE|PARENB); termios_p->c_cflag |= CS8;就是将终端设置为原始模式,该模式下所有的输入数据以字节为单位被处理。
在原始模式下,终端是不可回显的,而且所有特定的终端输入\\\/输出模式不可用。
C语言串口设置问题:linux下怎么用C语言设置串口通讯的MARK, SPACE校验
看你驱动程序的接口啊一般是是open(“串口名”)得到一个int小整数,作为接口函数的参数,表示这个串口然后read(),write()操作结束后不要忘记close()下面的实现就是驱动的实现了一般结合硬件也要自己去实现的
请问串口通信中的串口号设置我只知道直接设置
你 有 几个 COM,不知道吗
去 设备管理器 里看看如果 编程的话,只能 试着 打开一个串口,然后 分析返回的出错信息
推荐看书Visual C++_Turbo C串口通信编程实践Visual_Basic与_RS-232_串行通信控制Delphi串口通信工程开发实例导航
C语言中如何对串口进行操作
C语言会有操作串口的库函数的,按照串口库函数标识实现调用就可以了。



