S5PC100的pwm的背光控制

Topic:S5PC100的pwm的背光控制(作者:Baiduluckyboy)
//------------------------------------------------------------------------------------------------------------------------------

// Topic:S5PC100的pwm的背光控制(作者:Baiduluckyboy)

// 作者:Baiduluckyboy(wangyuluyulu@126.com

// 论坛账号:Baiduluckyboy (经常在CSDN出没)

// 版权:解放军电子工程学院Baiduluckyboy(wangyuluyulu@126.com

// 平台:wince6.0.0 S5PC100 BSP

// 发布日期:2010-09-08

// 最后修改:

// 注意事项:未经作者同意,商业网站不能转载,并且不得在转载的时候擅自修改、删除文章的任何部分

//------------------------------------------------------------------------------------------------------------------------------


/****************************************Copyright (c)**************************************************
**--------------File Info-------------------------------------------------------------------------------
** File Name:     pwm.c
** Last modified Date:           2010-7-09
** Last Version:   V1.0  
** Description:    S5PC100 PWM 驱动
**                                      This driver uses PWM with Timer0 or Timer1, the ouput is TOUT0 or TOUT1
**------------------------------------------------------------------------------------------------------
** Created By:     muscle boy
** Created date:    2010-7-09
** Version:     V1.0
** Descriptions:   The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/
#include <windows.h>
#include <ceddk.h>
#include <s5pc100.h>
#include <backlight_pdd.h>

#define PRIVATE   static
#define PUBLIC
#define IOCTL_PWM_SET_PRESCALER         1
#define IOCTL_PWM_SET_DIVIDER           2
#define IOCTL_PWM_START              3
#define IOCTL_PWM_GET_FREQUENCY         4
///LED
#define SMDKC100_LED2   GPH14_Output
#define SMDKC100_LED3   GPH15_Output
#define SMDKC100_LED4   GPH16_Output
#define SMDKC100_LED5   GPH17_Output

/* GPIO,PWM 寄存器对应的虚拟地址 */
PRIVATE volatile S5PC100_GPIO_REG * v_GPIOregs;
PRIVATE volatile S5PC100_PWM_REG * v_PWMregs;
PRIVATE DWORD  g_OpenCount = 0;
void PWM_SetPrescaler(BYTE t_num, BYTE value);
BOOL PWM_SetDivider(BYTE t_num, BYTE value);
/muscle boy
/*******************************************************************************************
函数名称: PWM_ConfigPin
描    述: 初始化 GPB0 为 TOUT0 功能
输入参数: DWORD t_num: 定时器编号: 0 或 1 
输出参数: 无
返    回: 无
********************************************************************************************/
PRIVATE void PWM_ConfigPin(DWORD t_num)//ok
{
    if (t_num == 0)
    {
        // TOUT0口设置
       Set_PinData(v_GPIOregs, GPD00_TOUT_0,1);
    Set_PinFunction(v_GPIOregs,GPD00_TOUT_0);
 
    }
    else if (t_num == 1)
    {
        // TOUT1口设置
      Set_PinData(v_GPIOregs, GPD01_TOUT_1,1);
   Set_PinFunction(v_GPIOregs,GPD01_TOUT_1);
    }
}
/*******************************************************************************************
函数名称: PWM_ConfigPWMDefault
描    述: 恢复 PWM0 和 PWM1 的硬件为默认值
输入参数: DWORD t_num: 定时器编号: 0 或 1 
输出参数: 无
返    回: 无
********************************************************************************************/
PRIVATE void PWM_ConfigPWMDefault(DWORD t_num)//OK
{
 if (t_num == 0)
 {
  // TOUT0口设置
  v_GPIOregs->GPDCON &= ~(0x03 << 0);           // rGPBCON[1:0] = 00b,设置GPD0 为输入GPIO
  v_GPIOregs->GPDPUD &= ~(0x1 << 0);               // 上拉
  v_PWMregs->TCFG0 &= ~0xFF;     // Timer0 预分频恢复为0
  v_PWMregs->TCFG1 &= ~0x0F;     // MUX0
  v_PWMregs->TCON &= ~0x1F;     // Timer0 TCON
  v_PWMregs->TCNTB0 = 0;       // 定时值(PWM周期)      
        v_PWMregs->TCMPB0 = 0;       // 设置PWM占空比
 }
 if (t_num == 1)
 {
  // TOUT1口设置
  v_GPIOregs->GPBCON &= ~(0x03 << 2);           // rGPBCON[1:0] = 00b,设置GPB1 为输入GPIO
  v_GPIOregs->GPDPUD &= ~(0x1 << 1);                        // 上拉   

  v_PWMregs->TCFG0 &= ~0xFF;     // Timer1 预分频恢复为0
  v_PWMregs->TCFG1 &= ~(0x0F << 4);           // MUX1

  v_PWMregs->TCON &= ~(0xF << 8);            // Timer1 TCON
  v_PWMregs->TCNTB1 = 0;       // 定时值(PWM周期)      
        v_PWMregs->TCMPB1 = 0;       // 设置PWM占空比 
 }


/*******************************************************************************************
函数名称: PWM_InitializeAddresses
描    述: 取得相关寄存器的虚拟地址
输入参数: 无 
输出参数: 无
返    回: > 0 分配到的虚拟地址;  FALSE: 失败 
********************************************************************************************/
 BOOL PWM_InitializeAddresses(void)//OK
{
  BOOL bRet = TRUE;
    PHYSICAL_ADDRESS    ioPhysicalBase = {0,0};
    ioPhysicalBase.LowPart = S5PC100_BASE_REG_PA_GPIO;
    v_GPIOregs = (volatile S5PC100_GPIO_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S5PC100_GPIO_REG), FALSE);
    if (v_GPIOregs == NULL)
    {
       // RETAILMSG(1, (TEXT("[BKL_PDD] v_pGPIORegs MmMapIoSpace() Failed /n/r")));
        return FALSE;
    }
    ioPhysicalBase.LowPart = S5PC100_BASE_REG_PA_PWM;
    v_PWMregs = (volatile S5PC100_PWM_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S5PC100_PWM_REG), FALSE);
    if (v_PWMregs == NULL)
    {
     // RETAILMSG(1, (TEXT("[BKL_PDD] v_pPWMRegs MmMapIoSpace() Failed /n/r")));
      return FALSE;
    }
    if (v_GPIOregs)
    {
      v_GPIOregs->GPDPUD = v_GPIOregs->GPDPUD&(~(3<<0)); //GPD0 Pull-up/down disabled
    }
 return TRUE;
}
/*******************************************************************************************
函数名称: PWM_SetPrescaler
描    述: 设置定时器 0 和 1 的预分频值
输入参数: BYTE t_num: 定时器编号: 0 或 1
          BYTE value: 预分频值, 值从 0 ~ 255
输出参数: 无
返    回: 无
********************************************************************************************/
void PWM_SetPrescaler(BYTE t_num, BYTE value)//OK  PWM_SetPrescaler(0, PWM0_1_PRESCALER)
{
 if ((t_num == 0) || (t_num == 1))
    {
     v_PWMregs->TCFG0 &= ~0xFF;
        v_PWMregs->TCFG0 |= (value<<0);      // 设置定时器 0,1 的预分频值 
    }
}

/*******************************************************************************************
函数名称: PWM_SetDivider
描    述: 设置定时器 0 和 1 的分频器分频值
输入参数: BYTE t_num: 定时器编号: 0 或 1
          BYTE value: 分频值: 2,4,8,16
输出参数: 无
返    回: TRUE: 成功;  FALSE: 失败
********************************************************************************************/
BOOL PWM_SetDivider(BYTE t_num, BYTE value)//OK  PWM_SetDivider(0, 2)
{
 BYTE tmp;
   
    if ((t_num > 1) || (value > 16))   
        return FALSE;
  
    for (tmp = 0; tmp < 4; tmp++)
    {
        if ((2 << tmp) == value)
            break;
    }  
   
    if (tmp > 4)                   
        return FALSE;                               // value 取值只能为 2,4,8,16
 
    if (t_num == 0)
    {
        v_PWMregs->TCFG1 &= ~0x0F;
        v_PWMregs->TCFG1 |= tmp;
    }
    else
    {
        v_PWMregs->TCFG1 &= ~(0x0F << 4);
        v_PWMregs->TCFG1 |= (tmp << 4);  
    }
    return TRUE;
}
/*******************************************************************************************
函数名称: PWM_StartPWM
描    述: 设置定时器 0 或 1 的周期和占空比, 并启动 pwm
输入参数: DWORD t_num: 定时器编号: 0 或 1
          DWORD cycle: 取值为 0 ~ 65535
          DWORD duty : 取值为 0 ~ 63535
输出参数: 无
返    回: TRUE: 成功;  FALSE: 失败
注    意: 占空比为 duty / cycle
********************************************************************************************/
BOOL PWM_StartPWM(DWORD t_num, DWORD cycle, DWORD duty)//OK  PWM_StartPWM(0, 100, 50)
{
 DWORD tmp;
    if ((cycle > 65535)||(duty > 65535))
 {
        return FALSE;
 }
    if ((duty > cycle)||(t_num > 1))
 {
  return FALSE;
 }
      if (t_num == 0)
     {
         PWM_ConfigPin(0);
   PWM_SetPrescaler(0, PWM0_1_PRESCALER);
         PWM_SetDivider(0, 2);
         v_PWMregs->TCNTB0 = cycle & 0xFFFF;      // 定时值(PWM周期)      
         v_PWMregs->TCMPB0 = duty & 0xFFFF;   // 设置PWM占空比
         v_PWMregs->TCON &= ~0x1f;//TCON[8:11]清零(包括停止定时器)
         v_PWMregs->TCON |= 0xF;//启用手动更新,立刻把TCNTB寄存器数值载入TCNT
         v_PWMregs->TCON &=~0x2;//启用手动更新,立刻把TCNTB寄存器数值载入TCNT
   }
   else
   {  
        PWM_ConfigPin(1);  
        v_PWMregs->TCNTB1 = cycle & 0xFFFF;     // 定时值(PWM周期) 
        v_PWMregs->TCMPB1 = duty & 0xFFFF;     // 设置PWM占空比
  v_PWMregs->TCON &= ~0xf;//TCON[8:11]清零(包括停止定时器)
        v_PWMregs->TCON |= 0xF;//启用手动更新,立刻把TCNTB寄存器数值载入TCNT
        v_PWMregs->TCON &=~0x2;//启用手动更新,立刻把TCNTB寄存器数值载入TCNT
   }
    return TRUE;
}
/*******************************************************************************************
函数名称: PWM_Init
描    述: 驱动程序初始化函数
输入参数: DWORD dwContext: 设备管理器传递给本驱动的参数, 通常为流接口驱动在注册表内的位置  
输出参数: 无
返    回: 驱动程序句柄
*******************************************************************************************/
PUBLIC DWORD BKL_Init(DWORD dwContext)
{
 
 PWM_InitializeAddresses(); 
   // RETAILMSG(1, (TEXT("::: PWM_Init Sucessfully. /r/n")));
 PWM_StartPWM(0, 5000, 2500);
    //Set_PinFunction(v_GPIOregs,SMDKC100_LED2); //LED OUTPUT
    return (DWORD)1;
}
/*******************************************************************************************
函数名称: DllEntry
描    述: 驱动程序动态库入口
输入参数:  
输出参数:
返    回:
*******************************************************************************************/
PUBLIC BOOL WINAPI
DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
    switch ( dwReason )
    {
 case DLL_PROCESS_ATTACH:
      RETAILMSG(0, (TEXT("PWM: DLL_PROCESS_ATTACH/r/n")));
      DisableThreadLibraryCalls((HMODULE) hInstDll);
      break;
         case DLL_PROCESS_DETACH:
      RETAILMSG(1, (TEXT("PWM: DLL_PROCESS_DETACH/r/n")));
      break;
    }   
    return (TRUE);
}
/*******************************************************************************************
函数名称: PWM_Close
描    述: 驱动程序关闭函数
输入参数: DWORD Handle:  驱动程序引用事例句柄
输出参数: 无
返    回: FALSE: 失败    TRUE: 成功
*******************************************************************************************/
BOOL BKL_Close(DWORD Handle)
{
 
 if (g_OpenCount > 0)
 {
  PWM_ConfigPWMDefault(0);  
  PWM_ConfigPWMDefault(1);
 }
     g_OpenCount = 0;
     return TRUE;
}
/*******************************************************************************************
函数名称: PWM_Deinit
描    述: 驱动程序卸载函数
输入参数: DWORD dwContext: 驱动程序句柄
输出参数: 无
返    回: FALSE: 失败    TRUE: 成功
*******************************************************************************************/
BOOL BKL_Deinit(DWORD dwContext)
{
 PWM_ConfigPWMDefault(0);       /* 恢复 PWM 相关硬件为默认值 */
 PWM_ConfigPWMDefault(1);   
    // 释放申请的虚拟空间
 if (v_GPIOregs)
    VirtualFree((PVOID) v_GPIOregs, 0, MEM_RELEASE);
 if (v_PWMregs)
    VirtualFree((PVOID) v_PWMregs, 0, MEM_RELEASE);
 return TRUE;
}// PWM_Deinit
/*******************************************************************************************
函数名称: PWM_Open
描    述: 打开驱动程序
输入参数: DWORD dwData     : 设备驱动程序句柄
          DWORD dwAccess   : 访问请求代码,是读和写的组合
          DWORD dwShareMode: 共享模式 
输出参数:
返    回: 驱动程序引用事例句柄
*******************************************************************************************/
DWORD BKL_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
{
 if (g_OpenCount > 0)
 return 0;
 PWM_ConfigPWMDefault(0);    /* 恢复 PWM 相关硬件为默认值 */
 PWM_ConfigPWMDefault(1);
 g_OpenCount++;
    return g_OpenCount;
}
/*******************************************************************************************
函数名称: PWM_IOControl
描    述: 驱动程序 I/O 请求
输入参数:
输出参数:
返    回: TRUE: 成功   FALSE: 失败
*******************************************************************************************/
BOOL
BKL_IOControl(
    DWORD Handle,
    DWORD dwIoControlCode,
    PBYTE pInBuf,
    DWORD nInBufSize,
    PBYTE pOutBuf,
    DWORD nOutBufSize,
    PDWORD pBytesReturned
    )
{
 BOOL bErr = FALSE; 
  
 switch (dwIoControlCode)
 {
           case IOCTL_PWM_SET_PRESCALER:     /* 设置预分频值 */
      PWM_StartPWM(0, 5000, 2500);
      bErr = TRUE;
      Set_PinData(v_GPIOregs, SMDKC100_LED2, 1);//LED DENG
      RETAILMSG(1, (TEXT("PWM: IOCTL_PWM_SET_PRESCALER/r/n")));
    break;
    case IOCTL_PWM_SET_DIVIDER:
       break;
    case IOCTL_PWM_START:
        PWM_StartPWM(0, 5000, 2000);
     bErr = TRUE; 
     Set_PinData(v_GPIOregs, SMDKC100_LED2, 0);//LED DENG
     RETAILMSG(1, (TEXT("PWM: IOCTL_PWM_START/r/n")));
  break;
  case IOCTL_PWM_GET_FREQUENCY:
  break;  
  default:
  break;
 }
 
    return bErr;
}  
// PWM_IOControl
/*******************************************************************************************
函数名称: PWM_Read
描    述: 从 IIC 从机读取数据
输入参数: DWORD Handle    : 驱动程序引用事例句柄
          LPVOID pBuffer  : 接收缓冲区
          DWORD dwNumBytes: 要读的字节数
输出参数: 无
返    回: 实际读到字节数
*******************************************************************************************/
DWORD BKL_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes)
{
 return 0;
}


/*******************************************************************************************
函数名称: PWM_Write
描    述: 向 IIC 从机发送数据
输入参数:
输出参数:
返    回: 成功发送的字节数
*******************************************************************************************/
DWORD BKL_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes)
{
 return 0;
}


/*******************************************************************************************
函数名称: PWM_Seek
描    述: 对设备的数据指针进行操作,本驱动不支持该函数
输入参数:
输出参数:
返    回:
*******************************************************************************************/
DWORD BKL_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod)
{
 return 0;
}


/*******************************************************************************************
函数名称: pwm_PowerUp
描    述: 电源上电驱动处理函数
输入参数:
输出参数:
返    回: 无
*******************************************************************************************/
void BKL_PowerUp(void)
{
 return;
}


/*******************************************************************************************
函数名称: pwm_PowerDown
描    述: 电源下电驱动处理函数
输入参数:
输出参数:
返    回: 无
*******************************************************************************************/
void BKL_PowerDown(void)
{
 return;
}
                        

以上是我的pwm控制的驱动程序,经过自己测试已经通过,主要是通过在按键中断里面根据按键按下的长短来产生不同的PWM占空比,进行背光的控制。

如有不妥之处,请各位同仁指正,愿我们共同交流,共同进步。请给我留言。。。。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值