📄 msp430.txt
字号:
#include "msp430x44x.h"
#define uchar unsigned char
#define uint unsigned int
#define LCD_en 0x80
#define LCD_wr 0x40
#define LCD_rs 0x20
void msec(uint msec_number); //延时程序(单位ms)
void ceju(void);
void dlms(void); //小延时子程序
void stop(void);
void T_L(void); //小车转向控制
void T_R(void);
void go(void);
void LCD_int(void); //LCD 初始化
void LCD_w_data(uchar data);
void LCD_w_com(uchar com);
void display(uchar b);
void xs_shuzu(uchar *strand); //显示xs_shuzu("字符串%")
uint count=0;
uchar i=0;
uchar csflag = 1;
float dis=0,dis_l,dis_r;
void light(void); //光敏传感
uint result[4];
float L_V,M_V,R_V,C_V;
uchar flag_dir = 3;
uchar pan = 0;
uchar count_timer=0; //两个基本计时变量
uchar timer = 0;
uchar r=0;
uchar count_iron = 0; //记录铁片数量和路程
uchar icount_dis = 0;
float iron_dis[5];
double dis_data;
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // 停止看门狗
SCFQCTL=99;
M_V = 2.5; //M_V置初值 方便最后停入车去
P3DIR |= 0x0f;
P3SEL |= 0x00; //车轮转向控制口
P3OUT = 0x0f;
P4DIR |= 0x08;
P4SEL = 0x00;
P1SEL |= 0x04; //P1_3口为第二功能捕获
P1DIR |= 0x10;
P1OUT &= ~0x10;
P2SEL |= 0x01; //P2_0口第二功能捕获
P2DIR |= 0xE0;
P2IE |= 0x10; //P2.4用于检测铁片口
P2IES |= 0x10; //下降沿触发
P2IFG &= ~0x10; //清除中断标志
P1IE |= 0x08; //P1.3用于霍尔开关检测
P1IES |= 0x08;
P1IFG &= ~0x08;
P5SEL |= 0x00; //P5.0~P5.7 LCD数据口
P5DIR |= 0xFF; //LCD控制口初始化
P6SEL = 0xA3; //P6第二功能AD开启
LCD_int();
xs_shuzu("Ready!%");
IE2 |= BTIE; //基本定时器启动
FLL_CTL0 |= XCAP14PF;
BTCTL = BTDIV+BTIP1+BTIP0;
_EINT();
while(pan==0)
{
pan = P4IN&(0x07);
}
/**第一任务 循迹行进**/
while(count!=300)
{
pan = P4IN&(0x07);
switch(pan)
{
case 0x02: go();
break;
case 0x01: T_R();
break;
case 0x04: T_L();
break;
case 0x00: {
count++;
go();
break;
}
default: go();
break;
}
dlms();
}
stop();
//LCD_w_com(1); //清屏
//xs_shuzu("Stop!%");
count = 0; //count变量复位
P1OUT |= 0x08;
msec(1000);
P1OUT ^= 0x08;
msec(1000);
P1OUT ^= ~0x08;
msec(1000);
P1OUT ^= ~0x08;
msec(1000);
P1OUT ^= ~0x08;
msec(1000);
P1OUT ^= ~0x08; //发出断续声光信号
P1IE &= ~0x04; //关闭霍尔开关
P2IE &= ~0x10;
T_L();
msec(300);
go();
msec(300);
while(1)
{
csflag = 0;
ceju(); //左超声头测距
dis_l = dis;
csflag = 1;
ceju(); //右超声头测距
dis_r = dis;
if((dis_l<35)||(dis_r<35))
{
if(dis_l<dis_r){T_R();flag_dir = 0;}
else if(dis_l>dis_r){T_L();flag_dir = 1;}
while((dis_l<15)||(dis_r<15)){
csflag = 1;
ceju(); //右超声头测距
dis_r = dis;
csflag = 0;
ceju(); //左超声头测距
dis_l = dis;
if(flag_dir == 0)T_R();
else if(flag_dir == 1)T_L();
msec(90);
}
flag_dir = 3;
go();
msec(100);
}
else
{
light();
if((L_V<0.8)||(M_V<0.8)||(R_V<0.9)||(C_V<0.9))
{
if((L_V<M_V)&&(L_V<R_V)&&(L_V<C_V))T_L();
else if((M_V<L_V)&&(M_V<R_V)&&(M_V<C_V))go();
else if((R_V<M_V)&&(R_V<L_V)&&(R_V<C_V))T_R();
else if((C_V<M_V)&&(C_V<R_V)&&(C_V<L_V)){T_R();msec(550);}
//msec(250);
//go();
//msec(100);
}
else go();
}
if(M_V<0.135)break;
}
stop();
LCD_w_com(1); //清屏
xs_shuzu("Destiny!%");
LCD_w_com(0xC1); //显示全程时间
LCD_w_data(timer/10+0x30);
LCD_w_data(timer%10+0x30);
IE2 &= ~BTIE; //关闭基本定时器中断
while(1) //交替显示
{
LCD_w_com(0x80);
xs_shuzu("IRON: %"); //实时刷新铁片数量
for(count_iron = 0; count_iron<3; count_iron++)
{
LCD_w_com(0xC8);
dis_data = iron_dis[count_iron+1];
display(2);
xs_shuzu("cm%");
msec(2000);
}
}
}
void msec(unsigned int msec_number)
{ uchar msec_j ;
msec_number *= 4;
while ((msec_number--)!=0)
{ msec_j=0;
while(msec_j<123)
{ msec_j++;
}
}
}
void T_L(void)
{
count = 0;
P3OUT = 0x0E;
}
void T_R(void)
{
count = 0;
P3OUT = 0x0B;
}
void go(void)
{
//count = 0;
P3OUT = 0x0A;
}
void ceju(void)
{
i=0;
while(i<4){
TBCCTL0 = CCIE;
TBCCR0 = 40;
_BIS_SR(GIE); //开总中断允许
TBCTL = TBSSEL1 + MC0;
if(i==3){
TBCTL = TBSSEL1 + MC_0;
P4OUT |= 0x08;
count=0;
if(csflag==0)
{
CCTL1 &= ~CCIE; //关闭右头捕获
CCTL1 &= ~CAP;
CCTL2 = CAP+CM0+CCIE+SCS; //左超声头测距
TAR = 0;
TACTL = TASSEL1+MC1;
}
else if(csflag==1)
{
CCTL2 &= ~CCIE;
CCTL2 &= ~CAP; //关闭左头捕获
CCTL1 = CAP+CM0+CCIE+SCS;
TAR = 0;
TACTL = TASSEL1+MC1;
}
//while(count<10)count++; //延时消除假波
}
TBCTL = TBSSEL1 + MC0;
dis = 0;
while(count<=20); //连续发送10个脉冲
TBCCTL0 = 0x0000; //关闭Timer_B计数中断
P4OUT |=0x08; //P1.0置高
while((count<=2000)&&(i<5))count++;
count=0;
i++;}
//dis = 0;
msec(10);
if(dis==0)dis=999;
}
void light(void)
{
ADC12CTL0 = ADC12ON + MSC + SHT0_2;
ADC12CTL1 = SHP + CONSEQ_1;
ADC12MCTL0 = INCH_0; //通道A0:左探光头
ADC12MCTL1 = INCH_1; //通道A1:中探光头
ADC12MCTL5 = INCH_5; //通道A2: 右探光头
ADC12MCTL7 = INCH_7 + EOS; //通道A2: 右探光头
ADC12IE = 0x80;
ADC12CTL0 |= ENC; //使能转换
_EINT();
ADC12CTL0 |= ADC12SC;
msec(10);
}
void dlms(void)
{
unsigned int z;
for(z=2200;z>0;z--){}
}
void stop(void)
{
P3OUT = 0x0F;
}
/***************LCD控制子程序********************/
void LCD_int(void)
{
LCD_w_com(1); //清屏
LCD_w_com(2);
LCD_w_com(0x38); //显示模式
LCD_w_com(0x08);
LCD_w_com(0x0E);
LCD_w_com(0x06);
LCD_w_com(0x38); //显示开关
LCD_w_com(0x80);
}
void LCD_w_data(uchar data)
{
uchar a;
a = data;
P2OUT |= LCD_en + LCD_rs + LCD_wr;
P5OUT = a;
P2OUT &= ~LCD_wr;
msec(1);
P2OUT &= ~LCD_en;
msec(1);
P2OUT |= LCD_en + LCD_rs + LCD_wr;
}
void LCD_w_com(uchar com)
{
uchar b;
b = com;
P2OUT |= LCD_en + LCD_rs + LCD_wr;
P2OUT &= ~LCD_rs; //切换为指令输入
P5OUT = b;
P2OUT &= ~LCD_wr;
msec(1);
P2OUT &= ~LCD_en; //下降沿输入数据
msec(1);
P2OUT |= LCD_en + LCD_rs + LCD_wr;
}
void xs_shuzu(uchar *strand)
{ uchar xs_k=0;
while(*(strand+xs_k)!='%')
{ LCD_w_data(*(strand+xs_k));
xs_k++;
}
msec(1);
}
void display(uchar b)
{ uchar f_codef[5],f_codeb[4];
uchar j;
uint l;
l=(uint)dis_data;
dis_data=dis_data-l;
j=5;
while(j>0)
{ f_codef[j-1]=l%10;
l=l/10;
j--;
}
l=(uint)dis_data*10000;
j=4;
while(j>0)
{ f_codeb[j-1]=l%10;
l=l/10;
j--;
}
l=0;
j=0;
while(j<4)
{ if(l==0)
{ if(f_codef[j]!=0)
{ LCD_w_data(f_codef[j]+0x30);
l=1;
}
}
else LCD_w_data(f_codef[j]+0x30);
j++;
}
LCD_w_data(f_codef[4]+0x30);
xs_shuzu(".%");
j=0;
while(j<b)
{ LCD_w_data(f_codeb[j]+0x30);
j++;
}
}
#pragma vector=TIMERB0_VECTOR
__interrupt void Timer_B(void)
{
P4OUT^=0x08;
count=count+1;
}
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A1(void)
{
uchar flag=0;
flag = TAIV;
if(flag==4) count=CCR2; //count在此用于记录时间
if(flag==2) count=CCR1;
//count = CCR2;
TACTL = TASSEL1+MC_0; //停止计数
//CCTL1 = CAP+CM_0+CCIE+SCS;
// else CCTL2 = 0;
dis=count;
dis*=5.188147;
dis*=0.0005;
dis*=2;
dis-=4;
CCTL1 &= ~CCIE; //关闭中断允许
CCTL2 &= ~CCIE;
}
#pragma vector = ADC_VECTOR
__interrupt void ADC12ISR(void)
{
result[0] = ADC12MEM0;
L_V = (result[0]/2700.0)*2.5;
result[1] = ADC12MEM1;
M_V = (result[1]/2700.0)*2.5;
result[2] = ADC12MEM5;
R_V = (result[2]/2700.0)*2.5;
result[3] = ADC12MEM7;
C_V = (result[3]/2700.0)*2.5;
}
#pragma vector=PORT2_VECTOR //P2.4检测铁片
__interrupt void PORT_2(void)
{
P1IE &= ~0x04; //暂时关闭P1.3口中断
stop();
P1OUT |= 0x10; //发出声光信号
LCD_w_com(0x80);
count_iron ++;
xs_shuzu("IRON: %"); //实时刷新铁片数量
LCD_w_data(count_iron + 0x30);
msec(800);
iron_dis[count_iron] = (icount_dis/2.0)*1.8*3.14; //计算铁片距起跑线的距离
LCD_w_com(0xC8);
LCD_w_com(0xC8);
dis_data = iron_dis[count_iron];
display(2);
xs_shuzu("cm%");
P1OUT ^= 0x10; //发出声光信号
msec(800);
P1OUT ^= 0x10; //发出声光信号
msec(800);
P1OUT ^= 0x10; //发出声光信号
msec(800);
P2IFG &= ~0x10;
P1IE |= 0x04; //恢复中断
go();
}
#pragma vector=PORT1_VECTOR //P1.3测速
__interrupt void PORT_1(void)
{
icount_dis ++;
P1IFG &= ~0x08;
}
#pragma vector = BASICTIMER_VECTOR
__interrupt void basic_timer(void)
{
if(count_timer == 9)
{
LCD_int();
xs_shuzu("IRON: %"); //实时刷新铁片数量
LCD_w_data(count_iron + 0x30);
LCD_w_com(0xC8);
dis_data = iron_dis[count_iron];
display(2);
xs_shuzu("cm%");
LCD_w_com(0xC1);
timer += 1;
if(timer>9)
{
LCD_w_data(timer/10+0x30);
LCD_w_data(timer%10+0x30);
}
else LCD_w_data(timer+0x30);
count_timer = 0;
}
else count_timer++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -