📄 conrol.c
字号:
//通信9个字节,前3个字节为帧头,均为0xff;第四个字节为距离,a路占高4位
//bc路占低4位;第五个字节位速度a路占高4位,bc路占低4位;第六个字节为A路衰减量;
//第7个字节为B路衰减量;第8个字节为c路衰减量;第9个字节为控制开关信号,8位分别为
//* * * * 相参开关,c路开关,b路开关,a路开关,其中1为开,0为关
//系统采用15M晶振,每100ms更新一次距离延时,每秒钟更新10次对应速度分别0,100m/s
//200m/s,300m/s,400m/s,500m/s,所以每100ms应该更新的距离分别为0m,10m,20m,30m
//40m,50m。15M的晶振一个脉冲对应的距离是10m。所以0m,10m,20m,30m
//40m,50m对应的脉冲改变量分别为0,1个,2个,3个,4个,5个。
//
//
//
//
//
#include <C8051F020.h>
#include <absacc.h>
#include <stdio.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define a_dis_com XBYTE[0x0FFF]
#define a_updata_com XBYTE[0x1FFF]
#define bc_dis_com XBYTE[0x2FFF]
#define bc_updata_com XBYTE[0x3FFF]
#define a_bc_v_com XBYTE[0x4FFF]
#define a_att_com XBYTE[0x5FFF]
#define b_att_com XBYTE[0x6FFF]
#define c_att_com XBYTE[0x7FFF]
#define on_off_com XBYTE[0X8FFF]
bit flag_a;
bit flag_bc;
uint code distance[]={1500,2000,5000,8000,15000,18000,21000,24000,27000,30000,32000};
uchar count_interrupt=0;
uchar count_receive_data;
uchar receive_data[9];
uchar a_dis,bc_dis;
uint a_conversion_data,bc_conversion_data;
uint save_a_inital_distance,save_bc_inital_distance;
uchar hex_h,hex_l;
uchar a_velocity,bc_velocity;
void dec_hex(uint x)
{hex_h=x/0xff;
hex_l=x%0xff;
}
void config_mcu (void)
{
//----------------------------------------------------------------
//看门狗配置
WDTCN = 0x07; // Watchdog Timer Control Register
WDTCN = 0xde; // 禁止看门狗 WDTCN = 0xAD;
// Configure the XBRn Registers
XBR0 = 0x04; // XBAR0: Initial Reset Value串口0使能
XBR1 = 0x00; // XBAR1: Initial Reset Value
XBR2 = 0xC0; // XBAR2: Initial Reset Value弱上拉全局禁止
P0MDOUT = 0xff; // Output configuration for P0
P1MDOUT = 0xff; // Output configuration for P1
P2MDOUT = 0xff; // Output configuration for P2
P3MDOUT = 0xff; // Output configuration for P3
P74OUT = 0xff; // Output configuration for P4-7
P1MDIN = 0xFF; // Input configuration for P1
EMI0CF = 0x3f; // EMIF ACTIVE ON p4-p7非复用movx指令访问外部ram
}
//-------------------------------------------------------------------------
void SYSCLK_Init (void)
{
int i; /*延时计数器*/
OSCXCN = 0x67; /*打开外部晶体振荡器*/
for (i=0; i < 256; i++) ; /*延时*/
while (!(OSCXCN & 0x80)) ; /*查询外部晶体是否稳定起振*/
OSCICN = 0x08; /*用外部晶体作为系统时钟,并禁止时钟丢失检测*/
}
//--------------------------------------------------------------------------
void UART0_Init (void)
{
SCON0 = 0x50; /*SCON0:模式1,8位UART,时能RX*/
TMOD = 0x20; /*TMOD: 定时器工作再模式2, 8位重载*/
TH1=0xfa; //波特率设置
TL1=0xfa; /*设置定时1用作波特率的重载值*/
TR1 = 1; /*开定时器1*/
CKCON = 0x00; /*定时器1用系统时钟作12分频为它的时基,定时器0用系统时钟的12分频作为时钟,定时器2使用系统时钟的12分频作为时钟*/
PCON = 0x80; /*SMOD00 = 1*/
}
//---------------------------------------------------------------------------------
void ComTx(uchar x){
SBUF0=x;
while(TI0==0);
TI0=0;
}
//-------------------------------------------------------------------------------------
void output_control_paramater(uint a_distance_data,uint bc_distance_data,uchar a_bc_v_data ,uchar a_att_data,
uchar b_att_data,uchar c_att_data,uchar on_off_data)
{dec_hex(a_distance_data);
a_dis_com=hex_l;
a_dis_com=hex_h;
a_updata_com=0x00;
dec_hex(bc_distance_data);
bc_dis_com=hex_l;
bc_dis_com=hex_h;
bc_updata_com=0x00;
a_bc_v_com=a_bc_v_data ;
a_att_com=a_att_data;
b_att_com=b_att_data;
c_att_com=c_att_data;
on_off_com=on_off_data;
}
//-------------------------------------------------------------------------------------
void main(void)
{
uchar crc,i;
crc=0;
config_mcu();
SYSCLK_Init();
UART0_Init();
output_control_paramater(0X00,0X00,0X00,0X00,0X00,0X00,0x00);//A,B,C路关闭
count_receive_data=0;
receive_data[9]=(0,0,0,0,0,0,0,0,0);
TL0=0xdf; //定时器0定时60ms
TH0=0x01;
T2CON=T2CON & 0XF0;//
EA=1;//使能总中断
ES0=1;//使能串口0中断
ET0=1;//使能定时器0中断
ET2=1;//使能定时器2中断
//ComTx(0x30);
while(1)
{ do
{ if (count_receive_data>=1)
//TR0=1;
;
}
while(count_receive_data<9);
EA=0;
TR0=0;
TL0=0xdf;//定时器0定时20ms
TH0=0x01;
TL2=0x77; //定时器2定时50ms
TH2=0xec;
RCAP2L=0x77;
RCAP2H=0xec;
bc_dis=receive_data[3]&0x0f;//为转换BC路距离,可直接查表
a_dis=receive_data[3]>>4;//为转换后A路距离,可直接查表
a_velocity=(receive_data[4]>>4);//为转换后A路速度,
if (a_velocity>=8)
flag_a=1;
else
flag_a=0;
a_velocity=a_velocity&0x07;//去掉符号位
bc_velocity=(receive_data[4]&0x0f);//为转换后BC路速度,
if (bc_velocity>=8)
flag_bc=1;
else
flag_bc=0;
bc_velocity=bc_velocity&0x07;//去掉符号位
a_conversion_data=distance[a_dis];//转换成A路应延时的脉冲数
bc_conversion_data=distance[bc_dis];//转换成BC路应延时的脉冲数
save_a_inital_distance=a_conversion_data;
save_bc_inital_distance=bc_conversion_data;
if( receive_data[0]==0xff && receive_data[1]==0xff && receive_data[2]==0xff)
{for (i=3;i<9;i++)
crc=crc+receive_data[i];
ComTx(crc);
crc=0;
output_control_paramater(a_conversion_data,bc_conversion_data,receive_data[4],receive_data[5],receive_data[6],receive_data[7],receive_data[8]);
TR2=1;
}
count_receive_data=0;
receive_data[9]=(0,0,0,0,0,0,0,0,0);
EA=1;
}
}
/*串口中断0子程序*/
void UART0_ISR (void) interrupt 4
{
if(!TI0) //是发送中断还是接收中断
{ receive_data[count_receive_data]=SBUF0;
count_receive_data++;
RI0 = 0; /*清接收标志位*/
}
TI0 = 0; /*清发送标志位*/
}
/*定时器0中断服务程序*/
void Timer0_Isr(void) interrupt 1
{
TR0=0;
TL0=0xdf;//定时器0定时20ms
TH0=0x01;
count_receive_data=0;
receive_data[9]=(0,0,0,0,0,0,0,0,0);
}
void Timer2_ISR (void) interrupt 5
{
TF2=0; //清除中断标志
count_interrupt++;//中断次数加1
if (count_interrupt==2) //100ms定时到
{count_interrupt=0;
//A路转换后的距离换算
if(!flag_a)
a_conversion_data=a_conversion_data-a_velocity;
else
a_conversion_data=a_conversion_data+a_velocity;
//BC路转换后的距离换算
if(!flag_bc)
bc_conversion_data=bc_conversion_data-bc_velocity;
else
bc_conversion_data=bc_conversion_data+bc_velocity;
output_control_paramater(a_conversion_data,bc_conversion_data,receive_data[4],receive_data[5],receive_data[6],receive_data[7],receive_data[8]);
if ((a_conversion_data>36000 )||(a_conversion_data<5))
a_conversion_data=save_a_inital_distance;
if ((bc_conversion_data>=36000) ||(bc_conversion_data<=5))
bc_conversion_data=save_bc_inital_distance;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -