打印
[LOOK]

学习体会第八贴——LOOK中使用TFT屏【二】有总结有疑惑

[复制链接]
2563|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 gdmgb520 于 2011-10-2 14:35 编辑

实现的功能:
在我前一帖的基础上,使用了Timer。系统中跑两个任务,Timer任务用来计时,设置计时间隔为1000ms,对应显示屏上的Timer Timer:xxxxx;task_led1任务用来刷新屏幕,刷新间隔通过修改REFRESH_TIMES宏来设定,该任务刷新周期是通过延时实现,同时,在该任务中每延时到1s时间,计数器加1,对应屏上Running Time:xxxxx。

对程序的说明:
1.程序中有些代码没有用到的,为方便大家阅读已经删除。
2.Timer的程序是根据菜农大叔 LOOK_TIMER.rar 例程添加的,应该如果看懂了这个例程,那Timer就会用了。我还没完全看懂。
3.LOOK_TIMER 例程的脉络:
主线一,Timer任务:
step1.定时器定时时间到
step2.on_signal()函数内的if语句被执行,流水灯显示。
主线二,按键中断:
step1.当按键中断产生时,按键中断调用task_LOOK_TIMER_t类的成员函数send_message(-50),把一个参数-50发送到邮箱。
step2.task_LOOK_TIMER对象的routine()函数通过mbox.get()获取到该参数,并使用该参数修改定时器的interval值。

学习时遇到的疑惑以及在学习中的自问自答(希望能跟大家讨论):
1.timer类的构造函数
// 任务类 LOOK_TIMER 的构造函数
__INLINE__ task_LOOK_TIMER_t::task_LOOK_TIMER_t()
: timer(*this)           // 初始化定时器实例,并指定触发对象。
, interval(1000)                         //初始化显示间隔
, mbox(0)
{
        // TODO: 在此初始化 task_LOOK_TIMER_t 的类成员
}
首先,写法第一次见,应该是表示带了几个参数吗?
其次,对这几个参数的含义不了解:
interval 50 是表示每50个系统周期中断一次吗(已经证实表示50ms)?
mbox 0 是表示初始化邮箱吗(邮箱消息。如果值为 0,表示未获取到消息。)?

2.look::timer_t::do_start  ( uintptr_t  interval )  
这个函数参数的含义,interval = 1 表示多长时间?据我猜测,interval的单位是ms,= 1 表示 1ms (已经证实)。

3.bool task_LOOK_TIMER_t::send_message(int msg)
由Keyboard_t类的dsr()函数调用,是通过消息的方式发送一个参数到task_LOOK_TIMER的邮箱吗?


4.on_signal函数何时被调用,是在定时中产生时被调用吗,还是?这个函数好像是一个被重载的函数?

5.task_LOOK_TIMER是作为一个任务对象创建的。所以,就没有类似于这样的语句:Keyboard_t Key;。

6.用两种方式计时的结果想差很大,有些疑惑,(我知道延时控制并不是精确延时,是与系统负荷有关,但是为什么相差这么大,刷屏很耗资源?):
用两种方式计时,a,定时器计时;b,延时计时。两者的之间的差值如下:
每秒刷屏次数    定时器计数器值    延时计数器值
1        100        86
4        100        60
8        100        42
16        100        27
PS:根据与秒表对比,定时器计数100s与秒表100s基本吻合。验证了interval分辨率为1ms。

最后上传工程代码: LOOK_TFT3.rar (3.61 MB)

等等,艳照忘记了,白天手机比较给力,让大家养养眼:lol


相关帖子

沙发
gdmgb520|  楼主 | 2011-10-2 14:40 | 只看该作者
编译时可能会提示 count 变量定义的问题。

这是因为定义了一个全局变量,这是C的思维,按照C++,应该定义一个 timer 类的内部成员,然后定义一个public成员函数 get_count(),其他任务通过访问这个成员还是来获取count变量的值。

你也试试:D

使用特权

评论回复
板凳
gdmgb520|  楼主 | 2011-10-2 14:53 | 只看该作者

有问题!!

好像不能按楼上的说法做。出现如下编译错误:
Build target 'Release'
compiling led.cpp...
led.cpp: In member function 'void task_led1_t::routine()':
led.cpp(57): error: 'class instantiate::task' has no member named 'get_count'
compiling Timer.cpp...
Timer.cpp: In member function 'void task_LOOK_TIMER_t::routine()':
Timer.cpp(23): warning: unused variable 'msg'
Timer.cpp: At global scope:
Timer.cpp(71): error: no 'long unsigned int task_LOOK_TIMER_t::get_count()' member function declared in class 'task_LOOK_TIMER_t'
Target not created
主要代码如下:
led.cpp
#include "led.h"

#define LOOK_H 1

#if LOOK_H == 0
#include "NUC1xx.h"
#include "NUC1xxM051Seriescfg.h"
#else
#define __HAVE_GPIO
#include <nuc120re3an.h>
using namespace nuvoton;
#endif
                          
#include "tft.h"
#include "Timer.h"

task_tft_t tftObj;                //创建tft对象

//-------------------------------------------------------------------------------------------------------------------------
//               
//-------------------------------------------------------------------------------------------------------------------------
// 任务类 task_led_t 的例程
void task_led1_t::routine()
{
        // TODO: 在此编写 task_led_t 例程的内容
#define X_DIS                        9        //显示信息的位置
#define Y_DIS                        7
#define        FONT_HEIGHT                19        //行高
#define REFRESH_TIMES        16        //每秒的刷新次数
        unsigned char cnt_i = 0;        //次数计数器,一定次数后cnt加1
        uint32_t cnt = 0;        //时间计数器,延时方式,每1s延时后加一
        unsigned long count = 0;        //时间计数器,定时方式,
        unsigned char str[6] = {0};
        
        tftObj.LCD_Init();
//        test_lcd_mon();
        tftObj.LCD_CLEAR(0,0,240,320);
         while (true) {
                // TODO: 在此编写 task_led_t 例程的内容
                tftObj.LCD_Display();

                cnt_i++;
                if(cnt_i > (REFRESH_TIMES-1))
                {
                        cnt_i = 0;
                        cnt++;
                }

                str[0] = (unsigned char)(cnt / 10000) + 0x30;
                str[1] = cnt % 10000 / 1000 + 0x30;
                str[2] = cnt % 1000  / 100 + 0x30;
                str[3] = cnt % 100   / 10 + 0x30;
                str[4] = (unsigned char)(cnt % 10) + 0x30;
                tftObj.LCD_ShowString(X_DIS,Y_DIS,"Running Time:");
                tftObj.LCD_ShowNumStr(X_DIS+81,Y_DIS-2,str);

                count =  task_LOOK_TIMER.get_count();
                str[0] = (unsigned char)(count / 10000) + 0x30;
                str[1] = count % 10000 / 1000 + 0x30;
                str[2] = count % 1000  / 100 + 0x30;
                str[3] = count % 100   / 10 + 0x30;
                str[4] = (unsigned char)(count % 10) + 0x30;
                tftObj.LCD_ShowString(X_DIS,Y_DIS+FONT_HEIGHT,"Timer Time:");
                tftObj.LCD_ShowNumStr(X_DIS+81,Y_DIS-2+FONT_HEIGHT,str);

                delay(LOOK_TICKS_PER_SEC / REFRESH_TIMES);         //每秒刷新屏幕10次
         }
}


#ifdef LOOK_SCHEDULING_PRIORITY
instantiate::task<task_led1_t, LOOK_STACK_SIZE> task_led1(0);
instantiate::task<task_LOOK_TIMER_t, LOOK_STACK_SIZE> task_LOOK_TIMER(0);
#else
instantiate::task<task_led1_t, LOOK_STACK_SIZE> task_led1;
instantiate::task<task_LOOK_TIMER_t, LOOK_STACK_SIZE> task_LOOK_TIMER;
#endif
2.Timer.h
#ifndef __LOOK_TIMER_H
#define __LOOK_TIMER_H

#include "look_config.h"
#include <look.h>
//#include <instantiate>

//extern unsigned int count;

// 任务类 task_LOOK_TIMER_t 的定义
class task_LOOK_TIMER_t : public task_t {
public:
        __INLINE__ task_LOOK_TIMER_t();        // 构造函数
    void on_signal(void* addr, uintptr_t signal);    // 定义on_signal()        
        bool send_message(int msg);
        unsigned long get_count(void);
protected:
        void routine();                // 任务例程
private:
        timer_t timer;
        int interval;
        mbox_t<int> mbox;
        unsigned long count;
};

// 任务类 LOOK_TIMER 的构造函数
__INLINE__ task_LOOK_TIMER_t::task_LOOK_TIMER_t()
: timer(*this)           // 初始化定时器实例,并指定触发对象。
, interval(1000)                         //初始化显示间隔
, mbox(0)
{
        // TODO: 在此初始化 task_LOOK_TIMER_t 的类成员
}

extern instantiate::task<task_LOOK_TIMER_t, LOOK_STACK_SIZE> task_LOOK_TIMER;

#endif        // __LOOK_TIMER_H
3.Timer.cpp
#include "Timer.h"

#define LOOK_H 1

#if LOOK_H == 0
#include "NUC1xx.h"
#include "NUC1xxM051Seriescfg.h"
#else
#define __HAVE_GPIO
#include <nuc120re3an.h>
using namespace nuvoton;
#endif



// 任务类 task_LOOK_TIMER_t 的例程
void task_LOOK_TIMER_t::routine()
{
        // TODO: 在此编写 task_LOOK_TIMER_t 例程的内容
        timer.start(interval);       //定时器
        while (true) {
                // TODO: 在此编写 task_LOOK_TIMER_t 例程的内容
                int msg = mbox.get();                                        // 等待邮箱消息
//                if (msg != 0)
//                {
//                        if ((msg + interval) > 0) {//间隔为0非法,不响
//                                interval += msg;        
//#if LOOK_H == 0
//                                GPIOBs.DMASK.Bits.Pin10 = 0;
//#else
//                                GPIOB.DMASK().DMASK10(0);
//#endif
//                                msg = (msg > 0) ? 1 : 2;//+ 响1声,- 响2声
//                                for (int i = 0; i < (msg * 2); i ++){
//#if LOOK_H == 0
//                                  GPIOBs.DOUT.Bits.Pin10 ^= 1;//蜂鸣器响PB10=1,不响PB10=0
//#else
//                                  GPIOB.DOUT().DOUT10 ^= 1;
//#endif
//                                  delay(LOOK_TICKS_PER_SEC / 20);
//                                }
//#if LOOK_H == 0
//                                GPIOBs.DOUT.Bits.Pin10 = 0;
//#else
//                                GPIOB.DOUT().DOUT10(0);
//#endif
//                        }
//                }
        }
}

void task_LOOK_TIMER_t:n_signal(void* addr, uintptr_t signal)
{
        if (addr == &timer) {
                timer.do_start(interval);       // 重置定时器
                // 处理定时器事务
                count ++;
        }
        else {
                task_t:n_signal(addr, signal);
        }

}

bool task_LOOK_TIMER_t::send_message(int msg)
{
        return mbox.do_tryput(msg);                //发送消息
        
}

unsigned long task_LOOK_TIMER_t::get_count(void)
{
        return count;
}
还望大家指导。

使用特权

评论回复
地板
nixianmin| | 2011-10-2 15:37 | 只看该作者
本帖最后由 nixianmin 于 2011-10-2 15:55 编辑

顶,不错,timer_t我还没学呢,先看看
1、第一个问题我在C++看过是用来初始化类的变量成员的,
你可以找找那个类里面是不是定一个那几个变量成员
4、上次和lee老师聊谈到过on_signal()这函数,不过还是有点晕,
我简单的说下老师和我说的:只有timer类用到了on_signal(),
但用户程序也可以使用on_signal()来传递一些简单的消息,
调度器也有on_signal(),当时间片到时,timer就会触发,
调度器的on_signal()就会被调用。调度器只需在on_signal()处理中,切换任务即可。

根据上面老师说的话应该不难理解,on_signal是在timer对象时间到后被调用的,
用户也可以自己写on_signal()的内容,在调度器和任务里我们都能看到on_signal()这个虚函数

对这函数我也有点迷糊,希望老师再指点下
上传下上次和老师的聊天记录:

老师的讲解.rar

9.76 KB

使用特权

评论回复
5
nixianmin| | 2011-10-2 15:52 | 只看该作者
看了这个例子我可能知道了,看下面这个任务类
下面是一个邮箱,一个任务对象,通过timer对象可以设置定时
的时间,当时间到时会自动调用程序里的所有on_signal()函数,
怎么能调用所有的我不知道不过可能用一个look::signal_sink_t的
对像指针,并通过on_signal()里的addr == &timer这句来判断
是否是LOOK_TIMER_t类中的timer对像产生的。

那个send_message函数就是用函数方式将消息存到类的邮箱
class task_LOOK_TIMER_t : public task_t {
public:
        __INLINE__ task_LOOK_TIMER_t();        // 构造函数
    void on_signal(void* addr, uintptr_t signal);    // 定义on_signal()       
        bool send_message(int msg);
protected:
        void routine();                // 任务例程
private:
        timer_t timer;
        int interval;
        mbox_t mbox;
};
void task_LOOK_TIMER_t::on_signal(void* addr, uintptr_t signal)
{
        if (addr == &timer) {
                timer.do_start(interval);       // 重置定时器
                // 处理定时器事务
                count ++;
        }
        else {
                task_t::on_signal(addr, signal);
        }

}
差不多,期待老师详细的解答,如果错了那就误人子弟了

使用特权

评论回复
6
gdmgb520|  楼主 | 2011-10-2 16:12 | 只看该作者
4# nixianmin

在楼上的提醒下,我找到了问题1的答案,其实上次看过,只是又忘记了。

使用特权

评论回复
7
weshiluwei6| | 2011-10-9 21:55 | 只看该作者
高手如云啊  这个屏几个钱

使用特权

评论回复
8
abin0415| | 2012-4-29 02:05 | 只看该作者
多谢LZ共享

使用特权

评论回复
9
gdmgb520|  楼主 | 2012-4-30 15:58 | 只看该作者
8# abin0415

过去这么久了,能帮到别人真是很高兴啊

使用特权

评论回复
10
mcs8098| | 2012-8-1 21:25 | 只看该作者
:victory:

使用特权

评论回复
11
mcs8098| | 2012-8-1 21:26 | 只看该作者
:victory:

使用特权

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

本版积分规则

个人签名:了解新东西才知道自己的不足。 www.elecbench.com

67

主题

452

帖子

1

粉丝