[新手园地] 第四批笔记之PWM调光

[复制链接]
3561|6
 楼主| hello某人 发表于 2011-11-17 20:14 | 显示全部楼层 |阅读模式
这个程序其实就是把原来下载的两个程序综合到了一起,原来两个程序分别为从串口输入数据调节占空比和按键调节点空比。现在可以同时用按键和串口控制点穴比。我把按键的功能稍微改了一下,改成按KEY2固定点空比90%,按KEY1占空比减10%。

main.c

  1. /*---------------------------------------------------------------------------------------------------------*/
  2. /* */
  3. /* Copyright(c) 2011 Nuvoton Technology Corp. All rights reserved. */
  4. /* */
  5. /*---------------------------------------------------------------------------------------------------------*/
  6. #include "includes.h" //包含所需的头文件

  7. volatile uint8_t PWM0_Duty_Cycle = 50; //PWM占空比

  8. void Init_Uart (void);
  9. void UART_INT_HANDLE(uint32_t u32IntStatus);

  10. /*****************************
  11. ** Name: UART_INT_HANDLE
  12. ** Function: UART Callback function
  13. ** Input: u32IntStatus
  14. ** OutPut: None
  15. ** Data: 2011-03-17
  16. ** Note:
  17. ****************************/
  18. void UART_INT_HANDLE(uint32_t u32IntStatus)
  19. {

  20. uint8_t bInChar[1]={0xFF};

  21. if(u32IntStatus & DRVUART_RDAINT)
  22. {
  23. /* Get all the input characters */
  24. while(UART0->ISR.RDA_IF==1)
  25. {
  26. /* Get the character from UART Buffer */
  27. DrvUART_Read(UART_PORT0,bInChar,1);

  28. if ((bInChar[0]<='9')&&(bInChar[0]>='0'))
  29. {
  30. PWM0_Duty_Cycle= (bInChar[0]-0x30)*10;
  31. printf("您输入的占空比为:%d:100.\n",PWM0_Duty_Cycle);
  32. }
  33. else
  34. printf("您的输入有误!\n");
  35. }
  36. }
  37. }
  38. void Init_Uart(void)
  39. {
  40. STR_UART_T param;
  41. /*
  42. 声明 UART设置的结构体 位于DRVUART.H
  43. 结构体如下
  44. typedef struct DRVUART_STRUCT
  45. {
  46. uint32_t u32BaudRate;
  47. E_DATABITS_SETTINS u8cDataBits;
  48. E_STOPBITS_SETTINS u8cStopBits;
  49. E_PARITY_SETTINS u8cParity;
  50. E_FIFO_SETTINGS u8cRxTriggerLevel;
  51. uint8_t u8TimeOut ;
  52. }STR_UART_T;
  53. */
  54. DrvSYS_SelectIPClockSource(E_SYS_UART_CLKSRC,0); //使能UART时钟
  55. //SYSCLK->CLKSEL1.UART_S = 0; //UART时钟源选择. 00 =外部12MHz 晶振 01 = PLL 1x =内部 22MHz 振荡器

  56. DrvGPIO_InitFunction(E_FUNC_UART0); //GPB_MFP0-1-2-3置位 GPIO使能UART功能
  57. //outpw(&SYS->GPBMFP, inpw(&SYS->GPBMFP) | (0xF<<0));

  58. param.u32BaudRate = 115200; // 波特率
  59. param.u8cDataBits = DRVUART_DATABITS_8; // 数据位
  60. param.u8cStopBits = DRVUART_STOPBITS_1; // 停止位
  61. param.u8cParity = DRVUART_PARITY_NONE; // 校验位
  62. param.u8cRxTriggerLevel = DRVUART_FIFO_1BYTES; // FIFO存储深度 1 字节
  63. param.u8TimeOut = 0; // FIFO超时设定
  64. /* Set UART Configuration */
  65. if(DrvUART_Open(UART_PORT0,¶m) != E_SUCCESS) // 串口开启、结构体整体赋值
  66. printf("UART0 open failed\n");
  67. /* u32Port -[in] UART Channel: UART_PORT0 / UART_PORT1 /UART_PORT2 */
  68. /* sParam -[in] the struct parameter to configure UART */

  69. /* Enable Interrupt and install the call back function */
  70. DrvUART_EnableInt(UART_PORT0, DRVUART_RDAINT,UART_INT_HANDLE);
  71. /*u32Port -[in] UART Channel: UART_PORT0 / UART_PORT1 / UART_PORT2 */
  72. /*u32InterruptFlag -[in] DRVUART_LININT/DRVUART_WAKEUPINT/DRVUART_BUFERRINT/DRVUART_RLSINT */
  73. /* DRVUART_MOSINT/DRVUART_THREINT/DRVUART_RDAINT/DRVUART_TOUTINT */
  74. /*pfncallback -[in] A function pointer for callback function */
  75. }

  76. /*************************************************************************************
  77. ** Function name: main
  78. ** Descriptions: Key1键按下 调整占空比,灯变亮
  79. Key2键按下 输出周期为 12M/2/(99*+1) = 60KHZ 占空比为90%
  80. ** input parameters: 无
  81. ** output parameters: 无
  82. ** Returned value: 无
  83. *************************************************************************************/
  84. int main (void)
  85. {
  86. uint8_t test = 250;
  87. uint8_t PWM0_Duty_Cycle_tmp = 50;
  88. uint16_t PWM_CNR0_tmp = 0;
  89. Set_System(); //封装一些初始化模块
  90. Init_Uart();
  91. printf("\n");
  92. printf("/*==========================\n");
  93. printf("======菜农 %d 助学计划======\n",test);
  94. printf("========NUC120助学板========\n");
  95. printf("======程序参考新唐BSP库======\n");
  96. printf("=======2010年04月09日=======\n");
  97. printf("=========PWM实验=========\n");
  98. printf("PWM基本配置如下:\n");
  99. printf("PWMA 预分频为:0x%x\n",PWMA->PPR.CP01);
  100. printf("PWMA 时钟选择寄存器:0x%x\n",PWMA->CSR.CSR0);
  101. PWM_CNR0_tmp = PWMA->CNR0;
  102. printf("PWM 计数器寄存器CNR0: 0x%x\n",PWM_CNR0_tmp);
  103. printf("PWM 比较寄存器 CMR0: 0x%x\n", PWMA->CMR0);
  104. printf("请输入0~9(占空比*10/100)调整占空比开始测试!\n");
  105. printf("==========================*/\n");

  106. while(1)
  107. {
  108. KeyCode = GetKey();
  109. switch(KeyCode)
  110. {
  111. case KEY1_DOWN_USER:
  112. {
  113. PWMA->CNR0 = 99;
  114. if(PWMA->CMR0 > 0)
  115. {
  116. PWMA->CMR0 = PWMA->CMR0 - 10;
  117. PWM0_Duty_Cycle_tmp = PWMA->CMR0;
  118. PWM0_Duty_Cycle = PWMA->CMR0;
  119. }
  120. else
  121. {
  122. PWMA->CMR0 = 90;
  123. PWM0_Duty_Cycle_tmp = PWMA->CMR0;
  124. PWM0_Duty_Cycle = PWMA->CMR0;
  125. }
  126. }
  127. break;
  128. case KEY2_DOWN_USER:
  129. {
  130. PWMA->CNR0 = 99;
  131. PWMA->CMR0 = 90;
  132. }
  133. break;
  134. default:break;
  135. }

  136. if (PWM0_Duty_Cycle_tmp!=PWM0_Duty_Cycle)
  137. {
  138. //更改CMR0 调整PWM0输出占空比
  139. PWM0_Duty_Cycle_tmp = PWM0_Duty_Cycle;
  140. if (0==PWM0_Duty_Cycle)
  141. {
  142. PWMA->CMR0 = 0;
  143. }
  144. else
  145. {
  146. PWMA->CMR0 = PWM0_Duty_Cycle;
  147. }
  148. }
  149. }
  150. }



初始化


  1. #include "includes.h"  //包含所需的头文件
  2. /*************************************************************************************
  3. ** Function name:       Set_System
  4. ** Descriptions:        封装一些初始化模块
  5. ** input parameters:    count
  6. ** output parameters:   无
  7. ** Returned value:      无
  8. *************************************************************************************/
  9. void Set_System(void)
  10. {
  11.   InitButtonVar();           //按键初始化
  12.   RCC_Configuration();       //配置系统时钟
  13.   GPIO_Configuration();      //配置GPIO
  14.   
  15.   TIMER_Configuration();     //配置TIMER
  16.   
  17.   PWM_Configuration();       //配置PWM
  18. }
  19. /*************************************************************************************
  20. ** Function name:       RCC_Configuration
  21. ** Descriptions:        系统时钟源设置
  22. ** input parameters:    none
  23. ** output parameters:   none
  24. ** Returned value:      none
  25. *************************************************************************************/
  26. void RCC_Configuration(void)
  27. {
  28.    UNLOCKREG();                    // 对写保护位操作时 需要一次向0x50000 0100写入 0x59,0x16,0x88,
  29.    DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);//与其 SYSCLK->PWRCON.XTL12M_EN = 1; 等同
  30.                                       // PWRCON寄存器(这些寄存器在上电复位到用户解锁定之前是锁定的)除了 BIT[6]位其他位都受写保护
  31.                                    // 解除这些需要向 0x50000 0100写入 0x59,0x16,0x88,
  32.               // 令PWRCON寄存器的BITP[0]为1(即设定12M外部晶振)
  33.    delay_ms(100);                     //while (DrvSYS_GetChipClockSourceStatus(E_SYS_XTL12M) != 1);//等待外部12MHZ晶振就绪
  34.    LOCKREG();                    // 向“0x5000_0100”写入任何值,就可以重锁保护寄存器
  35. }
  36. /*************************************************************************************
  37. ** Function name:       GPIO_Configuration
  38. ** Descriptions:        GPIO配置
  39. ** input parameters:    none
  40. ** output parameters:   none
  41. ** Returned value:      none
  42. *************************************************************************************/
  43. void GPIO_Configuration()
  44. {
  45.    DrvGPIO_Open( E_GPA, 2, E_IO_OUTPUT ); //led端口设置为输出
  46.    DrvGPIO_Open( E_GPA, 3, E_IO_OUTPUT );
  47.    DrvGPIO_Open( E_GPA, 4, E_IO_OUTPUT );
  48.    DrvGPIO_Open( E_GPA, 5, E_IO_OUTPUT );
  49.    DrvGPIO_ClrBit(E_GPA,2);
  50.    DrvGPIO_ClrBit(E_GPA,3);
  51.    DrvGPIO_ClrBit(E_GPA,4);
  52.    DrvGPIO_ClrBit(E_GPA,5);
  53.    DrvGPIO_Open( E_GPA, 12, E_IO_OUTPUT );//PWM01端口设置为输出
  54.    DrvGPIO_Open( E_GPB, 14, E_IO_INPUT ); //按键端口设置为输入
  55.    DrvGPIO_Open( E_GPB, 15, E_IO_INPUT );
  56. }
  57. /*************************************************************************************
  58. ** Function name:       TIMER_Configuration
  59. ** Descriptions:        TIMER配置
  60. ** input parameters:    none
  61. ** output parameters:   none
  62. ** Returned value:      none
  63. *************************************************************************************/
  64. void TIMER_Configuration()
  65. {
  66.     DrvTIMER_Init();              //初始化定时器
  67.     DrvSYS_SelectIPClockSource(E_SYS_TMR0_CLKSRC,0);      //使用外设时注意必须设置该外设的时钟    设置TIMER0的时钟源为外部12MHZ
  68. DrvTIMER_Open(E_TMR0,1000,E_PERIODIC_MODE);        //设定定时器timer0的tick周期,并且启动定时器:定时器通道 TMR0  每秒1000次  周期模式

  69. DrvTIMER_SetTimerEvent(E_TMR0,10,(TIMER_CALLBACK) Timer0_Callback,0); //安装一个10ms定时处理事件到 timer0通道
  70. DrvTIMER_EnableInt(E_TMR0);            //使能定时器中断  //TIMER0->TCSR.IE = 1
  71. DrvTIMER_Start(E_TMR0);             //定时器timer0开始计数 //TIMER0->TCSR.CEN = 1;
  72. }
  73. /*************************************************************************************
  74. ** Function name:       Timer0_Callback
  75. ** Descriptions:        定时处理事件 用来做按键扫描
  76. ** input parameters:    none
  77. ** output parameters:   none
  78. ** Returned value:      none
  79. *************************************************************************************/
  80. void Timer0_Callback (void)
  81. {
  82.      KeyPro();  //按键扫描 该函数在 button.c 中实现
  83. }
  84. /*************************************************************************************
  85. ** Function name:       PWM_Configuration
  86. ** Descriptions:        PWM配置
  87. ** input parameters:    none
  88. ** output parameters:   none
  89. ** Returned value:      none
  90. *************************************************************************************/
  91. void PWM_Configuration()
  92. {
  93.    S_DRVPWM_TIME_DATA_T sPt;
  94. /*
  95. 声明 PWM Timer设置的结构体 位于DRVPWM.H
  96. 结构体如下:
  97. typedef struct
  98. {
  99.   uint8_t   u8Mode;
  100.   uint8_t   u8HighPulseRatio;
  101.   uint8_t   u8ClockSelector;
  102.   uint8_t   u8PreScale;
  103.   uint32_t  u32Frequency;
  104.   uint32_t  u32Duty;
  105.    int32_t   i32Inverter;
  106. }S_DRVPWM_TIME_DATA_T;
  107. */

  108. /* PWM Timer property */
  109. sPt.u8Mode = DRVPWM_AUTO_RELOAD_MODE;  /*自动重载模式*/
  110. sPt.u32Frequency = 100;      /*PWM 频率 为400HZ即2500us为一周期*/
  111. sPt.u8HighPulseRatio =25;     /* 高脉冲宽度时间所占周期的百分比: 50%*/
  112. sPt.i32Inverter = 0;      /*反向关闭*/
  113. /* Enable PWM clock */
  114.     DrvPWM_Open();           //打开 PWM 时钟并且复位PWM
  115.             
  116. /* Select PWM engine clock */
  117. //DrvPWM_SelectClockSource(DRVPWM_TIMER0, DRVPWM_EXT_12M);//设置PWM 定时器0 为外部12 MHz crystal 时钟
  118. DrvSYS_SelectIPClockSource(E_SYS_PWM01_CLKSRC,0);  //使用外设时注意必须设置该外设的时钟    设置PWM01的时钟源为外部12MHZ     
  119. /* Set PWM Timer0 Configuration */
  120. DrvPWM_SetTimerClk(DRVPWM_TIMER0, &sPt);    //配置PWM 定时器0的一些参数 如配置频率/脉冲/模式/逆转功能
  121. /* Enable Output for PWM Timer0 */
  122. DrvPWM_SetTimerIO(DRVPWM_TIMER0, 1);       //使能或关闭PWM定时器0对应的IO口输出使能
  123. /* Set PWM pins */
  124. DrvGPIO_InitFunction(E_FUNC_PWM01);        //指定多功能引脚 即 PA12,PA13为PWM0和PWM1
  125.                
  126. /* Enable the PWM Timer 0 */
  127. DrvPWM_Enable(DRVPWM_TIMER0, 1);      //使能/关闭PWM定时器0
  128. }
  129. /*************************************************************************************
  130. ** Function name:       delay_ms
  131. ** Descriptions:        1ms(晶振为12MHZ)延时子程序
  132. ** input parameters:    count
  133. ** output parameters:   无
  134. ** Returned value:      无
  135. *************************************************************************************/
  136. void delay_ms(uint32_t count)
  137. {
  138.     uint32_t i,j;
  139. for(i=count;i>0;i--)
  140.     for(j=2395;j>0;j--);
  141. }



工程

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
hotpower 发表于 2011-11-17 20:18 | 显示全部楼层
山寨的不错。试试用hotisp的虚拟控制台控制。
 楼主| hello某人 发表于 2011-11-17 20:20 | 显示全部楼层
本帖最后由 hello某人 于 2011-11-17 20:29 编辑

其实这个程序还有一个BUG,就是系统第一次上电时如果按KEY1,刚灯L6会熄灭,需要按一下KEY2点亮后才可以正常工作,或者一上电先按KEY2开始正常工作。找了好久没找到原因,希望哪位高人能指点一下,当然我自己也在继续查原因。
hotpower 发表于 2011-11-17 21:21 | 显示全部楼层
?不解。hotisp和其他的一样呀。有进制的区别,自己设置的。
hotpower 发表于 2011-11-17 21:34 | 显示全部楼层
图太小,看不见你的发送设置。
估计你选择每行加入回车和换行了。即多了0x0d,0x0a


按惯例发放裤子,以便参加选美。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

18

主题

298

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部