找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2499|回复: 0
收起左侧

stc单片机PCA源码

[复制链接]
ID:293608 发表于 2018-4-5 00:06 | 显示全部楼层 |阅读模式

  1. /*************        功能说明        **************

  2. 输出3路9~16位变化的PWM信号。类似"呼吸灯"的驱动.

  3. PWM频率 = MAIN_Fosc / PWM_DUTY, 假设 MAIN_Fosc = 24MHZ, PWM_DUTY = 6000, 则输出PWM频率为4000HZ.

  4. ******************************************/

  5. #include        "PCA.h"

  6. bit                B_Capture0,B_Capture1,B_Capture2;
  7. u8                PCA0_mode,PCA1_mode,PCA2_mode;
  8. u16                CCAP0_tmp,PCA_Timer0;
  9. u16                CCAP1_tmp,PCA_Timer1;
  10. u16                CCAP2_tmp,PCA_Timer2;

  11. /*************        功能说明        **************


  12. ******************************************/

  13. u16        PWM0_low;        //PWM输出低电平的PCA时钟脉冲个数, 用户层不可见。
  14. u16        PWM1_low;        //PWM输出低电平的PCA时钟脉冲个数, 用户层不可见。
  15. u16        PWM2_low;        //PWM输出低电平的PCA时钟脉冲个数, 用户层不可见。


  16. //========================================================================
  17. // 函数: void PWMn_Update(u8 PCA_id, u16 high)
  18. // 描述: 更新占空比数据。
  19. // 参数: high:         占空比数据,即PWM输出高电平的PCA时钟脉冲个数。
  20. // 返回: 无
  21. // 版本: VER1.0
  22. // 日期: 2013-5-15
  23. // 备注:
  24. //========================================================================
  25. void PWMn_Update(u8 PCA_id, u16 high)
  26. {
  27.         if(PCA_id == PCA0)
  28.         {
  29.                 if(high > PWM_HIGH_MAX)        high = PWM_HIGH_MAX;        //如果写入大于最大占空比数据,强制为最大占空比。
  30.                 if(high < PWM_HIGH_MIN)        high = PWM_HIGH_MIN;        //如果写入小于最小占空比数据,强制为最小占空比。
  31.                 CR = 0;                                                        //停止PCA。
  32.                 PCA_Timer0 = high;                                //数据在正确范围,则装入占空比寄存器。
  33.                 PWM0_low = PWM_DUTY - high;        //计算并保存PWM输出低电平的PCA时钟脉冲个数。
  34.                 CR = 1;                                                        //启动PCA。
  35.         }
  36.         else if(PCA_id == PCA1)
  37.         {//        high=high+250; //左后电机较慢
  38.                 if(high > PWM_HIGH_MAX)        high = PWM_HIGH_MAX;        //如果写入大于最大占空比数据,强制为最大占空比。
  39.                 if(high < PWM_HIGH_MIN)        high = PWM_HIGH_MIN;        //如果写入小于最小占空比数据,强制为最小占空比。
  40.                 CR = 0;                                                        //停止PCA。
  41.                 PCA_Timer1 = high;                                //数据在正确范围,则装入占空比寄存器。
  42.                 PWM1_low = PWM_DUTY - high;        //计算并保存PWM输出低电平的PCA时钟脉冲个数。
  43.                 CR = 1;                                                        //启动PCA。
  44.         }
  45.         else if(PCA_id == PCA2)
  46.         {
  47.                 if(high > PWM_HIGH_MAX)                high = PWM_HIGH_MAX;        //如果写入大于最大占空比数据,强制为最大占空比。
  48.                 if(high < PWM_HIGH_MIN)                high = PWM_HIGH_MIN;        //如果写入小于最小占空比数据,强制为最小占空比。
  49.                 CR = 0;                                                        //停止PCA。
  50.                 PCA_Timer2 = high;                                //数据在正确范围,则装入占空比寄存器。
  51.                 PWM2_low = PWM_DUTY - high;        //计算并保存PWM输出低电平的PCA时钟脉冲个数。
  52.                 CR = 1;                                                        //启动PCA。
  53.         }
  54. }



  55. //========================================================================
  56. // 函数: void UpdatePwm(u8 PCA_id, u8 pwm_value)
  57. // 描述: 更新PWM值.
  58. // 参数: PCA_id: PCA序号. 取值 PCA0,PCA1,PCA2,PCA_Counter
  59. //                 pwm_value: pwm值, 这个值是输出低电平的时间.
  60. // 返回: none.
  61. // 版本: V1.0, 2012-11-22
  62. //========================================================================
  63. /*
  64. void        UpdatePwm(u8 PCA_id, u8 pwm_value)
  65. {
  66.         if(PCA_id == PCA0)                CCAP0H = pwm_value;
  67.         else if(PCA_id == PCA1)        CCAP1H = pwm_value;
  68.         else if(PCA_id == PCA2)        CCAP2H = pwm_value;
  69. }
  70. */

  71. //========================================================================
  72. // 函数: void        PCA_Init(PCA_id, PCA_InitTypeDef *PCAx)
  73. // 描述: PCA初始化程序.
  74. // 参数: PCA_id: PCA序号. 取值 PCA0,PCA1,PCA2,PCA_Counter
  75. //                 PCAx: 结构参数,请参考PCA.h里的定义.
  76. // 返回: none.
  77. // 版本: V1.0, 2012-11-22
  78. //========================================================================
  79. void        PCA_Init(u8 PCA_id, PCA_InitTypeDef *PCAx)
  80. {
  81.         if(PCA_id > PCA_Counter)        return;                //id错误

  82.         if(PCA_id == PCA_Counter)                        //设置公用Counter
  83.         {
  84.                 CR = 0;
  85.                 CH = 0;
  86.                 CL = 0;
  87.                 AUXR1 = (AUXR1 & ~(3<<4)) | PCAx->PCA_IoUse;                        //切换IO口
  88.                 CMOD  = (CMOD  & ~(7<<1)) | PCAx->PCA_Clock;                        //选择时钟源
  89.                 CMOD  = (CMOD  & ~1) | (PCAx->PCA_Interrupt_Mode & 1);        //ECF
  90.                 if(PCAx->PCA_Polity == PolityHigh)                PPCA = 1;        //高优先级中断
  91.                 else                                                                        PPCA = 0;        //低优先级中断
  92.                 if(PCAx->PCA_RUN == ENABLE)        CR = 1;
  93.                 return;
  94.         }

  95.         PCAx->PCA_Interrupt_Mode &= (3<<4) + 1;
  96.         if(PCAx->PCA_Mode >= PCA_Mode_SoftTimer)        PCAx->PCA_Interrupt_Mode &= ~(3<<4);

  97.         if(PCA_id == PCA0)
  98.         {
  99.                 CCAPM0    = PCAx->PCA_Mode | PCAx->PCA_Interrupt_Mode;        //工作模式, 中断模式
  100.                 PCA_PWM0  = (PCA_PWM0 & ~(3<<6)) | PCAx->PCA_PWM_Wide;        //PWM宽度

  101.                 PCA_Timer0 = PCAx->PCA_Value;
  102.                 B_Capture0 = 0;
  103.                 PCA0_mode = PCAx->PCA_Mode;
  104.                 CCAP0_tmp = PCA_Timer0;
  105.                 CCAP0L = (u8)CCAP0_tmp;                        //将影射寄存器写入捕获寄存器,先写CCAP0L
  106.                 CCAP0H = (u8)(CCAP0_tmp >> 8);        //后写CCAP0H
  107.         }
  108.         if(PCA_id == PCA1)
  109.         {
  110.                 CCAPM1    = PCAx->PCA_Mode | PCAx->PCA_Interrupt_Mode;
  111.                 PCA_PWM1  = (PCA_PWM1 & ~(3<<6)) | PCAx->PCA_PWM_Wide;

  112.                 PCA_Timer1 = PCAx->PCA_Value;
  113.                 B_Capture1 = 0;
  114.                 PCA1_mode = PCAx->PCA_Mode;
  115.                 CCAP1_tmp = PCA_Timer1;
  116.                 CCAP1L = (u8)CCAP1_tmp;                        //将影射寄存器写入捕获寄存器,先写CCAP0L
  117.                 CCAP1H = (u8)(CCAP1_tmp >> 8);        //后写CCAP0H
  118.         }
  119.         if(PCA_id == PCA2)
  120.         {
  121.                 CCAPM2    = PCAx->PCA_Mode | PCAx->PCA_Interrupt_Mode;
  122.                 PCA_PWM2  = (PCA_PWM2 & ~(3<<6)) | PCAx->PCA_PWM_Wide;

  123.                 PCA_Timer2 = PCAx->PCA_Value;
  124.                 B_Capture2 = 0;
  125.                 PCA2_mode = PCAx->PCA_Mode;
  126.                 CCAP2_tmp = PCA_Timer2;
  127.                 CCAP2L = (u8)CCAP2_tmp;                        //将影射寄存器写入捕获寄存器,先写CCAP0L
  128.                 CCAP2H = (u8)(CCAP2_tmp >> 8);        //后写CCAP0H
  129.         }
  130. }


  131. //========================================================================
  132. // 函数: void        PCA_Handler (void) interrupt PCA_VECTOR
  133. // 描述: PCA中断处理程序.
  134. // 参数: None
  135. // 返回: none.
  136. // 版本: V1.0, 2012-11-22
  137. //========================================================================
  138. void        PCA_Handler (void) interrupt PCA_VECTOR
  139. {
  140.         if(CCF0)                //PCA模块0中断
  141.         {
  142.                 CCF0 = 0;                //清PCA模块0中断标志
  143.                 if(P25)        CCAP0_tmp += PCA_Timer0;        //输出为高电平,则给影射寄存器装载高电平时间长度
  144.                 else        CCAP0_tmp += PWM0_low;        //输出为低电平,则给影射寄存器装载低电平时间长度
  145.                 CCAP0L = (u8)CCAP0_tmp;                        //将影射寄存器写入捕获寄存器,先写CCAP0L
  146.                 CCAP0H = (u8)(CCAP0_tmp >> 8);        //后写CCAP0H
  147.         }

  148.         if(CCF1)        //PCA模块1中断
  149.         {
  150.                 CCF1 = 0;                //清PCA模块1中断标志
  151.                 if(P26)        CCAP1_tmp += PCA_Timer1;        //输出为高电平,则给影射寄存器装载高电平时间长度
  152.                 else        CCAP1_tmp += PWM1_low;        //输出为低电平,则给影射寄存器装载低电平时间长度
  153.                 CCAP1L = (u8)CCAP1_tmp;                        //将影射寄存器写入捕获寄存器,先写CCAP0L
  154.                 CCAP1H = (u8)(CCAP1_tmp >> 8);        //后写CCAP0H
  155.         }

  156. //        if(CCF2)        //PCA模块2中断
  157. //        {
  158. //                CCF2 = 0;                //清PCA模块1中断标志
  159. //                if(P27)        CCAP2_tmp += PCA_Timer2;        //输出为高电平,则给影射寄存器装载高电平时间长度
  160. //                else        CCAP2_tmp += PWM2_low;        //输出为低电平,则给影射寄存器装载低电平时间长度
  161. //                CCAP2L = (u8)CCAP2_tmp;                        //将影射寄存器写入捕获寄存器,先写CCAP0L
  162. //                CCAP2H = (u8)(CCAP2_tmp >> 8);        //后写CCAP0H
  163. //        }

  164. /*        if(CF)        //PCA溢出中断
  165.         {
  166.                 CF = 0;                        //清PCA溢出中断标志
  167.         }
  168. */
  169. }

  170. void        PCA_config(void)
  171. {
  172.         PCA_InitTypeDef                PCA_InitStructure;

  173.         PCA_InitStructure.PCA_Clock    = PCA_Clock_1T;                //PCA_Clock_1T, PCA_Clock_2T, PCA_Clock_4T, PCA_Clock_6T, PCA_Clock_8T, PCA_Clock_12T, PCA_Clock_Timer0_OF, PCA_Clock_ECI
  174.         PCA_InitStructure.PCA_IoUse    = PCA_P24_P25_P26_P27;        //PCA_P12_P11_P10_P37, PCA_P34_P35_P36_P37, PCA_P24_P25_P26_P27
  175.         PCA_InitStructure.PCA_Interrupt_Mode = DISABLE;                //ENABLE, DISABLE
  176.         PCA_InitStructure.PCA_Polity   = PolityHigh;                        //优先级设置        PolityHigh,PolityLow
  177.         PCA_InitStructure.PCA_RUN      = DISABLE;                        //ENABLE, DISABLE
  178.         PCA_Init(PCA_Counter,&PCA_InitStructure);

  179.         PCA_InitStructure.PCA_Mode     = PCA_Mode_HighPulseOutput;                //PCA_Mode_PWM, PCA_Mode_Capture, PCA_Mode_SoftTimer, PCA_Mode_HighPulseOutput
  180.         PCA_InitStructure.PCA_PWM_Wide = 0;                                        //PCA_PWM_8bit, PCA_PWM_7bit, PCA_PWM_6bit
  181.         PCA_InitStructure.PCA_Interrupt_Mode = ENABLE;                //PCA_Rise_Active, PCA_Fall_Active, ENABLE, DISABLE
  182.         PCA_InitStructure.PCA_Value    = 65535;                        //对于软件定时, 为匹配比较值
  183.         PCA_Init(PCA0,&PCA_InitStructure);

  184.         PCA_InitStructure.PCA_Mode     = PCA_Mode_HighPulseOutput;                //PCA_Mode_PWM, PCA_Mode_Capture, PCA_Mode_SoftTimer, PCA_Mode_HighPulseOutput
  185.         PCA_InitStructure.PCA_PWM_Wide = 0;                                        //PCA_PWM_8bit, PCA_PWM_7bit, PCA_PWM_6bit
  186.         PCA_InitStructure.PCA_Interrupt_Mode = ENABLE;                //PCA_Rise_Active, PCA_Fall_Active, ENABLE, DISABLE
  187.         PCA_InitStructure.PCA_Value    = 65535;                                //对于软件定时, 为匹配比较值
  188.         PCA_Init(PCA1,&PCA_InitStructure);

  189. //        PCA_InitStructure.PCA_Mode     = PCA_Mode_HighPulseOutput;                //PCA_Mode_PWM, PCA_Mode_Capture, PCA_Mode_SoftTimer, PCA_Mode_HighPulseOutput
  190. //        PCA_InitStructure.PCA_PWM_Wide = 0;                                        //PCA_PWM_8bit, PCA_PWM_7bit, PCA_PWM_6bit
  191. ////  PCA_InitStructure.PCA_PWM_Wide = PCA_PWM_8bit;
  192. //  PCA_InitStructure.PCA_Interrupt_Mode = ENABLE;                //PCA_Rise_Active, PCA_Fall_Active, ENABLE, DISABLE
  193. //        PCA_InitStructure.PCA_Value    = 65535;                                //对于软件定时, 为匹配比较值
  194. //        PCA_Init(PCA2,&PCA_InitStructure);
  195. }


复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表