金牌会员
无
- 积分
- 1557
- 威望
- 424
- 贡献
- 913
- 兑换币
- 60
- 注册时间
- 2008-10-21
- 在线时间
- 110 小时
|
300贡献
最近将38k红外用在飞思卡尔上,红外中用到PIT0作脉冲时间的监测,单独使用时是ok的,可以控制小车前进后退,加AD采样后出现出现程序跑飞现象,将中断关掉后单独,AD可以使用。难道说二者有冲突还是程序有问题,特将全部程序贴出,300贡献求解:
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#include <MC9S12Xs128.h>
#define Ir_Pin PTH_PTH0
#define LED1 PTT_PTT0 //数据口
#define LED2 PTT_PTT2
#define LED3 PTT_PTT4
#define LED4 PTT_PTT6
#define speed 25
int AD_value[8]={255,255,255,255,255,255,255,255}; //探头探测的信号值
int count,i,j;
unsigned char Led_Buf[4]; //显示缓冲区
unsigned char Ir_Buf[4]; //用于保存解码结果
void advance(void);
void back(void);
void turn_left(int angle);
void turn_right(int angle);
void stop(void);
void PLL_init(void);
void PWM_init(void);
void ad_init(void);
void delayms(int ms);
void caiji(void);
void Ir_Get_Low(void);
void Ir_Get_High(void);
void control(void);
void IO(void);
void main(void)
{
PLL_init();
PWM_init();
IO();
ad_init(); // 将此句注释或将下面一句注释掉,程序都可以运行
EnableInterrupts; //将此句注释或将上面一句注释掉,程序都可以运行
//当然注释掉,想要功能就不能实现了
while(1)
{
//下面这一段是用于红外接收,led是调试用的标志
restart:
while(Ir_Pin);
LED1=0;
Ir_Get_Low();
if(count<425 || count>475) continue;//引导脉冲低电平9000us
Ir_Get_High();
if(count<200 || count>250) continue;//引导脉冲高电平4500
LED2=0;
for(i=0;i<4;i++) //4个字节
for(j=0;j<8;j++) //每个字节8位
{ LED3=0;
Ir_Get_Low();
if(count<10 || count>40) goto restart;
Ir_Get_High();
if(count<10 || count>100) goto restart;
Ir_Buf[i]>>=1;
if(count>56)
{
Ir_Buf[i]|=0x80;
LED4=0;
}
}
control();
}
}
void PLL_init(void) //时钟初始化
{
//40M bus_clock
CLKSEL=0X00;
PLLCTL_PLLON=1;
SYNR =0xc0 | 0x04;
REFDV=0x80 | 0x01;
POSTDIV=0x00;
_asm(nop);
_asm(nop);
while(!(CRGFLG_LOCK==1));
CLKSEL_PLLSEL =1;
}
void PWM_init(void) //脉宽调制初始化
{
PWME=0x00;
PWMCTL_PSWAI=1;
PWMCTL_PFRZ=1;
PWMPOL=0X00;
PWMCLK=0Xf0;// 67使用clock SB,45使用clock SA
PWMPRCLK=0X33; //clock A=clock B=5M
PWMSCLA=5; //SA=SB=1M
PWMSCLB=5;
PWMPER4=25;
PWMPER5=25;
PWMDTY5=0;
PWMDTY4=0;
PWMPER6=25;
PWMPER7=25;
PWMDTY7=0;
PWMDTY6=0;
PWME=0Xf0;
}
void ad_init(void) //AD初始化
{
ATD0CTL1=0X00;
ATD0CTL2=0X42;
ATD0CTL3=0Xc3; //0Xe4为12 0xc3为8 6_3转换序列长度1100 12通道
ATD0CTL4=0xF3;
ATD0CTL5=0x30;
ATD0DIEN=0x00;
}
void caiji(void) //将采集的信号赋值给数组AD_value[]
{
AD_value[0]=ATD0DR0;
AD_value[1]=ATD0DR1;
AD_value[2]=ATD0DR2;
AD_value[3]=ATD0DR3;
AD_value[4]=ATD0DR4;
AD_value[5]=ATD0DR5;
AD_value[6]=ATD0DR6;
AD_value[7]=ATD0DR7;
}
void Ir_Get_Low()
{
count=0;
PITCFLMT_PITE=0; //关闭PIT
PITCE_PCE0=1;//使能通道0
//微定时器的装载寄存器
PITMTLD0= 40-1;//8位定时器初值设定。40分频,在40MHzBusClock下,为0.01MHz,即1us
//定时器的装载寄存器,
PITLD0 = 20 - 1 ;//16位定时器初值设定//定时20000*0.001ms = 20ms
PITMUX_PMUX0=0;//0:相应16位定时器与微时基0连接
PITINTE_PINTE0=1;//PIT相应通道溢出中断使能
PITCFLMT_PITE=1; //使能PIT ..
while(Ir_Pin==0);
PITCFLMT_PITE=0; //关闭PIT
}
//==============================================================
void Ir_Get_High(void)
{
count=0;
PITCFLMT_PITE=0; //关闭PIT
PITCE_PCE0=1;//使能通道0
//微定时器的装载寄存器
PITMTLD0= 40-1;//8位定时器初值设定。40分频,在40MHzBusClock下,为0.01MHz,即1us
//定时器的装载寄存器,
PITLD0 = 20 - 1 ;//16位定时器初值设定//定时20*0.001ms = 20us
PITMUX_PMUX0=0;//0:相应16位定时器与微时基0连接
PITINTE_PINTE0=1;//PIT相应通道溢出中断使能
PITCFLMT_PITE=1; //使能PIT ..
while(Ir_Pin==1); //知道
PITCFLMT_PITE=0; //关闭PIT
}
void control(void)
{
if(Ir_Buf[2]==5)
{
advance();
}
if(Ir_Buf[2]==27)
{
back();
}
if(Ir_Buf[2]==8)
{
stop();
}
if(Ir_Buf[2]==7)
{
turn_left(90);
}
if(Ir_Buf[2]==9)
{
turn_right(90);
}
}
void advance(void) //前进
{
PWMDTY4=0;
PWMDTY5=speed;
PWMDTY6=0;
PWMDTY7=speed;
}
void back(void) //后退
{
PWMDTY4=speed;
PWMDTY5=0;
PWMDTY6=speed;
PWMDTY7=0;
}
void turn_left(int angle) //左转
{
PWMDTY4=25;
PWMDTY5=0;
PWMDTY6=0;
PWMDTY7=25;
delayms(angle*14);
stop();
}
void turn_right(int angle) //右转
{
PWMDTY4=0;
PWMDTY5=25;
PWMDTY6=25;
PWMDTY7=0;
delayms(angle*14);
stop();
}
void stop(void) //stop
{
PWMDTY4=0;
PWMDTY5=0;
PWMDTY6=0;
PWMDTY7=0;
}
void IO(void)
{
DDRH_DDRH0=0;
DDRT_DDRT0=1; //定义LED口为输出
DDRT_DDRT2=1;
DDRT_DDRT4=1;
DDRT_DDRT6=1;
LED1=1;
LED2=1;
LED3=1;
LED4=1;
}
void delayms(int ms) //普通延时环节 调用1次大约1ms
{
int ii,jj;
if (ms<1) ms=1;
for(ii=0;ii<ms;ii++)
for(jj=0;jj<3338;jj++);
}
//定时器模块
#pragma CODE_SEG __NEAR_SEG NON_BANKED //指示该程序在不分页区
void interrupt 66 PIT0(void)
{
count++;
PITTF_PTF0=1;//清中断标志位
} |
|