单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:4339|回复:7
打印上一主题下一主题

用STC单片机做的7KW电动车充电桩源程序

 [复制链接]
跳转到指定楼层
楼主
ID:878048发表于 2021-1-16 09:56|只看该作者回帖奖励
用是STCD 15W404AS 做主控,片内资源用到了,可调PWM,ADC , 串口(用来读取计量模块的数据),具体功能,可按键调充电功率,1602显示实时电压,电流,功率,电能累计,
设计有1602显示,但是不知道时序写的还有些问题还是干扰问题,充电的时候就白屏了或者乱码了,,不充电有时候有时候是正常的,这里还需要调试,目前已经正常充电,电流30A

单片机源程序如下:
  1. #include< reg52.h>
  2. #include "intrins.h"
  3. sfr AUXR       =   0x8E;   //0000,0000 辅助寄存器
  4. sfr T2H       =   0xD6;   //0000,0000 T2高字节
  5. sfr T2L       =   0xD7;   //0000,0000 T2低字节

  6. sfr P0M1 = 0x93;
  7. sfr P0M0 = 0x94;
  8. sfr P1M1 = 0x91;
  9. sfr P1M0 = 0x92;
  10. sfr P2M1 = 0x95;
  11. sfr P2M0 = 0x96;
  12. sfr P3M1 = 0xb1;
  13. sfr P3M0 = 0xb2;
  14. sfr P4M1 = 0xb3;
  15. sfr P4M0 = 0xb4;
  16. sfr P5M1 = 0xC9;
  17. sfr P5M0 = 0xCA;
  18. sfr P6M1 = 0xCB;
  19. sfr P6M0 = 0xCC;
  20. sfr P7M1 = 0xE1;
  21. sfr P7M0 = 0xE2;
  22. /////////////////////////////////////////////////////////////////////////////////////////////
  23. //PWM模块寄存器定义
  24. sfr P_SW1  = 0xA2;         //外设功能切换寄存器1   针脚选择功能寄存器

  25. #define CCP_S0 0x10             //P_SW1.4       选择针脚功能
  26. #define CCP_S1 0x20             //P_SW1.5       选择针脚功能
  27. #define S1_S1 0x80             //P_SW3.6       选择针脚功能
  28. #define S1_S0 0x40             //P_SW3.7       选择针脚功能
  29. sfr ADC_CONTR   =   0xBC;         //ADC控制寄存器
  30. sfr ADC_RES     =   0xBD;         //ADC高8位结果
  31. sfr ADC_LOW2   =   0xBE;         //ADC低2位结果
  32. sfr P1ASF     =   0x9D;         //P1口第2功能控制寄存器

  33. #define ADC_POWER   0x80         //ADC电源控制位
  34. #define ADC_FLAG   0x10         //ADC完成标志
  35. #define ADC_START   0x08         //ADC起始控制位
  36. #define ADC_SPEEDLL 0x00         //540个时钟
  37. #define ADC_SPEEDL  0x20         //360个时钟
  38. #define ADC_SPEEDH  0x40         //180个时钟
  39. #define ADC_SPEEDHH 0x60         //90个时钟
  40.                                                                                                                                         
  41. sfr CCON       =   0xD8;         //PCA控制寄存器
  42. sbit CCF0     =   CCON^0;       //PCA模块0中断标志
  43. sbit CCF1     =   CCON^1;       //PCA模块1中断标志
  44. sbit CR       =   CCON^6;       //PCA定时器运行控制位
  45. sbit CF       =   CCON^7;       //PCA定时器溢出标志
  46. sfr CMOD       =   0xD9;         //PCA模式寄存器
  47. sfr CL       =   0xE9;         //PCA定时器低字节
  48. sfr CH       =   0xF9;         //PCA定时器高字节
  49. sfr CCAPM0     =   0xDA;         //PCA模块0模式寄存器  
  50. sfr CCAP0L     =   0xEA;         //PCA模块0捕获寄存器 LOW
  51. sfr CCAP0H     =   0xFA;         //PCA模块0捕获寄存器 HIGH
  52. sfr CCAPM1     =   0xDB;         //PCA模块1模式寄存器
  53. sfr CCAP1L     =   0xEB;         //PCA模块1捕获寄存器 LOW
  54. sfr CCAP1H     =   0xFB;         //PCA模块1捕获寄存器 HIGH
  55. sfr CCAPM2     =   0xDC;         //PCA模块2模式寄存器
  56. sfr CCAP2L     =   0xEC;         //PCA模块2捕获寄存器 LOW
  57. sfr CCAP2H     =   0xFC;         //PCA模块2捕获寄存器 HIGH
  58. sfr PCA_PWM0   =   0xf2;         //PCA模块0的PWM寄存器
  59. sfr PCA_PWM1   =   0xf3;         //PCA模块1的PWM寄存器
  60. sfr PCA_PWM2   =   0xf4;         //PCA模块2的PWM寄存器
  61. ///////////////////////////////////////////////////////////函数列表、、、、、、、、、、、、、、、、、、、、、、、、、、、
  62. void UartInit();   //初始化串口
  63. void Timer0Init(); //初始化T0
  64. void UartWxd();       //发送数据查询实时信息
  65. void jiexibuf();       //解析接受到的数据
  66. void pwm();       //解析接受到的数据
  67. void InitADC(); //初始化ADC
  68. void GetADCResult();   //读取ADC的值存储在变量adc里面
  69. void Delay(unsigned int n);       //软件延时 1.6毫秒左右
  70. void chongdian();             //       充电流程
  71. void  diannengjisuan();//J计算初始电能并计算已用电能
  72. void dianliuxuanze(); //按钮选项电流
  73. ///////////////////////////////////////////////////////////定义的一些变量、、、、、、、、、、、、、、、、、、、、、、、、、、、
  74. bit flagTxd = 0; //单字节发送完成标志,用来替代 TXD 中断标志位
  75. sbit s1 = P3^3;       //切换继电器
  76. sbit km = P3^2;       //功率继电器接触器
  77. sbit pwmdip = P1^1;
  78. sbit k1 = P3^0;         //按钮
  79. //sbit LED = P1^2;
  80. unsigned char cntRxd = 0; //接收字节计数器
  81. unsigned char pdata bufRxd[30]; //接收字节缓冲区
  82. unsigned char code bufWxd[8] ={0x01,0x03,0x00,0x48,0x00,0x0A,0x45,0xDB,};//发送的数据     增加了code关键字,此数组写在程序区减少使用内部内存128K
  83. unsigned long pdata cnt = 0; //毫秒计数
  84. unsigned long pdata sec; //秒计数
  85. //unsigned cha *but;// 发送指针
  86. unsigned int pdata vcc; // 电压
  87. unsigned int pdata vci; // 电流
  88. unsigned int pdata power; // 功率
  89. unsigned long pdata kwh=0; // 电能
  90. unsigned long pdata kwh1; // 初始电能
  91. unsigned char pw;       //设定的空占比%
  92. unsigned char cp; //充电桩PWM波形 cp电压采集信号     120
  93. ////         关于LCD 1602       /////////////////LCD的一些定义
  94. sfr P5   = 0xC8;
  95. unsigned char pdata lcd1[16];       //LCD第一行
  96. unsigned char pdata lcd2[16];       //LCD第二行
  97. sbit LCD1602_RS = P5^5;       //命令、数据选择 H\L
  98. sbit LCD1602_E = P5^4;       //使能
  99. unsigned char pdata ki;     //电流显示1表示16A   2表示32A

  100. #define LCD1602_DATAPINS P1   //定义P1口为数据端
  101. void LcdWriteCom(unsigned char com); /*LCD1602写入8位数据子函数*/    
  102. void LcdWriteData(unsigned char dat);     /*LCD1602写入8位数据子函数*/
  103. void LcdInit();             /*LCD1602初始化子程序*/    
  104. void lcd1602();       //1602显示刷新
  105. void Lcd1602_Delay5ms();
  106. void Lcd1602_Delay1ms();

  107. void main(){
  108.    P0M0 = 0x00;
  109.    P0M1 = 0x00;
  110.    P1M0 = 0x00;
  111.    P1M1 = 0x00;
  112.    P2M0 = 0x00;
  113.    P2M1 = 0x00;
  114.    P3M0 = 0x00;
  115.    P3M1 = 0x00;
  116.    P4M0 = 0x00;
  117.    P4M1 = 0x00;
  118.    P5M0 = 0x00;
  119.    P5M1 = 0x00;
  120.    P6M0 = 0x00;
  121.    P6M1 = 0x00;
  122.    P7M0 = 0x00;
  123.    P7M1 = 0x00;
  124.      P_SW1=P_SW1|S1_S0;
  125.    EA = 1; //使能总中断
  126.      ES = 1;   //使能串口1中断
  127.        UartInit();       //初始化串口
  128.          pwm();       //初始化pwm模块设置
  129.      InitADC(); //初始化ADC
  130.     
  131.      Timer0Init(); //初始化T0
  132.          LcdInit();//初始化lcd
  133.           
  134.    while (1){
  135.      chongdian();  //充电流程
  136.      dianliuxuanze(); //电流选择函数
  137.     
  138.      if(TF0==1){                   //t0溢出的次数
  139.            cnt++;}
  140.      if(pwmdip==1){       //检测            
  141.        GetADCResult(); //读取刷新ADC的值       cp就是读取的8位电压信号
  142.         
  143.          }
  144.      if(cnt>=20000){           //大概1秒钟,还可以调整
  145.               
  146.          cnt=0;
  147.            sec++;
  148.                               
  149.            UartWxd();       //发送电能模块读取命令          
  150.            jiexibuf();  //解析接受到的数据
  151.            diannengjisuan(); //电能计算函数
  152.            lcd1602();       //lcd显示      
  153.                  }

  154.       

  155.                        }  }
  156.   void chongdian(){       //、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、充电流程

  157.        if(cp>111){     //当cp电压大于11.1时               状态1
  158.            s1=1;             //小接触器不吸合 常闭点12V  s1
  159.            km=1;
  160.                }       //主接触器不吸合  
  161.        if(98>cp&& cp>81){       //当cp电压大于8.1V小于9.8时       状态2           与车辆已连接
  162.            s1=0;             //小接触器吸合       切换至PWM
  163.            km=1;             }       //主接触器不吸合
  164.        if(66>cp&& cp>51){           //当cp电压大于5.1小于6.6时       状态3       充电中
  165.            s1=0;           //小接触器吸合       切换至PWM
  166.            km=0;                     //主接触器吸合  开始充电
  167.         
  168.                }
  169.              }

  170.   void dianliuxuanze(){               //电流选择初始值16A
  171.            bit i=0;         //电流选择初始值16A
  172.            if (i==1){         //不切换电流16A
  173.                  pw=33;
  174.                    ki=1;}
  175.            else{pw=60;
  176.            ki=2;}       // 切换电流32A

  177.      if(k1==0)
  178.        {  Lcd1602_Delay5ms();
  179.            Lcd1602_Delay5ms();
  180.            if(k1==0){
  181.            i=!i;//k1按下置反i
  182.                    }
  183.     

  184. }
  185.      }

  186.   void pwm(){  //PWM程序、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

  187.   
  188.    ACC = P_SW1;                     //累加器 等于外设寄存器
  189.    ACC& = ~(CCP_S0 | CCP_S1);     //CCP_S0=0 CCP_S1=0
  190.    P_SW1 = ACC;               //(P1.2/ECI, P1.1/CCP0, P1.0/CCP1, P3.7/CCP2)       读取累加器的值写进外设寄存器
  191.    CCON = 0;                 //初始化PCA控制寄存器
  192.                          //PCA定时器停止
  193.                          //清除CF标志
  194.                          //清除模块中断标志
  195.    CL = 0;                 //复位PCA寄存器
  196.    CH = 0;
  197.      CMOD = 0x04;
  198.    // CMOD = 0x04;               //设置PCA时钟源     t0定时器
  199.                          //禁止PCA定时器溢出中断
  200.    PCA_PWM0 = 0x00;           //PCA模块0工作于8位PWM
  201.    CCAP0H = CCAP0L =255-255*60/100;       //PWM0的占空比为87.5% ((100H-20H)/100H)       255-255*设定空占比     /100
  202.    CCAPM0 = 0x42;             //00101010  PCA模块0允许比较功能     使用CCP0脚为可调脉冲输出       P1.1

  203.                    }
  204. void Timer0Init()         //T0作为PWM频率基准发生
  205. {
  206.     
  207.      AUXR |= 0x80;         //定时器时钟1T模式
  208.      TMOD& = 0xF0;         //设置定时器模式
  209.      TL0 = 0xd5;     //设置定时初值         计算方法,65536-晶振/(256*需要频率)  
  210.      TH0 = 0xFf;         //设置定时初值    
  211.      TR0 = 1;         //定时器0开始计时
  212.        ET0 =0;             // 禁止T0中断
  213.      TF0 = 0;         //清除TF0标志
  214. //     EA  =0;             关闭总总中断
  215.    CR = 1; }                 //PCA定时器开始工作

  216. ///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  217. //     AUXR |= 0x80;         //定时器时钟1T模式
  218. //     TMOD& = 0xF0;         //设置定时器模式
  219. //     TL0 = 0xff;         //设置定时初值
  220. //     TH0 = 0xf6;         //设置定时初值
  221. //     TF0 = 0;         //清除TF0标志
  222. //     TR0 = 1;         //定时器0开始计时
  223. /*----------------------------
  224. 初始化ADC
  225. ----------------------------*/
  226. void InitADC() //初始化ADC
  227. {
  228.    P1ASF = 0x01;             //设置P1.0口为AD口
  229.    ADC_RES = 0;               //清除结果寄存器
  230.    ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
  231.    Delay(2);                 //ADC上电并延时
  232. }
  233. /*----------------------------
  234. 读取ADC结果
  235. ----------------------------*/
  236. void GetADCResult()
  237. {     unsigned long y;
  238.    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | 0 | ADC_START;       //ADC电源   540个时钟ADC_SPEEDHH   ADC_SPEEDLL  通道号       启动
  239.    _nop_();                 //等待4个NOP
  240.    _nop_();
  241.    _nop_();
  242.    _nop_();
  243.    while (!(ADC_CONTR& ADC_FLAG));//等待ADC转换完成
  244.    ADC_CONTR& = ~ADC_FLAG;       //Close ADC
  245.       
  246.        //实际滤波测得4.6V一下不予处理
  247.        if(ADC_RES>0x64){
  248.        y=12000000/256*(ADC_RES+1);                           //ADC结果转换 单位是最大12000毫伏      
  249.        cp=y/100000;                                 //结果转换120v  放大10倍最大电压
  250.                      }
  251. }

  252.    void jiexibuf()           //解析接受到的数据
  253. {     unsigned long h;
  254.      unsigned long j;
  255.      unsigned long l;
  256.      unsigned long o;
  257.      vcc   = (bufRxd[3]<<8)| bufRxd[4];     //电压       int16位
  258.      vci   = (bufRxd[5]<<8)| bufRxd[6];     //电流       int16位
  259.      power  = (bufRxd[7]<<8)| bufRxd[8];     //功率       int16位
  260.        h     = (bufRxd[9]<<8)| bufRxd[10];//电能 32位数据高16位
  261.        j       = (bufRxd[11]<<8)|bufRxd[12];//电能 32位数据低16位
  262.        l     = h<<16;
  263.        o     = (l|j)*100;
  264.      kwh   =  o/3200;        
  265.                  }
  266. void  diannengjisuan()     //计算电能显示函数
  267. {       unsigned long x;
  268.        static bit p=1;
  269.     
  270.        if(p==1){     //开始初始电能记录
  271.              if(s1==0){  //刷新是否有电能数据
  272.                      x=kwh1;         // 初始电能传给x
  273.                      p=0;         //退出初始电能记录
  274.                                  }    
  275.                }
  276.      // kwh=kwh1-x;
  277.          }

  278. void UartInit()         //4800bps@11.0592MHz

  279. {
  280. //     P_SW1=P_SW1|S1_S0;
  281.      SCON = 0x50;         //8位数据,可变波特率
  282.      AUXR |= 0x01;         //串口1选择定时器2为波特率发生器
  283.      AUXR |= 0x04;         //定时器2时钟为Fosc,即1T
  284.      T2L = 0xC0;         //设定定时初值
  285.      T2H = 0xFD;         //设定定时初值
  286.      AUXR |= 0x10;         //启动定时器2
  287. }
  288. void UartWxd(){    
  289.      unsigned char u; //数据位置       bufWxd[u]  
  290.        for(u=0;u<=7;u++)
  291.        {    
  292.        flagTxd=0;
  293.          SBUF=bufWxd[u];         //       SBUF=bufWxd[u];
  294.          while(!flagTxd);
  295.                         
  296.      }
  297.                      }

  298. /*----------------------------
  299. 软件延时
  300. ----------------------------*/
  301. void Delay(unsigned int n)
  302. {
  303.    unsigned int x;

  304.    while (n--)
  305.    {
  306.        x = 5000;
  307.        while (x--);
  308.    }
  309. }



  310. void InterruptUART() interrupt 4{
  311.    if (RI){ //接收到字节
  312.        RI = 0; //手动清零接收中断标志位
  313.        bufRxd[cntRxd++] = SBUF; //接收的数据存到接收缓冲区,数组
  314.        if(cntRxd==25){           //接收24帧数据,然后复位接收计数器,下次从0开始接收
  315.            cntRxd=0;
  316.                  }
  317.    }
  318.    if (TI){ //字节发送完毕
  319.      TI = 0; //手动清零发送中断标志位
  320.        flagTxd = 1; //设置字节发送完成标志
  321.    }
  322.      }
  323. //清中断标志/清中断标志
  324. //void PCA_isr() interrupt 7
  325. //{
  326. //   CCF0 = 0;                 //清中断标志
  327. //   CCAP0L = value;
  328. //   CCAP0H = value >> 8;         //更新比较值
  329. //   value += T100Hz;
  330. //   if (cnt-- == 0)
  331. //   {
  332. //       cnt = 100;             //记数100次
  333. //     PCA_LED = !PCA_LED;       //每秒闪烁一次
  334. //   }
  335. //}
  336. ////         关于LCD 1602 LCD 1602 LCD 1602 LCD 1602 LCD 1602 LCD 1602 LCD 1602                   /////////////////LCD的一些定义

  337. void LcdWriteCom(unsigned char com)       //写入命令
  338. {
  339.      LCD1602_E = 0;       //使能清零
  340.      LCD1602_RS = 0;       //选择写入命令

  341.      LCD1602_DATAPINS = com >>2;     //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
  342.      Lcd1602_Delay1ms();

  343.      LCD1602_E = 1;       //写入时序
  344.      Lcd1602_Delay5ms();
  345.      LCD1602_E = 0;

  346.      LCD1602_DATAPINS = com<< 2; //发送低四位    
  347.      Lcd1602_Delay1ms();

  348.      LCD1602_E = 1;       //写入时序
  349.      Lcd1602_Delay5ms();
  350.      LCD1602_E = 0;
  351.                  }
  352. void LcdWriteData(unsigned char dat)             //写入数据
  353. {
  354.      LCD1602_E = 0;       //使能清零
  355.      LCD1602_RS = 1;       //选择写入数据
  356. //     LCD1602_RW = 0;       //选择写入
  357.       
  358.         
  359.      LCD1602_DATAPINS = dat >>2;     //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
  360.      Lcd1602_Delay1ms();

  361.      LCD1602_E = 1;       //写入时序
  362.      Lcd1602_Delay5ms();
  363.      LCD1602_E = 0;

  364.      LCD1602_DATAPINS = dat<< 2; //写入低四位
  365.      Lcd1602_Delay1ms();

  366.      LCD1602_E = 1;       //写入时序
  367.      Lcd1602_Delay5ms();
  368.      LCD1602_E = 0;
  369. }
  370. void LcdInit()                           //LCD初始化子程序
  371. {    
  372.      Delay(20);
  373.      LcdWriteCom(0x32);       //将8位总线转为4位总线
  374.      LcdWriteCom(0x28);       //在四位线下的初始化
  375.      LcdWriteCom(0x0c);  //开显示不显示光标
  376.      LcdWriteCom(0x06);  //写一个指针加1
  377.      LcdWriteCom(0x01);  //清屏
  378.      //LcdWriteCom(0x80);  //设置数据指针起点
  379. }
  380. void lcd1602()
  381. {     LcdWriteCom(0x80);  //设置数据指针起点
  382.      LcdWriteData('V');
  383.      LcdWriteData(':');
  384.      LcdWriteData('0'+vcc/10000%10);
  385.      LcdWriteData('0'+vcc/1000%10);
  386.      LcdWriteData('0'+vcc/100%10);
  387.      LcdWriteData('.');
  388.      LcdWriteData('0'+vcc/10%10);
  389.      LcdWriteData('0'+vcc%10);
  390.      LcdWriteData(' ');
  391. ……………………

  392. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


所有程序51hei提供下载:
485 - 通讯程序加显示.zip(53.37 KB, 下载次数: 126)

评分

黑币 +50
收起理由
+ 50
共享资料的黑币奖励!

查看全部评分

沙发
ID:864602发表于 2021-1-20 21:15|只看该作者
学习利器,谢谢
板凳
ID:507641发表于 2022-9-22 10:14|只看该作者
原理图都没有,怎么分析??/
地板
ID:507641发表于 2022-9-22 10:25|只看该作者
原理图与 pcb都可能,结合程序分析才能分析.下载看你的还要币???怎么的会有人帮分析老大???
5#
ID:1046301发表于 2022-9-30 08:34|只看该作者
从事电源类开发的。加个好友一起学习一下。
6#
ID:899981发表于 2024-6-21 18:31|只看该作者
AD能接LCD1602?
7#
ID:899981发表于 2024-7-6 11:14|只看该作者
我换了STC154K32S4,PWM无输出,也是这个程序:#include< reg52.h>
#include "intrins.h"
sfr AUXR       =   0x8E;   //0000,0000 辅助寄存器
sfr T2H       =   0xD6;   //0000,0000 T2高字节
sfr T2L       =   0xD7;   //0000,0000 T2低字节

sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;
sfr P7M1 = 0xE1;
sfr P7M0 = 0xE2;


sfr     P7     = 0xF8;

//PWM模块寄存器定义
sfr P_SW1  = 0xA2;         //外设功能切换寄存器1   针脚选择功能寄存器

#define CCP_S0 0x10             //P_SW1.4       选择针脚功能
#define CCP_S1 0x20             //P_SW1.5       选择针脚功能
#define S1_S1 0x80             //P_SW3.6       选择针脚功能
#define S1_S0 0x40             //P_SW3.7       选择针脚功能
sfr ADC_CONTR   =   0xBC;         //ADC控制寄存器
sfr ADC_RES     =   0xBD;         //ADC高8位结果
sfr ADC_LOW2   =   0xBE;         //ADC低2位结果
sfr P1ASF     =   0x9D;         //P1口第2功能控制寄存器

#define ADC_POWER   0x80         //ADC电源控制位
#define ADC_FLAG   0x10         //ADC完成标志
#define ADC_START   0x08         //ADC起始控制位
#define ADC_SPEEDLL 0x00         //540个时钟
#define ADC_SPEEDL  0x20         //360个时钟
#define ADC_SPEEDH  0x40         //180个时钟
#define ADC_SPEEDHH 0x60         //90个时钟
                                                                                                                                        
sfr CCON       =   0xD8;         //PCA控制寄存器
sbit CCF0     =   CCON^0;       //PCA模块0中断标志
sbit CCF1     =   CCON^1;       //PCA模块1中断标志
sbit CR       =   CCON^6;       //PCA定时器运行控制位
sbit CF       =   CCON^7;       //PCA定时器溢出标志
sfr CMOD       =   0xD9;         //PCA模式寄存器
sfr CL       =   0xE9;         //PCA定时器低字节
sfr CH       =   0xF9;         //PCA定时器高字节
sfr CCAPM0     =   0xDA;         //PCA模块0模式寄存器  
sfr CCAP0L     =   0xEA;         //PCA模块0捕获寄存器 LOW
sfr CCAP0H     =   0xFA;         //PCA模块0捕获寄存器 HIGH
sfr CCAPM1     =   0xDB;         //PCA模块1模式寄存器
sfr CCAP1L     =   0xEB;         //PCA模块1捕获寄存器 LOW
sfr CCAP1H     =   0xFB;         //PCA模块1捕获寄存器 HIGH
sfr CCAPM2     =   0xDC;         //PCA模块2模式寄存器
sfr CCAP2L     =   0xEC;         //PCA模块2捕获寄存器 LOW
sfr CCAP2H     =   0xFC;         //PCA模块2捕获寄存器 HIGH
sfr PCA_PWM0   =   0xf2;         //PCA模块0的PWM寄存器
sfr PCA_PWM1   =   0xf3;         //PCA模块1的PWM寄存器
sfr PCA_PWM2   =   0xf4;         //PCA模块2的PWM寄存器
///////////////////////////////////////////////////////////函数列表、、、、、、、、、、、、、、、、、、、、、、、、、、、

void Timer0Init(); //初始化T0


void pwm();       //解析接受到的数据


void Delay(unsigned int n);       //软件延时 1.6毫秒左右

///////////////////////////////////////////////////////////定义的一些变量、、、、、、、、、、、、、、、、、、、、、、、、、、、
bit flagTxd = 0; //单字节发送完成标志,用来替代 TXD 中断标志位
sbit s1 = P3^3;       //切换继电器
sbit km = P3^2;       //功率继电器接触器
sbit pwmdip = P1^1;
sbit k1 = P3^0;         //按钮
sbit PCA_LED = P1^2;

unsigned char cntRxd = 0; //接收字节计数器
unsigned char pdata bufRxd[30]; //接收字节缓冲区
unsigned char code bufWxd[8] ={0x01,0x03,0x00,0x48,0x00,0x0A,0x45,0xDB,};//发送的数据     增加了code关键字,此数组写在程序区减少使用内部内存128K
unsigned long pdata cnt = 0; //毫秒计数
//unsigned long pdata sec; //秒计数
//unsigned cha *but;// 发送指针
unsigned int pdata vcc; // 电压
unsigned int pdata vci; // 电流
unsigned int pdata power; // 功率
unsigned long pdata kwh=0; // 电能
unsigned long pdata kwh1; // 初始电能
unsigned char pw;       //设定的空占比%
unsigned int value; // 电压
unsigned char cp; //充电桩PWM波形 cp电压采集信号     120
////         关于LCD 1602       /////////////////LCD的一些定义
sfr P5   = 0xC8;
unsigned char pdata lcd1[16];       //LCD第一行
unsigned char pdata lcd2[16];       //LCD第二行
sbit LCD1602_RS = P5^5;       //命令、数据选择 H\L
sbit LCD1602_E = P5^4;       //使能
unsigned char pdata ki;     //电流显示1表示16A   2表示32A

#define LEDDATA P7   //定义P1口为数据端
#define T100Hz 256
void LcdWriteCom(unsigned char com); /*LCD1602写入8位数据子函数*/    
void LcdWriteData(unsigned char dat);     /*LCD1602写入8位数据子函数*/
void LcdInit();             /*LCD1602初始化子程序*/    
void lcd1602();       //1602显示刷新
void Lcd1602_Delay5ms();
void Lcd1602_Delay1ms();




                

void main(){
   P0M0 = 0x00;
   P0M1 = 0x00;
   P1M0 = 0x00;
   P1M1 = 0x00;
   P2M0 = 0x00;
   P2M1 = 0x00;
   P3M0 = 0x00;
   P3M1 = 0x00;
   P4M0 = 0x00;
   P4M1 = 0x00;
   P5M0 = 0x00;
   P5M1 = 0x00;
   P6M0 = 0x00;
   P6M1 = 0x00;
   P7M0 = 0x00;
   P7M1 = 0x00;

     P_SW1=P_SW1|S1_S0;
   EA = 1; //使能总中断

  
         pwm();       //初始化pwm模块设置

    
     Timer0Init(); //初始化T0



   while (1){

                       }
}
  
    



   void pwm(){  //PWM程序、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

  
   ACC = P_SW1;                     //累加器 等于外设寄存器
   ACC& = ~(CCP_S0 | CCP_S1);     //CCP_S0=0 CCP_S1=0
   P_SW1 = ACC;               //(P1.2/ECI, P1.1/CCP0, P1.0/CCP1, P3.7/CCP2)       读取累加器的值写进外设寄存器
   CCON = 0;                 //初始化PCA控制寄存器
                         //PCA定时器停止
                         //清除CF标志
                         //清除模块中断标志
   CL = 0;                 //复位PCA寄存器
   CH = 0;
     CMOD = 0x04;

    
   PCA_PWM0 = 0x00;           //PCA模块0工作于8位PWM
   CCAP0H = CCAP0L =255-255*60/100;       //PWM0的占空比为87.5% ((100H-20H)/100H)       255-255*设定空占比     /100
   CCAPM0 = 0x42;             //00101010  PCA模块0允许比较功能     使用CCP0脚为可调脉冲输出       P1.1

                   }
void Timer0Init()         //T0作为PWM频率基准发生
{
    
     AUXR |= 0x80;         //定时器时钟1T模式
     TMOD& = 0xF0;         //设置定时器模式
     TL0 = 0xd5;     //设置定时初值         计算方法,65536-晶振/(256*需要频率)  
     TH0 = 0xFf;         //设置定时初值    
     TR0 = 1;         //定时器0开始计时
       ET0 =0;             // 禁止T0中断
     TF0 = 0;         //清除TF0标志
//     EA  =0;             关闭总总中断
   CR = 1;
     }                 //PCA定时器开始工作





8#
ID:899981发表于 2024-7-6 11:15|只看该作者
485 - 通讯程序加显示.7z(946.05 KB, 下载次数: 2)
这是源码带PWM仿真,没有PWM输出。

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

Powered by 单片机教程网