Using potentiometer to control motor infinite speed change through AD and PWM in STC12C2052AD microcontroller

Publisher:幸福之舞Latest update time:2021-07-02 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere


/********************************************************


        Function: Use potentiometer to control motor speed through STC12C2052AD chip AD and PWM


        MCU;STC12C2052AD


        Crystal oscillator: 12M



************************************************************/


#include //header file


#include //51 basic operations (including _nop_ empty function) 


#define uchar unsigned char


#define uint unsigned int


uint M;




/****************************************************


Function name: PWM initialization function


Call: PWM_init();


Parameters: None


Return value: None


Result: Initialize PCA to PWM mode with an initial duty cycle of 0


Note: If you need more PWM outputs, just plug them into CCAPnH and CCAPnL.


/************************************************************/


void PWM_init (void)


{


        CMOD=0x02; //Set PCA timer


          CL=0x00; 


          CH=0x00;


        CCAPM0=0x42; //PWM0 sets PCA working mode to PWM mode (0100 0010)


        CCAP0L=0x00; //Set the initial value of PWM0 to be the same as CCAP0H


          CCAP0H=0x00; // PWM0 is initially 0


        CCAPM1=0x42; //PWM1 sets PCA working mode to PWM mode (delete when using //)


        CCAP1L=0x00; //Set the initial value of PWM1 to be the same as CCAP0H


          CCAP1H=0x00; // PWM1 is initially 0


        //CCAPM2=0x42; //PWM2 sets PCA working mode to PWM mode


        //CCAP2L=0x00; //Set the initial value of PWM2 to be the same as CCAP0H


          //CCAP2H=0x00; // PWM2 is initially 0


        //CCAPM3=0x42; //PWM3 sets PCA working mode to PWM mode


        //CCAP3L=0x00; //Set the initial value of PWM3 to be the same as CCAP0H


          //CCAP3H=0x00; // PWM3 is initially 0


          CR=1; //Start PCA timer


}


/******************************************************************/


void delay(uint z)


{


        uint x,y;


        for(x=z;x>0;x--)


        for(y=420;y>0;y--);


}


/**********************************************************


Function name: PWM0 duty cycle setting function


Call: PWM0_set();


Parameter: 0x00~0xFF (0~255 can also be used)


Return value: None


Result: Set the PWM mode duty cycle, all high level when it is 0, all low level when it is 1


Note: If you need the setting function of PWM1, just change the 0 in CCAP0L and CCAP0H to 1.


/***************************************************/


void PWM0_set (uchar a) //p3^7 output PWM


{


        CCAP0L= a; //Set the value to be written directly into CCAP0L


          CCAP0H= a; //Set value directly write to CCAP0H


}


/***************************************************/


void PWM1_set (uchar a) //P3^5 output PWM


{


        CCAP1L= a; //Set value to be written directly into CCAP0L


          CCAP1H= a; //Set value to be written directly into CCAP0H


}


/************************AD conversion*******************************/


uchar Read (uchar CHA)


{  


        uchar AD_FIN=0; //Store A/D conversion flag  


/******The following is the ADC initialization program********************************/      


        CHA &= 0x07; //Select one of the 8 interfaces of ADC


// (0000 0111 clear high 5 bits)     


        ADC_CONTR = 0x40; //ADC conversion speed setting     


        _nop_(); _nop_(); _nop_(); _nop_();     


        ADC_CONTR |= CHA; //Select the current A/D channel     


        _nop_();_nop_(); _nop_(); _nop_();      


        ADC_CONTR |= 0x80; //Start A/D power supply      


        delay(2); //Let the input voltage stabilize (1ms is enough?  


/******The following is the ADC execution program********************************/


        ADC_CONTR |= 0x08; //Start A/D conversion (0000 1000 ADCS = 1)     


        _nop_();_nop_(); _nop_(); _nop_();    


        while (AD_FIN == 0)


        { //Wait for A/D conversion to finish      


                AD_FIN=(ADC_CONTR & 0x10); //0001 0000 Test whether A/D conversion is finished     


        }      


                ADC_CONTR &=0xE7; //1111 0111 clear ADC_FLAG bit, turn off A/D conversion, 


                return (ADC_DATA); //Return A/D conversion result (8 bits) 


}


void main (void)


{




        PWM_init(); //PWM initialization


        P1M0 = 0x01; //P1.0/P1.1: 0000 0011 (high impedance)  


        P1M1 = 0x00; //P1.0/P1.1: 0000 0000 ON=1;


// PWM0_set(80); //Set the initial PWM duty cycle


// PWM1_set (80);


        while(1)


        {         


                M=Read(0); //P1.0 port analog conversion  


                PWM0_set(M); //The conversion result is assigned to PWM0 P3^7 output duty cycle 


                M=Read(1); //P1.1 port analog conversion  


                PWM1_set(M); //Conversion result is assigned P3^5 output duty cycle to PWM0  


        }


}


Copy code


#ifndef __STC12C2052AD_H_


#define __STC12C2052AD_H_




/////////////////////////////////////////////////




/* The following is STC additional SFR or change */




/* sfr AUXR = 0x8e; */


/* sfr IPH = 0xb7; */




/* Watchdog Timer Register */


sfr WDT_CONTR = 0xe1;    




/* ISP_IAP_EEPROM Register */


sfr ISP_DATA = 0xe2;


sfr ISP_ADDRH = 0xe3;


sfr ISP_ADDRL = 0xe4;


sfr ISP_CMD = 0xe5;


sfr ISP_TRIG = 0xe6;


sfr ISP_CONTR = 0xe7;




/* IDLE, Clock Divider */


sfr IDLE_CLK = 0xc7;




/* I_O Port Mode Set Register */


sfr P0M0 = 0x93;


sfr P0M1 = 0x94;


sfr P1M0 = 0x91;


sfr P1M1 = 0x92;


sfr P2M0 = 0x95;


sfr P2M1 = 0x96;


sfr P3M0 = 0xb1;


sfr P3M1 = 0xb2;




/* SPI Register */


sfr SPSTAT = 0x84;


sfr SPCTL = 0x85;


sfr SPDAT = 0x86;




/* ADC Register */


sfr ADC_CONTR = 0xc5;


sfr ADC_DATA = 0xc6;


sfr ADC_LOW2 = 0xbe;


sfr P1ASF=0x9d;


sfr ADC_RES =0xbd;


sfr ADC_RESL = 0XBE;


//zhuanhuan sulv


#define ADC_SPEEDLL 0x00


#define ADC_SPEEDL 0X20


#define ADC_SPEEDH 0X40 //


#define ADC_SPEEDHH 0X60 //90




/* PCA SFR */


sfr CCON = 0xD8;


sfr CMOD = 0xD9;


sfr CCAPM0 = 0xDA;


sfr CCAPM1 = 0xDB;


sfr CCAPM2 = 0xDC;


sfr CCAPM3 = 0xDD;


sfr CCAPM4 = 0xDE;


sfr CCAPM5 = 0xDF;




sfr CL = 0xE9;


sfr CCAP0L = 0xEA;


sfr CCAP1L = 0xEB;


sfr CCAP2L = 0xEC;


sfr CCAP3L = 0xED;


sfr CCAP4L = 0xEE;


sfr CCAP5L = 0xEF;




sfr CH = 0xF9;


sfr CCAP0H = 0xFA;


sfr CCAP1H = 0xFB;


sfr CCAP2H = 0xFC;


sfr CCAP3H = 0xFD;


sfr CCAP4H = 0xFE;


sfr CCAP5H = 0xFF;




sfr PCA_PWM0 = 0xF2;


sfr PCA_PWM1 = 0xF3;


sfr PCA_PWM2 = 0xF4;


sfr PCA_PWM3 = 0xF5;


sfr PCA_PWM4 = 0xF6;


sfr PCA_PWM5 = 0xF7;




/* CCON */


sbit CF = CCON^7;


sbit CR = CCON^6;


sbit CCF5 = CCON^5;


sbit CCF4 = CCON^4;


sbit CCF3 = CCON^3;


sbit CCF2 = CCON^2;


sbit CCF1 = CCON^1;


sbit CCF0 = CCON^0;




/* Above is STC additional SFR or change */




/*--------------------------------------------------------------------------


REG51F.H




Header file for 8xC31/51, 80C51Fx, 80C51Rx+


Copyright (c) 1988-1999 Keil Elektronik GmbH and Keil Software, Inc.


All rights reserved.




Modification according to DataSheet from April 1999


- SFR's AUXR and AUXR1 added for 80C51Rx+ derivatives


--------------------------------------------------------------------------*/




/* BYTE Registers */


sfr P0 = 0x80;


sfr P1 = 0x90;


sfr P2 = 0xA0;


sfr P3 = 0xB0;


sfr PSW = 0xD0;


sfr ACC = 0xE0;


sfr B = 0xF0;


sfr SP = 0x81;


sfr DPL = 0x82;


sfr DPH = 0x83;


sfr PCON = 0x87;


sfr TCON = 0x88;


sfr TMOD = 0x89;


sfr TL0 = 0x8A;


sfr TL1 = 0x8B;


sfr TH0 = 0x8C;


sfr TH1 = 0x8D;


sfr IE = 0xA8;


sfr IP = 0xB8;


sfr SCON = 0x98;


sfr SBUF = 0x99;




/* 80C51Fx/Rx Extensions */


sfr AUXR = 0x8E;


/* sfr AUXR1 = 0xA2; */


sfr SADDR = 0xA9;


sfr IPH = 0xB7;


sfr SADEN = 0xB9;


sfr T2CON = 0xC8;


sfr T2MOD = 0xC9;


sfr RCAP2L = 0xCA;


sfr RCAP2H = 0xCB;


sfr TL2 = 0xCC;


sfr TH2 = 0xCD;






/* BIT Registers */


/* PSW */


sbit CY = PSW^7;


sbit AC = PSW^6;


sbit F0 = PSW^5;


sbit RS1 = PSW^4;


sbit RS0 = PSW^3;


sbit OV = PSW^2;


sbit P = PSW^0;




/* TCON */


sbit TF1 = TCON^7;


sbit TR1 = TCON^6;


sbit TF0 = TCON^5;


sbit TR0 = TCON^4;


sbit IE1 = TCON^3;


sbit IT1 = TCON^2;


sbit IE0 = TCON^1;


sbit IT0 = TCON^0;




/* P3 */


sbit RD = P3^7;


sbit WR = P3^6;


sbit T1 = P3^5;


sbit T0 = P3^4;


sbit INT1 = P3^3;


sbit INT0 = P3^2;


sbit TXD = P3^1;


sbit RXD = P3^0;




/* SCON */


sbit SM0 = SCON^7; // alternatively "FE"


sbit FE = SCON^7;


sbit SM1 = SCON^6;


sbit SM2 = SCON^5;


sbit REN = SCON^4;


sbit TB8 = SCON^3;


sbit RB8 = SCON^2;


sbit TI = SCON^1;


sbit RI = SCON^0;


             




sbit T2EX = P1^1;


sbit T2 = P1^0;




/* T2CON */


sbit TF2 = T2CON^7;


sbit EXF2 = T2CON^6;


sbit RCLK = T2CON^5;


sbit TCLK = T2CON^4;


sbit EXEN2 = T2CON^3;


sbit TR2 = T2CON^2;


sbit C_T2 = T2CON^1;


sbit CP_RL2 = T2CON^0;




/* PCA Pin */




sbit CEX3 = P2^4;


sbit CEX2 = P2^0;


sbit CEX1 = P3^5;


sbit CEX0 = P3^7;


sbit ECI = P3^4;




/* IE */


sbit EA = IE^7;


sbit EPCA_LVD = IE^6;


sbit EADC_SPI = IE^5;


sbit ES = IE^4;


sbit ET1 = IE^3;


sbit EX1 = IE^2;


sbit ET0 = IE^1;


sbit EX0 = IE^0;




/* IP */ 


sbit PPCA_LVD = IP^6;


sbit PADC_SPI = IP^5; 


sbit PS = IP^4;


sbit PT1 = IP^3;


sbit PX1 = IP^2;


sbit PT0 = IP^1;


sbit PX0 = IP^0;




/////////////////////////////////////////////////




#endif


Reference address:Using potentiometer to control motor infinite speed change through AD and PWM in STC12C2052AD microcontroller

Previous article:Solution to LCD screen not displaying due to excessive pull-up of MCU
Next article:PWM adjusts the brightness of 2 LEDs from 00 to FF, with 255 levels of brightness automatically adjusted

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号