搜索
bottom↓
回复: 11

请教马老师:我按照您的<<一个USART(RS232)低层驱动+中间层软件示例&

[复制链接]

出0入0汤圆

发表于 2009-4-6 13:12:58 | 显示全部楼层 |阅读模式
这个程序我是按照马老师的<<一个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[TX_BUFFER_SIZE];//发送缓冲区
#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[tx_rd_index];
        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[tx_wr_index] = 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:51  4800:103  2400: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');       
     }
}

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

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

 楼主| 发表于 2009-4-6 17:57:44 | 显示全部楼层
也请大家帮忙看看啊!谢谢了!

出0入0汤圆

发表于 2009-4-7 10:48:44 | 显示全部楼层
熔丝位是否配置了看门狗,而在程序中没有看门狗的初始化代码或者没有喂狗呢?

出0入0汤圆

 楼主| 发表于 2009-4-7 14:47:03 | 显示全部楼层

M16熔丝位配置 (原文件名:123.jpg)
我这样配置对吗?

出0入0汤圆

发表于 2009-4-7 16:36:16 | 显示全部楼层

(原文件名:ATMEGA128下载器熔丝配置界面.JPG)

出0入0汤圆

发表于 2009-4-7 16:41:22 | 显示全部楼层
单片机为ATMEGA128
(1)、BODLEVEL=打勾 表示:门限电压选择4.3V
(2)、BODEN=打勾     表示上电时低于4.3V单片机将不会工作
(3)、SUT1=不打勾 SUT0=打勾 表示最长启动时间
(4)、CKSEL3=打勾 CKSEL2=打勾 CKSEL1=打勾 CKSEL0=打勾  表示选择外部晶体振荡器
(5)、EESAVE=打勾 表示下载时,不擦除EEPROM中的数据
(6)、WDTON=不打勾 表示禁止单片机的看门狗

出0入0汤圆

 楼主| 发表于 2009-4-7 19:08:38 | 显示全部楼层
我的芯片是M16,没有你上面提到的"(6)、WDTON=不打勾 表示禁止单片机的看门狗 " 这一选项,现在我又在程序的初始化里加了以下关闭看门狗的程序,但是单片机还是在不停的复位!!
void WDT_off(void)
{
CLI();
WDR();/* WDT 复位*/
WDTCR |= (1<<WDTOE) | (1<<WDE);/* 置位 WDTOE 和 WDE*/
WDTCR = 0x00;/* 关闭WDT */
SEI();
}
    可以肯定的是单片机的不断复位是由于我开了"UCSRB |= 1<<TXCIE;//开中断 "这个引起的--我把这句去掉,单片机就不会出现不断复位的现象了,但是我现在已经关了看门狗,还有什么会使单片机不断复位呢?

    麻烦大家帮我看看是怎么回事,是不是我有个别地方由于没有理解透或没有注意到...谢谢!

出0入0汤圆

发表于 2009-4-8 08:44:09 | 显示全部楼层
是不是因为有中断服务程序的初始化代码,而没有在程序中编写中断服务程序。
  这种情况,也可能导致上述现象。

出0入0汤圆

 楼主| 发表于 2009-4-8 11:33:27 | 显示全部楼层
但是我程序里有中断服务程序的:
UCSRB |= 1<<TXCIE;//开中断
与其对应的是:
#pragma interrupt_handler uart0_tx_isr:14
void uart0_tx_isr(void)
{   
    if (tx_cnter)  
    {   
        tx_cnter--;
        UDR = tx_buffer[tx_rd_index];  
        if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index = 0;  
    }
}

出0入0汤圆

 楼主| 发表于 2009-4-8 15:29:06 | 显示全部楼层
本人掌握的AVR知识不够多,也不够精,所以这样一个可能让大家感到很简单的问题就把我卡住了好几天,在这里一个初学者请大家帮帮我,给我指出其中的问题,谢谢大家了!

出0入0汤圆

发表于 2009-4-9 14:44:40 | 显示全部楼层
会不会是数组溢出了。



void uart0_tx_isr(void)  
{   
    if (tx_cnter)   
    {   
        tx_cnter--;  
        UDR = tx_buffer[tx_rd_index];   
        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;
}

出0入0汤圆

 楼主| 发表于 2009-4-11 09:53:42 | 显示全部楼层
结帖了,感谢大家的支持和帮助!
    经过几天的郁闷,在网友的提示下,终于找到了问题:我之前一直用iccv6.31,前几天又装了v7--考虑到还没有找到注册码,暂时先用v6.31,这就是问题所在了,v7会使v6.31编译错误但是又没有任何错误提示,后来我在电脑上只装一个软件就ok了!
    希望我的教训能使可能会遇到这个问题的朋友以提示!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-10-2 23:15

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

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