|
最近在研究多個(gè)舵機(jī)的控制,上網(wǎng)找了很多資料,編寫(xiě)了一個(gè)程序,用三個(gè)電位器分別控制三個(gè)舵機(jī),只用tc0定時(shí)計(jì)數(shù)器,最后無(wú)法實(shí)現(xiàn),原理是對(duì)的,不知道哪里出了問(wèn)題,程序如下:
#include <iom16v.h>
#include <macros.h>
#include "1602LCD_drive.h"
//unsigned char line1_data[]={"ADC1:"}; //
//unsigned char line2_data[]={"ADC3:"};
//unsigned char line3_data[]={"ADC2:"};
#define uchar unsigned char
#define uint unsigned int
#define OUTPUT PORTC
#define SER0 0x01
#define SER1 0x02
#define SER2 0x04
#define ADCN ADMUX
#define ADC0 0x40
#define ADC1 0x41
#define ADC2 0x42
char Counter=1;
char num=0;
char time=0;
/************延時(shí)函數(shù)***********/
void delay(unsigned int ms)
{
unsigned int i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<1141;j++);
}
}
/*********端口設(shè)置函數(shù)*********/
void port_init(void)
{
PORTB=0XFF; //設(shè)置1602端口的
DDRB=0XFF;
DDRD=0XFF;
PORTD=0Xff;
DDRC=0XFF; //設(shè)置pc口為舵機(jī)pwm輸出
PORTC|=0X00;
DDRA&=0X00; //adc口設(shè)為輸入,帶上啦電阻
PORTA|=0Xff;
}
void timer0_init()
{
SREG=0X80;
TIMSK|=(1<<TOIE0); //是能溢出中斷
TCCR0|=(0<<CS02)|(0<<CS01)|(1<<CS00); //12mhz晶振 無(wú)預(yù)分頻60/12m=5us
TCNT0=0; //計(jì)數(shù)器初值
}
/**********ad轉(zhuǎn)換函數(shù)**********/
unsigned int adc_()
{
unsigned int addata;
ADMUX=0X40; //AVCC為基準(zhǔn)電,AD0為輸入通道 01000010
ADCSRA=0XC0; //使能ADC,自動(dòng)連續(xù)轉(zhuǎn)換 11000000
ADCSRA|=BIT(ADSC); //開(kāi)始A/D轉(zhuǎn)換
while(!(ADCSRA&(BIT(ADIF)))); //等待轉(zhuǎn)換完成
addata=ADCL; //獲取ADC結(jié)果
addata=addata+ADCH*256;
return addata; //返回ADC值
}
/**ADC通道轉(zhuǎn)換函數(shù)**/
uint adc_change()
{
unsigned int ada, adcx;
ada=adc_();
adcx=ada/2.5+100;
return adcx;
}
/********************主函數(shù)**********************/
void main()
{
port_init();
adc_();
timer0_init();
adc_change();
}
#pragma interrupt_handler timer0_ovf:10
void timer0_ovf()
{
TCNT0=196; //重新賦值256-196=60,溢出一次等于5us
adc_change(); //adc值轉(zhuǎn)換成counter計(jì)數(shù)值最大值
Counter++;
time++;
if(num==0&&Counter<=1) //這里
{
ADCN=ADC0; //設(shè)置adc通道為adc0
OUTPUT|=SER0; //輸出口為PC0
//k[0]=adc_change()/100;
//k[1]=(adc_change()%100)/10;
//LCD_write_char(14,1,k[0]+0x30);
//LCD_write_char(15,1,k[1]+0x30);
}
if(num==1&&Counter<=1)
{
ADCN=ADC1; //adc通道為adc1
OUTPUT|=SER1; //修改輸出口為pc1
//k[0]=adc_change()/100;
//k[1]=(adc_change()%100)/10;
//LCD_write_char(5,1,k[0]+0x30);
//LCD_write_char(6,1,k[1]+0x30);
}
if(num==2&&Counter<=1)
{
ADCN=ADC2; //adc通道為adc2
OUTPUT|=SER2; //輸出口為pc2
}
if(Counter>=adc_change()) //如果計(jì)數(shù)值大于adc轉(zhuǎn)換值
{
OUTPUT&=0X00; //所有輸出口拉低
num=num+1; //num+1
Counter=0; //重新計(jì)數(shù)
if(num>=3) //num大于三所有c口拉低
OUTPUT&=0X00;
}
if(time>=4000) //計(jì)數(shù)達(dá)到4000?4000*5us=20000us=20ms為舵機(jī)周期
{
num=0; //全部重新賦值
time=0;
Counter=0;
}
}
小白一個(gè),求大神指教!
|
|