|
用電位器經過單片機片內AD再由定時器產生PWM控制舵機角度- /*****************************************************
- 穩定的電位器控制舵機程序在多功能實驗板通過驗證
- 沒用單片機片內PWM
- 功能 :用電位器通過單片機片內AD再經過定時器產生
- PWM信號控制舵機角度,
- 舵機角度隨電位器旋轉同步轉動.
- 1602顯示2路AD采集電壓值
- 單片機:STC12C5A60S2
- 晶振 :11.0592M
- 作者 :蘇義江
- 時間 :2016-6-5
- 注 釋; 單片機電壓由7805穩壓供給。舵機電壓由7806穩壓供給,
-
- ******************************************************/
- #include<stc12c5a60s2.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- /*Define ADC operation const for ADC_CONTR*/
- #define ADC_POWER 0x80 //ADC power control bit
- #define ADC_FLAG 0x10 //ADC complete flag 模數轉換結束標志位
- #define ADC_START 0x08 //ADC start control bit 模數轉換啟動控制位
- //轉換速度控制位SPEED0和SPEED1,共四種狀態,對應四種轉換速度
- #define ADC_SPEEDLL 0x00 //540 clocks
- #define ADC_SPEEDL 0x20 //360 clocks
- #define ADC_SPEEDH 0x40 //180 clocks
- #define ADC_SPEEDHH 0x60 //90 clocks
- sbit rs=P2^7;
- sbit rw=P2^6; //已接地
- sbit lcden=P2^5;
- sbit pwm=P1^3; //第一路舵機
- sbit pwm1=P1^4;//第二路舵機
-
- uint temp,bai,shi,ge;
- uint ADtemp,ADtemp1; //定義全局變量
- uint high,low;
- static uint count1;
- void write_com(uchar);
- void write_data(uchar);
- void delay(uint x) //簡單延時
- {
- uint a,b;
- for(a=x;a>0;a--)
- for(b=400;b>0;b--);
- }
- //AD初始化
- void InitADC()
- {
- P1ASF = 0x03; //設置P1,0.P1,1口為AD口
- ADC_RES = 0;
- //清除結果寄存器
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
- delay(2); //ADC上電并延時
- }
- /*********************************
- 讀取第幾路ADC結果
- ***********************************/
- uint GetADCResult(uchar ch)
- {
- int V;
- 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
- V=ADC_RES;
- return V;
- }
- void display(float ver) //液晶顯示 第一路AD
- {
- temp=(int)ver;
- bai=temp/100+0x30;
- shi=temp%100/10+0x30;
- ge=temp%10+0x30;
- write_com(0x87) ;
- write_data(bai);
- write_data('.');
- write_data(shi);
- write_data(ge);
- }
- void display1(float ver) //液晶顯示 第二路AD
- {
- temp=(int)ver;
- bai=temp/100+0x30;
- shi=temp%100/10+0x30;
- ge=temp%10+0x30;
- write_com(0x80+0x47) ;
- write_data(bai);
- write_data('.');
- write_data(shi);
- write_data(ge);
- }
- void write_com(uchar com) //寫指令
- {
-
- rs=0;
- rw=0;
- lcden=0;
- P0=com;
- delay(10);
- lcden=1;
- delay(10);
- lcden=0;
- }
- void write_data(uchar date) //寫數據
- {
-
- rs=1;
- rw=0;
- lcden=0;
- P0=date;
- delay(10);
- lcden=1;
- delay(10);
- lcden=0;
- }
- void LCD_init() //液晶顯示初始化
- {
- write_com(0x38);
- _nop_();
- write_com(0x06);
- _nop_();
- write_com(0x01);
- _nop_();
- write_com(0x0c);
- _nop_();
- write_com(0x83) ;
- write_data('V');
- write_data('1');
- write_data('=');
- write_com(0x80+0X43) ;
- write_data('V');
- write_data('2');
- write_data('=');
- }
- void pwm_init_t0() //PWM波初始化
- {
- TMOD |=0x01;
- //定時器設置 0.1ms in 11.0592M crystal
- TH0=(65536-78)/256;
- TL0=(65536-78)%256; //定時0.1mS
- ET0=1;//定時器中斷打開
- EA=1;//總中斷
- TR0=1; //啟動定時器0
- }
- void main() //主函數
- {
- uint angle,angle1;
- pwm_init_t0(); //PWM波初始化
- LCD_init();
- InitADC();
- ADtemp=GetADCResult(0);
- high=65075-7.2*ADtemp;
- low=47563+7.2*ADtemp;
- ADtemp1=GetADCResult(1);
- high=65075-7.2*ADtemp1;
- // ( high=65035-7.8*ADtemp;12MHz)
- //(65535-(460+7.2*ADtemp 11.0592MHz)
- low=47563+7.2*ADtemp1;
- // ( low=46035+7.8*ADtemp; )
- //( 65535-(17972-7.2*ADtemp 11.0592MHz )
-
-
- while(1)
- { angle=ADtemp*1.8;
- angle1=ADtemp1*1.8;
- ADtemp=GetADCResult(0);
- high=65075-7.2*ADtemp;
- low=47563+7.2*ADtemp;
- ADtemp1=GetADCResult(1);
- high=65075-7.2*ADtemp1;
- low=47563+7.2*ADtemp1;
- display(angle);
- display1(angle1);
- }
- }
- void time0() interrupt 1 //定時器T1
- {
- static uchar count;
-
- if (!count)
- {
- pwm = 1; //第一路給高電平
- pwm1= 1; //第二路給高電平
- TH0=high/256;
- TL0=high%256; //定時0.05mS,經過示波器的測量
- }
- else
- {
- pwm =0 ; //第一路給低電平
- pwm1=0; //第二路給低電平
- TH0=low/256;
- TL0=low%256; //定時0.05mS,經過示波器的測量
- }
- count=~count;
-
- }
復制代碼
|
|