搜索
bottom↓
回复: 60

相应马老师的号召,我把cvavr中usart中断子程序注释了一下

[复制链接]

出0入0汤圆

发表于 2005-10-19 20:27:32 | 显示全部楼层 |阅读模式
相应马老师的号召,我把cvavr中usart中断子程序注释了一下,里面也有几句不懂的地方,希望高手帮我注释一下,谢谢

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

This program was produced by the

CodeWizardAVR V1.24.4a Standard

Automatic Program Generator

?Copyright 1998-2004 Pavel Haiduc, HP InfoTech s.r.l.

http://www.hpinfotech.com

e-mail:office@hpinfotech.com



Project :

Version :

Date    : 2005-10-19

Author  : df                              

Company : dadf                           

Comments:





Chip type           : ATmega8L

Program type        : Application

Clock frequency     : 8.000000 MHz

Memory model        : Small

External SRAM size  : 0

Data Stack size     : 256

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



#include <mega8.h>



#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];   //定义接受缓冲区8个char型变量组成的数组

                                                                 

#if RX_BUFFER_SIZE<256            //若缓冲区大于256个字节,定义为 int型数组

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            //usart接受中断服务程序

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)  //记录缓冲区还有多少个字节没有读取,如果超出了缓冲区容量,置位缓冲区溢出标志

      {

      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-         //?????????

#endif



// Standard Input/Output functions

#include <stdio.h>



// Declare your global variables here



void main(void)

{

// Declare your local variables here



// Input/Output Ports initialization

// Port B initialization

// Func7=In Func6=In Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=1 State4=1 State3=T State2=T State1=T State0=T

PORTB=0x30;

DDRB=0x30;



// Port C initialization

// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTC=0x00;

DDRC=0x00;



// Port D initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTD=0x00;

DDRD=0x00;



// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: Timer 0 Stopped

TCCR0=0x00;

TCNT0=0x00;



// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: Timer 1 Stopped

// Mode: Normal top=FFFFh

// OC1A output: Discon.

// OC1B output: Discon.

// Noise Canceler: Off

// Input Capture on Falling Edge

TCCR1A=0x00;

TCCR1B=0x00;

TCNT1H=0x00;

TCNT1L=0x00;

ICR1H=0x00;

ICR1L=0x00;

OCR1AH=0x00;

OCR1AL=0x00;

OCR1BH=0x00;

OCR1BL=0x00;



// Timer/Counter 2 initialization

// Clock source: System Clock

// Clock value: Timer 2 Stopped

// Mode: Normal top=FFh

// OC2 output: Disconnected

ASSR=0x00;

TCCR2=0x00;

TCNT2=0x00;

OCR2=0x00;



// External Interrupt(s) initialization

// INT0: Off

// INT1: Off

MCUCR=0x00;



// Timer(s)/Counter(s) Interrupt(s) initialization

TIMSK=0x00;



// 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=0x98;

UCSRC=0x86;

UBRRH=0x00;

UBRRL=0x33;



// Analog Comparator initialization

// Analog Comparator: Off

// Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0x80;

SFIOR=0x00;



// Global enable interrupts

#asm("sei")



while (1)

      {

      // Place your code here



      };

}

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

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2005-10-19 21:04:37 | 显示全部楼层
#ifndef _DEBUG_TERMINAL_IO_     //?????????



#define _ALTERNATE_GETCHAR_     //?????????

#pragma used+                   //?????????

#pragma used-         //?????????





高手,这几句是什么意思?

出0入0汤圆

发表于 2005-10-19 21:21:13 | 显示全部楼层
您一说高手,没人敢回答了:D



俺是低手,瞎说两句:那些都是编译指示,和具体程序关系不太大的。主要取决于编译器。

出0入0汤圆

 楼主| 发表于 2005-10-19 21:28:48 | 显示全部楼层
呵呵,谢谢,只要能当我老师,您就是高手:)

出0入0汤圆

发表于 2006-3-12 13:03:36 | 显示全部楼层
看了下中文的资料,上边也没有明确说明,不过有这样一段:

// 关闭编译时的warning

#pragma used+

// 库函数原型

int sum(int a, int b);

int mul(int a, int b);

#pragma used-

// #pragma 指示符告诉编译器从 mylib.lib 库中编译或连接函数



#pragma used+是关闭编译时的warning,那#pragma used-就是打开了。。。

不知道对不对,仅作参考!

出0入0汤圆

发表于 2006-3-13 08:27:47 | 显示全部楼层
注释好,看程序花的时间少。支持!!!

出0入0汤圆

发表于 2006-3-25 11:19:38 | 显示全部楼层
#pragma used+

#pragma used-

应该是否提示警告信息,编译时如果定义后没使用会提示警告信息。我也是新手,跟大家学习,不知道理解是否正确。

出0入0汤圆

发表于 2006-5-1 22:06:12 | 显示全部楼层
高手哪去了?给个GCC的程序啊!

出0入0汤圆

发表于 2006-5-2 23:01:19 | 显示全部楼层
因为ICC默认的getchar()和putchar()是采用查询方式编写的.

此处是中断方式,所以要重新定义getchar()和普通char();

这些语句不是标准C编译器里有的,不用太在意.

出0入0汤圆

发表于 2007-3-12 01:43:59 | 显示全部楼层
一年半的旧贴了,把它翻出来做些解释。

下面是1楼的贴子,开了好头,但没有好的结尾,原因是......不说了。我在它的基础上画个句号吧。



=================================================================================



相应马老师的号召,我把cvavr中usart中断子程序注释了一下,里面也有几句不懂的地方,希望高手帮我注释一下,谢谢



#include <mega8.h>



#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];   // 接收缓冲区,为char型变量组成的数组,该数组构成环形对列,个数为RX_BUFFER_SIZE



// 定义接收缓冲区环形对列的控制指针:rx_wr_index为写指针,rx_rd_index为读指针,rx_counter为在队列中接收到的字符个数

#if RX_BUFFER_SIZE<256            // 若接收缓冲区小于256个字节,定义为环形队列的指针为char型变量

    unsigned char rx_wr_index,rx_rd_index,rx_counter;

#else                             // 否则为int型变量

    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            //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)      //判断本接收到的数据是否有数据帧、校验或数据溢出错误(此处指USART的硬件接收溢出)

   {

       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;                   // 队列满了,队列中收到字符个数为0,表示队列中所有以前的数据作废,因为最后的数据已经把最前边的数据覆盖了                                

            rx_buffer_overflow=1;           //置缓冲区溢出标志。在主程序中必要的地方需要判断该标志,以证明读到数据的完整性

        };

   };

}



#ifndef _DEBUG_TERMINAL_IO_     // 如果在主程序中没有定义 _DEBUG_TERMINAL_IO_ 则下面程序有效(注1)

  // Get a character from the USART Receiver buffer

  #define _ALTERNATE_GETCHAR_     // 定义标示字 _ALTERNATE_GETCHAR_ ,该标示字在本程序中不起作用,主要应用于编写其他模块时告之系统的getchar()函数已经被本程序的Ggetchar()替换

  #pragma used+                   // CVAVR的伪指令,通知编译系统,编译到与系统提供的同名函数时,使用以下的代码

  char getchar(void)

  {

    char data;

    while (rx_counter==0);      //接收数据队列中没有数据可以读取,等待......(注2)

    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



// Standard Input/Output functions

#include <stdio.h>



// Declare your global variables here



void main(void)

{

// Declare your local variables here



// Input/Output Ports initialization

// Port B initialization

// Func7=In Func6=In Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In  

// State7=T State6=T State5=1 State4=1 State3=T State2=T State1=T State0=T  

PORTB=0x30;

DDRB=0x30;



// Port C initialization

// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In  

// State6=T State5=T State4=T State3=T State2=T State1=T State0=T  

PORTC=0x00;

DDRC=0x00;



// Port D initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In  

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T  

PORTD=0x00;

DDRD=0x00;



// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: Timer 0 Stopped

TCCR0=0x00;

TCNT0=0x00;



// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: Timer 1 Stopped

// Mode: Normal top=FFFFh

// OC1A output: Discon.

// OC1B output: Discon.

// Noise Canceler: Off

// Input Capture on Falling Edge

TCCR1A=0x00;

TCCR1B=0x00;

TCNT1H=0x00;

TCNT1L=0x00;

ICR1H=0x00;

ICR1L=0x00;

OCR1AH=0x00;

OCR1AL=0x00;

OCR1BH=0x00;

OCR1BL=0x00;



// Timer/Counter 2 initialization

// Clock source: System Clock

// Clock value: Timer 2 Stopped

// Mode: Normal top=FFh

// OC2 output: Disconnected

ASSR=0x00;

TCCR2=0x00;

TCNT2=0x00;

OCR2=0x00;



// External Interrupt(s) initialization

// INT0: Off

// INT1: Off

MCUCR=0x00;



// Timer(s)/Counter(s) Interrupt(s) initialization

TIMSK=0x00;



// 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=0x98;

UCSRC=0x86;

UBRRH=0x00;

UBRRL=0x33;



// Analog Comparator initialization

// Analog Comparator: Off

// Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0x80;

SFIOR=0x00;



// Global enable interrupts

#asm("sei")



while (1)

      {

      // Place your code here



      };

}

====================================================================

在CVAVR系统提供的标准库函数stdio.h中,提供了getchar()函数,该函数是采用轮询方式从USART接收数据的,轮询方式不仅效率低,而且会丢失数据,不能实现多任务的并行处理。



CVAVR程序向导中给出的采用中断+缓冲的方式接受数据,同PC的串口接受数据的方法一样,充分利用了AVR的高速和RAM多的优点,体现出了如何才能充分发挥AVR的特点的程序设计思想,这种思路在32位系统中也是这样的。



使用AVR的话,对软件的设计能力要求更高了,否则根本不能发挥和体现AVR的特点。许多人有了一点C的基础,就认为采用C编写单片机程序没问题,很快就会掌握AVR了,对此我只能一笑了之。看看本站上众多的代码,再看看本贴的遭遇,能说什么呢?



回到本题:

注1:

如果在程序的开头部分加上语句

#define _DEBUG_TERMINAL_IO_

那么程序在编译时仍使用系统自己的getchar()函数,这样在软件模拟仿真时,可以从模拟的终端读取数据,便于在软件模拟环境中调试整个系统,而需要正式运行时,则把该句注释掉。

注2:

此处在正式应用中应根据实际情况做适当的修改。否则当主程序调用getchar()时,如果缓冲队列中没有数据,同时对方也没有发数据的情况时,程序会在此死循环。

比较简单的办法是将这句删掉,而在调用getchar()函数前先判断rx_counter的值,为0的话就不调用了。

或改为:

  signed int getchar(void)

  {

    signed int data;

    if (rx_counter == 0)

    {

        data = -1;   

    }

    else

    {

        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;

}



注3:

有兴趣希望深入实在学习的网友,可将CVAVR生成的USART发送代码仔细分析以下。它的发送代码非常完美,可以马上使用。

#include <mega16.h>



#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 Transmitter buffer

#define TX_BUFFER_SIZE 8

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>



// Declare your global variables here



void main(void)

{

// Declare your local variables here



// Input/Output Ports initialization

// Port A initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTA=0x00;

DDRA=0x00;



// Port B initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTB=0x00;

DDRB=0x00;



// Port C initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTC=0x00;

DDRC=0x00;



// Port D initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTD=0x00;

DDRD=0x00;



// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: Timer 0 Stopped

// Mode: Normal top=FFh

// OC0 output: Disconnected

TCCR0=0x00;

TCNT0=0x00;

OCR0=0x00;



// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: Timer 1 Stopped

// Mode: Normal top=FFFFh

// OC1A output: Discon.

// OC1B output: Discon.

// Noise Canceler: Off

// Input Capture on Falling Edge

// Timer 1 Overflow Interrupt: Off

// Input Capture Interrupt: Off

// Compare A Match Interrupt: Off

// Compare B Match Interrupt: Off

TCCR1A=0x00;

TCCR1B=0x00;

TCNT1H=0x00;

TCNT1L=0x00;

ICR1H=0x00;

ICR1L=0x00;

OCR1AH=0x00;

OCR1AL=0x00;

OCR1BH=0x00;

OCR1BL=0x00;



// Timer/Counter 2 initialization

// Clock source: System Clock

// Clock value: Timer 2 Stopped

// Mode: Normal top=FFh

// OC2 output: Disconnected

ASSR=0x00;

TCCR2=0x00;

TCNT2=0x00;

OCR2=0x00;



// External Interrupt(s) initialization

// INT0: Off

// INT1: Off

// INT2: Off

MCUCR=0x00;

MCUCSR=0x00;



// Timer(s)/Counter(s) Interrupt(s) initialization

TIMSK=0x00;



// USART initialization

// Communication Parameters: 8 Data, 1 Stop, No Parity

// USART Receiver: Off

// USART Transmitter: On

// USART Mode: Asynchronous

// USART Baud rate: 9600

UCSRA=0x00;

UCSRB=0x48;

UCSRC=0x86;

UBRRH=0x00;

UBRRL=0x19;



// Analog Comparator initialization

// Analog Comparator: Off

// Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0x80;

SFIOR=0x00;



// Global enable interrupts

#asm("sei")



while (1)

      {

      // Place your code here

      putchar(0x55);

      };

}



思考分析:

我在主程序的循环里仅有一句不停的发0X55,问题是AVR的运行速度非常快,而USART串出的速度肯定明显的慢(按9600bps计算,需要1秒多时间才能送出1000个字符),那么,假定主程序循环了1000次,发送1000个0x55,请判断在UASRT口上能否正确的发出1000个0x55,有没有丢失或溢出现象存在?
-----此内容被machao于2007-03-12,02:11:58编辑过

出0入0汤圆

发表于 2007-3-12 07:50:22 | 显示全部楼层
ouravr推荐使用winavr 使用gcc的应该很多。高手们如能在繁忙的工作中挤点时间,为论坛造福。提供一个gcc的m16多机通讯实例,供大家学习用。非常感谢!

















静思语:与朋友相处要多感恩、知足、善解、包容。

出0入0汤圆

发表于 2007-3-13 15:45:45 | 显示全部楼层
烦请斑竹把本贴移到我的讨论组里。它在这里有些不合适。谢谢了。

出0入0汤圆

发表于 2007-3-16 10:44:50 | 显示全部楼层
非常感谢~!前不久我用CVAVR系统生成了USART程序,有很多地方我也不明白.今天算是取到经了.

出0入0汤圆

发表于 2007-4-28 17:23:05 | 显示全部楼层
新发现的老帖子,对新手来说非常好,交作业了:



思考分析:

我在主程序的循环里仅有一句不停的发0X55,问题是AVR的运行速度非常快,而USART串出的速度肯定明显的慢(按9600bps计算,需要1秒多时间才能送出1000个字符),那么,假定主程序循环了1000次,发送1000个0x55,请判断在UASRT口上能否正确的发出1000个0x55,有

没有丢失或溢出现象存在?

答:不会。因为putchar()中有这句:



while (tx_counter == TX_BUFFER_SIZE);



表示如果缓冲满就等待。

出0入0汤圆

发表于 2007-4-28 19:29:02 | 显示全部楼层
GOOD

出0入0汤圆

发表于 2008-1-10 21:17:47 | 显示全部楼层
学习了

出0入0汤圆

发表于 2008-2-12 21:37:55 | 显示全部楼层
思考分析:
我在主程序的循环里仅有一句不停的发0X55,问题是AVR的运行速度非常快,而USART串出的速度肯定明显的慢(按9600bps计算,需要1秒多时间才能送出1000个字符),那么,假定主程序循环了1000次,发送1000个0x55,请判断在UASRT口上能否正确的发出1000个0x55,有没有丢失或溢出现象存在?


不能正确发出1000个,有丢失的现象,理由是:缓存有限.

出0入0汤圆

发表于 2008-4-9 14:30:59 | 显示全部楼层
各位好,我能不能问下关于USART发送和接收的问题。上面程序中如果我把中断那块去掉、同时保留putchar(getchar)与#include<stdio.h>中的一个,我的发送程学仍然可以。请问这中间的区别是什么阿?我刚开始学,请大家理解。

出0入0汤圆

发表于 2008-5-22 10:59:32 | 显示全部楼层
谢谢,学习了!

出0入0汤圆

发表于 2008-5-22 11:25:08 | 显示全部楼层
xiexie

出0入10汤圆

发表于 2008-5-30 14:37:09 | 显示全部楼层
收藏了,正要学习使用串口

出0入0汤圆

发表于 2008-5-30 20:15:04 | 显示全部楼层
呵呵 这算啥呀  我写的串口打印驱动早就用循环队列了 呵呵

出0入0汤圆

发表于 2008-5-30 22:12:15 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2009-3-16 21:14:17 | 显示全部楼层
mark。

出0入0汤圆

发表于 2009-3-17 09:00:36 | 显示全部楼层
cvavr中,T/C1的比较匹配A的中断标号是什么?

出0入0汤圆

发表于 2009-3-20 21:12:32 | 显示全部楼层
JH

出0入0汤圆

发表于 2009-3-20 21:22:38 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-9-24 20:36:16 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-9-25 16:12:15 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-9-25 22:11:38 | 显示全部楼层
Mark

出0入0汤圆

发表于 2009-10-29 10:16:18 | 显示全部楼层
谢谢莫站长给我们提供这么好的学习平台,更感谢那些高手大侠们在繁忙的工作之余穿梭于各个板块之间,参与讨论,给出解决方法,分享经验,上传资料。大大缩短了我学习的时间,在此致以深深的感谢,我也会尽快学有所成,参与其中。

出0入0汤圆

发表于 2009-11-10 14:59:06 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-3-9 20:11:04 | 显示全部楼层
ji

出0入0汤圆

发表于 2010-4-22 17:23:56 | 显示全部楼层
顶。

出0入0汤圆

发表于 2010-5-22 12:38:32 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-2 18:22:05 | 显示全部楼层
// 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)      //判断本接收到的数据是否有数据帧、校验或数据溢出错误(此处指USART的硬件接收溢出)  
   {  
       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;                   // 队列满了,队列中收到字符个数为0,表示队列中所有以前的数据作废,因为最后的数据已经把最前边的数据覆盖了                                 
            rx_buffer_overflow=1;           //置缓冲区溢出标志。在主程序中必要的地方需要判断该标志,以证明读到数据的完整性  
        };  
   };  
}  



上面一段程序中后面带/********/中,不明白为什么(++rx_counter == RX_BUFFER_SIZE)时最后的数据已经把最前边的数据覆盖!我觉得缓存区刚满,应该是当(++rx_counter == (RX_BUFFER_SIZE+1))最后的数据才把最前边的数据覆盖.



                                                   高手不吝赐教!

出0入0汤圆

发表于 2010-9-29 19:39:34 | 显示全部楼层
学习了

出0入0汤圆

发表于 2010-11-7 23:08:04 | 显示全部楼层
尚未有人讨论中断保护的问题,用NAKED好像能提高效率。

出0入0汤圆

发表于 2010-11-8 07:52:07 | 显示全部楼层

出0入0汤圆

发表于 2010-11-9 22:01:45 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-7 16:36:39 | 显示全部楼层
和35楼有相同的疑问,是不是应该写成 if (rx_counter++ == RX_BUFFER_SIZE)

高手指点。。。

出0入0汤圆

发表于 2010-12-7 21:54:11 | 显示全部楼层
记号.

出0入0汤圆

发表于 2010-12-9 13:06:55 | 显示全部楼层
向楼主致敬…

出0入0汤圆

发表于 2010-12-9 22:05:28 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-21 00:23:44 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-21 01:18:44 | 显示全部楼层
新手表示还木有看明白,明天再研究研究了···

出0入0汤圆

发表于 2010-12-21 08:48:25 | 显示全部楼层
记一下

出0入0汤圆

发表于 2010-12-21 17:00:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-18 15:13:42 | 显示全部楼层
再次看马老师的回复,受益匪浅

出0入0汤圆

发表于 2011-7-27 23:05:28 | 显示全部楼层
学习了

出0入0汤圆

发表于 2011-8-24 10:38:27 | 显示全部楼层
最近遇到的问题,看了看,还是有点迷惑啊

出0入0汤圆

发表于 2011-8-24 13:42:18 | 显示全部楼层
mark and thanks

出0入0汤圆

发表于 2011-8-25 11:12:23 | 显示全部楼层
做个记号!最近也在学这个!

出0入0汤圆

发表于 2012-6-15 10:16:08 | 显示全部楼层
#ifndef _DEBUG_TERMINAL_IO_     //?????????

// Get a character from the USART Receiver buffer

#define _ALTERNATE_GETCHAR_     //?????????

#pragma used+                   //?????????

其实。我真的很关心这几句啊。。。。。。求解释。

出0入0汤圆

发表于 2012-8-1 22:59:38 | 显示全部楼层
请马潮老师给个正确答案,谢谢了!

出0入0汤圆

发表于 2012-8-2 12:00:08 | 显示全部楼层
好东西,顶一个

出0入0汤圆

发表于 2012-9-2 17:05:27 | 显示全部楼层
正在研究AVR的串口通信,谢谢各位了~

出0入0汤圆

发表于 2012-9-2 21:58:35 | 显示全部楼层
学习了,这么好的帖子:)

出0入0汤圆

发表于 2012-10-14 10:24:01 | 显示全部楼层
真好

出0入0汤圆

发表于 2012-12-26 18:21:23 | 显示全部楼层
                学习了

出0入0汤圆

发表于 2013-3-17 13:50:36 | 显示全部楼层
周末没事 mark优秀帖
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-7-24 03:20

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

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