首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > WinCE >

wince上6410用定时中断模拟PWM

2012-09-03 
wince下6410用定时中断模拟PWM大家好!本人现在在wince下6410用定时中断模拟PWM,因为6410的两路PWM被蜂鸣器

wince下6410用定时中断模拟PWM
大家好!本人现在在wince下6410用定时中断模拟PWM,因为6410的两路PWM被蜂鸣器和lcd占用了。我也不太了解工作的原理,就参照网上的程序写了中断部分,但是现在IO口没有电压输出,麻烦各位帮忙看下问题出在哪,谢谢!

//定时器监视线程
DWORD WINAPI TimerThread(LPVOID lpParameter)
{
DWORD dwRes = 0;
BOOL bRes = 1;
WCHAR str[255];
memset(str, 0, 255*2);
while (bTimerThreadRun)
{
 
dwRes = WaitForSingleObject(hTimerEvent, 5000);
InterruptDone(dwSysIntr);
if (dwRes != WAIT_OBJECT_0)
{
MessageBox(NULL,_T("Wait timer event failed."), NULL, MB_OK);
return 0;
}
else
{
//MessageBox(NULL,_T("Wait timer event ok."), NULL, MB_OK);
if (bRes)
{
GpioUp();
}
else
{
GpioDown();
}
bRes = !bRes;
}
}
return 0;
}

//将GPIO拉高
void GpioUp()
{
v_pGPIORegs->GPKDAT|= 0x01 << 0;
}
//拉低GPIO
void GpioDown()
{
v_pGPIORegs->GPKDAT&= ~(0x01 << 0);
}
//定时器寄存器的初始化
BOOL InitTimer()
{
DWORD dwIrq = IRQ_TIMER1;
BOOL bRes;
 
//获取逻辑中断号
bRes = KernelIoControl( IOCTL_HAL_REQUEST_SYSINTR,
&dwIrq,
sizeof( dwIrq ),
&dwSysIntr,
sizeof( dwSysIntr ),
NULL );
if (!bRes)
{
RETAILMSG(1,(TEXT("Get system interrupt failed. \n")));
return FALSE;
}
hTimerEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
bRes = InterruptInitialize(dwSysIntr,hTimerEvent,NULL,0); //edit for 5.0
if (bRes)
{
RETAILMSG(1,(TEXT("Init interrupt ok! \n")));
}
else
{
RETAILMSG(1,(TEXT("Init interrupt failed! \n")));
return FALSE;
}

//配置定时器寄存器
BOOLRetValue = TRUE;
PHYSICAL_ADDRESS ioPhysicalBase = {0,0};
ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_PWM;
v_pPWMRegs = (volatile S3C6410_PWM_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_PWM_REG), FALSE);
//设置timer1为1/8分频,[7:4]=0x0010
v_pPWMRegs->TCFG1 &= ~(0x01 << 4);
v_pPWMRegs->TCFG1 |= 0x01 << 5;
v_pPWMRegs->TCFG1 &= ~(0x11 << 6);
//设置timer1的控制寄存器
v_pPWMRegs->TCON |= 0x01 << 11; //auto reload
v_pPWMRegs->TCON &= ~(0x01 << 10); //output off
//pTimerReg->TCON |= 0x01 << 10; //output on
v_pPWMRegs->TCON &= ~(0x01 << 9); //manual update off
v_pPWMRegs->TCON &= ~(0x01 << 8); //timer1 stop

///////////////PCLK = 50M, prescaler = 0
//设置定时器的counter寄存器,2ms;
v_pPWMRegs->TCNTB1 = 12500;
//设置定时器的compare寄存器
v_pPWMRegs->TCMPB1 = 0;

//创建定时器中断线程
DWORD dwThreadId;
hTimerThread = CreateThread(NULL, 0, TimerThread, NULL, CREATE_SUSPENDED, &dwThreadId);
return TRUE;
}

BOOL DeinitTimer()
{
CloseHandle(hTimerThread);
//MmUnmapIoSpace((void *)pTimerReg,sizeof(S3C2440A_PWM_REG));
if (hTimerEvent) CloseHandle(hTimerEvent);
InterruptDisable(dwSysIntr);
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &dwSysIntr, sizeof(UINT32), NULL ,0 ,NULL);
return TRUE;
}
void StartTimer()
{
v_pPWMRegs->TCON |= 0x01 << 9; //manual update on, load the counter
Sleep(1);
//set start bit and clear manual update bit
v_pPWMRegs->TCON |= 0x01 << 8;
v_pPWMRegs->TCON &= ~(0x01 << 9);
//启动线程
bTimerThreadRun = TRUE;
ResumeThread(hTimerThread);
}
void StopTimer()
{
v_pPWMRegs->TCON &= ~(0x01 << 8);
bTimerThreadRun = FALSE;
}
这部分程序放在GPIODriver里,调用的时候是在BOOL GIO_IOControl加了一个IO控制命令
  case IOCTL_MO_START:
StartTimer();
break;
麻烦大家帮忙看下问题出在哪里,谢谢!

[解决办法]
默认的GPIO口是输入的,在上面的代码里木有看到LZ把你那个GPK的IO口配置成输出的
[解决办法]
先看看中断来了么?中断不来一切都是浮云啊
[解决办法]
还不行?既然这样,建议你不要用中断和定时器,先用简单的延时控制GPIO口的高低变换,然后检测一下输出,看看是否有你想要的波形输出。等这个搞通了之后,再加上定时器来搞。

看你那个,用的是动态绑定中断,这个的话,要先申请一个中断号,然后映射中断,再绑定线程,这样才能够在触发中断后,响应到你的中断线程那边。在弄这个的时候,建议你检测一下你中断是否有产生,然后在看看你的中断是否映射成功。

如果都不行的话,那么,你可能需要修改为静态的方式来映射中断和服务线程
[解决办法]
if (dwRes != WAIT_OBJECT_0)
你试试把这个判断条件改成v_pINTRregs->INTMSK & (1<<IRQ_TIMER1)

热点排行