打印
[ZLG-ARM]

请教LPC2106

[复制链接]
1661|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ycz9999|  楼主 | 2011-10-1 12:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 ycz9999 于 2011-10-1 12:33 编辑

这是一个小项目中的一段代码,由于手头没有板子可以跑,便用proteus仿真的,但是遇到了个BUG,就是定时器0匹配0中断标志位不置位,我不确定是不是仿真软件的问题还是代码的问题,代码检测了很久没有找到问题。代码如下,麻烦帮我看下到底有没有BUG,先谢了。
代码在2楼。

相关帖子

沙发
ycz9999|  楼主 | 2011-10-1 12:33 | 只看该作者
/*
* 功能:
* 作者:
* 时间:
*/

#include  "config.h"
/* 系统初始化时钟参数如下:
*           Fcclk = Fosc*4 = 14.745MHz*4 = 58.98MH
*        Fpclk = Fcclk/4 = 58.98MHz/4 = 14.745MHz
*/
#define        LED_BJ                (0x1<<0)                        // P0.0控制LED_BJ,低电平点亮
#define        LED_BJCZ                (0x1<<1)                        // P0.1控制LED_BJCZ,低电平点亮
#define        LED_QYZD        (0x1<<2)                        // P0.2控制LED_QYZD,低电平点亮
#define        LED_QYJC        (0x1<<3)                        // P0.3控制LED_QYJC,低电平点亮

#define         MR0_30S                (14745000*30)                // T0 MR0匹配30s
#define         MR0_2_5S        (14745000*2.5)                // T0 MR0匹配2.5s

/*
* 系统临界频率点,用户可自行设定
* 当输入脉冲频率高于该频率时,系统激活
* 当输入脉冲频率低于该频率时,系统不工作
*/
#define        FRE                1000                // 单位:HZ       


uint32 temp1,temp2,TEMP1,TEMP2,TEMP3,TEMP4;                // 测量按键引脚电平变化的变量
uint32 key_statues;                        // 按键引脚对用的外部电平状态
uint8 Flag30s1;                // 30s长按下标志
uint8 Flag30s2;                // 30s内未按下标志
uint8 flag;                // 循环次数计数器 保证定时器只在第一次进入循环时才初始化

/*
* 测频时用于存储定时器1计数器值
* 其中TIME = time2 - time1
*/
uint32 time1;
uint32 time2;
uint32 TIME;
uint32 frequency;


/*
* 功能:定时器1测频函数 (有误差测量)
* 描述:所测脉冲频率为14745000/(TIME*2)
*/
void freqmeas(void)
{
        T1TC = 0;                                                        // 定时器1计数器初始化为0
            T1PR = 0;                                                        // 设置定时器1分频为0
            T1TCR = 0x03;                                                // 启动并复位T1TC
            T1TCR = 0x01;
           
        while((IOPIN & (0x1<<11)) != 0);                // 等待外部脉冲输入引脚为低
        time1 = T1TC;                                                // 读取定时器1计数器的初始值
        while((IOPIN & (0x1<<11)) == 0);                // 等待外部脉冲输入引脚为高
        time2 = T1TC;                                                // 读取定时器1计数器的结束值
        T1TCR = 0x00;                                                // 关闭定时器1
       
        TIME = (time2 - time1);                                // 此时所测脉冲频率为:14745000/(TIME*2)
        frequency = (14745000/(TIME*2));
}

/*
* 功能:定时器0使能函数
* 描述:开启定时器0,定时器计数器复位0,30s/2.5s匹配,不中断
*/
void timer0_enable(void)
{
        T0TC = 0;                                // 定时器0计数器初始化为0
            T0PR = 0;                                // 设置定时器分频为0
            T0MCR = 0x03;                // 匹配通道0发生匹配时中断标志T0IR[0]-MR0中断标志置位且T0TC复位
            if(T0MR0 == MR0_30S)
            {
                    T0MR0 = MR0_2_5S;                // 2.5s匹配
            }
            else
            {
                    T0MR0 = MR0_30S;                // 30s匹配
            }
            T0TCR = 0x03;                        // 启动并复位T0TC
            T0TCR = 0x01;
}

/*
* 功能:定时器0禁用函数
* 描述:关闭定时器0
*/
void timer0_disable(void)
{
        T0TCR = 0x00;                                                // 关闭定时器0
}

/*
* 功能:报警函数
* 描述:点亮报警指示灯
*/
void BJ(void)
{
        IOCLR = (LED_BJ | LED_BJCZ);       
}

/*
* 功能:牵引制动函数
* 描述:点亮牵引制动指示灯
*/
void QYZD(void)
{
        IOCLR = (LED_QYZD | LED_QYJC);       
}

/*
* 功能:系统C函数入口点
*/
int main(void)
{
        PINSEL0 = (PINSEL0 & 0x00000000);                // 所有引脚为GPIO                                               
        PINSEL1 = (PINSEL1 & 0x00000000);
        IODIR = (LED_BJ | LED_BJCZ | LED_QYZD | LED_QYJC);                // 设置LED控制引脚为输出、按键和测频引脚默认为输入  
        IOSET = (LED_BJ | LED_BJCZ | LED_QYZD | LED_QYJC);                // LED控制引脚输出初始化,置位灭灯
        key_statues = ((IOPIN & 0x00000400)>>10);
        T0MR0 = 0;
        flag = 0;
       
        while(1)
        {
                freqmeas();
                while(frequency>=FRE)
                {
                        // 前30s
                        temp2 = temp1 = 1;
                        temp1= key_statues;
                        while((temp1==0)&(temp2==1))                // 第一次按下
                        {
                               
                                if(flag == 0)
                                {
                                        timer0_enable();                // 开启定时器0,定时器计数器复位0,30s匹配,不中断
                                }
                                TEMP2 = TEMP1 = 0;
                                TEMP1 = key_statues;
                                if((TEMP1==1)&(TEMP2==0))                // 正常松开
                                {
                                        T0IR = 0x01;                        // T0IR清零
                                        timer0_disable();                // 关闭定时器0
                                        flag = 0;
                                        break;                                // 跳出最近大循环       
                                }
                                if((T0IR&0x01)==1)                // 按下超过了30s       
                                {
                                        T0IR = 0x01;                // T0IR清零
                                        timer0_disable();        // 关闭定时器0               
                                        BJ();                                // 报警
                                        flag = 0;
                                        Flag30s1 = 1;                // 30s长按下标志
                                        break;                        // 跳出最近大循环
                                }
                                flag ++;
                        }
                        while((temp1==1)&(temp2==1))                // 第一次未按下
                        {
                                if(flag==0)
                                {
                                        timer0_enable();                // 开启定时器0,定时器计数器复位0,30s匹配,不中断
                                }
                                TEMP2 = TEMP1 = 1;
                                TEMP1 = key_statues;
                                while((TEMP1==0)&(TEMP2==1))                // 按下
                                {
                                        TEMP4 = TEMP3 = 0;
                                        TEMP3 = key_statues;
                                        if((TEMP3==1)&(TEMP4==0))        // 正常松开       
                                        {
                                                T0IR = 0x01;                        // T0IR清零
                                                timer0_disable();        // 关闭定时器0
                                                flag = 0;
                                                goto loop;                // 跳出多层嵌套大循环
                                        }
                                        if((T0IR&0x01)==1)                // 按下超过了30s
                                        {
                                                BJ();                                // 报警
                                                T0IR = 0x01;                        // T0IR清零
                                                timer0_disable();        // 关闭定时器0
                                                flag = 0;
                                                Flag30s1 = 1;                // 30s长按下标志
                                                goto loop;                // 跳出多层嵌套大循环
                                        }
                                }
                                if((T0IR&0x01)==1)                // 30s内仍未按下
                                {
                                        BJ();                                // 报警
                                        T0IR = 0x01;                        // T0IR清零
                                        timer0_disable();        // 关闭定时器0
                                        flag = 0;
                                        Flag30s2 = 1;                // 30s内未按下标志
                                        break;                        // 跳出最近大循环
                                }
                                flag ++;
                        }
                       
                        loop: ;
                       
                        // 后2.5s
                        if(Flag30s1==1)                // 30s内长按下
                        {
                                timer0_enable();                        // 开启定时器0,定时器计数器复位0,2.5s匹配,不中断
                                while((T0IR&0x01)==0);                // 等待2.5s后匹配
                                temp2 = temp1 = 0;
                                temp1= key_statues;
                                T0IR = 0x01;                        // T0IR清零
                                timer0_disable();                        // 关闭定时器0
                               
                                if((temp1==0)&(temp2==0))                // 2.5s后仍按下
                                {
                                        QYZD();                // 牵引制动
                                }
                               
                        }
                        if(Flag30s2==1)                // 30s内未按下
                        {
                                timer0_enable();                // 开启定时器0,定时器计数器复位0,2.5s匹配,不中断
                                while((T0IR&0x01)==0);        // 等待2.5s后匹配
                                temp2 = temp1 = 1;
                                temp1= key_statues;
                                T0IR = 0x01;                        // T0IR清零
                                timer0_disable();                // 关闭定时器0
                                if((temp1==1)&(temp2==1))                // 2.5s后仍未按下
                                {
                                        QYZD();                // 牵引制动
                                }
                        }
                       
                freqmeas();                // 32.5s后再次测频
                }
        }
        return 0;
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

858

帖子

1

粉丝