请大家帮忙看下我的中断方式UART程序有什么问题
/**************************************************** Atmega88 AT24C04 TWI,USART通信程序 ***
**** 中断方式UART 测试程序 ***
**** ***
**** 作者:Fantasy zx ***
**** 编译器:WinAVR-20050214-install ***
**** ***
************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/delay.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; //发送数据绶冲区
uchar g_aRecvBuf; //接收数据缓冲区
void PORT_Init(void)
{
PORTB = 0xFF;
DDRB= 0x00;
PORTC = 0xFF; //m103 output only
DDRC= 0x00;
PORTD = 0xFF;
DDRD= 0x00;
}
/***********uart 初始化**************************/
// 晶振频率 : 8.0MHz
// 通信参数: 8 Data, 1 Stop, No Parity
// 波特率:
// UBRR0L= 0x0C 19200;
// UBRR0L= 0x19 9600;
// UBRR0L= 0x33 4800;
// UBRR0L= 0x67 2400
void USART_Init(void )
{
/* 设置波特率*/
UBRR0H = 0x00;
UBRR0L = 0x33;//9600 baud 8MHz:51 u2x0=0 103 u2x0=1
//接收中断允许、发送中断允许、接收使能、发送使能
UCSR0B = (1<<RXCIE0)|(1<<TXCIE0)|(1<<RXEN0)|(1<<TXEN0);
//UCSR0C|= (1<<UCSZ01)|(1<<UCSZ00); //8位数据位+1位停止位,异步操作
}
/***********接收中断*****************************/
SIGNAL(SIG_UART_RECV)
{
uchar c=UDR0;
if(g_bRxdLen>0)
{
g_aRecvBuf=c;
g_bRxdLen--;
}
}
/***********发送中断*****************************/
SIGNAL (SIG_UART_TRANS)
{
if(--g_bTxdLen>0)
UDR0=g_aSendBuf[++g_bTxdPos];
}
//是否接收完成
uchar RecvComplete(void)
{
return g_bRxdLen==0;
}
/***********从发送缓冲区发送指定长度数据**********/
void SendToUart(uchar size)
{
g_bTxdPos=0;
g_bTxdLen=size;
UDR0=g_aSendBuf;
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 )
{
uchar i;
cli();
PORT_Init();
USART_Init();
sei();//总中断允许
while(1)
{
//异步接收16 字节数据
RecvFromUart(32,0);
//等待接收完成
while(!RecvComplete());
//将接收到的数据复制到发送缓冲区
for(i=0;i<32;i++)
g_aSendBuf=g_aRecvBuf;
//发送回接收到的数据
SendToUart(32);
}
}
调试发送数据,发现串口没有任何数据返回!步知道哪里出问题了 int main( void )
{
uchar i;
PORT_Init();
USART_Init();
sei();//总中断允许
put_str(" init ok ") ;
while(1)
{
//异步接收16 字节数据
RecvFromUart(32,0);
//等待接收完成
while(!RecvComplete());
//将接收到的数据复制到发送缓冲区
for(i=0;i<32;i++)
get_SendBuf=get_RecvBuf;
//发送回接收到的数据
SendToUart(32);
}
}
我在main函数加了各put_str(" init ok ") 发现串口不断收到init ok,我没有循环串口也没有发送数据应该只出现1次init ok啊? 如果程序没有问题的话就是 一直复位,硬件 看们狗,自己好好检查吧、11111 硬件看门狗我没有fuse啊,应该时程序不知道 哪里出了问题 全局变量带入中断
看看这个帖子
http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=490692&bbs_page_no=1&bbs_id=1000 volatile uchar get_bbfferTxdPos=0; //发送定位计数器
volatile uchar get_bbfferTxdLen=0; //等待发送字节数
volatile uchar get_bbfferRxdPos=0; //接收定位计数器
volatile uchar get_bbfferRxdLen=0; //等待接收字节数
volatile uchar get_SendBuf; //发送数据绶冲区
volatile uchar get_RecvBuf; //接收数据缓冲区
都改了也没用啊,我看有人说时M103的熔丝位问题,这个熔丝mega88有吗?我没有找到啊 并且有时init ok 正常显示有时全部是JJJJJJJJJJJJJJJJJJJJJJJJJJ
到底我的熔丝哪里没设置好啊? http://cache.amobbs.com/bbs_upload782111/files_6/armok01128877.jpg JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ init okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit okinit ok
这个就是串口显示的程序,怎么可能一直在put_str(" init ok ") ;而不进入while(1)那 这个程序是完全按照芯艺的写的啊,不知道什么问题
还有我要将串口数据放入缓冲区,是否必须使用中断接收?查询如何写啊? 最近人气不行啊我发了好多贴都没几个回贴的啊,有经验的大哥出来说句话啊!小弟是在没看出这个有什么问题 没发现你用的什么终端?如果拨特路每问题,改为16进制接受吧 我用的是串口调试助手,现在显示问题暂不说,程序怎么可能一直在运行put_str(" init ok ") ;而不进入while(1)那 搂主你的程序有很多错误:atmega88串口中断向量的宏与atmega8的只差一个字符,你用的是atmega8的宏,因此串口中断向量并没有指向你所期望的函数而是空函数,它将使系统复位,看看*.lss就知道了;其它接口函数也有问题,就不指出了。
以下是我在你的程序上作了修改:
/************************************************
**** Atmega88 AT24C04 TWI,USART???? ***
**** ????UART ???? ***
**** ***
**** ??:Fantasy zx ***
**** ???:WinAVR-20050214-install ***
**** ***
************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
//#include <avr/signal.h>
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int
#if defined(__AVR_ATmega8__)
#define UBRR0H UBRRH
#define UBRR0L UBRRL
#define UCSR0B UCSRB
#define UCSR0C UCSRC
#define UDR0 UDR
#define RXCIE0 RXCIE
#define TXCIE0 TXCIE
#define RXEN0 RXEN
#define TXEN0 TXEN
#define UCSZ00 UCSZ0
#define UCSZ01UCSZ1
#elif defined(__AVR_ATmega48__)||defined(__AVR_ATmega88__)||defined(__AVR_ATmega168__)
#define SIG_UART_RECV SIG_USART_RECV
#define SIG_UART_TRANS SIG_USART_TRANS
#endif
volatile uchar g_bTxdPos=0; //???????
volatile uchar g_bTxdLen=0; //???????
volatile uchar g_bRxdPos=0; //???????
volatile uchar g_bRxdLen=0; //???????
uchar g_aSendBuf; //???????
uchar g_aRecvBuf; //???????
void PORT_Init(void)
{
PORTB = 0xFF;
DDRB= 0x00;
PORTC = 0xFF; //m103 output only
DDRC= 0x00;
PORTD = 0xFF;
DDRD= 0x00;
}
/***********uart ???**************************/
// ???? : 8.0MHz
// ????: 8 Data, 1 Stop, No Parity
// ???:
// UBRR0L= 0x0C 19200;
// UBRR0L= 0x19 9600;
// UBRR0L= 0x33 4800;
// UBRR0L= 0x67 2400
void USART_Init(void )
{
/* ?????*/
UBRR0H = 0x00;
UBRR0L = 0x33;//9600 baud 8MHz:51 u2x0=0 103 u2x0=1
//???????????????????????
UCSR0B = (1<<RXCIE0)|(1<<TXCIE0)|(1<<RXEN0)|(1<<TXEN0);
#if defined(__AVR_ATmega8__)
UCSRC|=(1<<URSEL) | (1<<UCSZ1)|(1<<UCSZ0); //8????+1????,????
#elif defined(__AVR_ATmega48__)||defined(__AVR_ATmega88__)||defined(__AVR_ATmega168__)
UCSR0C|= (1<<UCSZ01)|(1<<UCSZ00); //8????+1????,????
#endif
}
/***********????*****************************/
SIGNAL(SIG_UART_RECV)
{
uchar c=UDR0;
if(g_bRxdLen)
{
g_aRecvBuf=c;
g_bRxdLen--;
}
else g_bTxdPos=0;
}
/***********????*****************************/
SIGNAL (SIG_UART_TRANS)
{
if(g_bTxdLen)
{
UDR0=g_aSendBuf[++g_bTxdPos];
g_bTxdLen--;
}
else g_bTxdPos=0;
}
//??????
uchar RecvComplete(void)
{
return (g_bRxdLen==0);
}
/***********??????????????**********/
void SendToUart(uchar size)
{
g_bTxdPos=0;
g_bTxdLen=size-1;
UDR0=g_aSendBuf;
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 )
{
uchar i;
cli();
PORT_Init();
USART_Init();
sei();//?????
while(1)
{
//????16 ????
RecvFromUart(32,0);
//??????
while(!RecvComplete());
//???????????????
for(i=0;i<32;i++)
g_aSendBuf=g_aRecvBuf;
//?????????
SendToUart(32);
}
}
PN2对中文显示不好,将就看吧。
用atmega8 再proteus仿真结果:
http://cache.amobbs.com/bbs_upload782111/files_6/armok01129067.JPG 万分感谢shenxf,SIGNAL (SIG_UART_TRANS)少个s差距就这么大呵呵,我现在查询和中断2个方式都搞好了!
感谢大家的帮忙! 忘记问shenxf大侠了*.lss是在哪里的,刚接触还不太了解这些!
并且你说的接口函数是我的port_init这些函数问题吗 好像是winavr生成的是把,但是我没有生成这个文件啊
我直接用avrstudio调用的gcc 这些中断的名称定义都在哪里有显示那?还是要自己定义
SIGNAL(SIG_2WIRE_SERIAL)这个TWI的该如何定义那 ok找到了在avrstudio的project-configuation options里面有生成,还不太了解这个lss是什么用处! lss文件是目标代码的反汇编文件,包含许多信息,如启动、初始化、结束代码等等,可以发现优化或不优化的差别,找出莫名其妙的错误,对优化程序和了解avrgcc编译器的特点很有帮助。
我通过观察lss文件发现:同样的分支结构的代码用IF结构比swith结构要小很多,因此在中断服务程序中要用IF结构分支。 感谢shenxf ,有空仔细研究一下lss
还有个问题:
这些中断的名称定义都在哪里有显示那?还是要自己定义
SIGNAL(SIG_2WIRE_SERIAL)这个TWI的该如何定义那 也是总warning avr-libc用户手册,在WinAVR\doc\avr-libc目录 学习一下....
页:
[1]