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口配置成输出的