搜索
bottom↓
回复: 5

用定时中断后进入不了接收中断

[复制链接]

出0入0汤圆

发表于 2013-2-20 10:52:35 | 显示全部楼层 |阅读模式
各位:新年好!
   我最近写了个程序,串口接收中断里改变一个flag,然后定时中断里查询这个flag,可我发现定时中断可以照常运行,而接收中断根本进不去,这个问题我一直在解决,可是一直没有搞定,前前后后大概有一个月了,现在是又急又没头绪,望各位路过这个帖子时能指点一二,不胜感激!

出0入0汤圆

发表于 2013-2-20 11:02:38 | 显示全部楼层
什么型号的单片机,用的什么编译器,程序代码等等,什么都没有,怎么解答?

出0入0汤圆

 楼主| 发表于 2013-2-20 11:13:22 | 显示全部楼层
本帖最后由 双飞燕泡茶 于 2013-2-20 11:17 编辑
faw 发表于 2013-2-20 11:02
什么型号的单片机,用的什么编译器,程序代码等等,什么都没有,怎么解答? ...


AVR mega8 用的是ICC,
程序代码我给个简化的:
#include "iom8v.h"
#include<macros.h>
#define fosc 8000000         //晶振8MHZ
#define baud 9600            //波特率定义
#define uchar unsigned char
#define uint unsigned int

                                                          
unsigned char i=0,counter=0;
unsigned char flag=0;
unsigned char receive_cnt=0;
unsigned char my[7]={0,0,0,0,0,0,0};
unsigned char my0[7]={0xc0,0xa8,0xff,0xf3,0xf4,0xf5,0xf6};//0xf3,0xf4,


//1us延时函数
void delay_1us(void)                 
{
   asm("nop");
}
//N us延时函数
void delay_nus(unsigned int n)      
{
   unsigned int j=0;
   for (j=0;j<n;j++)
   delay_1us();
}

void uart0_init(void)
{
UCSRB = 0x00;
UCSRA = 0x00;
UCSRC |= (1<<URSEL)|(1 << UCSZ1)|(1 << UCSZ0);          //异步,数据格式8,N,1
UBRRL=(fosc/16/(baud+1))%256;                                  //设置波特率寄存器
UBRRH=(fosc/16/(baud+1))/256;
UCSRB |= (1 << RXCIE)|(1 << TXEN)|(1 << RXEN); //接收中断使能,发送接收使能
}

void uart0_send(unsigned char i)
{
while(!(UCSRA&(1<<UDRE)));                 //只有数据寄存器为空时才能发送数据
UDR=i;
}

/*************发送数组函数*************/
void usart_shuzu_send(unsigned char arry[])
{
        //unsigned char i=0;
        for(i=0;i<7;i++)
        {
                while(!(UCSRA&BIT(UDRE)));
        UDR=arry;
        }
}

void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x3D; //set count 25ms
TCCR0 = 0x05; //start timer
}

void init_devices(void)
{
CLI();       
DDRB=0X00;
PORTB=0X00;
PORTC=0XFF;
DDRC=0XFF ;
PORTD=0X00;              //USART的发送接收端口分别为PD0和PD1                              //0x04
DDRD|=(1<<PD1)|(1 << PD4);
timer0_init();
MCUCR = 0x00;
GICR  = 0x00;
TIMSK = 0x01;
SREG=0x80;
}


void main(void)
{  
init_devices();
uart0_init();
while(1){
                 ;
         }                               
}

#pragma interrupt_handler USART_RXC_vect:12
void USART_RXC_vect(void)
{
uchar udr;
udr=UDR;//读取接收到的数值
PORTD|=(1<<PD4);
switch(receive_cnt)//判断是第几次中断
                        {
                                                 case 0: //第一次
                                                my[receive_cnt++]=udr;//记录接收值
                                     if(my[0]!=0x08) receive_cnt=0;break;
                                 case 1://第二次,能执行到此处说明第一次接收到的为0X08                               
                                                                        my[receive_cnt++]=udr;//记录接收值
                                        if(my[1]!=0x11) receive_cnt=0;break;
                                 case 2: //第三次,能执行到此处说明第二次接收到的为0X11
                                                         my[receive_cnt++]=udr;//记录接收值
                                      if(my[2]!=0x01) receive_cnt=0;
                                                else if(my[2]==0x01){flag=1;} break;
                                 default://>=3次,说明前三次依次为0x08 0x11 ,0x01,以后正常接收
                                                           {
                                                       my[receive_cnt++]=udr;//记录当前接收值
                                                       if(receive_cnt==7) receive_cnt=0;//清零接收中断计数                                       
                                                       }
                                           }
}

#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
SREG=0x80;
TCNT0 = 0x3D;
if(++counter>=10)
         {
                counter=0;
                if(flag==1)
                        {
                                usart_shuzu_send(my0);
                                flag=0;//清零被呼叫标志
                        }                                       
         }                                                      
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-2-20 13:19:35 | 显示全部楼层
1.分步调试,不使用定时中断,只用接收中断,看看是否好用!判断检查硬件电路是否有问题

出0入0汤圆

 楼主| 发表于 2013-2-20 13:40:42 | 显示全部楼层
faw 发表于 2013-2-20 13:19
1.分步调试,不使用定时中断,只用接收中断,看看是否好用!判断检查硬件电路是否有问题 ...

硬件没问题,为了赶任务,同事给我一份程序,我改了后可以在定时中断里访问接收中断置位的flag,改过来能跑,
我发现这个问题就是因为我没用定时中断时进入了接收中断,而用定时中断时却进不了,

出0入0汤圆

 楼主| 发表于 2013-2-20 16:48:48 | 显示全部楼层
问题好像找到了,是同事帮的忙,原因是定时中断溢出,把定时中断里的语句减少,或者加长定时中断,(本例可用time1)
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-19 11:43

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

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