|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2012-11-4 13:03:24
|
显示全部楼层
框架是用CVAVR生成的,现象为上电复位后,芯片可以工作,比如发送串口数据。但是进不去接收中断,如果用ISP下载器重新下载程序或者进行其他操作后,芯片相当于重新
复位,软件就可以进入接收中断。现在不明白,是硬件问题还是软件问题。
1、硬件采用AVR内部复位电路。
#include <mega64.h>
#include<delay.h>
#include<stdio.h>
// I2C Bus functions
#asm
.equ __i2c_port=0x12 ;PORTD
.equ __sda_bit=7
.equ __scl_bit=6
#endasm
#include <i2c.h>
// PCF8583 Real Time Clock functions
#include <pcf8583.h>
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
#define Setbit(x,y) x=x|(1<<y)
#define Clrbit(x,y) x=x&(~(1<<y))
void putchar1(char c);
void AnalysisCommand();
// USART1 Receiver buffer
#define RX_BUFFER_SIZE1 8
volatile char rx_buffer1[RX_BUFFER_SIZE1];
#if RX_BUFFER_SIZE1<256
unsigned char rx_wr_index1,rx_rd_index1,rx_counter1;
#else
unsigned int rx_wr_index1,rx_rd_index1,rx_counter1;
#endif
// This flag is set on USART1 Receiver buffer overflow
bit rx_buffer_overflow1;
// USART1 Receiver interrupt service routine
interrupt [USART1_RXC] void usart1_rx_isr(void)
{
char status,data;
status=UCSR1A;
data=UDR1;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer1[rx_wr_index1]=data;
if (++rx_wr_index1 == RX_BUFFER_SIZE1) rx_wr_index1=0;
if (++rx_counter1 == RX_BUFFER_SIZE1)
{
rx_counter1=0;
rx_buffer_overflow1=1;
};
};
}
// Get a character from the USART1 Receiver buffer
#pragma used+
char getchar1(void)
{
char data;
while (rx_counter1==0);
data=rx_buffer1[rx_rd_index1];
if (++rx_rd_index1 == RX_BUFFER_SIZE1) rx_rd_index1=0;
#asm("cli")
--rx_counter1;
#asm("sei")
return data;
}
#pragma used-
// Write a character to the USART1 Transmitter
#pragma used+
void putchar1(char c)
{
while ((UCSR1A & DATA_REGISTER_EMPTY)==0);
UDR1=c;
}
void AnalysisCommand() //命令分析,完成系统设置或者继电器控制。
{
if ((rx_buffer1[0]==0x0A)&&(rx_buffer1[7]==0x7F))
switch (rx_buffer1[1])
{
case 1: //获取系统时间,发送至主机
rtc_get_time(0,&h,&m,&s,&hs);
rtc_get_date(0,&date,&month,&year);
rx_buffer1[0] = 0xA0;
rx_buffer1[2]= year;
rx_buffer1[3] = month;
rx_buffer1[4] = date;
rx_buffer1[5] = h;
rx_buffer1[6] = m;
rx_buffer1[7] = 0x7F;
for(SendCount=0;SendCount<8;SendCount++)
{
putchar1(rx_buffer1[SendCount]);
}
break;
case 2: //设置系统时间
year=rx_buffer1[2];
month=rx_buffer1[3];
date=rx_buffer1[4];
h=rx_buffer1[5];
m=rx_buffer1[6];
rtc_set_date(0, date, month,year);
rtc_set_time(0, h, m, 0, 0);
rx_buffer1[0] = 0xA0;
rx_buffer1[7] = 0x7F;
for(SendCount=0;SendCount<8;SendCount++)
{
putchar1(rx_buffer1[SendCount]);
}
break;
case 5: //获取继电器的状态信息,确定是打开还是关闭
GetSW_Status();
break;
case 6: //判断打开哪路继电器
SwitchCommand=rx_buffer1[2];
OpenSW();
break;
case 9: //获取开关量的状态信息
GetAlarmInfo();
break;
default:break;
}
} |
|