|
楼主 |
发表于 2010-8-23 11:02:32
|
显示全部楼层
经过连续长时间运行,发现错误是固定的,即:从站给中转站发送的应答包(至少14个字节),中转站只接收到1个字节后,T2就溢出了。
程序比较简单:
(1)、两个溢出中断 T0,T2
进入串口0中断服务程序后,开启T0;进入T0溢出中断服务程序后,关闭T0。
进入串口1中断服务程序后,开启T2;进入T2溢出中断服务程序后,关闭T2。
(2)、两个接收中断
采用中断+缓存方式接收数据。
(3)、两个发送中断
采用中断+缓存方式发送数据。
(4)、两个数据包解析函数
(5)、两个接收计数器
USART0_RECV = 串口0接收指针
USART1_RECV = 串口1接收指针
单片机上面有两个指示灯LED1和LED2,我用来跟踪错误原因:
LED1 亮 LED2 熄灭 ----> 表示中转站接收从站数据包时,产生错误,USART1_RECV =1 表示中转站应答包只接收到1个字节。
LED1 熄灭 LED2 亮 ----> 表示中转站接收主站数据包时,产生错误,表示中转站应答包只接收到2-4个字节
(原文件名:未命名.JPG)
#define TIMER0_START() (TCCR0 = (0 << WGM00) | (0 << WGM01) | (1 << CS02) | (1 << CS01) | (0 << CS00)) // T0启动
#define TIMER0_STOP() (TCCR0 = 0x00) // T0停止
#define TIMER2_START() (TCCR2 = (0 << WGM20) | (0 << WGM21) | (1 << CS22) | (0 << CS21) | (0 << CS20)) // T2启动
#define TIMER2_STOP() (TCCR2 = 0x00) // T2停止
//====================================================================================================
//TIMER0 initialize - prescale:256
// WGM: Normal
// desired value: 1.25mSec
// actual value: 1.250mSec (0.0%)
//====================================================================================================
void TIMER0_Init(void)
{
TCCR0 = 0x00;
ASSR = 0x00;
TCNT0 = 0xCA;
OCR0 = 0x35;
TIMSK |= (1 << TOIE0); // 允许T0溢出中断
}
//====================================================================================================
//TIMER2 initialize - prescale:256
// WGM: Normal
// desired value: 1.25mSec
// actual value: 1.250mSec (0.0%)
//====================================================================================================
void TIMER2_Init(void)
{
TCCR2 = 0x00;
ASSR = 0x00;
TCNT2 = 0xCA;
OCR0 = 0x35;
TIMSK |= (1 << TOIE2); // 允许T2溢出中断
}
//T0溢出中断服务程序
#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
TIMER0_STOP(); // T0停止
USART0_OK_mark = TRUE; // 3.5字符静止时间到时,置中转站已经接收到“主站”一帧完整的请求包
}
//T2溢出中断服务程序
#pragma interrupt_handler timer2_ovf_isr:iv_TIM2_OVF
void timer2_ovf_isr(void)
{
TIMER2_STOP(); // T2停止
USART1_OK_mark = TRUE; // 3.5字符静止时间到时,置中转站已经接收到“从站”一帧完整的应答包
}
//串口0接收中断 (串口0接收中断---中转站接收主站的请求包)
#pragma interrupt_handler USART0_RI_ISR:iv_USART0_RX
void USART0_RI_ISR(void)
{
INT8U ch;
ch = UDR0;
if (USART0_receCount < 255)
USART0_mscomm_buffer[USART0_receCount++] = ch;
TCNT0 = 0xCA; // 开启T0溢出中断
TIMER0_START();
}
//串口1接收中断 (串口10接收中断---中转站接收从站的应答包)
#pragma interrupt_handler USART1_RI_ISR:iv_USART1_RX
void USART1_RI_ISR(void)
{
INT8U ch;
ch = UDR1;
if (USART1_receCount < 255)
USART1_mscomm_buffer[USART1_receCount++] = ch;
TCNT2 = 0xCA; // 开启T2溢出中断
TIMER2_START();
}
void main(void)
{
CLI();
PORT_Init();
TIMER0_Init();
TIMER2_Init();
USART0_Init();
USART1_Init();
SEI();
while (1)
{
if (USART0_OK_mark) // 如果T0溢出,则认为中转站已经完整的接收了一帧“主站”的请求包
{
USART0_OK_mark = FALSE;
USART0_Modbus_Analyze();
}
if (USART1_OK_mark) // 如果T2溢出,则认为中转站已经完整的接收了一帧“从站”的应答包
{
USART1_OK_mark = FALSE;
USART1_Modbus_Analyze();
}
}
} |
|