ai8h8k64u红外接收问题
我想用定时器0和外部中断1做一个红外接收模块,但是发现一个问题,在主频40mhz下,定时器0 16位自动重载,采用12T模式下,计数值加1表示计时0.3us,用软件延时测试,15ms加15us延时,定时器能正常计时,显示15015.主要代码如下,但是使用外部中断1进行计时测试时,发现计时不正确,如下第二段测试代码#include <Ai8h.H>
#include <INTRINS.H>
/**
* @brief定时器0初始化
* @param无
* @retval 无
*/
void Timer0_Init(void) //@40.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初始值
TH0 = 0x00; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 0; //定时器0不计时
}
/**
* @brief定时器计时开关控制
* @paramSwitchFlag:开关控制, 0:定时器0开始计时
1:定时器0停止计时
* @retval 无
*/
void Timer_CntSwitch(unsigned char SwitchFlag)
{
if(SwitchFlag){TR0=1;}//定时器0开始计时
else{TR0=0;}//定时器0停止计时
}
/**
* @brief定时器计数值清零
* @param无
* @retval 无
*/
void Timer_CntClear(void)
{
TL0 = 0x00; //设置定时初始值清0
TH0 = 0x00; //设置定时初始值清0
TF0 = 0;//清除TF0标志
}
/**
* @brief获取定时器计时us值
* @param无
* @retval 返回计时的时间,单位us
*/
unsigned int Timer_ReadCnt(void)
{
unsigned int cnt;
unsigned int th0=(unsigned int)TH0;
unsigned int tl0=(unsigned int)TL0;
cnt=(th0<<8) | (tl0 & 0xFF);//获取计数值
cnt=(unsigned int)(cnt*0.3);//将计数值转换为us数
return cnt;
}
void Delay15ms(void) //@40.000MHz
{
unsigned char data i, j, k;
_nop_();
_nop_();
i = 4;
j = 12;
k = 50;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay15us(void) //@40.000MHz
{
unsigned char data i;
i = 198;
while (--i);
}
//软件延时测试
void main()
{
IO_INIT();
IR_Init();
St7735s_Init();
P26=0;
St7735s_DisplayInversion(1);
St7735s_ShowLattice(0,0,160,80,black);//tft显示点阵
while(1)
{
Timer_CntSwitch(1);
Delay15ms();
Delay15us();
Timer_CntSwitch(0);
St7735s_ShowNum(0,0,Timer_ReadCnt(),5,white,8,cover);
}
}
//外部中断测试
unsigned char x=0;
unsigned char temp=0;
void INT1_Isr(void) interrupt 2
{
if(!temp){
Timer_CntClear();//先清零0
Timer_CntSwitch(1);//开始计数
temp=1;
}
else
{
x=Timer_ReadCnt();
Timer_CntSwitch(0);
temp=0;
}
}
void Ext_Init(void)
{
IT1 = 1; //INT1(P3.3)下降沿中断
EX1 = 1; //使能INT1中断
EA=1;
IP|=0x04;
IPH|=0x04;
}
在P33外部中断1引脚产生脉冲,计时值不正确,请各位大佬能给予批评指正
x=Timer_ReadCnt();这里的x被定义成了u8型,数据被截断了,其次Timer_ReadCnt这个函数内部必须采用飞读的操作,避免读到错误的数据,因为TL0可能随时产生进位,关于飞读可以上网搜搜 Ayb_ice 发表于 2026-1-4 08:44
x=Timer_ReadCnt();这里的x被定义成了u8型,数据被截断了,其次Timer_ReadCnt这个函数内部必须采用飞读的操 ...
好的,谢谢,
我把unsigned char类型改了之后,start信号和repeat信号可以正常接收,
但是数据信号时长有误,
然后我在进入中断后直接先把定时器停止,在状态机里面再打开定时器,
所有的数据就都正常了
换方案吧,接收这些信息最好用的还是PWM定时器的输入捕获功能。{:4_168:}
页:
[1]