tag 标签: 三色

相关博文
  • 热度 18
    2015-9-22 19:09
    2768 次阅读|
    0 个评论
    朋友问能否用模拟量控制PWM,这么简单当然easy了,我用STC15W408AS的DIP20脚的单片机,因为这种单片机具有AD输入通道和PWM输出,很快做好了一个单通道的实验,完事想这个单片机有三个PWM输出,我可以驱动三色LED进行显示玩玩,用三个电位器控制三色LED的亮度变化就可以输出各种颜色了: 硬件很简单,就是三个10K电位器对电源5V分压,调整端电压进三个AD:P1.0,1.1,1.2,PWM输出在P3.5,3.6,3.7,三色LED红蓝绿正极接一起接5V正极,三个LED负极分别接1K电阻进三个PWM输出,调整电位器分别控制PWM输出驱动LED亮度变化,不同组合就是不同颜色。 C程序如下,大部分摘录自STC的下载工具里面的范例,大部分选项参数并没有清理,原汁原味,当然也有一点错误给予修正: //STC15W408AS DIP20 11.0592MHz 串口115.2K比特率   //本程序电位器输入三个模拟量,AD结果送串口,同时输出三个PWM驱动三基色LED //PWM移动到第二输出口,以便让开AD三个输入通道 //PWM设定为8bit输出,AD只取高八位,刚好对应   #include "reg51.h" #include "intrins.h"   #define FOSC    11059200L #define BAUD    115200   typedef unsigned char BYTE; typedef unsigned int WORD;   #define     URMD    0           //0:使用定时器2作为波特率发生器                                 //1:使用定时器1的模式0(16位自动重载模式)作为波特率发生器                                 //2:使用定时器1的模式2(8位自动重载模式)作为波特率发生器   sfr T2H   = 0xd6;               //定时器2高8位 sfr T2L   = 0xd7;               //定时器2低8位   sfr  AUXR       =   0x8e;       //辅助寄存器                                 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 P_SW1       = 0xA2;             //外设功能切换寄存器1   #define CCP_S0 0x10                 //P_SW1.4 #define CCP_S1 0x20                 //P_SW1.5   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 InitUart(); void InitADC(); void SendData(BYTE dat); BYTE GetADCResult(BYTE ch); void Delay(WORD n); void ShowResult(BYTE ch);   void main() {      // 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)        ACC = P_SW1;   ACC = ~(CCP_S0 | CCP_S1);      //CCP_S0=1 CCP_S1=0   ACC |= CCP_S0;                  //(P3.4/ECI_2, P3.5/CCP0_2, P3.6/CCP1_2, P3.7/CCP2_2)   P_SW1 = ACC;   //   //  ACC = P_SW1; //  ACC = ~(CCP_S0 | CCP_S1);      //CCP_S0=0 CCP_S1=1 //  ACC |= CCP_S1;                  //(P2.4/ECI_3, P2.5/CCP0_3, P2.6/CCP1_3, P2.7/CCP2_3) //  P_SW1 = ACC;    CCON = 0;                       //初始化PCA控制寄存器                                     //PCA定时器停止                                     //清除CF标志                                     //清除模块中断标志     CL = 0;                         //复位PCA寄存器     CH = 0;     CMOD = 0x02;                    //设置PCA时钟源                                     //禁止PCA定时器溢出中断     PCA_PWM0 = 0x00;                //PCA模块0工作于8位PWM     CCAPM0 = 0x42;                  //PCA模块0为8位PWM模式     CCAP0H = CCAP0L = 0x00;         //PWM0的占空比初值       PCA_PWM1 = 0x00;                //PCA模块1工作于8位PWM     CCAPM1 = 0x42;                  //PCA模块1为8位PWM模式     CCAP1H = CCAP2L = 0x00;         //PWM1的占空比初值       PCA_PWM2 = 0x00;                //PCA模块2工作于8位PWM     CCAPM2 = 0x42;                  //PCA模块2为8位PWM模式     CCAP2H = CCAP2L = 0x00;         //PWM2的占空比初值   CR = 1;                         //PCA定时器开始工作   InitUart();                     //初始化串口     InitADC();                      //初始化ADC     while (1)     {         ShowResult(0);              //显示通道0     CCAP0H = CCAP0L = GetADCResult(0);//PWM0输出AD0通道的值         ShowResult(1);              //显示通道1     CCAP1H = CCAP1L = GetADCResult(1);//PWM1输出AD1通道的值         ShowResult(2);              //显示通道2     CCAP2H = CCAP2L = GetADCResult(2);//PWM2输出AD2通道的值 //        ShowResult(3);              //显示通道3 //        ShowResult(4);              //显示通道4 //        ShowResult(5);              //显示通道5 //        ShowResult(6);              //显示通道6 //        ShowResult(7);              //显示通道7 // Delay(10);     } }   /*---------------------------- 发送ADC结果到PC ----------------------------*/ void ShowResult(BYTE ch) {     SendData(ch);                   //显示通道号     SendData(GetADCResult(ch));     //显示ADC高8位结果   //    SendData(ADC_LOW2);           //显示低2位结果 // Delay(20);   }   /*---------------------------- 读取ADC结果 ----------------------------*/ BYTE GetADCResult(BYTE ch) {     ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;     _nop_();                        //等待4个NOP     _nop_();     _nop_();     _nop_();     while (!(ADC_CONTR ADC_FLAG));//等待ADC转换完成     ADC_CONTR = ~ADC_FLAG;         //Close ADC       return ADC_RES;                 //返回ADC结果 }   /*---------------------------- 初始化串口 ----------------------------*/ void InitUart() {     SCON = 0x5a;                //设置串口为8位可变波特率 #if URMD == 0     T2L = (65536 - (FOSC/4/BAUD));   //设置波特率重装值     T2H = (65536 - (FOSC/4/BAUD))8;     AUXR = 0x14;                //T2为1T模式, 并启动定时器2     AUXR |= 0x01;               //选择定时器2为串口1的波特率发生器 #elif URMD == 1     AUXR = 0x40;                //定时器1为1T模式     TMOD = 0x00;                //定时器1为模式0(16位自动重载)     TL1 = 0xd8;                 //设置波特率重装值     TH1 = 0xff;                 //115200 bps(65536-18432000/4/115200)     TR1 = 1;                    //定时器1开始启动 #else     TMOD = 0x20;                //设置定时器1为8位自动重装载模式     AUXR = 0x40;                //定时器1为1T模式     TH1 = TL1 = 0xfb;           //115200 bps(256 - 18432000/32/115200)     TR1 = 1; #endif }   /*---------------------------- 初始化ADC ----------------------------*/ void InitADC() {     P1ASF = 0xff;                   //设置P1口为AD口     ADC_RES = 0;                    //清除结果寄存器     ADC_CONTR = ADC_POWER | ADC_SPEEDLL;     Delay(2);                       //ADC上电并延时 }   /*---------------------------- 发送串口数据 ----------------------------*/ void SendData(BYTE dat) {     while (!TI);                    //等待前一个数据发送完成     TI = 0;                         //清除发送标志     SBUF = dat;                     //发送当前数据 }   /*---------------------------- 软件延时 ----------------------------*/ void Delay(WORD n) {     WORD x;       while (n--)     {         x = 5000;         while (x--);     } }    
相关资源