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());
}
}