请教马老师:我按照您的<<一个USART(RS232)低层驱动+中间层软件示例&
这个程序我是按照马老师的<<一个USART(RS232)低层驱动+中间层软件示例>>( http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=147242&bbs_page_no=1&search_mode=1&search_text=USART&bbs_id=9999 )改写的但是不知为什么,每次单片机都是不断的复位,详见以下程序,能否麻烦马老师抽空帮我看看!我想这是由于我的浮躁(记得马老师批过我这类学习态度)和急于求成造成的吧,但目前实在是找不到原因,还请马老师批评指正!以前通过看马老师的帖子和回复跟着马老师学了不少知识,在此感谢马老师!//tool:ICCAVR
//crystal:8M (M16)
#include "iom16v.h"
#include "macros.h"
#define TEST_LED_ON (PORTB|=(1<<PB4)) //=======LED_ON
#define TEST_LED_OF (PORTB&=~(1<<PB4))//=======LED_OF
#define DATA_REGISTER_EMPTY (1<<UDRE)
// USART Transmitter buffer========================================
#define TX_BUFFER_SIZE 20
unsigned char tx_buffer;//发送缓冲区
#if TX_BUFFER_SIZE<256 //定义发送缓冲区环形对列的控制指针
unsigned char tx_wr_index;// tx_wr_index为写指针,
unsigned char tx_rd_index;// tx_rd_index为读指针
unsigned char tx_cnter ;// tx_cnter为在队列中要发送的字符个数
#else
unsigned int tx_wr_index,tx_rd_index,tx_cnter;//
#endif
//==================================================================
void Delayms(unsigned int i)
{
unsigned int j;
for (;i!=0;i--)
{for (j=100;j!=0;j--); }
}
//=================================================================
#pragma interrupt_handler uart0_tx_isr:14
void uart0_tx_isr(void)
{
if (tx_cnter)
{
tx_cnter--;
UDR = tx_buffer;
if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index = 0;
}
}
void TX_char(unsigned char c)
{
while(tx_cnter == TX_BUFFER_SIZE) ;
CLI();
if (tx_cnter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
{
tx_buffer = c;
if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
++tx_cnter;
}
else UDR = c;
SEI();
}
//================================================================
void main(void) //==============main
{
CLI(); //disable all interrupts
PORTA = 0x00;
DDRA= 0x00;
PORTB = 0x00;//
DDRB= 0x10;
PORTC = 0x00; //
DDRC= 0x00;
PORTD = 0x00;
DDRD= 0x02;//
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = (1<<URSEL)|(0<<UMSEL)|(1<<UCSZ1)|(1<<UCSZ0)|(0<<UCPOL);//异步模式,8位数据+1位停止位
UBRRL = 51; //set baud rate lo 9600:514800:1032400:207(8MHz)
UBRRH = 0x00; //set baud rate hi
UCSRB=(0<<RXEN)|(1<<TXEN)|(0<<RXCIE)|(0<<TXCIE);//允许发送
SEI();
tx_cnter=0;//
TEST_LED_ON ;//LED亮
Delayms(1000);
UCSRB |= 1<<TXCIE;//开中断
while(1)
{
Delayms(1000);//
TEST_LED_OF ;//LED在此熄灭,只要单片机不复位,就不会亮了,但是它一直在亮!!!!
//用示波器看了一下,上电后LED有4次反复短暂熄灭后又亮了的过程,之后就一直亮!
//上电时用串口调试助手测试TX脚收到数据:82828282,之后就没有数据了!
//此外单片机的电源很稳定.
TX_char('8');
TX_char('2');
TX_char('3');
TX_char('4');
TX_char('5');
}
} 也请大家帮忙看看啊!谢谢了! 熔丝位是否配置了看门狗,而在程序中没有看门狗的初始化代码或者没有喂狗呢? http://cache.amobbs.com/bbs_upload782111/files_13/ourdev_433702.jpg
M16熔丝位配置 (原文件名:123.jpg)
我这样配置对吗? http://cache.amobbs.com/bbs_upload782111/files_13/ourdev_433776.JPG
(原文件名:ATMEGA128下载器熔丝配置界面.JPG) 单片机为ATMEGA128
(1)、BODLEVEL=打勾 表示:门限电压选择4.3V
(2)、BODEN=打勾 表示上电时低于4.3V单片机将不会工作
(3)、SUT1=不打勾 SUT0=打勾 表示最长启动时间
(4)、CKSEL3=打勾 CKSEL2=打勾 CKSEL1=打勾 CKSEL0=打勾 表示选择外部晶体振荡器
(5)、EESAVE=打勾 表示下载时,不擦除EEPROM中的数据
(6)、WDTON=不打勾 表示禁止单片机的看门狗 我的芯片是M16,没有你上面提到的"(6)、WDTON=不打勾 表示禁止单片机的看门狗 " 这一选项,现在我又在程序的初始化里加了以下关闭看门狗的程序,但是单片机还是在不停的复位!!
void WDT_off(void)
{
CLI();
WDR();/* WDT 复位*/
WDTCR |= (1<<WDTOE) | (1<<WDE);/* 置位 WDTOE 和 WDE*/
WDTCR = 0x00;/* 关闭WDT */
SEI();
}
可以肯定的是单片机的不断复位是由于我开了"UCSRB |= 1<<TXCIE;//开中断 "这个引起的--我把这句去掉,单片机就不会出现不断复位的现象了,但是我现在已经关了看门狗,还有什么会使单片机不断复位呢?
麻烦大家帮我看看是怎么回事,是不是我有个别地方由于没有理解透或没有注意到...谢谢! 是不是因为有中断服务程序的初始化代码,而没有在程序中编写中断服务程序。
这种情况,也可能导致上述现象。 但是我程序里有中断服务程序的:
UCSRB |= 1<<TXCIE;//开中断
与其对应的是:
#pragma interrupt_handler uart0_tx_isr:14
void uart0_tx_isr(void)
{
if (tx_cnter)
{
tx_cnter--;
UDR = tx_buffer;
if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index = 0;
}
} 本人掌握的AVR知识不够多,也不够精,所以这样一个可能让大家感到很简单的问题就把我卡住了好几天,在这里一个初学者请大家帮帮我,给我指出其中的问题,谢谢大家了! 会不会是数组溢出了。
把
void uart0_tx_isr(void)
{
if (tx_cnter)
{
tx_cnter--;
UDR = tx_buffer;
if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index = 0;
}
}
改写成
int num=0;
void uart0_tx_isr(void)
{
UDR = num;
if (num > 255)
num =0;
} 结帖了,感谢大家的支持和帮助!
经过几天的郁闷,在网友的提示下,终于找到了问题:我之前一直用iccv6.31,前几天又装了v7--考虑到还没有找到注册码,暂时先用v6.31,这就是问题所在了,v7会使v6.31编译错误但是又没有任何错误提示,后来我在电脑上只装一个软件就ok了!
希望我的教训能使可能会遇到这个问题的朋友以提示!
页:
[1]