标题:
STM8单片机—从机LIN通讯协议代码
[打印本页]
作者:
李鑫都
时间:
2021-8-16 16:01
标题:
STM8单片机—从机LIN通讯协议代码
最近写的一个汽车LIN通讯分享
#include"STC12C5408.H"
typedef enum
{
Init,
send_data,
rece_data
} LIN_SLAVE_state;
LIN_SLAVE_state LIN_SLAVE = Init;
typedef enum
{
task1,
task2
} TASK_state;
TASK_state TASK = Init;
//定义数据类型
#define uchar unsigned char
#define uint unsigned int
uchar send_datas[]={0,0,0,0,0,0,0,0};
uchar rece_datas[]={0,0,0,0,0,0,0,0};
uchar code F_Rotation[4]={0x01,0x02,0x04,0x08};//正转表格
uchar code B_Rotation[4]={0x08,0x04,0x02,0x01};//反转表格
uchar code rotation[]={0x01,0x02,0x04,0x08};
uchar num=8;
uchar ID;
uchar dianjistate;
uchar dianjistate1;
uchar start=0x00;
#define AD_SPEED 0x60 //0110,0000 1 1 270个时钟周期转换一次,
#define b4800 0XFA
#define b9600 0XFD
void SetBaud(uchar baud)
{
TR1=0;
TMOD|=0X20; 、//定时器方式2的自动重载功能,THX=TLX
TH1=baud;
TL1=baud;
TR1=1; //定时器1动行控制位。启动定时器1
}
void UartSend(uchar byte)
{
REN=0; //禁止串口接收数据
SCON=0X50;//SCON为串口控制寄存器 SM0 SM1=01为串口工作方式1:10位异步收发(8位数据),波特率可变(由定时器1的溢出率控制)
TI=0; //取消中断审请
SBUF=byte;
while(TI==0);//串行发送停止位的开始时,由内部硬件使TI置1,向CPU发出中断审请
}
uchar UartReceive()
{
uchar temp;
SCON=0X50;
RI=0; //接收中断标志,内部硬件置1,手动清零
while(RI==0); //方式0串行接收第八位数据结束时,或在其他方式,串行接收停止位的中间时,由内部硬件使RI置1
temp=SBUF;
return temp;
}
void SendSynchBreak()
{
SetBaud(b4800);
UartSend(0x80); //唤醒信号
}
void SendSynch()
{
SetBaud(b9600);
UartSend(0x55);
}
void SendID(uchar ID_temp)
{
SetBaud(b9600);
UartSend(ID_temp);
}
void SendData(uchar *datas,uchar n)
{
SetBaud(b9600);
for(;n>0;n--)
{
UartSend(*datas);
datas++;
}
}
uchar check_sum;
uchar checksum(uchar *chk8,uchar n)
{
uchar temp=0;
for( ;n>0;n--)
{
temp=temp+*chk8;
if(temp<*chk8)
temp++;
chk8++;
}
return(0xff-temp);
}
void SendChecksum(uchar checksum_temp)
{
SetBaud(b9600);
UartSend(checksum_temp);
}
uchar ReceChecksum()
{
SetBaud(b9600);
return UartReceive();
}
void ReceiveData(uchar *datas,uchar n)
{
SetBaud(b9600);
for(;n>0;n--)
{
*datas=UartReceive();
datas++;
}
}
uchar JudgeLength(uchar id)
{
uchar len_temp;
id &= 0x30;
if(id == 0x00) len_temp = 2;
if(id == 0x10) len_temp = 2;
if(id == 0x20) len_temp = 4;
if(id == 0x30) len_temp = 8;
return len_temp;
}
//---------------------------------------------------------------------
void delay(uchar delay_time) // 延时函数
{
uchar n;
while(delay_time--)
{
n = 6000;
while(--n);
}
}
//---------------------------------------------------------------------
//
uchar get_AD_result(uchar channel)
{
ADC_DATA = 0;
channel &= 0x07; //0000,0111 清0高5位
ADC_CONTR = AD_SPEED;
ADC_CONTR = 0xE0; //1110,0000 清 ADC_FLAG, ADC_START 位和低 3 位
ADC_CONTR |= channel; //选择 A/D 当前通道
delay(1); //使输入电压达到稳定
ADC_CONTR |= 0x08; //0000,1000 令 ADCS = 1, 启动A/D转换,
while (1) //等待A/D转换结束
{
if (ADC_CONTR & 0x10) //0001,0000 测试A/D转换结束否
{ break; }
}
ADC_CONTR &= 0xE7; //1111,0111 清 ADC_FLAG 位, 关闭A/D转换,
return (ADC_DATA); //返回 A/D 10 位转换结果
}
uchar i,j;
uchar templ,temph,IDH,IDL;
bit task1_en,task2_en;
void LIN(uchar ID_temp, uchar num_temp, bit send_or_rece);
uchar cheakheader();
void dianji();
void delay1(uchar del);
void dianji1(uchar c);
void dianji2(uchar k);
void judge();
void dianjireset();
void LIN_Init(void)
{
ADC_CONTR |= 0x80; //1000,0000 打开 A/D 转换电源
}
void TIME0_Init()
{
EA = 1; //允许CPU中断
TMOD |= 0x01; //设定时器0和1为16位模式1
ET0 = 1; //定时器0中断允许
TH0 = (-50000)/256;
TL0 = (-50000)%256; //设定时每隔50ms中断一次
TR0 = 1;
}
//---------------------------------------------------------------------
void yanshi(unsigned char del)
{
unsigned char i;
for(;del>0;del--)
for(i=0;i<125;i++)
{;}
}
void main()
{
TIME0_Init();
while(1)
{
if(task1_en) //判断进入中断
{
if(cheakheader()==1)
{
uchar jiaoyan;
ReceiveData(rece_datas,8);
jiaoyan=ReceChecksum();
send_datas[0]=rece_datas[0];
LIN(0XD0, 8, 1);
judge();
send_datas[0]=rece_datas[0];
LIN(0XD0, 8, 1);
}
task1_en = 0;
}
if(task2_en)
{
//LIN(0X20, 4, 0);
//task2_en = 0;
}
}
}
void timeint0(void) interrupt 1
{
TH0 = (-50000)/256;
TL0 = (-50000)%256; //设定时每隔50ms中断一次
switch(TASK) //TASK默认为 0
{
case task1: //task1默认为0
TASK = task2;
task1_en = 1;
task2_en = 0;
break;
case task2:
TASK = task1;
task1_en = 0;
task2_en = 1;
break;
default:
TASK = task1;
task1_en = 0;
task2_en = 0;
break;
}
}
void LIN(uchar ID_temp, uchar num_temp, bit send_or_rece)
{
ID = ID_temp;
num = num_temp;
if(send_or_rece)
LIN_SLAVE = send_data; //1发送,0接收 ,此处为发送,send_data的值为1,所以LIN_SLAVE也为1
else
LIN_SLAVE = rece_data; //1发送,0接收 ,此处为接收,rece_data的值为2,所以LIN_SLAVE也为2
SendSynchBreak(); //主机任务
SendSynch();
SendID(ID);
switch(LIN_SLAVE) //从机任务,LIN_SLAVE的默认值为Init,即为0
{
case Init:
LIN_SLAVE = Init;
break;
case send_data: //发送数据 ,1
SendData(send_datas,num);
check_sum=checksum(send_datas,num);
SendChecksum(check_sum);
LIN_SLAVE = Init;
break;
case rece_data: //接收数据 ,2
//check_sum=ReceChecksum();
// ReceiveData(rece_datas,num);
// //check_sum = ReceChecksum();
break;
default :
LIN_SLAVE = Init;
break;
}
}
//识别起始间隔,同步间隔,ID号
uchar cheakheader()
{ uchar header,idhao;
while(1)
{
SetBaud(b9600);
header= UartReceive();
if(header==0x55)
{
SetBaud(b9600);
idhao=UartReceive();
if(idhao==0xF0)
break;
}
}
return(1);
}
// 逆转
void dianji1(uchar c)
{
unsigned char b,d,h;
for(h=0;h<c;h++)
{
for (b=0;b<15;b++)
{
for (d=0;d<4;d++)
{
P2 = B_Rotation[d];
yanshi(50);
}
}
}
}
//顺转
void dianji2(uchar k)
{
unsigned char b,g,d;
for(g=0;g<k;g++)
{
for (b=0;b<15;b++)
{
for (d=0;d<4;d++)
{
P2 = F_Rotation[d];
yanshi(50);
}
}
}
}
void judge()
{
while(start!=0x00)
{
dianjistate = rece_datas[0];
if((dianjistate1<=0x20 && dianjistate1>=0x00)==1)//0x20---0x00
{
if((dianjistate<=0x20 &&dianjistate>=0x00)==1)
{
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x40 && dianjistate>0x20)==1)
{
dianji2(1);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x60 &&dianjistate>0x40)==1)
{
dianji2(2);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x80 &&dianjistate>0x60)==1)
{
dianji2(3);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xA0 &&dianjistate>0x80)==1)
{
dianji2(4);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xC0 &&dianjistate>0xA0)==1)
{
dianji2(5);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xFF &&dianjistate>0xC0)==1)
{
dianji2(6);
dianjistate1=rece_datas[0];
break;
}
}
else if((dianjistate1<=0x40 && dianjistate1>0x20)==1)//0x40--0x20
{
if((dianjistate<=0x20 &&dianjistate>=0x00)==1)
{
dianji1(1);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x40 &&dianjistate>0x20)==1)
{
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x60 &&dianjistate>0x40)==1)
{
dianji2(1);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x80 &&dianjistate>0x60)==1)
{
dianji2(2);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xA0 &&dianjistate>0x80)==1)
{
dianji2(3);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xC0 &&dianjistate>0xA0)==1)
{
dianji2(4);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xFF &&dianjistate>0xC0)==1)
{
dianji2(5);
dianjistate1=rece_datas[0];
break;
}
}
else if((dianjistate1<=0x60&&dianjistate1>0x40)==1)//0x60--0x40
{
if((dianjistate<=0x20 &&dianjistate>=0x00)==1)
{
dianji1(2);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x40 &&dianjistate>0x20)==1)
{ dianji1(1);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x60 &&dianjistate>0x40)==1)
{
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x80 &&dianjistate>0x60)==1)
{
dianji2(1);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xA0 &&dianjistate>0x80)==1)
{
dianji2(2);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xC0 &&dianjistate>0xA0)==1)
{
dianji2(3);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xFF &&dianjistate>0xC0)==1)
{
dianji2(4);
dianjistate1=rece_datas[0];
break;
}
}
else if((dianjistate1<=0x80 && dianjistate1>0x60)==1)//0x80--0x60
{
if((dianjistate<=0x20 &&dianjistate>=0x00)==1)
{
dianji1(3);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x40 &&dianjistate>0x20)==1)
{
dianji1(2);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x60 &&dianjistate>0x40)==1)
{
dianji1(1);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x80 &&dianjistate>0x60)==1)
{
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xA0 &&dianjistate>0x80)==1)
{
dianji2(1);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xC0 &&dianjistate>0xA0)==1)
{
dianji2(2);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xFF &&dianjistate>0xC0)==1)
{
dianji2(3);
dianjistate1=rece_datas[0];
break;
}
}
else if((dianjistate1<=0xA0 && dianjistate1>0x80)==1)//0xA0--0x80
{
if((dianjistate<=0x20 &&dianjistate>=0x00)==1)
{
dianji1(4);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x40 &&dianjistate>0x20)==1)
{
dianji1(3);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x60 &&dianjistate>0x40)==1)
{
dianji1(2);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x80 &&dianjistate>0x60)==1)
{
dianji1(1);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xA0 &&dianjistate>0x80)==1)
{
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xC0 &&dianjistate>0xA0)==1)
{
dianji2(1);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xFF &&dianjistate>0xC0)==1)
{
dianji2(2);
dianjistate1=rece_datas[0];
break;
}
}
else if((dianjistate1<=0xC0 && dianjistate1>0xA0)==1)//0xC0--0xA0
{
if((dianjistate<=0x20 &&dianjistate>=0x00)==1)
{
dianji1(5);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x40 &&dianjistate>0x20)==1)
{
dianji1(4);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x60 &&dianjistate>0x40)==1)
{
dianji1(3);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x80 &&dianjistate>0x60)==1)
{
dianji1(2);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xA0 &&dianjistate>0x80)==1)
{
dianji1(1);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xC0 &&dianjistate>0xA0)==1)
{
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xFF &&dianjistate>0xC0)==1)
{
dianji2(1);
dianjistate1=rece_datas[0];
break;
}
}
else if((dianjistate1<=0xFF && dianjistate1>0xC0)==1)//0xFF--0xC0
{
if((dianjistate<=0x20 &&dianjistate>=0x00)==1)
{
dianji1(6);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x40 &&dianjistate>0x20)==1)
{
dianji1(5);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x60 &&dianjistate>0x40)==1)
{
dianji1(4);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0x80 &&dianjistate>0x60)==1)
{
dianji1(3);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xA0 &&dianjistate>0x80)==1)
{
dianji1(2);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xC0 &&dianjistate>0xA0)==1)
{
dianji1(1);
dianjistate1=rece_datas[0];
break;
}
else if((dianjistate<=0xFF &&dianjistate>0xC0)==1)
{
dianjistate1=rece_datas[0];
break;
}
}
}//end for while(start != 0x00)
if(start==0x00)
{
//dianjireset();
dianjistate1=rece_datas[0];
start=0xFF;
}
}
void dianjireset()
{
dianjistate = rece_datas[0];
if(dianjistate>=0x00 && dianjistate<=0x40)
{
dianji2(1);
dianji2(1);
}
else if (dianjistate>0x40 && dianjistate<=0x80)
dianji2(1);
else if(dianjistate>0x80 && dianjistate<=0xC0)
dianji1(1);
else if(dianjistate>0xC0 && dianjistate<=0xFF)
{
dianji1(1);
dianji1(1);
}
else
{;}
}
复制代码
51hei.png
(2.48 KB, 下载次数: 57)
下载附件
2021-8-16 16:08 上传
以上2个文件下载:
lin从机源代码(1).rar
(4.5 KB, 下载次数: 44)
2021-8-16 15:58 上传
点击文件名下载附件
STM8从机LIN代码
下载积分: 黑币 -5
作者:
philix
时间:
2021-12-4 13:34
这是stc单片机吧,不是STM8吧
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1