/*****************************************************
稳定的电位器控制舵机程序在多功能实验板通过验证
没用单片机片内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
**it rs=P2^7;
**it rw=P2^6; //已接地
**it lcden=P2^5;
**it pwm=P1^3; //第一路舵机
**it 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;
}
稳定的电位器控制舵机程序在多功能实验板通过验证
没用单片机片内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
**it rs=P2^7;
**it rw=P2^6; //已接地
**it lcden=P2^5;
**it pwm=P1^3; //第一路舵机
**it 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;
}