📄 main.c
字号:
#include <hidef.h> /* common defines and macros */
#include <mc9s12dg128.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"
#define curve_speed 0x20 //弯道速度
#define straight_speed 0x30 //直道速度
#define left_black 33 //左边激光管黑线的判断边界
#define right_black 33 //右边激光管黑线的判断边界
#define curve_number 2 //确定为弯道的计数数值
#define straight_number 4 //确定为直道的计数数值
uchar v_ref=0x40;//速度设定值
uchar left_laser[2]={0,0};//左边的激光管采样值
uchar right_laser[2]={0,0};//右边的激光管采样值
uchar left_filter=0;//左边激光管滤波后的采样值
uchar right_filter=0;//右边激光管滤波后的采样值
uchar left_mark=0;//检测到左弯
uchar right_mark=0;//检测到右弯
uchar try_ad1;
uchar try_ad2;
void ad_init()//初始化ad
{
ATD0CTL2=0XC0;//ad模块上电,快速清零,无等待模式,禁止外部触发,中断禁止
ATD0CTL3=0X10;//2个ad转换
ATD0CTL4=0X87;//8位ad精度,1MHZadclock,adclock=bus/2/[psr+1]
ATD0CTL5=0XB0;//右对齐,无符号,多通道,通道0开始
ATD0DIEN=0X00;//禁止数字输入
}
void get_ad()//获取激光管的值
{
uchar flag=0;
while(flag<=2)
{
while(ATD0STAT1_CCF0!=1)
;
left_laser[flag]=ATD0DR0;
while(ATD0STAT1_CCF1!=1)
;
right_laser[flag]=ATD0DR1;
flag++;
}
left_filter=(left_laser[0]+left_laser[1])/2;
right_filter=(right_laser[0]+right_laser[1])/2;
left_laser[0]=0;
left_laser[1]=0;
right_laser[0]=0;
right_laser[1]=1;
//left_filter=try_ad1;
//right_filter=try_ad2;
}
void deal_ad()//处理ad采样程序
{
get_ad();
if(left_filter<=left_black)
{
left_filter=0;
left_mark=1; //左侧有黑线
}
else
{
left_filter=0;
left_mark=0; //左侧无黑线
}
if(right_filter<=right_black)
{
right_filter=0;
right_mark=1; //右侧有黑线
}
else
{
right_filter=0;
right_mark=0; //右侧无黑线
}
}
void accelerate()//激光管控制速度调整程序
{
static uchar straight_count=0;//直道计数
static uchar curve_count=0;//弯道计数
static uchar straight_mark=0;//直道标志
static uchar curve_mark=0;//弯道标志
static uchar curve_state=0;//检测状态为弯道
static uchar straight_state=0;//检测状态为直道
static uchar check_state=0;//有检测到需要的信号
deal_ad();
if(left_mark==1||right_mark==1) //判断是否有弯道
{
curve_state=1; //检测到弯道
straight_state=0; //检测的不是直道
check_state=1; //检测到需要的信息
}
if(left_mark==0&&right_mark==0) //判断是否有直道
{
curve_state=0; //检测到不是弯道
straight_state=1; //检测到是直道
check_state=1; //检测到需要的信息
}
if(check_state) //是否检测到有用的信息
{
if(curve_state==1) //检测到弯道弯道计数增加
curve_count++;
else //不是检测到弯道重新计数
curve_count=0;
if(straight_state==1) //检测到直道直道计数增加
straight_count++;
else //不是检测到直道重新计数
straight_count=0;
}
if(curve_count==curve_number) //判断确认是否为弯道
{
curve_mark=1; //确认是弯道的标志
straight_mark=0; //重新计数同时消除直道标志
straight_count=0;
curve_count=0;
}
if(straight_count==straight_number) //判断确认是否为直道
{
straight_mark=1; //确定是直道的标志
straight_count=0; //重新计数同时消除弯道标志
curve_mark=0;
curve_count=0;
}
if(curve_mark==1) //判断是否为弯道
v_ref=curve_speed; //设定速度为弯道速度
if(straight_mark==1) //判断是否为直道
v_ref=straight_speed; //设定速度为直道速度
try_ad1=v_ref;//读当前速度
try_ad2=v_ref;//读当前速度
}
void sci_init()//串口sci初始化
{
uchar clear;
SCI0BDH=0X00;
SCI0BDL=0X0D;//设置波特率为38400
SCI0CR1=0X13;//设置9位数据开启奇偶校验采用偶校验
SCI0CR2=0X0C;//始能接收发送
clear=SCI0SR1;//清楚sci状态寄存器
}
void sci_trans(uchar ch)//串口发送程序
{
SCI0DRL=ch;
while(SCI0SR1_TDRE!=1)
;
SCI0SR1_TDRE=0;
}
void TimerOverflow(void) //使用定时器延时程序
{
/* This function waits for th timer overflow.
Then it changes the LEDs bargraph display */
while (TCNT != 0x0000);
while (TCNT == 0x0000);
while(TCNT!=0X0000);
while(TCNT=0X0000);
}
void main(void) {
uchar a=0xaa;
uchar b=0xbb;
uchar c=0xcc;
sci_init();
ad_init();
DDRB=0XFF;
PORTB=0XAA;
TSCR1 = 0x80; /* enable timer TCNT */
TSCR2 = 0x07; /* TCNT prescaler setup */
/* put your own code here */
EnableInterrupts;
for(;;)
{
//delay();
//get_ad();
accelerate();
TimerOverflow();
sci_trans(a);
sci_trans(try_ad1);
sci_trans(b);
sci_trans(try_ad2);
sci_trans(c);
continue;
} /* wait forever */
/* please make sure that you never leave this function */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -