该程序应该从Wii远程读取加速度值,并根据这些值启动LED。我遇到的唯一防止汇编的错误是pbase在main.cpp中未定义。main.cpp包括zedboard.h和zedboard.cpp,其中定义了PBASE,因此我无法在此处看到该问题。我已经尝试解决了一段时间,但我无法弄清楚。
zedboard.h
#ifndef ZEDBOARD_H
#define ZEDBOARD_H
const int gpio_led1_offset = 0x12C; // Offset for LED1
const int gpio_led2_offset = 0x130; // Offset for LED2
const int gpio_led3_offset = 0x134; // Offset for LED3
const int gpio_led4_offset = 0x138; // Offset for LED4
const int gpio_led5_offset = 0x13C; // Offset for LED5
const int gpio_led6_offset = 0x140; // Offset for LED6
const int gpio_led7_offset = 0x144; // Offset for LED7
const int gpio_led8_offset = 0x148; // Offset for LED8
const int gpio_sw1_offset = 0x14C; // Offset for Switch 1
const int gpio_sw2_offset = 0x150; // Offset for Switch 2
const int gpio_sw3_offset = 0x154; // Offset for Switch 3
const int gpio_sw4_offset = 0x158; // Offset for Switch 4
const int gpio_sw5_offset = 0x15C; // Offset for Switch 5
const int gpio_sw6_offset = 0x160; // Offset for Switch 6
const int gpio_sw7_offset = 0x164; // Offset for Switch 7
const int gpio_sw8_offset = 0x168; // Offset for Switch 8
const int gpio_pbtnl_offset = 0x16C; // Offset for left push button
const int gpio_pbtnr_offset = 0x170; // Offset for right push button
const int gpio_pbtnu_offset = 0x174; // Offset for up push button
const int gpio_pbtnd_offset = 0x178; // Offset for down push button
const int gpio_pbtnc_offset = 0x17C; // Offset for center push button
// Physical base address of GPIO
const unsigned gpio_address = 0x400d0000;
// Length of memory-mapped IO window
const unsigned gpio_size = 0xff;
// Class Definition
class ZedBoard {
private:
char *pBase; // virtual address where I/O was mapped
int fd; // file descriptor for dev memory
int dummyValue; // for testing without a Zedboard
public:
ZedBoard(); // Default Constructor
~ZedBoard(); // Destructor
void RegisterWrite(char *pBase, int offset, int value);
int RegisterRead(int offset);
void Write1Led(char *pBase, int ledNum, int state);
void WriteAllLeds(int value);
int Read1Switch(int switchNum);
int ReadAllSwitches();
};
#endif
zedboard.cpp
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <iostream>
#include "ZedBoard.h"
using namespace std;
/**
* Constructor Initialize general-purpose I/O
* - Opens access to physical memory /dev/mem
* - Maps memory at offset 'gpio_address' into virtual address space
*
* @param None Default constructor does not need arguments.
* @return None Default constructor does not return anything.
*/
ZedBoard::ZedBoard(){
cout << "nStarting...." << endl;
// dummyValue = 99;
// Uncomment this block of code when connected to the Zedboard
fd = open( "/dev/mem", O_RDWR);
pBase = (char *) mmap(NULL,gpio_size,PROT_READ | PROT_WRITE,
MAP_SHARED,fd,gpio_address);
// Check error
if (pBase == MAP_FAILED)
{
cerr << "Mapping I/O memory failed - Did you run with 'sudo'? n";
exit(1); // Returns 1 to the operating system;
}
}
/**
* Destructor to close general-purpose I/O.
* - Uses virtual address where I/O was mapped.
* - Uses file descriptor previously returned by 'open'.
*
* @param None Destructor does not need arguments.
* @return None Destructor does not return anything.
*/
ZedBoard::~ZedBoard(){
munmap(pBase, gpio_size);
}
/*
* Write a 4-byte value at the specified general-purpose I/O location.
*
* - Uses base address returned by 'mmap'.
* @parem offset Offset where device is mapped.
* @param value Value to be written.
*/
void ZedBoard::RegisterWrite(char *pBase, int offset, int value)
{
* (int *) (pBase + offset) = value;
// dummyValue = value;
}
/**
* Read a 4-byte value from the specified general-purpose I/O location.
- Uses base address returned by 'mmap'.
@param offset Offset where device is mapped.
@return Value read.
*/
int ZedBoard::RegisterRead(int offset)
{
return * (int *) (pBase + offset);
// return dummyValue;
}
/*
Changes the state of an LED (ON or OFF)
- Uses base address of I/O
@param ledNum LED number (0 to 7)
@param state State to change to (ON or OFF)
*/
/*
Show lower 8 bits of integer value on LEDs
- Calls Write1Led() to set all LEDs
@param value Value to show on LEDs
*/
void ZedBoard::WriteAllLeds(int value)
{
cout << "nWriting to all LEDs...." << endl;
for(int i = 0; i < 8; i++) {// write to all LEDs
Write1Led(pBase, i, (value / (1<<i)) % 2);
}
}
void ZedBoard::Write1Led(char *pBase, int ledNum, int state)
{
cout << "nWriting to LED " << ledNum << ": LED state = " << state << endl;
if (ledNum == 1)
{
RegisterWrite(pBase, gpio_led1_offset, state);
}
else
{
RegisterWrite(pBase, gpio_led1_offset + (ledNum * 4), state);
}
}
/*
Reads the value of a switch
- Uses base address of I/O
@param switchNum Switch number (0 to 7)
@return Switch value read
*/
int ZedBoard::Read1Switch(int switchNum)
{
cout << "nReading Switch " << switchNum << endl;
//return RegisterRead(gpio_sw1_offset + (switchNum * 4));
return switchNum;
}
/*
Reads the switch values into a decimal integer
- Calls Read1Switch() to read all switches
@return Switches' value read
*/
int ZedBoard::ReadAllSwitches()
{
int switchValue = 0;
cout << "nReading all switches...." << endl;
for(int i = 7; i >= 0; i--) {// read all switches
switchValue = (switchValue << 1) + Read1Switch(i);
}
return switchValue;
}
wiimoteaccel.h
#ifndef WIIMOTEACCEL_H
#define WIIMOTEACCEL_H
class WiimoteAccel{
public:
WiimoteAccel();
~WiimoteAccel();
void Wiimote();
void Listen();
virtual void AccelerationEvent(int code, int acceleration);
private:
int fd;
};
#endif
WiimoteAccel.cpp
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include "ZedBoard.h"
#include "WiimoteAccel.h"
WiimoteAccel::WiimoteAccel()
{
}
WiimoteAccel::~WiimoteAccel()
{
}
void WiimoteAccel::Wiimote()
{
fd = open("/dev/input/event0", O_RDONLY);
if (fd == -1)
{
std::cerr << "Error: Could not open event file - forgot sudo?n";
exit(1);
}
}
void WiimoteAccel::Listen()
{
for (;;)
{
// Read a packet of 16 bytes from Wiimote
char buffer[16];
read(fd, buffer, 16);
// Extract code (byte 10) and value (byte 12) from packet
int code = buffer[10];
short acceleration = * (short *) (buffer + 12);
this->AccelerationEvent(code, acceleration);
}
}
void WiimoteAccel::AccelerationEvent(int code, int acceleration)
{
// Print them
std::cout << "Code = " << code << ", acceleration = " << acceleration << 'n';
}
main.cpp
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include "WiimoteAccel.h"
#include "ZedBoard.h"
#include "ZedBoard.cpp"
using namespace std;
class WiimoteToLed : public WiimoteAccel {
private:
ZedBoard* zed_board;
public:
WiimoteToLed(ZedBoard* zed_board);
~WiimoteToLed();
void AccelerationEvent(int code, int acceleration)
{
int x = 0;
for(;;)
{
if (code == 3)
{
cout << "ACCELERATION IS "<< acceleration <<"!n";
if(acceleration == 0)
{
x = 0;
}
else if(acceleration > -100 && acceleration <= -75)
{
x = 1;
}
else if(acceleration > -75 && acceleration <= -50)
{
x = 2;
}
else if(acceleration > -50 && acceleration <= -25)
{
x = 3;
}
else if(acceleration > -25 && acceleration > 0)
{
x = 4;
}
else if(acceleration < 0 && acceleration >= 25)
{
x = 5;
}
else if(acceleration < 25 && acceleration >= 50)
{
x = 6;
}
else if(acceleration < 50 && acceleration >= 75)
{
x = 7;
}
else if(acceleration < 75 && acceleration >= 100)
{
x = 8;
}
switch(x)
{
case 0:
cout << "Wiimote isn't movingn";
zed_board->Write1Led(pBase,1,0);
zed_board->Write1Led(pBase,2,0);
zed_board->Write1Led(pBase,3,0);
zed_board->Write1Led(pBase,4,0);
zed_board->Write1Led(pBase,5,0);
zed_board->Write1Led(pBase,6,0);
zed_board->Write1Led(pBase,7,0);
zed_board->Write1Led(pBase,8,0);
case 1:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,0);
zed_board->Write1Led(pBase,3,0);
zed_board->Write1Led(pBase,4,0);
zed_board->Write1Led(pBase,5,0);
zed_board->Write1Led(pBase,6,0);
zed_board->Write1Led(pBase,7,0);
zed_board->Write1Led(pBase,8,0);
case 2:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,1);
zed_board->Write1Led(pBase,3,0);
zed_board->Write1Led(pBase,4,0);
zed_board->Write1Led(pBase,5,0);
zed_board->Write1Led(pBase,6,0);
zed_board->Write1Led(pBase,7,0);
zed_board->Write1Led(pBase,8,0);
case 3:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,1);
zed_board->Write1Led(pBase,3,1);
zed_board->Write1Led(pBase,4,0);
zed_board->Write1Led(pBase,5,0);
zed_board->Write1Led(pBase,6,0);
zed_board->Write1Led(pBase,7,0);
zed_board->Write1Led(pBase,8,0);
case 4:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,1);
zed_board->Write1Led(pBase,3,1);
zed_board->Write1Led(pBase,4,1);
zed_board->Write1Led(pBase,5,0);
zed_board->Write1Led(pBase,6,0);
zed_board->Write1Led(pBase,7,0);
zed_board->Write1Led(pBase,8,0);
case 5:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,1);
zed_board->Write1Led(pBase,3,1);
zed_board->Write1Led(pBase,4,1);
zed_board->Write1Led(pBase,5,1);
zed_board->Write1Led(pBase,6,0);
zed_board->Write1Led(pBase,7,0);
zed_board->Write1Led(pBase,8,0);
case 6:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,1);
zed_board->Write1Led(pBase,3,1);
zed_board->Write1Led(pBase,4,1);
zed_board->Write1Led(pBase,5,1);
zed_board->Write1Led(pBase,6,1);
zed_board->Write1Led(pBase,7,0);
zed_board->Write1Led(pBase,8,0);
case 7:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,1);
zed_board->Write1Led(pBase,3,1);
zed_board->Write1Led(pBase,4,1);
zed_board->Write1Led(pBase,5,1);
zed_board->Write1Led(pBase,6,1);
zed_board->Write1Led(pBase,7,1);
zed_board->Write1Led(pBase,8,0);
case 8:
zed_board->Write1Led(pBase,1,1);
zed_board->Write1Led(pBase,2,1);
zed_board->Write1Led(pBase,3,1);
zed_board->Write1Led(pBase,4,1);
zed_board->Write1Led(pBase,5,1);
zed_board->Write1Led(pBase,6,1);
zed_board->Write1Led(pBase,7,1);
zed_board->Write1Led(pBase,8,1);
default:
cout << "Code = " << code <<'n';
}
}
else
{
continue;
}
}
}
};
WiimoteToLed::WiimoteToLed(ZedBoard* zed_board)
{
Wiimote();
}
WiimoteToLed::~WiimoteToLed()
{
}
int main()
{
// Instantiate ZedBoard object statically
ZedBoard zed_board;
// Instantiate WiimoteToLed object statically, passing a pointer to the
// recently created ZedBoard object.
WiimoteToLed wiimote_to_led(&zed_board);
// Enter infinite loop listening to events. The overridden function
// WiimoteToLed::AccelerationEvent() will be invoked when the user moves
// the Wiimote.
wiimote_to_led.Listen();
// Unreachable code, previous function has an infinite loop
return 0;
}
makefile
WiimoteAccel: main.o WiimoteAccel.o
g++ main.o WiimoteAccel.o -o WiimoteAccel
main.o: main.cpp WiimoteAccel.h
g++ -g -Wall -c main.cpp
WiimoteAccel.o: WiimoteAccel.cpp WiimoteAccel.h
g++ -g -Wall -c WiimoteAccel.cpp
clean:
rm main.o WiimoteAccel.o WiimoteAccel
在WiimoteToLed::AccelerationEvent
中您呼叫
zed_board->Write1Led(pBase,1,1);
,但在此范围中未声明pBase
。您有zed_board
的pBase
成员,但这是另一个。