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

📄 m16_usart.c

📁 AVR单片机ATmega16的串口测试程序
💻 C
字号:
/*===================================================================
			CopyLeft(CL) FORVERE Late Lee 
			   All rights NOT reserved
		     版权所无,翻版不究,但请保留此处信息。
			http://www.cnbolgs.com/latelee
			       latelee@163.com
*文件名:	串口通信测试程序
*文件说明:	实现多种格式收发
*版本:          v1.0
*芯片:          ATmega16
*晶振:          内部 7372800MHz晶振
*作者:          Late Lee
*日期:          2009年1月26日 已丑年初一晚 	
*编译环境:      UltraEdit+WinAVR20080610(gcc 4.3.0) 经仿真测试
*说明:		下面是一些说明和笔记:
模式说明:
// M1:8位数据位,1位停止位,无校验
// M2:8位数据位,1位停止位,奇校验
// M3:8位数据位,2位停止位,无校验
// M4:8位数据位,2位停止位,偶校验
// M5:9位数据位,1位停止位,无校验
// M6:9位数据位,1位停止位,奇校验
// M7:9位数据位,2位停止位,无校验
// M8:9位数据位,2位停止位,偶校验	

此次修改了关于自定义类型的一些小问题,AVRGCC建议用其定义的类型。
// 测试笔记:
1、未添加中断处理部分
2、严重声明:在发送、接收数据处理时很不合理!如果真的要分8位和9位传送,
则分开写就可以了。  2009-1-24 23:00
3、两芯片仿真时9位数据发送不正常,未与PC仿真,2009-1-24 23:05
4、usart_receive9()编译有警告,不知原因。2009-1-25 18:40
5、解决警告问题,if语句有些表达得不好,9位数据收发测试正常 1-26 21:07
====================================================================*/

#include "M16_USART.h"

/*------------------------------------------------------
关于波特率的设置,还是直接赋给寄存器比较好,减少CPU工作量
--------------------------------------------------------*/
// 形参为波特率
void usart_init_baud(uint16 baud)
{
//	UBRRH = (uint8)(baud>>8);			//high
//	UBRRL = (uint8)baud;				//low

#ifdef U2XX						// 倍速
	UCSRA |= (1<<U2X);
	UBRRL= (F_CPU/baud/8-1)%256;
	UBRRH= (F_CPU/baud/8-1)/256;
#else
	UCSRA &= ~(1<<U2X);
	UBRRL= (F_CPU/baud/16-1)%256;			// OK here
	UBRRH= (F_CPU/baud/16-1)/256;

#endif

//////////////////////////////////////////////
#if   METHOD == 1
	UCSRC = (1<<URSEL) | (3<<UCSZ0);		//8位数据位,1位停止位,无校验
	UCSRB = (1<<RXEN) | (1<<TXEN);			// 使能发送接收
#elif METHOD == 2
	UCSRC = (1<<URSEL) | (3<<UPM0) | (3<<UCSZ0);	//8位数据位,1位停止位,奇校验
	UCSRB = (1<<RXEN) | (1<<TXEN);			// 使能发送接收
#elif METHOD == 3
	UCSRC = (1<<URSEL) | (1<<USBS) |(3<<UCSZ0);	//8位数据位,2位停止位,无校验
	UCSRB = (1<<RXEN) | (1<<TXEN);			// 使能发送接收
#elif METHOD == 4
	UCSRC = (1<<URSEL) | (2<<UPM0) | (1<<USBS) |(3<<UCSZ0);	//8位数据位,2位停止位,偶校验
	UCSRB = (1<<RXEN) | (1<<TXEN);			// 使能发送接收
#elif METHOD == 5
	UCSRC = (1<<URSEL)|(3<<UCSZ0);			//9位数据位,1位停止位,无校验
	UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<UCSZ2);	// 使能发送接收
#elif METHOD == 6
	UCSRC = (1<<URSEL) | (3<<UPM0) | (3<<UCSZ0);	//9位数据位,1位停止位,奇校验
	UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<UCSZ2);	// 使能发送接收
#elif METHOD == 7
	UCSRC = (1<<URSEL) | (1<<USBS) |(3<<UCSZ0);	//9位数据位,2位停止位,无校验
	UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<UCSZ2);	// 使能发送接收
#elif METHOD == 8
	UCSRC = (1<<URSEL) | (2<<UPM0) | (1<<USBS) |(3<<UCSZ0);	//9位数据位,2位停止位,偶校验
	UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<UCSZ2);	// 使能发送接收
#endif
}

// 用库函数设置
void usart_init_std(void)
{
	// 利用库函数设置
	UBRRH= UBRRH_VALUE;
	UBRRL= UBRRL_VALUE;
#ifdef U2XX						// 倍速
	UCSRA |= (1<<U2X);
#else
	UCSRA &= ~(1<<U2X);

#endif

//////////////////////////////////////////////
#if   METHOD == 1
	UCSRC = (1<<URSEL) | (3<<UCSZ0);		//8位数据位,1位停止位,无校验
	UCSRB = (1<<RXEN) | (1<<TXEN);			// 使能发送接收
#elif METHOD == 2
	UCSRC = (1<<URSEL) | (3<<UPM0) | (3<<UCSZ0);	//8位数据位,1位停止位,奇校验
	UCSRB = (1<<RXEN) | (1<<TXEN);			// 使能发送接收
#elif METHOD == 3
	UCSRC = (1<<URSEL) | (1<<USBS) |(3<<UCSZ0);	//8位数据位,2位停止位,无校验
	UCSRB = (1<<RXEN) | (1<<TXEN);			// 使能发送接收
#elif METHOD == 4
	UCSRC = (1<<URSEL) | (2<<UPM0) | (1<<USBS) |(3<<UCSZ0);	//8位数据位,2位停止位,偶校验
	UCSRB = (1<<RXEN) | (1<<TXEN);			// 使能发送接收


#elif METHOD == 5
	UCSRC = (1<<URSEL)|(3<<UCSZ0);			//9位数据位,1位停止位,无校验
	UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<UCSZ2);	// 使能发送接收
#elif METHOD == 6
	UCSRC = (1<<URSEL) | (3<<UPM0) | (3<<UCSZ0);	//9位数据位,1位停止位,奇校验
	UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<UCSZ2);	// 使能发送接收
#elif METHOD == 7
	UCSRC = (1<<URSEL) | (1<<USBS) |(3<<UCSZ0);	//9位数据位,2位停止位,无校验
	UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<UCSZ2);	// 使能发送接收
#elif METHOD == 8
	UCSRC = (1<<URSEL) | (2<<UPM0) | (1<<USBS) |(3<<UCSZ0);	//9位数据位,2位停止位,偶校验
	UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<UCSZ2);	// 使能发送接收
#endif
}

// 无形参,波特率直接赋给UBRRH和UBRRL
void usart_init(void)
{
#ifdef U2XX						// 倍速
	UCSRA |= (1<<U2X);
	UBRRH= 0;
	UBRRL= 0x0B;					// 些处添加 38400

#else
	UCSRA &= ~(1<<U2X);
	UBRRH= 0;
	UBRRL= 0x0B;			

#endif

//////////////////////////////////////////////
#if   METHOD == 1
	UCSRC = (1<<URSEL) | (3<<UCSZ0);		//8位数据位,1位停止位,无校验
	UCSRB = (1<<RXEN) | (1<<TXEN);			// 使能发送接收
#elif METHOD == 2
	UCSRC = (1<<URSEL) | (3<<UPM0) | (3<<UCSZ0);	//8位数据位,1位停止位,奇校验
	UCSRB = (1<<RXEN) | (1<<TXEN);			// 使能发送接收
#elif METHOD == 3
	UCSRC = (1<<URSEL) | (1<<USBS) |(3<<UCSZ0);	//8位数据位,2位停止位,无校验
	UCSRB = (1<<RXEN) | (1<<TXEN);			// 使能发送接收
#elif METHOD == 4
	UCSRC = (1<<URSEL) | (2<<UPM0) | (1<<USBS) |(3<<UCSZ0);	//8位数据位,2位停止位,偶校验
	UCSRB = (1<<RXEN) | (1<<TXEN);			// 使能发送接收


#elif METHOD == 5
	UCSRC = (1<<URSEL)|(3<<UCSZ0);			//9位数据位,1位停止位,无校验
	UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<UCSZ2);	// 使能发送接收
#elif METHOD == 6
	UCSRC = (1<<URSEL) | (3<<UPM0) | (3<<UCSZ0);	//9位数据位,1位停止位,奇校验
	UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<UCSZ2);	// 使能发送接收
#elif METHOD == 7
	UCSRC = (1<<URSEL) | (1<<USBS) |(3<<UCSZ0);	//9位数据位,2位停止位,无校验
	UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<UCSZ2);	// 使能发送接收
#elif METHOD == 8
	UCSRC = (1<<URSEL) | (2<<UPM0) | (1<<USBS) |(3<<UCSZ0);	//9位数据位,2位停止位,偶校验
	UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<UCSZ2);	// 使能发送接收
#endif
}

// 8位发送
void usart_transmit8(uint8 data)
{
	while ( !(UCSRA & (1<<UDRE)) )			// 不为空,等之
		;
	UDR = data;			
}

// 9位发送
void usart_transmit9(uint16 data)
{
	while ( !(UCSRA & (1<<UDRE)) )			// 不为空,等之
		;												
	UCSRB &= ~(1<<TXB8);				// 先清零
	if (data & 0x0100)				// 第9位为1
		UCSRB |= (1<<TXB8);
	UDR = data;		
}

// 发送字符串
void usart_sendstring(uint8 *string)
{
	while (*string)
	{
		usart_transmit8(*string++);
	}
	usart_transmit8(0x0d);
	usart_transmit8(0x0a);				// 最后发送回车换行 
}

// 8位接收
uint8 usart_receive8(void)
{
	while ( !(UCSRA & (1<<RXC)) )
		;
	return UDR;	
}

// 9位接收
uint16 usart_receive9(void)
{
	uint16 status,resulth,resultl;
	while ( !(UCSRA & (1<<RXC)) )
		;
	status = UCSRA;
	resulth = UCSRB;
	resultl = UDR;
	if ((uint8)status & ((1<<FE) | (1<<DOR) | (1<<PE)))	// 如果出现某些错误
		return -1;
	resulth = (resulth>>1) & 0x01;
	return ((resulth<<8) | resultl);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -