找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5700|回复: 5
收起左侧

一个两路ADC采样两路PWM输出可调程序

  [复制链接]
ID:115172 发表于 2016-4-19 12:03 | 显示全部楼层 |阅读模式
使用的是STC12C5A60S2芯片,不能仿真实在是很蛋疼啊

0.png
dac.c文件:
  1. #include "stc12c5a60s2.h"
  2. #include "intrins.h"
  3. #include "adc.h"
  4. #include "key.h"
  5. #include "pwm.h"
  6. #include "lcd1602.h"

  7. #define U8 unsigned char
  8. #define uint unsigned int
  9. #define uchar unsigned char


  10. #define ADC_POWER   0x80            //ADC power control bit 电源控制位
  11. #define ADC_FLAG    0x10            //ADC complete flag   标志位
  12. #define ADC_START   0x08            //ADC start control bit 启动控制位
  13. #define ADC_SPEEDLL 0x00            //420 clocks
  14. #define ADC_SPEEDL  0x20            //280 clocks
  15. #define ADC_SPEEDH  0x40            //140 clocks
  16. #define ADC_SPEEDHH 0x60            //70 clocks

  17. unsigned char in_str[]="0.00V";
  18. unsigned char d[5];
  19. uint  ch=0, number=0;
  20. uint light_input, key_input, shi_input;


  21. void  ADC_Init();                                  // 初始化AD
  22. void  Delay(unsigned int z);         // 延时
  23. void  ADC_lcd1602();



  24. void ADC_start()
  25. {
  26.         uint a = 0;
  27.        
  28.         PWM_Initial();
  29.         PWM_clock(2);      // PCA/PWM时钟源为 定时器0的溢出

  30.         while(1)
  31.         {  
  32.                 ADC_lcd1602();
  33.                 a = KeyPro();

  34.                 if(a == 0)
  35.                 {
  36.                          PWM_start(0,1);
  37.                          CCAP0L = 0XC0;
  38.                          CCAP0H = 0XC0;   //模块0初始输出 占空因数为25%
  39.                          PWM_start(1,1);
  40.                          CCAP1L = 0XC0;
  41.                      CCAP1H = 0XC0;   //模块1初始输出 占空因数为25%
  42.                 }

  43.                 else if(a == 1)
  44.                 {
  45.                          PWM_start(0,1);
  46.                          CCAP0L = 0X80;
  47.                          CCAP0H = 0X80;   //模块0初始输出 占空因数为50%
  48.                          
  49.                          PWM_start(1,1);
  50.                          CCAP1L = 0X40;
  51.                      CCAP1H = 0X40;   //模块1初始输出 占空因数为75%
  52.                 }

  53.                 else if(a == 2)
  54.                 {
  55.                          PWM_start(0,1);
  56.                          CCAP0L = 0X40;
  57.                          CCAP0H = 0X40;   //模块0初始输出 占空因数为75%
  58.                          
  59.                          PWM_start(1,1);
  60.                          CCAP1L = 0X40;
  61.                      CCAP1H = 0X40;   //模块1初始输出 占空因数为75%
  62.                 }
  63.                 else if(a == 3)
  64.                 {
  65.                          PWM_start(0,1);
  66.                          CCAP0L = 0X80;
  67.                          CCAP0H = 0X80;   //模块0初始输出 占空因数为50%
  68.                          
  69.                          PWM_start(1,1);
  70.                          CCAP1L = 0X80;
  71.                      CCAP1H = 0X80;   //模块1初始输出 占空因数为50%
  72.                 }
  73.         }
  74. }  


  75. void ADC_lcd1602()
  76. {
  77.          uint L = 0, K = 0;
  78.          if (number==8000)
  79.                                 {
  80.                                         shi_input =shi_input&0xff;
  81.                                         L = (uint)((4700l*shi_input)/255);
  82.                                         d[1] = L / 1000;          //最高位
  83.                                         L = L % 1000;
  84.                                         d[2] = L / 100;                  //次高位
  85.                                         L = L % 100;
  86.                                         d[3] = L /10;                        //...
  87.                                         d[4] = L % 10;                        //....
  88.                                        
  89.                                         num_lcdDis(0,0x06,d[4],2);
  90.                                         num_lcdDis(0,0x05,d[3],2);
  91.                                         num_lcdDis(0,0x04,d[2],2);
  92.                                         num_lcdDis(0,0x03,d[1],2);
  93.                                         num_lcdDis(0,0x02,d[0],2);
  94.                                 //        delay5ms();


  95.                                         light_input = light_input&0xff;
  96.                                         K =   (uint)((4700l*light_input)/255);
  97.                                         in_str[1] = K / 1000;          //最高位
  98.                                         K = K % 1000;
  99.                                         in_str[2] = K / 100;                  //次高位
  100.                                         K = K % 100;
  101.                                         in_str[3] = K /10;                        //...
  102.                                         in_str[4] = K % 10;                        //....


  103.                                         num_lcdDis(1,0x06,in_str[4],2);
  104.                                         num_lcdDis(1,0x05,in_str[3],2);
  105.                                         num_lcdDis(1,0x04,in_str[2],2);
  106.                                         num_lcdDis(1,0x03,in_str[1],2);
  107.                                         num_lcdDis(1,0x02,0,2);
  108.                 //                        delay5ms();
  109.                                           number=0;
  110.                         }
  111. }


  112. void ADC_Init()
  113. {

  114.     ADC_RES = 0;                                           //清除上次采集的结果       
  115.         IE=0xa0;
  116.         P1ASF=0xe0;                                            //设置AD输入通道为 P1.0-1.2
  117.     ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START|ch ;   //选择开启的通道
  118.     Delay(2);                                              //上电启动AD转换的延时
  119. }


  120. void Delay(unsigned int n)
  121. {
  122.         unsigned int x;
  123.     while (n--)
  124.                 {
  125.                           x=5000;
  126.                           while (x--);
  127.                 }
  128. }


  129. void ADC_isr(void) interrupt 5 using 1   //中断服务程序,每100ms读一次AD
  130. {

  131.         ADC_CONTR &= !ADC_FLAG;
  132.         if (number==20)
  133.         {
  134.                 if (ch==0  )            
  135.                  {
  136.                          shi_input= ADC_RES;
  137.                  }
  138.                 else if(ch==1)
  139.                 {
  140.                         light_input= ADC_RES;
  141.                         //light_input = 127;
  142.                 }
  143.           //else if (ch==2)  { key_input= ADC_RES; }
  144.             if(++ch>1)
  145.                     ch=0;
  146.         }
  147.                 
  148.         number++;
  149.         ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START|ch ;
  150. }
复制代码

pwm.c
  1. #include<reg52.h>
  2. #include "pwm.h"
  3. #include "key.h"
  4. #include "adc.h"
  5. #include <intrins.h>
  6. #define U8 unsigned char
  7. #define U16 unsigned int


  8. void PWM_clock(U8 clock);
  9. void PWM_start(U8 Module,U8 mode);
  10. void PMW_mode(void);
  11. U16 count = 0;

  12. void DelayMs(U8 ms) //在11.0592M晶振下,stc10f系列(单周期指令)的ms级延时
  13. {      
  14.         U16 i;
  15.         while(ms--)
  16.         {
  17.            for(i = 0; i < 850; i++);
  18.         }
  19. }

  20. sfr CCON     = 0xD8;         //PCA控制寄存器
  21. sfr CMOD     = 0xD9;         //PCA模式寄存器
  22. sfr CCAPM0   = 0xDA;         //PCA模块0模式寄存器 //模块0对应P1.3/CEX0/PCA0/PWM0(STC12C5A60S2系列)   
  23. sfr CCAPM1   = 0xDB;         //PCA模块1模式寄存器 //模块1对应P1.4/CEX1/PCA1/PWM1(STC12C5A60S2系列)
  24. sfr CL       = 0xE9;    //PCA 定时寄存器 低位
  25. sfr CH       = 0xF9;         //PCA 定时寄存器 高位
  26. sfr CCAP0L   = 0xEA;         //PCA模块0的 捕获寄存器 低位
  27. sfr CCAP0H   = 0xFA;    //PCA模块0的 捕获寄存器 高位
  28. sfr CCAP1L   = 0xEB;         //PCA模块1的 捕获寄存器 低位
  29. sfr CCAP1H   = 0xFB;         //PCA模块1的 捕获寄存器 高位
  30. sfr PCA_PWM0 = 0xF2;         //PCA PWM 模式辅助寄存器0
  31. sfr PCA_PWM1 = 0xF3;         //PCA PWM 模式辅助寄存器1
  32. sbit CF   = 0xDF;       //PCA计数溢出标志位
  33. sbit CR   = 0xDE;       //PCA计数器 运行控制位
  34. sbit CCF1 = 0xD9;       //PCA模块1中断标志
  35. sbit CCF0 = 0xD8;       //PCA模块0中断标志

  36. //* CCAPOH = CCAPOL = 0XC0; //模块0输出 占空因数为25%
  37. //* CCAPOH = CCAPOL = 0X80; //模块0输出 占空因数为50%
  38. //* CCAPOH = CCAPOL = 0X40; //模块0输出 占空因数为75%

  39. void PWM_clock(U8 clock)
  40. {
  41.         CMOD |= (clock<<1);
  42.         CL = 0x00;
  43.         CH = 0x00;
  44. }

  45. void PWM_Initial(void)           // 模块0,模块1设置为PWM输出,无中断,初始占空因素为50%
  46. {
  47.         U16 a = 0;
  48.         TMOD|=0x02;                    // timer 0 mode 2: 8-Bit reload  
  49.         TH0=0xff;
  50.         TR0=1;
  51.         PWM_clock(2);                 // PCA/PWM时钟源为 定时器0的溢出
  52.         CCAP0L = 0X80;
  53.         CCAP0H = 0X80;         //模块0初始输出 占空因数为50%
  54.         CCAP1L = 0X80;
  55.         CCAP1H = 0X80;         //模块1初始输出 占空因数为50%
  56.         PWM_start(2,2);
  57. }  


  58. void PWM_start(U8 module,U8 mode)
  59. {
  60.         if(module==0)
  61.         {
  62.                 switch(mode)
  63.                 {
  64.                         case 0: CCAPM0 = 0X42;break;         //模块0设置为8位PWM输出,无中断
  65.                         case 1: CCAPM0 = 0X53;break;         //模块0设置为8位PWM输出,下降沿产生中断
  66.                         case 2: CCAPM0 = 0X63;break;         //模块0设置为8位PWM输出,上升沿产生中断
  67.                         case 3: CCAPM0 = 0X73;break;         //模块0设置为8位PWM输出,跳变沿产生中断
  68.                         default: break;
  69.                 }
  70.         }
  71.         else if(module==1)
  72.                 {
  73.                         switch(mode)
  74.                         {
  75.                                 case 0: CCAPM1 = 0X42;break;         //模块1设置为8位PWM输出,无中断
  76.                                 case 1: CCAPM1 = 0X53;break;         //模块1设置为8位PWM输出,下降沿产生中断
  77.                                 case 2: CCAPM1 = 0X63;break;         //模块1设置为8位PWM输出,上升沿产生中断
  78.                                 case 3: CCAPM1 = 0X73;break;         //模块1设置为8位PWM输出,跳变沿产生中断
  79.                                 default: break;
  80.                         }
  81.                 }
  82.         else if(module==2)
  83.                 {
  84.                         switch(mode)
  85.                         {
  86.                                 case 0: CCAPM0 = CCAPM1 = 0X42;break; //模块0和1设置为8位PWM输出,无中断
  87.                                 case 1: CCAPM0 = CCAPM1 = 0X53;break; //模块0和1设置为8位PWM输出,下降沿产生中断
  88.                                 case 2: CCAPM0 = CCAPM1 = 0X63;break; //模块0和1设置为8位PWM输出,上升沿产生中断
  89.                                 case 3: CCAPM0 = CCAPM1 = 0X73;break; //模块0和1设置为8位PWM输出,跳变沿产生中断
  90.                                 default: break;
  91.                         }
  92.                 }
  93.         CR=1; //PCA计数器开始计数
  94. }



  95. void PCA_Intrrpt(void) interrupt 7
  96. {
  97.         if(CCF0)
  98.                 CCF0=0;
  99.         if(CCF1)
  100.                 CCF1=0;   //软件清零
  101.         if(CF)   
  102.                 CF=0;     //软件清零
  103. }
复制代码



ADC和PWM波可调.zip

74.49 KB, 下载次数: 77, 下载积分: 黑币 -5

STC12C5A60S2 ADC PWM

评分

参与人数 2黑币 +55 收起 理由
qq274255093 + 5 绝世好帖!
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:48413 发表于 2016-4-20 17:17 | 显示全部楼层
学习一下谢谢楼主
回复

使用道具 举报

ID:138549 发表于 2016-9-7 11:29 | 显示全部楼层
不错 挺好的
回复

使用道具 举报

ID:78522 发表于 2016-9-7 14:07 | 显示全部楼层
不错,顶一下,好好学习天天向上
回复

使用道具 举报

ID:216505 发表于 2017-7-2 11:03 | 显示全部楼层
学习一下,谢谢!
回复

使用道具 举报

ID:412814 发表于 2018-11-12 20:50 | 显示全部楼层
感谢楼主,下载了学习下。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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