?? receivetest__.c
字號(hào):
#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總線狀態(tài),當(dāng)狀態(tài)為0時(shí)才允許發(fā)送數(shù)據(jù)
#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 // 定義回復(fù)包數(shù)據(jù)長(zhǎng)度為八個(gè)字節(jié)
#define RS485_Address_Self 0x21 // 本機(jī)自己的地址
#define RS485_Address_Broad 0x00 // 廣播地址
// #define Address_Broad 0x00 // 接收到的為廣播地址時(shí)回復(fù)0
// #define Address_Self 0x01 // 接收到的為本機(jī)自己的地址時(shí)回復(fù)1
// #define Address_Rong 0x02 // 接收到不為本機(jī)地址也不為廣播地址時(shí)回復(fù)2
#define Repeat_Send_Count 0x0A // 重發(fā)延時(shí)機(jī)制的延時(shí)時(shí)間,定為10ms
#define Check_Count 0xC8 // 檢測(cè)回復(fù)包延時(shí)計(jì)數(shù)器,一次為50ms,延時(shí)200ms計(jì)數(shù)4次
#define Long_Wait_Count 0xF0 // 超時(shí)等待計(jì)數(shù)器,一次為1ms,延時(shí)250MS計(jì)數(shù)250次
#define Repeat_Send_Delay 0x01 // 重發(fā)延時(shí)狀態(tài)
#define Long_Wait_Delay 0x02 // 超時(shí)等待狀態(tài)
#define Send_Broad_Delay 0x03 // 回復(fù)廣播包延時(shí)狀態(tài)
#define Check_Delay 0x04 // 檢測(cè)回復(fù)包延時(shí)狀態(tài)
#define Other_Delay 0x00 // 其他中斷延時(shí)狀態(tài)
#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總線接收狀態(tài)
INT8U RS485_Receive_Status;
INT8U ReSendFlag; // 重發(fā)數(shù)據(jù)標(biāo)志位
INT8U ReSendCount; // 重發(fā)數(shù)據(jù)計(jì)數(shù)器
INT8U *P_RS485_Send_Buff; // 定義發(fā)送緩沖區(qū)指針
INT8U RS485_Send_Buff[Send_Buff_Size]={0x00,0x21,0x10,0x00,0x00,0x02,0x00,0x44}; // 定義待發(fā)送數(shù)據(jù)緩沖區(qū)
INT8U RS485_Receive_Buff[Receive_Buff_Size]; // 定義接收數(shù)據(jù)緩沖區(qū)
INT8U RS485_Receive_Save[128]; // 保存接收到的數(shù)據(jù)緩沖區(qū)
INT8U RS485_Answer_Buff[8]; // 回復(fù)包接收緩沖區(qū),回復(fù)包只為8個(gè)字節(jié)
INT8U RS485_Answer_Send_Buff[8]; // 回復(fù)數(shù)據(jù)包的發(fā)送緩沖區(qū)
INT8U Tx_Count; // 定義發(fā)送數(shù)據(jù)計(jì)數(shù)器
INT8U Receive_Count; // 定義接收數(shù)據(jù)計(jì)數(shù)器
INT8U Answer_Data_Count; // 回復(fù)包接收計(jì)數(shù)器
INT8U Tx_Send_End; // 發(fā)送完一幀數(shù)據(jù)標(biāo)志位
INT8U Send_Broad_Delay_Flag; // 發(fā)送廣播回復(fù)包延時(shí)標(biāo)志
INT8U Repeat_Send_Data_Flag; // 重發(fā)第二次數(shù)據(jù)包標(biāo)志
INT8U Send_Data_Flag; // 發(fā)送數(shù)據(jù)包(包括首發(fā)和重發(fā)標(biāo)志),通過(guò)此標(biāo)志去檢驗(yàn)是否有回復(fù)包
INT8U RS485_Send_Flag; // 發(fā)送標(biāo)志位
INT8U Send_Answer_Flag; // 發(fā)送回復(fù)包標(biāo)志
INT8U Send_Broad_Flag; // 發(fā)送廣播回復(fù)包標(biāo)志
INT8U Add_Time_Flag; // 重發(fā)延時(shí)首次檢測(cè)到總線不空間,對(duì)延時(shí)加3ms標(biāo)志
INT8U RS485_Answer; // 回復(fù)包標(biāo)志位
INT8U Send_Size; // 待發(fā)送數(shù)據(jù)的長(zhǎng)度
INT8U Byte_Len; // 接收字節(jié)的長(zhǎng)度,8;40;128;0
INT8U Receive_Data; // 接收的一個(gè)字節(jié)的數(shù)據(jù)
INT8U Receive_Status; // 接收數(shù)據(jù)時(shí)的狀態(tài)
INT8U Receive_CheckHead; // 數(shù)據(jù)包頭接收和校驗(yàn)
INT8U Receive_CheckData; // 數(shù)據(jù)包數(shù)據(jù)接收和校驗(yàn)
INT8U Send_CheckHead; // 數(shù)據(jù)包頭發(fā)送和校驗(yàn)
INT8U Send_CheckData; // 數(shù)據(jù)包數(shù)據(jù)發(fā)送和校驗(yàn)
INT8U RS485_Bus_Status; // 定義485總線狀態(tài)
INT8U Send_Status; // 發(fā)送數(shù)據(jù)狀態(tài)
INT8U Delay_Status; // 延時(shí)中斷狀態(tài)
INT8U Start_Delay; // 啟動(dòng)延時(shí)檢測(cè)回復(fù)包程序
INT8U Repeat_Send_Time; // 重發(fā)延時(shí)剩余時(shí)間計(jì)數(shù)器
INT8U Long_Wait_Time; // 超時(shí)等待剩余時(shí)間計(jì)數(shù)器
INT8U Com_Revert_Time; // 競(jìng)爭(zhēng)回復(fù)延時(shí)剩余時(shí)間計(jì)算器
INT8U Check_Time; // 檢測(cè)回復(fù)包延時(shí)剩余時(shí)間計(jì)算器
INT8U Long_Time_End; // 超時(shí)等待結(jié)束標(biāo)志
INT8U UpdateFlag; // 狀態(tài)更新標(biāo)志
INT8U IICSendCount; // IIC發(fā)送計(jì)數(shù)器,一次通信接收8個(gè)字節(jié)
INT8U IICReceiveCount; // IIC接收計(jì)數(shù)器,一次通信接收8個(gè)字節(jié)
INT8U IICReceiveBuff[8]={0x01,0x01,0x02,0x01,0x02,0x03,0x04,0x0e}; // IIC接收緩沖區(qū)
INT8U IICSendBuff[8]; // IIC發(fā)送緩沖區(qū)
INT8U IICChecksum; // IIC接收校驗(yàn)和
INT8U IICCSendDataheck; // IIC發(fā)送數(shù)據(jù)的校驗(yàn)和
INT8U Check_Receive_Data_Flag;
INT8U RS485_Receive_End; // 485總線接收結(jié)束標(biāo)志
// INT8U Buff;
// INT8U Length;
// INT8U Address;
// 競(jìng)爭(zhēng)回復(fù)延時(shí)計(jì)數(shù)器,沒(méi)計(jì)數(shù)一次延時(shí)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};
//---------------------------------------------------------------------------------------
//
//獲取當(dāng)前485接收狀態(tài)
INT8U GetCurrentRS485RxStatus(void)
{
return RS485_Receive_Status;
}
//---------------------------------------------------------------------------------------
//
//設(shè)置當(dāng)前485總線接收狀態(tài)
void SetCurrentRS485RxStatus(INT8U status)
{
RS485_Receive_Status=status;
}
//----------------------------------------------------------------------------------------------
//
//啟動(dòng)發(fā)送程序
void RS485_Start_Send(void)
{
while (!(UCSRA&(1<<UDRE))); // 當(dāng)數(shù)據(jù)寄存器為空時(shí)
DRE=1; // 將485轉(zhuǎn)換到發(fā)送狀態(tài)
UDR=0x7E; // 發(fā)送一幀的數(shù)據(jù)的開(kāi)頭0x7E
}
//---------------------------------------------------------------------------------------
//
// 重發(fā)延時(shí)函數(shù)
void Repeat_Delay_Program(void)
{
//Long_Time_End=0;
Repeat_Send_Time=Repeat_Send_Count; // 延時(shí)10ms
Delay_Status=Repeat_Send_Delay; // 進(jìn)入重發(fā)延時(shí)中斷狀態(tài)
// //開(kāi)中斷,啟動(dòng)發(fā)送延時(shí)機(jī)制
// TCNT0=0xFC; // 定時(shí)1ms
// TCCR0=0x05; // 1024分頻,計(jì)數(shù)39.0625次就為10ms
}
//---------------------------------------------------------------------------------------
//
//發(fā)送數(shù)據(jù),包括首發(fā)和重發(fā) 執(zhí)行這程序之前需將485引腳定義為發(fā)送狀態(tài)
void RS485_Send_Subprogram(void)
{
if(ReSendFlag==1) // 判斷是否為重發(fā)數(shù)據(jù)
{
ReSendFlag=0; // 重發(fā)標(biāo)志清0
//將數(shù)據(jù)第二字節(jié)功能代碼的第七位置位,表示為重發(fā)數(shù)據(jù)
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) // 第一次同第二次重發(fā)之間的超時(shí)等待
{
Long_Wait_Time=Long_Wait_Count;
Delay_Status=Long_Wait_Delay; // 進(jìn)入超時(shí)等待延時(shí)中斷狀態(tài)
// Repeat_Send_Data_Flag=1;
// //啟動(dòng)定時(shí)器T00 // 超時(shí)等待350ms
// TCNT0=0x3D; // 定時(shí)50ms
// TCCR0=0x05;
// 超時(shí)等待未結(jié)束,執(zhí)行其他程序
// 超時(shí)等待350ms結(jié)束,再執(zhí)行重發(fā)延時(shí)
// while(Repeat_Send_Data_Flag==1)
// {
// if(Long_Time_End==0)
// {
// // Place your code here
// }
// else // 超時(shí)等待350ms結(jié)束,再執(zhí)行重發(fā)延時(shí)
// {
// Long_Time_End=0;
// Repeat_Send_Data_Flag=0;
// Repeat_Delay_Program();
// }
// }
}
else
{
Repeat_Delay_Program();
}
} // 首發(fā)數(shù)據(jù)不用延時(shí),直接發(fā)送
else
{
///
Delay_Status=Start_Send;
///
// RS485_Start_Send(); // 啟動(dòng)發(fā)送,即將0x7E發(fā)送到數(shù)據(jù)寄存器
}
}
//----------------------------------------------------------------------------------------------
//
// 發(fā)送點(diǎn)對(duì)點(diǎn)回復(fù)包子程序
void RS485_Answer_Subprogram(void)
{
Send_Size=8; // 發(fā)送回復(fù)包數(shù)據(jù),固定為8個(gè)字節(jié)
P_RS485_Send_Buff=RS485_Answer_Send_Buff; // 將指針P_RS485_Send_Buff指向發(fā)送緩沖區(qū)RS485_Answer_Send_Buff首地址
Delay_Status=Start_Send;
//RS485_Start_Send(); // 啟動(dòng)發(fā)送
}
//----------------------------------------------------------------------------------------------
//
// 發(fā)送點(diǎn)對(duì)類,廣播回復(fù)包子程序
void RS485_Answer_Broad_Subprogram(void)
{
Send_Size=8; // 發(fā)送回復(fù)包數(shù)據(jù),固定為8個(gè)字節(jié)
P_RS485_Send_Buff=RS485_Answer_Send_Buff; // 將指針P_RS485_Send_Buff指向發(fā)送緩沖區(qū)RS485_Answer_Send_Buff首地址
Com_Revert_Time=Delay_Time_Count[RS485_Answer_Send_Buff[0]];
Delay_Status=Send_Broad_Delay; // 進(jìn)入發(fā)送廣播回復(fù)包延時(shí)中斷狀態(tài)
// Send_Broad_Delay_Flag=1;
// // 開(kāi)定時(shí)中斷
// TCNT0=0xFC; // 定時(shí)1ms
// TCCR0=0x05; // 1024分頻,約計(jì)數(shù)4次為1ms
// while(Send_Broad_Delay_Flag==1)
// {
// ;// Place your code here
//
// //led3=!led3;
//
// }
// led3=0;
//
// Delay_Status=Start_Send;
// //RS485_Start_Send(); // 啟動(dòng)發(fā)送
}
//----------------------------------------------------------------------------------------------
//發(fā)送中斷程序
interrupt [USART_TXC] void usart_tx_isr(void)
{
led3=!led3;
if(Tx_Send_End==0) // 一幀數(shù)據(jù)尚未發(fā)完
{
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -