标题:
KEIL RTX51_TINY仿真无法使用单片机T2定时器的解决方法
[打印本页]
作者:
太空将军
时间:
2021-12-21 11:38
标题:
KEIL RTX51_TINY仿真无法使用单片机T2定时器的解决方法
最近做板子采用新唐N79E814,由于功能多而繁杂,我决定采用RTX51_TINY (2.02版)作为RTOS系统
由于仿真调试确实方便,所以没有下载到板子上观察,使用T1定时器时,仿真没有问题(T0被RTOS使用)
当我使用定时器2时,发现定时器2的中断,无论怎么都进不去,接下来花了一天排查各种可能的人为错误
经过排查,我坚信,除了给老婆认错之外(调代码把老婆丢一边),我是不可能向代码认错的
发现使用KEIL仿真逻辑分析仪波形显示如下
波形.png
(55.99 KB, 下载次数: 89)
下载附件
2021-12-21 12:03 上传
定时器T2的EIE寄存器的ET2(开T2中断)这个位,置1了,但是逻辑分析仪显示为0,所以,应该是不支持T2的仿真好吧,下载到板子上试一下~~单片机代码如下:
#include <stdio.h>
#include <rtx51tny.h>
#include "N79E81x.h"
#include "Typedef.h"
#include "Define.h"
#include "LOGIC.h"
/*重要说明**本程序使用N79E814A内部11.0592M*/
/*重要说明**本程序使用N79E814A内部11.0592M*/
//Conf_tny.A51中INT_CLOCK 设置为 9216 正好是 100HZ滴答 时间片是10ms
//Conf_tny.A51中TIMESHARING 设置为0时,轮换执行各任务
//Conf_tny.A51中TIMESHARING 设置为1时,每个任务分得10ms
//Conf_tny.A51中TIMESHARING 设置为2时,每个任务分得20ms
/*因为我自己使用信号来驱动事件,所以TIMESHARING我设置为0*/
/**********************************************************************************/
/* Struct init & I/O init: */
/**********************************************************************************/
struct time ctime = { 12, 0, 0 }; /* storage for clock values */
/***********************************************************************************/
/* Task 0 'init': Initialize */
/***********************************************************************************/
void init (void) _task_ INIT { /* program execution starts here */
ET2 = 1; //开T2中断使能,EA受到RTOS控制,不用写EA = 1
os_create_task (CLOCK); /* create clock 1 task */
os_create_task (KEYREAD); /* create key 2 task */
//os_create_task (BUZZOUT); /* create key 2 task */
os_delete_task (INIT); /* del init task (no longer needed) */
}
/***********************************************************************************/
/* Task 1 'clock' @1HZ */
/***********************************************************************************/
void clock (void) _task_ CLOCK {
while (1) { /* loop */
if (++ctime.sec == 60) { /* calculate the second */
ctime.sec = 0;
if (++ctime.min == 60) { /* calculate the minute */
ctime.min = 0;
if (++ctime.hour == 24) { /* calculate the hour */
ctime.hour = 0;
}
}
}
os_wait (K_IVL, 100, 0); /* wait interval: 1 second */
P06 = ~P06; //每秒反转一次
TF2 = 1; //每秒置位一次T2中断标志,进入T2中断
}
}
/***********************************************************************************/
/* Task 2 'keyread': process key from push button or EC12 */
/***********************************************************************************/
struct PressedReg PressedReg = {0,0,0,0,0}; /* 按键被按下的次数 */
void keyread (void) _task_ KEYREAD {
UINT8 Count;
BIT Keys_in;
while (1) { /* loop */
Count = 0; /* 10 ms interrupt count */
do
{
os_wait(K_TMO, 1, 0); //os_wait()用于把CPU交给其它任务使用
} while (!Any_KeyPressed);
os_wait(K_TMO,1,0);
do
{
if(Any_KeyPressed&&Keys_in == UnLock)
{
Count = 0;
Keys_in = Locked;
//os_send_signal (BUZZOUT); /* signal to task BUZZOUT: Any_KeyPressed */
os_wait (K_TMO, 1, 0); /* 10ms 消抖 */
if(key1_pressed)
{
PressedReg.key1 ++;
}
if (key2_pressed)
{
PressedReg.key2 ++;
}
if (key3_pressed)
{
PressedReg.key3 ++;
}
if (EC12_key_pressed)
{
PressedReg.EC12_key ++;
}
}
else
{
os_wait (K_TMO, 1, 0);
Count ++;
}
if (All_KeyIdle)
{
Keys_in = UnLock;
Count ++;
os_wait (K_TMO, 1, 0);
}
//你可以更改 100为150,表示1500ms内检测按下次数
} while (Count<=100); //检测1000ms内按下多少次,可以响应单击,双击,三击,四击,五击。。。等
if(key1_pressed&&PressedReg.key1==SingleClick) /* 单击且1秒后还没放手就是长按*/
{
PressedReg.key1 = LongPressed;
//os_send_signal (BUZZOUT);
}
if (key2_pressed&&PressedReg.key2==SingleClick)
{
PressedReg.key2 = LongPressed;
//os_send_signal (BUZZOUT);
}
if (key3_pressed&&PressedReg.key3==SingleClick)
{
PressedReg.key3 = LongPressed;
//os_send_signal (BUZZOUT);
}
if (EC12_key_pressed&&PressedReg.EC12_key==SingleClick)
{
PressedReg.EC12_key = LongPressed;
//os_send_signal (BUZZOUT); /* signal to task BUZZOUT: Any_KeylongPressed 按下1秒又响了就是长按 */
}
if(
PressedReg.key1 != 0 || \
PressedReg.key2 != 0 || \
PressedReg.key3 != 0 || \
PressedReg.EC12_key != 0 \
)
{
//如果按键单击,双击,三击,四击,长按,执行此处代码,或者有按键动作,就发送信号给your_TASK
//os_send_signal (your_TASK); /* signal to task Logic: Any_KeyPressed */
}
PressedReg.key1 = 0;
PressedReg.key2 = 0;
PressedReg.key3 = 0;
PressedReg.EC12_key = 0;
}
}
/***********************************************************************************/
/* T2 中断函数 */
/***********************************************************************************/
void Timer2_ISR(void) interrupt 5 // Vecotr @ 0x2B
{
P07 = ~P07; //反转LED,使得LED闪烁
TF2 = 0; //清除T2中断标志
}
/***********************************************************************************/
/* Task 4 'buzzout'蜂鸣器: process buzz from push button or warning */
/***********************************************************************************/
void buzzout (void) _task_ BUZZOUT {
while (1) { /* endless loop */
os_wait(K_SIG,0,0); /* 等待按键任务发来信号*/
/* your code PWM开 */
//os_wait(K_TMO,10,0); //让PWM开100ms,os_wait()不会像delay()函数死死的占用CPU时间,
/* your code PWM关 */
os_switch_task(); /* 把时间交给其它任务 */
}
}
复制代码
电路.png
(20.45 KB, 下载次数: 78)
下载附件
2021-12-21 12:03 上传
结果就是,仿真不行,但是实际烧录运行后,能进入Timer 2 中断:P06每秒反转表示正在运行,P07发生翻转表明进入了中断
本试验只用到了task CLOCK和中断,按键部分的代码只是分享出来,万一你用得着呢~~~
完整代码请下载
N79E814.zip
(79.13 KB, 下载次数: 12)
2021-12-21 11:38 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1