微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > TI蓝牙设计交流 > CC2541 定时器1不能产生中断

CC2541 定时器1不能产生中断

时间:10-02 整理:3721RD 点击:

今天想要在CC2541上写个外红发射程序,因为要加到BLE中,所以就用定时器1和定时器3配置产生外红信号,考虑到准确性,还用到了DMA通道。

代码基于BLE协议栈的HIDAdvRemote例程,实际上也没用到BLE和OSAL。

思路如下:

初始化:首先使用定时器3比较输出一个38K载波信号(datasheet中有描述)。在使用定时器1的updown模式,置定时器1的通道1为比较输出模式,产生一个前导位。使能定时器1中断。

在等待定时器1产生updown模式的中断。

定时器中断中:在前导位的结束时,产生定时器1的中断,在定时器1的中断中使能DMA,使用DMA来修改定时器1的通道0的比较值,用于改变一个BIT的时间长短。再配置定时器1的通道1为比较输出模式,定时器1为Modulo,在关闭定时器中断。

等待DMA完成中断。

在DMA中断中:关闭定时器1,和3,关闭外红模式,设置定时器1,为updown模式,使能定时器1中断。设置好外红剩余的等待时间,等待中断。

到了这里就出问题了。

设置好定时器1后,就产生不了定时器1的中断。(EA和定时器1中断都已使能!)

下面看下代码。

#include "hal_types.h"
#include "hal_drivers.h"

#include "hal_dma.h"
#include "hal_mcu.h"

#define IR_USERCODE1_OFFSET 0
#define IR_USERCODE2_OFFSET (IR_USERCODE1_OFFSET + 8)
#define IR_DATA1_OFFSET (IR_USERCODE2_OFFSET + 8)
#define IR_DATA2_OFFSET (IR_DATA1_OFFSET + 8)


extern halDMADesc_t dmaCh1234[4];

const unsigned short IR_BIT_TIME[2] = { 46, 84 };//定时器1通道0的发送IR0和1的时寄存器值
const unsigned short IR_BIT_SENDTIME[2] = { 1125, 2250};
unsigned short IR_TIME_BUF[32];

unsigned long IR_TotalTick = 108000;//us
unsigned long IR_HadSendTick = 0;
unsigned long IR_NeedSendTick = 0;

void IR_WrtieByteToBuf(unsigned char Data, unsigned short* IR_Buf)
{
unsigned char i;
unsigned char bit = 1;
unsigned char temp = 0;
for(i=0; i<8; i++)
{
temp = (Data&bit)?1:0;
IR_HadSendTick += IR_BIT_SENDTIME[temp];
IR_Buf[i] = IR_BIT_TIME[temp];
bit <<= 1;
}
}

void IR_SendDataWriteBuf(unsigned char UserCode1, unsigned char UserCode2, unsigned char IR_Data)
{
IR_WrtieByteToBuf(UserCode1, IR_TIME_BUF + IR_USERCODE1_OFFSET);
IR_WrtieByteToBuf(UserCode2, IR_TIME_BUF + IR_USERCODE2_OFFSET);
IR_WrtieByteToBuf(IR_Data, IR_TIME_BUF + IR_DATA1_OFFSET);
IR_WrtieByteToBuf(~IR_Data, IR_TIME_BUF + IR_DATA2_OFFSET);
}

unsigned char Timer1_Irq_statue;

void DMA_CH1_Irq(void)
{
//DMA完成中断
IRCTL = 0x00;//关闭红外
T3CCTL0 = 0x40;
T3CTL = 0x00;//关闭载波

T1STAT = 0x00;
TIMIF = 0x00;
T1CCTL1 = 0x40;
T1CTL = 0x00;
T1IF = 0;//如果加了这句话,就产生不了中断,但是如果不加,则定时器1马上产生中断!
//IR发送在32M时最大需要发送54000us,小于65535
IR_NeedSendTick = IR_NeedSendTick>>1;//采用up down模式

T1CC0L = (unsigned char)IR_NeedSendTick;
T1CC0H = IR_NeedSendTick>>8;

Timer1_Irq_statue = 2;
T1IE = 1;
T1CTL = 0x0B;
}

void Timer1_Irq_Fun(void);

HAL_ISR_FUNCTION( Timer1_Irq, T1_VECTOR )
{
HAL_ENTER_ISR();
Timer1_Irq_Fun();
T1IF = 0;
T1STAT = 0;
HAL_EXIT_ISR();
return;
}

void Timer1_Irq_Fun(void)
{
switch(Timer1_Irq_statue)
{
case 0://引导码结束中断
if(!(T1STAT&0x20))
{

return ;
}
T1CNTL = 0;
T1CCTL1 = 0;

DMAARM |= 0x02;//DMA使能
T1IE = 0;//取消中断,等待数据段发送完成

T1CC0L = IR_TIME_BUF[0];//84,46
T1CC0H = IR_TIME_BUF[0]>>8;

T1CC1L = 21;//21
T1CC1H = 0;

T1CCTL1 = 0x64;
T1CCTL1 = 0x7C; //比较输出模式100
T1CTL = 0x02;//00001110
break;
case 2: //计算剩余时间结束
Timer1_Irq_statue = 0;//跑不到这里
T1CTL = 0x00;
T1CCTL1 = 0x00;
T1STAT = 0x00;
T1IE = 0;
P0SEL &= ~BV(3);
P0DIR &= ~BV(3);
P0 &= ~BV(3);
break;
}
}

int main(void)
{
HAL_BOARD_INIT();
osal_int_disable( INTS_ALL );

P0SEL |= BV(3);
P0DIR |= BV(3);
PERCFG = 0x33;

IR_HadSendTick = 0;

IR_SendDataWriteBuf(0x0E,0x0E,0xAA);
IR_NeedSendTick = IR_TotalTick - IR_HadSendTick - 9000 + ((IR_TIME_BUF[31] == IR_BIT_TIME[0])?565:1690);

dmaCh1234[0].srcAddrH = (unsigned short)IR_TIME_BUF>>8;
dmaCh1234[0].srcAddrL = (unsigned short)IR_TIME_BUF;
dmaCh1234[0].dstAddrH = 0x62;
dmaCh1234[0].dstAddrL = 0xA6;
dmaCh1234[0].xferLenV = 0x20;
dmaCh1234[0].xferLenL = 32;
dmaCh1234[0].ctrlA = 0x83;
dmaCh1234[0].ctrlB = 0x49;

HalDmaInit();

Timer1_Irq_statue = 0;

//38K载波
T3CTL = 0x46;//Tickfrequency/4,Overflow Interrupt is disabled,Modulo,CLR
T3CC0 = 211;
T3CCTL1 = 0x64;//Channel 1 interrupt is enabled, Clear output on compare-up,Compare mode,No capture
T3CC1 = 70;
T3CTL = 0x52;//01010010


IRCTL = 0x01;
T1IF = 0;
T1IE = 1;
T1CNTL = 0;
T1CCTL1 = 0;


T1CC0L = 254;//84,46
T1CC0H = 0;

T1CC1L = 169;//21,224
T1CC1H = 0;

T1CCTL1 = 0x5C;

T1CCTL1 = 0x7C;
T1CTL = 0x03;//使用updown模式产生前导位

HAL_ENABLE_INTERRUPTS();
while(1);
}

如下代码是time1 PWM定时器中断配置,供参考
T1CTL = 0x0A; // Div = 32, CLR, MODE = module ;PWM = 2.04MS
T1CCTL1 = 0x24; // IM = 0; CMP = Clear output on compare; Mode = Compare
T1CNTL = 0; // Reset timer to 0;
T1CNTH = 0; // Reset timer to 0;

//必须设置,否则定时器不工作
T1CCTL0 = 0x64; // IM = 1, CMP = Clear output on compare; Mode = Compare

T1CC0H = (0xff>>SFT_LBIT); // Ticks = 375 (2.4ms)
T1CC0L = (uint8)((0xff<<SFT_RBIT)); // Ticks = 375 (2.4ms)


IEN1 |= 0x26; // Enable T1 cpu interrupt
IEN0 |= 0x80;

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top