找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5874|回复: 7
打印 上一主题 下一主题
收起左侧

不知道有人做过正弦没有,这里发个正弦程序,用pic16f716做的,picc编译器

  [复制链接]
跳转到指定楼层
楼主
在protues中仿真的,波形还好,做到实际的话需要提高pwm点数


  1. //=====pic16f716全桥SPWM输出,单极性调制,半个周期300个点左右====================
  2. //=====外部晶体20MHZ==输出50HZ=======================================
  3. //=====AN0为电压反馈端小于2.578125伏大于2.5390625伏为正常=============
  4. //=====RB0为外部保护,低电平保护,加上拉电阻10K===========================
  5. //====RB4为外部保护,低电平保护,加上拉电阻10K=============================
  6. #include<pic16f716.h>
  7. #include<pic.h>
  8. __CONFIG(0X3F32);//关闭看门狗使用外部HS晶体
  9. static unsigned char sin_num;
  10. bank1 float  sin_am,sin_l,sin_d;//浮点数,幅值变量,临时变量,临时变量
  11. bit sin_zz;
  12. bit adc_power;
  13. unsigned char sin_pp;

  14. //----------------------------------------------------------
  15. const unsigned char SPWMTABLE[40]={
  16. 8,  24,  39,54, 68, 83, 96, 110,122,134,145,
  17.         
  18. 155,164,172,179,185,189,193,195,197,
  19.         
  20. 197,195,193,189,185,179,172,164,155,
  21.         
  22. 145,134,122,110,96,83,68,54,39,24,8

  23. };
  24. //------------------------------------------------------
  25. //-------------中断服务程序------------------------------------  
  26. void interrupt timer2()  
  27. {  

  28.         if(TMR2IE==1&&TMR2IF==1) //定时器2中断
  29.         {
  30. TMR2IF=0;//清除标志位
  31. sin_d=SPWMTABLE[sin_num];
  32. sin_l=sin_am*sin_d;

  33. if(sin_l>=255)sin_l=255;//限幅

  34. if(sin_zz==1)//全桥正向输出; P1D 被调制; P1A 有效; P1B 和 P1C 无效
  35. { P1M1=0;P1M0=1;  CCPR1L=(unsigned char)sin_l;}
  36. else //全桥反向输出; P1B 被调制; P1C 有效; P1A 和 P1D 无效
  37. { P1M1=1;P1M0=1;  CCPR1L=(unsigned char)sin_l;}
  38.   sin_num++;//指针加1
  39. if(sin_num==40){sin_num=0;sin_zz=!sin_zz;CCPR1L=0;}//查表40次  
  40. if(sin_num==19)adc_power=1;//输出最大开启adc检测峰值

  41.         }
  42.        
  43. if(ADIE==1&&ADIF==1)//adc中断
  44. {

  45. ADIF=0;//清除标志
  46. sin_pp=ADRES;

  47. }

  48. }

  49. //-------------------adc初始化------------------
  50. void adc0_init()
  51. {
  52. TRISA0=0;
  53. ADCS1=0;
  54. ADCS0=0;//FOSC/2
  55. ADCON1=0x04;//参考电压为5V
  56. //============================
  57. CHS2=0;
  58. CHS1=0;
  59. CHS0=0;//通道0
  60. ADON=1;//开启adc
  61. ADIE=1;
  62. ADIF=0;
  63. }   
  64. //软件延时子程序*/
  65. void DELAY()
  66. {
  67. unsigned int i;
  68.    for(i=50000;i>0;i--);
  69. }

  70. //------------pwm初始化函数-------------------
  71. void pwmInit()
  72. {
  73. PR2=138; //调spwm占空比138左右跟实际情况调
  74. //CCP1CON|=0x0c;// 1000 1100pwm双输出,占空比高2位清零,
  75. CCP1M3=1;
  76. CCP1M2=1;
  77. CCP1M1=0;
  78. CCP1M0=0;
  79. //=======死区为最大================
  80. DC1B1=0;
  81. DC1B0=0;
  82. //PWM 模式。P1A, P1C 高电平有效; P1B, P1D 高电平有效;
  83. CCPR1L=0;//占空比清零
  84. T2CON=0x44 ;//0100 0100预分频1,后分频9,使能timer2,/调为50hz
  85. TMR2IE=1; //允许TMR2 和 PR2 匹配中断
  86. TMR2IF=0; //Timer2 中断标志位清零
  87. PWM1CON=0X80;//软件使能关闭pwm
  88. ECCPAS2=1;//RB0(INT)引脚低电平(0)导致关闭
  89. ECCPAS0=1;//RB4引脚低电平 (0)导致关闭
  90. PSSAC1=0;//:引脚P1A 和P1C 关闭状态控制位
  91. PSSAC0=0;//00 = 驱动引脚P1A和 P1C 为 0
  92. PSSBD1=0;//:引脚P1B 和P1D关闭状态控制位
  93. PSSBD0=0;//00 = 驱动引脚P1B和 P1D 为 0
  94. }
  95. //-----------------------------------------------
  96. void init()
  97. {TRISB=0;//D端口为输出

  98. PORTB=0X00;
  99. TRISB0=1;
  100. TRISB4=1;//外部低电平保护
  101. }


  102. //------------主函数------------------------

  103. void main(void)  
  104. {
  105. init() ;
  106. adc0_init();
  107. pwmInit();
  108. sin_num=0;//数组指针变量
  109. PEIE=1; //(TM2中断为外设中断)所有未被屏蔽的外设中断1开放0关闭
  110. GIE=1; //使能所有未被屏蔽的中断1使能0关闭
  111. sin_zz=1;//正反向全桥输出标志
  112. sin_am=0;//sin函数的幅值
  113. sin_am=0.3000;//sin函数的幅值
  114. adc_power=1;//开启adc电源
  115. while(1)
  116.         {
  117. if(adc_power)
  118.         {
  119. adc_power=0;
  120. GODONE=1;//开启adc
  121. while(!(GODONE));//等待转换结束
  122.         }
  123. //=============5/256=0.01953125=========================
  124. //============== 132*0.01953125=2.578125伏==============
  125. if(sin_pp>153&&!ECCPASE)ECCPASE=1;//如果大于2.98828125就复位pwm

  126. if(sin_pp>132){sin_am-=0.005;if((sin_pp-132)>10)sin_am-=0.04; } //如果大于2.578125
  127. else  
  128. if((sin_pp<=132)&&(sin_pp>=130))sin_am+=0; //如果小于2.578125伏大于2.5390625就不加
  129. else  
  130. if(sin_pp<130) {sin_am+=0.005;if((130-sin_pp) >10)sin_am+=0.04;}

  131. if(sin_am>1.6)sin_am=1.6;//稳压变量,可调整


  132.         }
  133. }
复制代码


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的积分奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:80636 发表于 2015-5-25 21:38 | 只看该作者
不错!!!
回复

使用道具 举报

板凳
ID:288198 发表于 2018-3-6 14:39 | 只看该作者
可以有
回复

使用道具 举报

地板
ID:444221 发表于 2018-12-11 16:57 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

5#
ID:7199 发表于 2023-6-4 09:05 | 只看该作者
想下来看看,不知有没有用
回复

使用道具 举报

6#
ID:7199 发表于 2023-6-5 10:42 | 只看该作者
头文件能分享一下吗?
回复

使用道具 举报

7#
ID:1083996 发表于 2023-6-21 08:57 | 只看该作者
好骚气完美的波形,要是做的更细腻一些就更好了
回复

使用道具 举报

8#
ID:1109639 发表于 2024-3-17 02:37 | 只看该作者
Error   [192] C:\Users\WanChen\Desktop\PICPWM\pic16\main.c; 135.1 undefined identifier "GODONE"
有这样的报错怎么解决?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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