標(biāo)題:
STM8單片機—從機LIN通訊協(xié)議代碼
[打印本頁]
作者:
李鑫都
時間:
2021-8-16 16:01
標(biāo)題:
STM8單片機—從機LIN通訊協(xié)議代碼
最近寫的一個汽車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;
//定義數(shù)據(jù)類型
#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};//正轉(zhuǎn)表格
uchar code B_Rotation[4]={0x08,0x04,0x02,0x01};//反轉(zhuǎn)表格
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個時鐘周期轉(zhuǎn)換一次,
#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; //禁止串口接收數(shù)據(jù)
SCON=0X50;//SCON為串口控制寄存器 SM0 SM1=01為串口工作方式1:10位異步收發(fā)(8位數(shù)據(jù)),波特率可變(由定時器1的溢出率控制)
TI=0; //取消中斷審請
SBUF=byte;
while(TI==0);//串行發(fā)送停止位的開始時,由內(nèi)部硬件使TI置1,向CPU發(fā)出中斷審請
}
uchar UartReceive()
{
uchar temp;
SCON=0X50;
RI=0; //接收中斷標(biāo)志,內(nèi)部硬件置1,手動清零
while(RI==0); //方式0串行接收第八位數(shù)據(jù)結(jié)束時,或在其他方式,串行接收停止位的中間時,由內(nèi)部硬件使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) // 延時函數(shù)
{
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 當(dāng)前通道
delay(1); //使輸入電壓達到穩(wěn)定
ADC_CONTR |= 0x08; //0000,1000 令 ADCS = 1, 啟動A/D轉(zhuǎn)換,
while (1) //等待A/D轉(zhuǎn)換結(jié)束
{
if (ADC_CONTR & 0x10) //0001,0000 測試A/D轉(zhuǎn)換結(jié)束否
{ break; }
}
ADC_CONTR &= 0xE7; //1111,0111 清 ADC_FLAG 位, 關(guān)閉A/D轉(zhuǎn)換,
return (ADC_DATA); //返回 A/D 10 位轉(zhuǎn)換結(jié)果
}
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 轉(zhuǎn)換電源
}
void TIME0_Init()
{
EA = 1; //允許CPU中斷
TMOD |= 0x01; //設(shè)定時器0和1為16位模式1
ET0 = 1; //定時器0中斷允許
TH0 = (-50000)/256;
TL0 = (-50000)%256; //設(shè)定時每隔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; //設(shè)定時每隔50ms中斷一次
switch(TASK) //TASK默認(rèn)為 0
{
case task1: //task1默認(rèn)為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發(fā)送,0接收 ,此處為發(fā)送,send_data的值為1,所以LIN_SLAVE也為1
else
LIN_SLAVE = rece_data; //1發(fā)送,0接收 ,此處為接收,rece_data的值為2,所以LIN_SLAVE也為2
SendSynchBreak(); //主機任務(wù)
SendSynch();
SendID(ID);
switch(LIN_SLAVE) //從機任務(wù),LIN_SLAVE的默認(rèn)值為Init,即為0
{
case Init:
LIN_SLAVE = Init;
break;
case send_data: //發(fā)送數(shù)據(jù) ,1
SendData(send_datas,num);
check_sum=checksum(send_datas,num);
SendChecksum(check_sum);
LIN_SLAVE = Init;
break;
case rece_data: //接收數(shù)據(jù) ,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);
}
// 逆轉(zhuǎn)
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);
}
}
}
}
//順轉(zhuǎn)
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
{;}
}
復(fù)制代碼
51hei.png
(2.48 KB, 下載次數(shù): 57)
下載附件
2021-8-16 16:08 上傳
以上2個文件下載:
lin從機源代碼(1).rar
(4.5 KB, 下載次數(shù): 44)
2021-8-16 15:58 上傳
點擊文件名下載附件
STM8從機LIN代碼
下載積分: 黑幣 -5
作者:
philix
時間:
2021-12-4 13:34
這是stc單片機吧,不是STM8吧
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1