C ++“未在此范围内声明”编译错误和修改提示
我试图修改这段代码,试图让它在Arduino Mega上运行。 我对C非常陌生,所以我可能犯了一些重大错误。 顺便说一下,这是一个自平衡滑板。 :P
此代码取自ATmega32(来自:[url = http://sites.google.com/site/onewheeledselfbalancing/Home/twin-wheel-self-balancing-skateboard-lightweight-version/code4] http:// sites .google.com / site / onewheeledsel ... t-version / code4 [/ url],我试图让它在Arduino Mega上运行。
这段代码是为ATmega32开发板编写的http://www.active-robots.com/products/controllr/m32db.shtml
谢谢!
这是我遇到的第一个错误:
在函数'void timer_init()'中:错误:'TCCR0'未在此范围内声明在函数'int main()'中:
有人能解释我有什么不对吗? 我几乎是编程的初学者,但我已经阅读了很多书籍/网站,我也学得很快! ^^这里是完整的代码(它很长):
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <math.h>
定义CLOCK_SPEED 16000000
定义OCR1_MAX 1023
typedef unsigned char u8; void set_motor_idle(void); void InitPorts(void); float level = 0; float Throttle_pedal; 浮动aa; 浮动加速度; float x_acc; float accsum; float x_accdeg;
浮动陀螺仪
float gangleratedeg; 漂浮gang rate草 float ti = 2.2;
浮动整体增长; 浮动增益控制; float batteryvolts = 24; 浮动陀螺仪 浮动角度; float anglerads; float balance_torque; float softstart;
float cur_speed; float cycle_time = 0.0064; float balance_point; float a0,a1,a2,a3,a4,a5,a6; //用于加速度计的Savitzky-Golay变量
int i; int j; int tipstart; void InitPorts(void){PORTC = 0x00; //端口C上拉设置为低电平(无输出电压),以DDRC = 0xFF开头; //端口C的引脚全部通过端口C的方向寄存器设置为输出// PORTC | =(1 <
DDRA = 0×00; //所有端口A引脚设置为输入PORTA = 0x00; //端口A输入上拉设置为低拉低
DDRD = 0xFF的; //将所有端口D引脚配置为OCR1A(PinD5)和OCR1B(引脚D4)正常工作的先决条件
PORTB = 0×00; //端口B上拉设置为低(无输出电压),以DDRB = 0xFF开头; //将所有端口B引脚设置为输出
} / * IO:我使用带外部晶振的ATMega32 16MHz。 OSMC马达控制器PC4的新计划引脚排列板载LED PD5 / OC1A ALI - > OSMC引脚6 PD4 / OC1B BLI - > OSMC引脚8 PC1禁用 - > OSMC引脚4 PC2 BHI - > OSMC引脚7 PC3 AHI - > OSMC引脚5 PA6 / ADC6 Vbatt / 10 - > OSMC引脚3 PA1 / ADC1螺距速率陀螺仪PA0 / ADC0加速度计/ void adc_init(void){/关闭模拟比较器,因为我们不使用它/ ACSR =(1 << ACD); /选择PA0 / ADMUX = 0; ADMUX | =(1 <将ADC预分频器设置为128,使能ADC并开始转换/ ADCSRA = 0 |(1 <等待直到假转换完成* / while(ADCSRA&(1 << ADSC)){}}
uint16_t adc_read(uint8_t channel){
/ *选择通道/ ADMUX =通道; ADMUX | =(1 <开始转换/
ADCSRA | =(1 << ADSC); /等待转换完成/ while(ADCSRA&(1 << ADSC)){} /返回结果* /返回ADCW; }
/ *每秒156个周期,每个周期6.4ms MEASURED ON OSCILLOSCOPE * / / *读取所有ADC输入并做一些转换* / void sample_inputs(void){
uint16_t adc0, adc1, adc2, adc3, adc4, adc5;
gyrosum=0; adc0 = adc_read(0); /* accelerometer pin PA0 */ accelraw
=(float)adc0; for(j = 0; j <7; j ++){adc1 = adc_read(1); //陀螺仪引脚PA1 gyrosum =(浮动)gyrosum + adc1; //使用每个回路7个样本的平均值作为陀螺仪,以便在程序的每个循环都得到完整更新}
adc2 = adc_read(2); /* grey wire overallgain (via cutout switch)
位置PA2 * / adc3 = adc_read(3); / *定位杆拉回位置PA3 * / adc4 = adc_read(4); / * Throttle_pedal位置PA4 * / adc5 = adc_read(5); / *位置杆向前推动位置PA5 * / // adc6 = adc_read(6); / * OSMC的Vbatt输入(目前未使用)位置PA6 * / // Sav Golay滤波器仅用于加速a0 = a1; a1 = a2; a2 = a3; a3 = a4; a4 = a5; a5 = a6; a6 =(float)accelraw; accsum =(float)(( - 2 * a0)+(3 * a1)+(6 * a2)+(7 * a3)+(6 * a4)+(3 * a5)+( - 2 * a6)) / 21; // Sav Golay计算
gaincontrol = (float) gaincontrol*0.9 + 0.1*adc2/341;
//平滑任何电压尖峰并给出范围0-3 Throttle_pedal =(float)Throttle_pedal * 0.9 + 0.1 * adc4 / 341; //平滑任何电压尖峰并给出范围0-3
//如果dead mans按钮被释放,则切断电机//(如果(adc2 <100){Throttle_pedal = 0.001; gaincontrol = 0.001;} totalgain = gaincontrol * softstart; // gaincontrol变量也通过此按钮接入adc2如果杠杆拉回或向前推动或者没有做任何事情该怎么办:Balance_point = 514; if(adc3> 100)Balance_point = 534;
如果(adc5> 100)Balance_point = 494;
PORTB |= (1<<PB2);//Port B2 turned on/off once per loop so I can
用示波器测量回路时间
/ ACCELEROMETER信号处理//减去偏移量/ x_acc =(float)accsum - Balance_point; // accsum是加速度计的SG值,不是真正的“总和”,因此如果(x_acc <-250)x_acc = -250,则不需要除以7; //将加速度值加上-250到+250的范围(每个方向倾斜80度)if(x_acc> 250)x_acc = 250; / *加速度计角度变化在0-30度范围内每度倾斜约3.45单位(sinθ)将加速度传感器的倾斜度转换为倾斜度。 Sin角粗略=小角度的角度,因此不需要做三角函数。 下面的x_acc现在是DEGREES * /
x_accdeg =(float)x_acc / -3.45; //减号可以纠正后置加速度计的安装!
/*GYRO signal processing*/
/*Subtract offsets: Sensor reading is 0-1024 so "balance point"
即我所要求的零点将是读数减去512 * /
/陀螺仪角度变化为20mV每度每秒从数据表给出4.096单位(在0 - 1023的范围内)每度每秒角度变化的变化这将陀螺仪角度的变化率限制为仅低于其最大速率实际上能够测量(100deg / sec)。 注意,所有这些分数在它被发送到PWM发生器之前被四舍五入为整数,然后PWM发生器连接到电机控制器/ gangleratedeg =(float)((gyrosum / 7) - 508)/4.096; // gyrosum是一组7个样本的总和,所以如果(gangleratedeg <-92)gangleratedeg = -92,则陀螺仪值除以7; 如果(gangleratedeg
92)gangleratedeg = 92 /我在每个主程序循环中打开和关闭端口B2一次,这样我就可以将示波器连接到它并计算程序循环时间我使用循环时间来计算每个循环的陀螺仪角度变化,您必须知道这个时间间隔的长度/ PORTB&=(0 <
/ ti表示“i”或积分因子(此处为2.2)的缩放比例,gyroangledt是自上一次陀螺仪传感器周期后的角度变化,其中ti是比例因子(理论上应为大约1,但2.2会使板材感觉更紧)
ganglerate现在以度/秒为单位aa改变时间常数,即较小的aa值使得加速度计时间常数更长,因为它缓慢地校正陀螺仪漂移/
AA = 0.005; gyroangledt =(float)ticycle_timegangleratedeg;
gangleraterads =(浮点)gangleratedeg * 0.017453;
/角度=(float)((1-aa)*(角度+ gyroangledt))+(aa * x_accdeg)/ DEGREES中的新角度是旧角度加上自上一周期起陀螺仪角度的变化); //主角度计算函数* / //将角度从度数转换为弧度
anglerads=(float)angle*0.017453;
balance_torque=(float)(4.5*anglerads)
+(0.5 * gangleraterads);
cur_speed =(float)(cur_speed +(Throttle_pedal * balance_torque * cycle_time))* 0.999;
/ *电平值从-1到+1,表示要发送到电机的占空比。 转换为弧度有助于我们保持在这些限制之内level =(balance_torque + cur_speed)* overallgain;
}
void timer_init(){TCCR0 = 0 | (1 <
// PWM模式为“PWM,相位正确,10位”TCCR1A = 0 | (1 <
(1 <
void set_motor()
/ * leveli术语是从-1023到+1023重新定标的整数,作为一个整数准备发送到PWM电机控制端口,该端口依次连接到OSMC * / {
//如果(level <-0.9)level = -0.9; //检查我们是否在合理的范围内// if(level> 0.9)level = 0.9;
int16_t leveli =(int16_t)(level * 1023); //注意这里我们取浮点值作为“level”的结尾,我们将它乘以1023,然后在将值送入PWM发生器之前将其作为一个整数,作为“leveli”
如果(leveli <-1020)leveli = -1020; //双重检查我们是否在合理的PWM限制范围内,因为如果(leveli> 1020)leveli = 1020,不想突然从板上抛出。
/设置端口B1上的LED或蜂鸣器,如果要输出的扭矩大于最大可能值的50%,则警告我减速。原因是,如果开始以速度向前倾斜,则始终需要一些备用电机功率。If电机已经平稳运转,您将快速倒下! 有些使用自动回头程序自动限制最高速度。 现在我会这样做,因为更容易/
如果(级别<-0.7 ||级别> 0.7){
PORTB | =(1 <PORTB&=(0 <
softstart =(float)softstart + 0.001; 如果(softstart> 1.0)softstart = 1.0;
//PORTC |= (0<<PC1); // AHI=1 PinC3, BHI=1 PinC2 set both to ON for
OSMC工作,两者都关闭以关闭电机/ *注意:不知道为什么,但停止电机切换的方向变化我最终硬接线AHI和BHI到+ 12V / /未禁用OSMC通过设置PinC1输出为零,1将禁用OSMC * / PORTC | = 0x0c; //使C1下拉以禁用OSMC,即启用它。 PORTC&=〜0x02; //关闭if(leveli <0){OCR1A = -leveli; // ALI是PWM后退,因为leveli变量是一个负的有符号值,在这里保留减号! OCR1B = 0; // BLI = 0} else {OCR1A = 0; // ALI = 0继续前进,因为leveli变量是正数有符号值OCR1B = leveli; // BLI是PWM}}
int main(void){InitPorts();
adc_init();
timer_init();
/ *初始倾斜启动代码当板倾斜到一边时,打开微动,如果倾斜角度过零(中),平衡点算法变为可操作,否则永久锁定在该循环中,直到其倾斜到水平位置作为骑手登上* / tipstart = 0; accelraw = 0;
while(tipstart <1){
//在您查看accsum(下面)的值之前,您首先打开机器时需要使用此功能以允许SG过滤器达到适当的稳定值。
for(i = 0; i <20; i ++){
sample_inputs();
}
如果(accsum <504 || accsum> 524){//
if(x_accdeg> 0){tipstart = 0; } else {tipstart = 1;
软启动= 0.4; }}
角= 0; cur_speed = 0; / *结束倾斜起始码。 如果超出这一点,那么机器已经成为水平并且是活跃的* /
SEI();
while(1){sample_inputs();
set_motor();
}}
您最有可能为您的构建指定了错误的MCU。 尽管Arduino Mega上的ATmega1280上存在DDRA,但在常规Arduino的ATmega328上不存在DDRA。
如果您使用的是Arduino UI,请转至工具| 董事会并选择Arduino兆丰。
如果您使用自己的构建系统,则需要更新您在gcc命令行上为-mmcu =指定的值。
我想你可能在这里留下了一个结束语:
/*The level value is from -1 to +1 and represents the duty cycle to be sent to the motor. Converting to radians helps us stay within these limits >>>*/<<<
当编译器告诉你“在这个范围内没有声明”时,你自己也是这个问题:
什么范围被宣布?
如果你不能回答这个问题,那么你已经发现了这个问题。 毕竟,如果你不知道这个名字是指什么的话,你怎么期待编译器呢? 请记住,您是您编写的任何代码的专家。
如果您可以确定声明的范围,那么接下来的任务是确定该范围与您尝试使用它的范围的关系。典型问题包括(但不限于)以下内容:
::
scope-resolution操作符给出完全限定的名称。 如果你找不到它在什么范围内被宣布,那么有几件事可能是错误的:
#include
指令。 这可能是你的情况的问题。 上一篇: C++ “was not declared in this scope” compile error and modification tips