搜索
bottom↓
回复: 11

好久没看见马老师了!我等程序已经简化的和cvavr自动生成差不多了,为什么仍然复位?帮帮

[复制链接]

出0入0汤圆

发表于 2007-4-9 10:11:03 | 显示全部楼层 |阅读模式
只要用串口精灵发送大文件,就会收几个字节自动复位一次。由于我在初始化时,蜂鸣器响一声,所以每次蜂鸣器鸣响,表示自动复位了一次。

/*****************************************************

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_port  PORTD.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  //&frac12;&Oacute;&Ecirc;&Otilde;&frac12;á&Ecirc;&oslash;±ê&Ouml;&frac34;

#define TXC   6  //·&cent;&Euml;&Iacute;&frac12;á&Ecirc;&oslash;±ê&Ouml;&frac34;

#define UDRE  5  //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 RXEN  4

#define TXEN  3





#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[RX_BUFFER_SIZE];



#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 [USART_RXC] void usart_rx_isr(void)

{

char status,data;

status=UCSRA;

data=UDR;

if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)

   {

   rx_buffer[rx_wr_index]=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[rx_rd_index];

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[TX_BUFFER_SIZE];



#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 [USART_TXC] void usart_tx_isr(void)

{

if (tx_counter)

   {

   --tx_counter;

   UDR=tx_buffer[tx_rd_index];

   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[tx_wr_index]=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);

         }

      };

}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2007-4-19 13:29:12 | 显示全部楼层
简化了,仍然不行啊,同样恢复位,调试了很久了。想不通了。谁有马老师的实验板子,也调试一下好吗?

出0入0汤圆

 楼主| 发表于 2007-4-26 09:51:08 | 显示全部楼层
欲哭无泪了。我服了,就这么点东西,怎么都搞不定。究竟哪里出问题了?

出0入0汤圆

发表于 2007-4-27 00:48:43 | 显示全部楼层
等5.1有时间再帮你看。

出0入0汤圆

 楼主| 发表于 2007-4-28 16:47:29 | 显示全部楼层
急切期盼中,每天都会来看看。为马老师的风度感动!

出0入0汤圆

发表于 2007-4-28 22:09:05 | 显示全部楼层
我对以上你的程序进行了测试,仅改动了USART的初始化部分,因为我用的4M晶体,不过波特率仍为9600bps。



测试结果一次复位的情况也没有发生过,只是PC上的串口精灵接收到的字符比发送出去的字符少。这种现象是正常的,因为AVR收到一个字符要经过一定的时间才能发送出去。当接收缓冲区满的话,就出现了丢掉字符的现象了。但AVR不会复位的。



我采用每隔150ms连续发送128字符,此时发送的个数与接收的个数就完全一样了。再快就会丢失了。

出0入0汤圆

 楼主| 发表于 2007-4-29 08:57:41 | 显示全部楼层
哦,丢数据我是清楚的。因为没有调试握手协议。可是当发送文件时,就会复位。我用了11.0592M的晶体。现在我马上试验4M的晶体。附件为我发送的文件。您要有时间再试验一下。衷心感谢马老师不厌其烦的指点。

点击此处下载armok01152379.txt

出0入0汤圆

发表于 2007-4-29 09:45:59 | 显示全部楼层
与系统频率应该无关,只要是USART正确设置就行了。按你主栏的程序没有发现问题(就是不知道你为什么要-32)。



会不会是其它问题?



我测试使用串口精灵,以及超级终端,下串文件就是C代码文件本身。都没有发生复位情况。

出0入0汤圆

 楼主| 发表于 2007-4-29 11:29:36 | 显示全部楼层
程序又更改了一下,仅留下了接收部分。仍然会在传送过程中听到蜂鸣器的响声,而且更加频繁了。神了!

#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[RX_BUFFER_SIZE];   

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 [USART_RXC] 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[rx_wr_index]=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[rx_rd_index];   //读取缓冲队列中的数据  

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

      };

}

出0入0汤圆

 楼主| 发表于 2007-4-29 11:39:51 | 显示全部楼层
搞不明白,我死不瞑目!马老师,在麻烦麻烦您了。如果您仍然不会复位,我就想别的办法了。

出0入0汤圆

 楼主| 发表于 2007-4-29 16:57:43 | 显示全部楼层
用RS232自己焊接了一块串口板子,完全OK,不但不复位,数据也不丢了。有可能RS202的设计问题。松了口气了。早自己动手就好了。谢谢马老师的耐心指点。我又可以进展下一步的内容了。呵呵!高兴!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-24 13:52

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表