|
用电位器经过单片机片内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;
-
- }
复制代码
|
|