1、一.熟悉 AVR 单片机 UART 资源,首先从波特率和帧说起波特率:与 51 不同有单独的波特率发生器,不需要定时器来产生,节省了资源波特率计算公式,这里我采用 IccAVR 的配置功能,直接计算生成单片机支持的模式:异步正常模式,异步倍数模式,和同步模式,一般选第一种模式帧格式:起始位+数据位(5-9 位可选)+校验位(可选)+停止位(1、2 位) 空闲o * P 1 1 通讯电路空闲时为高电平二、大概了解了下硬件资源后,就要了解软硬件的桥梁寄存器了1.数据寄存器:数据来了要有个接受的地方吧,数据发送要有个数据发送的信封吧。这就是数据寄存器 UDR (RXB 和 TXB) 物理上为分开的,
2、地址上是一样的。就像写信和接信时,你家的地址只有同一个地址一样,但是写信和别人发给你的信封却有 2 个一样。使用时自动控制的。数据寄存器为空时才能发送数据,否则会无效。数据进入后,进入移位寄存器,由引脚 TXD 一位位发出。2.控制和状态寄存器 UCSRARXC TXC UDRE FE DOR PE U2X MPCM接受完成置 1 发送完成置 1 数据为空标志 帧错误 1 接受数据 校验位错误倍速模式 多机通信读取数据清 0 中断时自动清 0 数据完全到移 溢出1 1 1 地址位位寄存器中 1UCSRB 设置相关中断的允许RXCIE TXCIE UDRIE RXEN TXEN UXSZ2 RX
3、B8 TXB8接受中断允许 发送中断允许 空中断允许 数据接受允许 数据发送允许 位数设置 接受第 9 位RXEN,TXEN 设置时会改变时普通 IO 口,或者是当做复用口用,在发送数据时设置下,数据全部发送后才生效 RXB8,TXB8 需要先读写出UCSRCURSEL UMSEL UPM1 UPM0 USBS UCSZ1 UCSZ0 UCPOL寄存器选择 工作模式 校验方式 停止位 和上面的 UXSZ2 设置写时需要设为 1 1 异步 数据个数存在共用寄存器 00 禁止 11 奇 10 偶 0 为 1 个 1 为 2 个波特率寄存器:UBRRL UBRRHUBRRH 和 UCSRC 共用 了
4、底 4 位 加上 UBRRL 共 12 位 设置后正在传的数据会被打断需要注意 URSEL 的设置 :0 写入的比特率高 4 位1 写入的是寄存器的内容读 UBRRH,第一次是比特率的内容 在连续的 2 个时钟周期内再读一次就是 UCRSC 的内容 使用时可以查速查表,直接用 ICCAVR 生成工具即可。 三,相关操作 等练习个程序后补上1 初始化 关全局中断 TXC RXC 看数据是否完成 发送数据前 TXC 必须请零 把数据放入到发送缓冲器即可 UDR 中 5-8 位2 注意下空中断 允许后需要不断写数据 否则一直不断的中断产生 一般禁止就可以了TXEN 设置 0 后 所有数据发送后生效
5、然后就当普通 IO 口用了禁止接受 会立即 丢失数据四一些总线标准RS232 9 针 D 型接口 1 -3 -25 0 3-25V需要使用电平转换电路 MAX232五.工业设计中的串口这里如果大家看到了还是注意下比较好 ,网上写的不多的,我也是从工程实践和查找大量的参考书中总结的设计思路是基于状态机,并自定义了协议,同时协议中使用了 CRC 校验,和简易的加密技术思路是:主从方式,上位机发送数据包,下位机在中断中接受,接受数据时要一位位的确认,并不断进行切换,发送的位置状态,把初步确认的数据放到接受缓冲器里,等所有的数据接收好了,程序进入大循环了,就执行主程序中加入 uart 操作函数,这个函
6、数首先判断主机发送的命令和设置是否接受完成,在完成的状态下进行校验正确性,校验后,根据主机命令,组装数据包和存贮主机的设置数据,并把需要发送的数据包或设置完成数据包放在需要发送的数据缓冲区,接着改变下此时的状态:为我组好了,准备发送数据了,接着触发中断,可以直接往串口发个数据即可,正常发送后,单片机会执行其他程序,等上位机接受到这个触发数据后,下位机会中断,中断程序会根据状态,一位位的发生缓冲区的数据,直到所有的数据发送完成,发送完成后还要置位到接受数据状态 0。我的环境是 atmega128初始化uchar LED_Temp=0xFF;uchar OUT_temp=0x04;static u
7、char Uart_Status;static uchar R_Data_Lenth;uchar Tx_BufTxBufSize;uchar Rx_BufRxBufSize;uchar *P_Uart_Rx;uchar *P_Uart_Tx;uchar Rx_Count;uchar Tx_Count;void Uart_Init(void)/UCSR0B = 0x00; /先关闭UCSR0A=0x00;UCSR0C=0x06; /8 DATA ,1 STOP, NO PARITYUCSR0B = (18);UBRR0L=(unsigned char)tmp;/ 函数说明:串口接收中断函数#pr
8、agma interrupt_handler uart0_rx_isr:iv_USART0_RXCvoid uart0_rx_isr(void)/这里填写串口中断处理的内容,可以添加协议,使用状态机就可以了/把接收到得内容放在缓冲区,然后再创建个处理缓冲区数据的函数,直接放在主循环中即可/函数说明:串口发送完成中断函数 #pragma interrupt_handler uart0_tx_isr:iv_USART0_TXCvoid uart0_tx_isr(void)/发送数据的处理函数/ 函数说明:uart 进程函数 ,放在大循环中void Uart_Process(void)/接收到得数据
9、,再具体的在系统中实现,比如上位机的监控,或者传输数据等/函数说明:uart 测试程序 void Uart_Test(uchar data)UDR0 = 0x01;/发送数据/- 功能描述:串口发送字节的函数/- 函数属性:外部,使用户使用/- 参数说明:mydata:要发送的一个字节/ - 返回说明:无/ - 注:发送一个字节,是串口发送的基础操作void UART_Send_Byte(unsigned char mydata) / UCSR0B = (1RXCIE0)|(1TXCIE0)|(1RXEN0)|(1TXEN0);UCSR0B /关串口收发中断while(!(UCSR0A /等待发送缓冲区为空UDR0 = mydata;/ delay_nms(5);UCSR0B |= (1RXCIE0)|(1TXCIE0); /改的时候不要影响其它寄存器位,开串口中断