?? receivetest.c
字號:
#include <mega8.h>
#include <delay.h>
#include <string.h>
#define led PORTD.5
#define led1 PORTD.6
#define led2 PORTD.7
#define led3 PORTB.0
#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 DRE PORTD.2
#define DB_SENDMAXSIZE 7
#define Send_Buff_Size 128
#define Receive_Buff_Size 128
#define FunctionCode 2
#define Data_Head 0x7E
#define Data_Change 0x7D
//定義RS485總線狀態,當狀態為0時才允許發送數據
#define RS485_Bus_IDLE 0
#define RS485_Bus_BUSY 1
#define RS485_Receive_IDLE 0
#define RS485_Receive_RECEIVE 1
#define RS485_Receive_CHANGE 3
#define Answer_Size 8 // 定義回復包數據長度為八個字節
#define RS485_Address_Self 0x21 // 本機自己的地址
#define RS485_Address_Broad 0x00 // 廣播地址
// #define Address_Broad 0x00 // 接收到的為廣播地址時回復0
// #define Address_Self 0x01 // 接收到的為本機自己的地址時回復1
// #define Address_Rong 0x02 // 接收到不為本機地址也不為廣播地址時回復2
#define Repeat_Send_Count 0x0A // 重發延時機制的延時時間,定為10ms
#define Check_Count 0xC8 // 檢測回復包延時計數器,一次為50ms,延時200ms計數4次
#define Long_Wait_Count 0xF0 // 超時等待計數器,一次為1ms,延時250MS計數250次
#define Repeat_Send_Delay 0x01 // 重發延時狀態
#define Long_Wait_Delay 0x02 // 超時等待狀態
#define Send_Broad_Delay 0x03 // 回復廣播包延時狀態
#define Check_Delay 0x04 // 檢測回復包延時狀態
#define Other_Delay 0x00 // 其他中斷延時狀態
#define Start_Send 0x66
#define Order_Attribute 16
typedef unsigned char INT8U;
typedef char INT8S;
typedef unsigned short INT16U;
// This flag is set on USART Receiver buffer overflow
//定義RS485總線接收狀態
INT8U RS485_Receive_Status;
INT8U ReSendFlag; // 重發數據標志位
INT8U ReSendCount; // 重發數據計數器
INT8U *P_RS485_Send_Buff; // 定義發送緩沖區指針
INT8U RS485_Send_Buff[Send_Buff_Size]={0x00,0x21,0x10,0x00,0x00,0x02,0x00,0x44}; // 定義待發送數據緩沖區
INT8U RS485_Receive_Buff[Receive_Buff_Size]; // 定義接收數據緩沖區
INT8U RS485_Receive_Save[128]; // 保存接收到的數據緩沖區
INT8U RS485_Answer_Buff[8]; // 回復包接收緩沖區,回復包只為8個字節
INT8U RS485_Answer_Send_Buff[8]; // 回復數據包的發送緩沖區
INT8U Tx_Count; // 定義發送數據計數器
INT8U Receive_Count; // 定義接收數據計數器
INT8U Answer_Data_Count; // 回復包接收計數器
INT8U Tx_Send_End; // 發送完一幀數據標志位
INT8U Send_Broad_Delay_Flag; // 發送廣播回復包延時標志
INT8U Repeat_Send_Data_Flag; // 重發第二次數據包標志
INT8U Send_Data_Flag; // 發送數據包(包括首發和重發標志),通過此標志去檢驗是否有回復包
INT8U RS485_Send_Flag; // 發送標志位
INT8U Send_Answer_Flag; // 發送回復包標志
INT8U Send_Broad_Flag; // 發送廣播回復包標志
INT8U Add_Time_Flag; // 重發延時首次檢測到總線不空間,對延時加3ms標志
INT8U RS485_Answer; // 回復包標志位
INT8U Send_Size; // 待發送數據的長度
INT8U Byte_Len; // 接收字節的長度,8;40;128;0
INT8U Receive_Data; // 接收的一個字節的數據
INT8U Receive_Status; // 接收數據時的狀態
INT8U Receive_CheckHead; // 數據包頭接收和校驗
INT8U Receive_CheckData; // 數據包數據接收和校驗
INT8U Send_CheckHead; // 數據包頭發送和校驗
INT8U Send_CheckData; // 數據包數據發送和校驗
INT8U RS485_Bus_Status; // 定義485總線狀態
INT8U Send_Status; // 發送數據狀態
INT8U Delay_Status; // 延時中斷狀態
INT8U Start_Delay; // 啟動延時檢測回復包程序
INT8U Repeat_Send_Time; // 重發延時剩余時間計數器
INT8U Long_Wait_Time; // 超時等待剩余時間計數器
INT8U Com_Revert_Time; // 競爭回復延時剩余時間計算器
INT8U Check_Time; // 檢測回復包延時剩余時間計算器
INT8U Long_Time_End; // 超時等待結束標志
INT8U UpdateFlag; // 狀態更新標志
INT8U IICSendCount; // IIC發送計數器,一次通信接收8個字節
INT8U IICReceiveCount; // IIC接收計數器,一次通信接收8個字節
INT8U IICReceiveBuff[8]={0x01,0x01,0x02,0x01,0x02,0x03,0x04,0x0e}; // IIC接收緩沖區
INT8U IICSendBuff[8]; // IIC發送緩沖區
INT8U IICChecksum; // IIC接收校驗和
INT8U IICCSendDataheck; // IIC發送數據的校驗和
INT8U Check_Receive_Data_Flag;
INT8U RS485_Receive_End; // 485總線接收結束標志
// INT8U Buff;
// INT8U Length;
// INT8U Address;
// 競爭回復延時計數器,沒計數一次延時1ms
INT8U Delay_Time_Count[]={
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,
0, 2, 4, 6, 64, 102, 98, 155, 0, 0, 0, 0, 0, 0,0,0,
0, 8, 36, 60, 66, 104, 140, 142, 166,168, 170, 172, 174, 0,0,0,
0, 10, 38, 62, 68, 84, 85, 86, 0, 0, 0, 0, 0, 0,0,0,
0, 12, 44, 100, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,
0, 14, 46, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,
0, 16, 96, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,
0, 18, 94, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,
0, 20, 92, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,
0, 22, 40, 42, 70, 88, 90, 106, 156,158, 160, 162, 164, 0,0,0,
0, 24, 48, 72, 112, 124, 144, 143, 186,0, 0, 0, 0, 0,0,0,
0, 26, 50, 74, 114, 126, 146, 176, 188,0, 0, 0, 0, 0,0,0,
0, 28, 52, 76, 116, 128, 148, 178, 190,0, 0, 0, 0, 0,0,0,
0, 30, 54, 78, 118, 130, 150, 180, 191,0, 0, 0, 0, 0,0,0,
0, 32, 56, 80, 120, 132, 152, 182, 0, 0, 0, 0, 0, 0,0,0,
0, 34, 58, 82, 122, 134, 154, 184, 0, 0, 0, 0, 0, 0,0,0};
//---------------------------------------------------------------------------------------
//
//獲取當前485接收狀態
INT8U GetCurrentRS485RxStatus(void)
{
return RS485_Receive_Status;
}
//---------------------------------------------------------------------------------------
//
//設置當前485總線接收狀態
void SetCurrentRS485RxStatus(INT8U status)
{
RS485_Receive_Status=status;
}
//----------------------------------------------------------------------------------------------
//
//啟動發送程序
void RS485_Start_Send(void)
{
while (!(UCSRA&(1<<UDRE))); // 當數據寄存器為空時
DRE=1; // 將485轉換到發送狀態
UDR=0x7E; // 發送一幀的數據的開頭0x7E
}
//---------------------------------------------------------------------------------------
//
// 重發延時函數
void Repeat_Delay_Program(void)
{
//Long_Time_End=0;
Repeat_Send_Time=Repeat_Send_Count; // 延時10ms
Delay_Status=Repeat_Send_Delay; // 進入重發延時中斷狀態
// //開中斷,啟動發送延時機制
// TCNT0=0xFC; // 定時1ms
// TCCR0=0x05; // 1024分頻,計數39.0625次就為10ms
}
//---------------------------------------------------------------------------------------
//
//發送數據,包括首發和重發 執行這程序之前需將485引腳定義為發送狀態
void RS485_Send_Subprogram(void)
{
if(ReSendFlag==1) // 判斷是否為重發數據
{
ReSendFlag=0; // 重發標志清0
//將數據第二字節功能代碼的第七位置位,表示為重發數據
RS485_Send_Buff[7]= RS485_Send_Buff[7] - RS485_Send_Buff[FunctionCode];
RS485_Send_Buff[FunctionCode]=RS485_Send_Buff[FunctionCode]|0x40;
RS485_Send_Buff[7]= RS485_Send_Buff[7] + RS485_Send_Buff[FunctionCode];
if(ReSendCount==1) // 第一次同第二次重發之間的超時等待
{
Long_Wait_Time=Long_Wait_Count;
Delay_Status=Long_Wait_Delay; // 進入超時等待延時中斷狀態
// Repeat_Send_Data_Flag=1;
// //啟動定時器T00 // 超時等待350ms
// TCNT0=0x3D; // 定時50ms
// TCCR0=0x05;
// 超時等待未結束,執行其他程序
// 超時等待350ms結束,再執行重發延時
// while(Repeat_Send_Data_Flag==1)
// {
// if(Long_Time_End==0)
// {
// // Place your code here
// }
// else // 超時等待350ms結束,再執行重發延時
// {
// Long_Time_End=0;
// Repeat_Send_Data_Flag=0;
// Repeat_Delay_Program();
// }
// }
}
else
{
Repeat_Delay_Program();
}
} // 首發數據不用延時,直接發送
else
{
///
Delay_Status=Start_Send;
///
// RS485_Start_Send(); // 啟動發送,即將0x7E發送到數據寄存器
}
}
//----------------------------------------------------------------------------------------------
//
// 發送點對點回復包子程序
void RS485_Answer_Subprogram(void)
{
Send_Size=8; // 發送回復包數據,固定為8個字節
P_RS485_Send_Buff=RS485_Answer_Send_Buff; // 將指針P_RS485_Send_Buff指向發送緩沖區RS485_Answer_Send_Buff首地址
Delay_Status=Start_Send;
//RS485_Start_Send(); // 啟動發送
}
//----------------------------------------------------------------------------------------------
//
// 發送點對類,廣播回復包子程序
void RS485_Answer_Broad_Subprogram(void)
{
Send_Size=8; // 發送回復包數據,固定為8個字節
P_RS485_Send_Buff=RS485_Answer_Send_Buff; // 將指針P_RS485_Send_Buff指向發送緩沖區RS485_Answer_Send_Buff首地址
Com_Revert_Time=Delay_Time_Count[RS485_Answer_Send_Buff[0]];
Delay_Status=Send_Broad_Delay; // 進入發送廣播回復包延時中斷狀態
// Send_Broad_Delay_Flag=1;
// // 開定時中斷
// TCNT0=0xFC; // 定時1ms
// TCCR0=0x05; // 1024分頻,約計數4次為1ms
// while(Send_Broad_Delay_Flag==1)
// {
// ;// Place your code here
//
// //led3=!led3;
//
// }
// led3=0;
//
// Delay_Status=Start_Send;
// //RS485_Start_Send(); // 啟動發送
}
//----------------------------------------------------------------------------------------------
//發送中斷程序
interrupt [USART_TXC] void usart_tx_isr(void)
{
led3=!led3;
if(Tx_Send_End==0) // 一幀數據尚未發完
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -