基于PIC的LIN总线设计
2.SLAVE
// Lin总线
//---------------------------------------------
// 文件名: slave(mew).c
// 版本: V1.0
// 日期: 13/12/06
// 功能: Lin 总线从节点
// 编译环境: HiTech PIC C compiler v.8.05
// 使用MCU: PIC16F876(主频4M)
// 接收说明:
// 首先判断同步间隔场:符合要求进行下面操作,否则不予理睬并记录错误
// 同步间隔采集合格:采集同步头,主节点发送0x55,接收5个下降沿用于计算波特率
// 波特率计算成功:串口接收打开,进行ID接收,判断是否自己ID不是放弃接收后面数据
// ID校验成功:继续接收后面数据场,并进行校验,合格则进行相应操作,不合格记录错误
// 初始化,进行下一个同步头接收
//
//--------------------------------------------
#include
//--------------------------------------------
//---------------常量定义----------------------
#define TSync 1000 //同步间隔时间定义
#define FRest 0 //状态复位0
#define FSync 1 //同步间隔场检测
#define FSync1 2 //同步间隔场检测状态1
#define FTow 3 //同步头接收
#define FId 4 //地址字节接收
#define FData 5 //数据接收
#define CS RC1 //片选引脚,高有效
#define RFIN RC2 //同步间隔场和同步场输入端
#define Jiance RB7 //检测引脚,测试时候用
//--------------数据定义-----------------------
unsigned char Data[9]; //数据接收数组
bank1 unsigned int TimeData[5]; //CCP1捕捉时间记录函数
unsigned char RFdata; //状态判断
unsigned char FallCount; //同步头的下降沿计数
unsigned int Sytime; //同步头总时间保存
unsigned char RFstate; //接收状态指示
unsigned char Towallow; //波特率计算允许标志
unsigned char DataCount; //接收数据字节个数寄存器
unsigned char y;
volatile bit IDcheck; //数据校验合格标志
volatile bit Operate; //操作允许标志
volatile bit DatCheck; //数据和校验成功标志
//bank1 unsigned char Stat @ 0x8f; //
unsigned char IDmoment ; //ID号暂时保存
//#define AVR(adr,biti) ((unsigned)(&adr)*8+(biti))
//#define ID0 AVR(Stat,0) //位定义
//#define ID1 AVR(Stat,1)
//#define ID2 AVR(Stat,2)
//#define ID3 AVR(Stat,3)
//#define ID4 AVR(Stat,4)
//#define ID5 AVR(Stat,5)
//#define ID6 AVR(Stat,6)
//#define ID7 AVR(Stat,7)
union
{
struct
{
unsigned b0:1; //0位,冒号后面的是占的位数
unsigned b1:1;
unsigned b2:1;
unsigned b3:1;
unsigned b4:1;
unsigned b5:1;
unsigned b6:1;
unsigned b7:1;
}onebit;
unsigned char allbit;
}all;
#define ID0 all.onebit.b0
#define ID1 all.onebit.b1
#define ID2 all.onebit.b2
#define ID3 all.onebit.b3
#define ID4 all.onebit.b4
#define ID5 all.onebit.b5
#define ID6 all.onebit.b6
#define ID7 all.onebit.b7
#define Stat all.allbit
/*
上面位定义也可以用绝对寻址位操作(但不建议)
或者结构和联合体
应用方法:
all.onebit.b0=1; //给位0置1
all.allbit=0; //字节清0
*/
#define STATUSIT(avr,s) ((unsigned)(&avr)*8+(s)) //绝对寻址定义
static bit C @ STATUSIT(STATUS,0); //对进位位进行定义
union //16位时间计数器
{
unsigned int Counter;
unsigned char Time[2];
}ASD;
#define TimeL ASD.Time[0]
#define TimeH ASD.Time[1]
//--------------函数定义-----------------------
void Picint(void); //初始化
void Delay(void); //延时
void DataIn(void); //数据输入判断
void interrupt SDI(void); //中断函数
void DataClear(void); //数组清0
void Dispose(void); //数据处理函数
void DataCdc(unsigned char asd); //数据校验
//---------------------------------------------
//********************************************
//主函数
//********************************************
void main()
{
Picint();
while(1)
{
DataIn(); //数据查询
if(Operate) //是否允许操作,进行相应操作
{
DataCdc(DataCount); //数据校验是否合格
if(DatCheck)
{
Dispose();
}
}
}
}
//********************************************
//数据处理函数
//********************************************
void Dispose() //实验,并没具体做什么操作
{
if((Data[0]==0x12)&(Data[1]==0x13))
{
RB7=1;
}
if(Data[0]==0x22)
{
RB7=0;
}
}
//********************************************
//数据校验
//********************************************
void DataCdc(unsigned char asd) //计算数据校验和
{
unsigned char x,y;
DatCheck=0;
y=0;
asm("bcf _STATUS,0"); //清进位位
for(x=0;x<(asd-1);x++)
{
y=y+Data[x];
if(C)
{
C=0;
y=y+1;
}
}
y=y+Data[asd-1];
if(y==0xff) //校验成功
{
DatCheck=1;
}
}
//********************************************
//中断函数
//********************************************
void interrupt SDI() //用捕捉方式进行下降沿计数,计算同步头
{
if(CCP1IE&CCP1IF) //确认中断
{
CCP1IF=0; //清中断标志
TimeL=CCPR1L; //取数
TimeH=CCPR1H; //
TimeData[FallCount]=ASD.Counter; //写入数组
FallCount++;
if(FallCount==5)
{
CCP1CON=0x00; //禁止CCP1捕捉
CCP1IE=0; //禁止CCP1中断
CCP1IF=0; //清中断标志
FallCount=0;
Towallow=1; //波特率计算允许
TMR1ON=0;
TMR1L=0;
TMR1H=0;
}
}
}
//********************************************
//数据输入
//********************************************
void DataIn()
{
switch(RFstate)
{
case FSync: //同步间隔场检测
RFdata=RFIN; //采样值
if(RFdata==0) //下降沿检测
{
TMR1L=0;
TMR1H=0;
TMR1ON=1; //开启定时器1
RFstate=FSync1; //转向状态1
}
break;
PICLIN总 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)