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

📄 uarttxt.txt

📁 winavr环境下的一段与pc机进行通讯的程序
💻 TXT
字号:
1.为什么uart.c编译后无法正常运行,UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)无法修改值UCSRC;
2.使用外频4兆会稳定一些,UBRRL=25;
3.使用查询法可以运行,而使用中断却不能正常测试;
  /*
	查询方式UART测试程序 (试验通过)
	uartt.c
	硬件:AVR-51
	时钟:外部4MHz
	
	2008-4-15
*/

#include <avr/io.h>

#define uchar unsigned char
#define uint unsigned int

void put_c(uchar c)
{
	while( !(UCSRA & (1<<UDRE)) );
	UDR=c;
}

uchar getc(void)
{
	while( !(UCSRA & (1<<RXC)) );	
	return UDR;
}

int  main(void) 
{
	//uart 初始化
	UBRRH=0;
	UBRRL=25;//9600 baud 6MHz:38  4MHz:25
	UCSRB=(1<<RXEN)|(1<<TXEN);
	
	
	while(1)
	{
		put_c(getc());
	}
}
测试时,ComPort端口软件设置为com1,9600,8,1后可以正常运行;这时的UCSRC值是合适的吗?经查资料,UCSRC的初值为10000110,及UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0),但是在JTAG调试时不能显示UCSRC的值?
4.读UBRRH时一次就可以,而读UCSRC时需要进行两次:
unsigned char USART_ReadUCSRC(void)
{ 
       unsigned char ucsrc;
       //read UCSRC
       ucsrc=UBRRH;
       ucsrc=UCSRC;
       return ucsrc;
} 
4.中断运行时,不能退出程序,循环执行?如下:
SIGNAL (SIG_UART_TRANS)
{
    uchar c='a';
	UDR=c;
}
int  main( void )
{
    //uart初始化
	UBRRH=0;	
	UBRRL=25;	// baud=9600   UBRR=CK/(baud*16) -1 
	//接收使能、发送使能、接收中断允许、发送中断允许
    //8位数据传送,无奇偶,停止1位 
 	UCSRB=(1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN);
	sei();//总中断允许
    //UDR='s';
}
5.使用中断方式进行数据接收时,数据接收结束中断服务程序必须从UDR
读取数据以清RXC标志,否则只要中断处理程序一结束,一个新的中断就
会产生。可以手工清除RXC标志位。程序总是在while((IsRecvComplete()){};
处停止运行?原因是studio中的设置,-0s压缩时出现问题(2.7%),设为-00及
不压缩时(4.8%)程序运行正常。正确的程序如下:
/*
	中断方式UART测试程序 
	uart.c
	硬件:avr-51
	时钟:外部4MHz
	ATmega16
	2008-05-1
*/

#include <avr/io.h>
#include <avr/interrupt.h>
//#include <avr/signal.h>

#define uchar unsigned char
#define uint unsigned int

uchar g_bTxdPos=0;	//发送定位计数器
uchar g_bTxdLen=0;	//等待发送字节数
uchar g_bRxdPos=0;	//接收定位计数器
uchar g_bRxdLen=0;	//等待接收字节数

uchar g_aSendBuf[16];	//发送数据绶冲区
uchar g_aRecvBuf[16];	//接收数据缓冲区




//接收中断
SIGNAL(SIG_UART_RECV)
{
	uchar c;
	c=UDR; 
	if (g_bRxdLen>0)
	{
		g_aRecvBuf[g_bRxdPos++]=c;
		g_bRxdLen--;
        
	}
    UCSRA&=~_BV(RXC); //清除RXC标志位
    
}

//发送中断
SIGNAL (SIG_UART_TRANS)
{
	if(--g_bTxdLen>0)
		UDR=g_aSendBuf[++g_bTxdPos];
}


//是否接收完成
uchar IsRecvComplete(void)
{
    if(g_bRxdLen>0)
	return 1;
	else
	return 0;
}

void LedA0(void)//指示灯
{
    PORTA&=~_BV(PA0);
	DDRA|=_BV(PA0); 
}

//从发送缓冲区发送指定长度数据
void SendToUart(uchar size)
{
	g_bTxdPos=0;
	g_bTxdLen=size;
	UDR=g_aSendBuf[0];
	while(g_bTxdLen>0);
}

//接收指定长度数据到接收缓冲区
void RecvFromUart(uchar size,uchar bwait)
{
	g_bRxdPos=0;
	g_bRxdLen=size;
	if(bwait)
	   while(g_bRxdLen>0){};
	
}

int  main( void )
{   //初始化端口
    PORTD|=_BV(PD0);
	DDRD|=_BV(PD1);
	DDRD&=~_BV(PD0);
    
	uchar i;
    
    //uart初始化
   
	UBRRH=0;	
	UBRRL=25;	// baud=9600   UBRR=CK/(baud*16) -1 
	//接收使能、发送使能、接收中断允许、发送中断允许
 	UCSRB=(1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN);
	//8位数据传送,无奇偶,停止1位  
    //UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);//(1<<URSEL)
    
    sei();
	
	while(1)
	{   
	   
        
		//异步接收16字节数据
		RecvFromUart(16,0);
        
        
		//等待接收完成
		while(IsRecvComplete());
        
	  
		LedA0();
		//将接收到的数据复制到发送缓冲区
		
		for(i=0;i<16;i++)
			g_aSendBuf[i]=g_aRecvBuf[i];
		
		//发送回接收到的数据
		SendToUart(16);
		
	}
}

难道是studio+winavr071210有bug吗?
5.用studio+winavr编译以下这段程序时,出现奇怪问题,将studio的edit
 current configuration option设为-0s(代码压缩)时可编译通过,而设
为-00(不压缩)时则显示gcc plug-in: Error: Object file not found on 
expected location  G:\gcc\adc-disp\default\adc-disp.elf,为什么?
/*
	主程序 
	adc-disp.c
	硬件:avr-51
	时钟:内部4MHz
	ATmega8
	2008-05-09
*/


#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>

#define uchar unsigned char
#define uint  unsigned int

static uint g_aAdValue[8];	//A/D转换缓冲区

void IoInit(void)
{
   PORTC&=~_BV(PC0);        //初始化pc0
   DDRC&=~_BV(PC0);

}

uint AdcConvert(void)
{
	uchar i;
	uint ret;
	uchar max_id,min_id,max_value,min_value;
	
	ADMUX=0xc0;//内部2.56V参考电压,0通道
	ADCSRA=_BV(ADEN);//使能ADC,单次转换模式
	
	//连续转换8次
	for(i=0;i<8;i++)
	{
		ADCSRA|=_BV(ADSC);
		_delay_us(60);
		while(ADCSRA&_BV(ADSC))
			_delay_us(60);
		ret=ADCL;
		ret|=(uint)(ADCH<<8);
		g_aAdValue[i]=ret;
	}
	ret=0;
	for(i=1;i<8;i++)
		ret+=g_aAdValue[i];
	
	//找到最大和最小值索引	
	ret/=7;
	max_id=min_id=1;
	max_value=min_value=0;
	for(i=1;i<8;i++)
	{
		if(g_aAdValue[i]>ret)
		{
			if(g_aAdValue[i]-ret>max_value)
			{
				max_value=g_aAdValue[i]-ret;
				max_id=i;
			}
		}
		else
		{
			if(ret-g_aAdValue[i]>min_value)
			{
				min_value=ret-g_aAdValue[i];
				min_id=i;
			}
		}
	}
	
	//去掉第一个和最大最小值后的平均值
	ret=0;
	for(i=1;i<8;i++)
	{
		if((i!=min_id)&&(i!=max_id))
			ret+=g_aAdValue[i];     
	}
	if(min_id!=max_id)
		ret/=5;
	else  
		ret/=6;

	ADCSRA=0;//关闭ADC
	
	return ret;
}

int main(void)
{
	uchar i;
	IoInit();
	
	while(1)
	{
		scanf("%c",&i);
		if(i=='c')
		   printf("%d\n",AdcConvert());
	}
}



⌨️ 快捷键说明

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