好久没看见马老师了!我等程序已经简化的和cvavr自动生成差不多了,为什么仍然复位?帮帮
只要用串口精灵发送大文件,就会收几个字节自动复位一次。由于我在初始化时,蜂鸣器响一声,所以每次蜂鸣器鸣响,表示自动复位了一次。/*****************************************************
Chip type : ATmega16L
Program type : Application
Clock frequency : 11.059200 MHz
Memory model : Small
External SRAM size: 0
Data Stack size : 256
*****************************************************/
#include <mega16.h>
#include <delay.h>
#define buzzer_portPORTD.7
void buzzer(unsigned char times)
{
unsigned char i=0;
unsigned int buzzer_time=0;
while(i<times)
{
for(buzzer_time=0;buzzer_time<40;buzzer_time++)
{
buzzer_port=~buzzer_port;
delay_us(250);
}
i++;
}
buzzer_port=1;
}
//********************************
// USART
//********************************
//UCSRA
#define RXC 7//½ÓÊÕ½áÊø±êÖ¾
#define TXC 6//·¢ËͽáÊø±êÖ¾
#define UDRE5//USART DATA REGISTER EMPTY
#define FE 4//FRAME ERROR
#define DOR 3//DATA OVER RUN
#define PE 2//PARITY ERROR
//UCSRB
#define RXCIE 7
#define TXCIE 6
#define UDRIE 5
#define RXEN4
#define TXEN3
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<PE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
// USART Receiver buffer
#define RX_BUFFER_SIZE 128
char rx_buffer;
#if RX_BUFFER_SIZE<256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif
// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow;
// USART Receiver interrupt service routine
interrupt void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer=data;
if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if (++rx_counter >(RX_BUFFER_SIZE-32))
{
rx_counter=0;
rx_buffer_overflow=1;
// UCSRB&=~(1<<RXEN);
};
};
}
#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer;
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif
// USART Transmitter buffer
#define TX_BUFFER_SIZE 128
char tx_buffer;
#if TX_BUFFER_SIZE<256
unsigned char tx_wr_index,tx_rd_index,tx_counter;
#else
unsigned int tx_wr_index,tx_rd_index,tx_counter;
#endif
// USART Transmitter interrupt service routine
interrupt void usart_tx_isr(void)
{
if (tx_counter)
{
--tx_counter;
UDR=tx_buffer;
if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
};
}
#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter == TX_BUFFER_SIZE);
#asm("cli")
if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
{
tx_buffer=c;
if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
++tx_counter;
}
else
UDR=c;
#asm("sei")
}
#pragma used-
#endif
// Standard Input/Output functions
#include <stdio.h>
unsigned char ascii;
void main(void)
{
PORTA=0x00;
DDRA=0xFF;
PORTB=0x00;
DDRB=0xFF;
PORTC=0x00;
DDRC=0x00;
PORTD=0x80;
DDRD=0x80;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0xD8;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x47;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// Global enable interrupts
#asm("sei")
buzzer(4);
while (1)
{
// Place your code here
ascii=getchar();
if(ascii!=0)
{
putchar(ascii);
}
};
} 简化了,仍然不行啊,同样恢复位,调试了很久了。想不通了。谁有马老师的实验板子,也调试一下好吗? 欲哭无泪了。我服了,就这么点东西,怎么都搞不定。究竟哪里出问题了? 等5.1有时间再帮你看。 急切期盼中,每天都会来看看。为马老师的风度感动! 我对以上你的程序进行了测试,仅改动了USART的初始化部分,因为我用的4M晶体,不过波特率仍为9600bps。
测试结果一次复位的情况也没有发生过,只是PC上的串口精灵接收到的字符比发送出去的字符少。这种现象是正常的,因为AVR收到一个字符要经过一定的时间才能发送出去。当接收缓冲区满的话,就出现了丢掉字符的现象了。但AVR不会复位的。
我采用每隔150ms连续发送128字符,此时发送的个数与接收的个数就完全一样了。再快就会丢失了。 哦,丢数据我是清楚的。因为没有调试握手协议。可是当发送文件时,就会复位。我用了11.0592M的晶体。现在我马上试验4M的晶体。附件为我发送的文件。您要有时间再试验一下。衷心感谢马老师不厌其烦的指点。
点击此处下载armok01152379.txt 与系统频率应该无关,只要是USART正确设置就行了。按你主栏的程序没有发现问题(就是不知道你为什么要-32)。
会不会是其它问题?
我测试使用串口精灵,以及超级终端,下串文件就是C代码文件本身。都没有发生复位情况。 程序又更改了一下,仅留下了接收部分。仍然会在传送过程中听到蜂鸣器的响声,而且更加频繁了。神了!
#include <mega16.h>
#include <delay.h>
#define buzzer_port PORTD.7
void buzzer(unsigned char times) //响100ms,频率1khz
{
unsigned char i=0,buzzer_time=0;
while(i<times)
{
for(buzzer_time=0;buzzer_time<200;buzzer_time++)
{
buzzer_port=~buzzer_port;
delay_us(500);
}
i++;
}
buzzer_port=1;
}
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
// USART Receiver buffer
#define RX_BUFFER_SIZE 8
char rx_buffer;
unsigned int rx_wr_index,rx_rd_index,rx_counter;
// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow; //接收缓冲区溢出标志
// USART Receiver interrupt service routine //usart接受中断服务程序
interrupt void usart_rx_isr(void)
{
char status,data;
status=UCSRA;//读取接收状态标志位,必须先读,当读了UDR后,UCSRA便自动清
data=UDR; //读取USART数据寄存器,这句与上句位置不能颠倒的
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer=data;
if (++rx_wr_index == RX_BUFFER_SIZE)
rx_wr_index=0; //到了尾部,则指向头部(构成环状)
if (++rx_counter == RX_BUFFER_SIZE)//队列中收到字符加1,并判断是否队列
{
rx_counter=0; // 队列满了
rx_buffer_overflow=1;
//置缓冲区溢出标志。在主程序中必要的地方需要判断该标志,以证明读到数据的完整性
};
};
}
#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer; //读取缓冲队列中的数据
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
//读取指针指向下一个未读的数据,如果指到了队列尾部,则指回到队列头步
#asm("cli")
--rx_counter; //队列中未读数据个数减1。因为该变量在接收中断中要改变的,
#asm("sei") // 开中断
return data;
}
#pragma used- // CVAVR的伪指令,取消used+的作用
#endif
#include <stdio.h>
void main(void)
{
char rs_char;
PORTA=0x00;
DDRA=0x00;
PORTB=0x00;
DDRB=0x00;
PORTC=0x00;
DDRC=0x00;
PORTD=0x80;
DDRD=0x80;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0xD8;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x47;
ACSR=0x80;
SFIOR=0x00;
buzzer(2);
#asm("sei")
while (1)
{
rs_char=getchar();
};
} 搞不明白,我死不瞑目!马老师,在麻烦麻烦您了。如果您仍然不会复位,我就想别的办法了。 用RS232自己焊接了一块串口板子,完全OK,不但不复位,数据也不丢了。有可能RS202的设计问题。松了口气了。早自己动手就好了。谢谢马老师的耐心指点。我又可以进展下一步的内容了。呵呵!高兴!
页:
[1]