|
第3题:题上说假定主程序循环了1000次,发送1000个0x55,请判断串口能否发出1000个0x55,有没有产生字符丢失或溢出现象?
为了让主程序循环了1000次我的代码如下:
#include <mega8515.h>
#define BAUD 9600 //波特率采用9600bps
#define CRYSTAL 11059200 //系统时钟11.0592MHz
//计算和定义波特率设置参数
#define BAUD_SETTING (unsigned int)((unsigned long)CRYSTAL/(16*(unsigned long)BAUD)-1)
#define BAUD_H (unsigned char)(BAUD_SETTING>>8)
#define BAUD_L (unsigned char)(BAUD_SETTING)
// USART控制和状态寄存器的标志位定义
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<PE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
// USART Transmitter buffer
#define TX_BUFFER_SIZE 5
unsigned char tx_buffer[TX_BUFFER_SIZE];
unsigned char tx_wr_index,tx_rd_index,tx_counter;//队列写指针,读指针,待发送字符个数
// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{
if(tx_counter)//如果队列中还有未发送的数据
{
--tx_counter;//未发送字符个数减1
UDR=tx_buffer[tx_rd_index];//发送一个字符
if(++tx_rd_index==TX_BUFFER_SIZE)tx_rd_index=0;//读指针指向下一个未发送的字符,如果指到了队尾,则回到队首
}
}
void putchar(unsigned 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;//发送个数加1
}
else
UDR=c;//无待发送数据且发送寄存器空,直接发送
#asm("sei")//开总中断
}
void main(void)
{
unsigned int i=0;
PORTD=0x03;
DDRD=0x02;//TXD(PD1)输出,RXD(PD0)输入,上拉有效,TXD输出高电平
UCSRA=0X00;
UCSRB=(1<<TXCIE)|(1<<TXEN);//使能TXC中断,接收不允许,发送允许
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);//8位数据位,1位停止位,无奇偶位
UBRRH=BAUD_H;
UBRRL=BAUD_L;//设置波特率
#asm("sei")//使能总中断
while(1)
{
putchar(0x55);
if(++i==1000)UCSRB=(0<<TXCIE)|(0<<TXEN);
}
}
用变量i计数,当i=1000时,关闭发送使能和发送中断使能(我不知道这样测试行不行)
实验结果,每次单片机复位后,串口调试助手接收到的数如下
串口调试助手接收情况 (原文件名:2.jpg)
本来我以为不会丢失,但每次按下复位按钮后,都只能收到995个数,所以我认为会产生丢失字符。后来我又把i改成2000或者别的数,但每次都是收到的数都少5个,我的发送中断缓冲区大小是5,后来又改了发送缓冲区的大小,发现发送缓冲区是多大,就会丢多少个数据,请马老师解释一下吧
第4题:当本机没有收到任何数据时在主程序中调用getchar(),我认为会发生死等现象,就是程序会一直停在while(rx_counter==0);上导致系统不能干其他的事,我的解决办法是将while(rx_counter==0)改成
if(rx_counter==0)return
else...后面的程序不变,不知道行不行? |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|