C和汇编代写-ECE 6483
时间:2022-05-02
Simon Kahn
ECE 6483
Exam 2

1)
A)
#ifndef ASENSOR_H
#define ASENSOR_H
#include "mbed.h"
//the sensor's 7-bit address
#define SENSOR_ADDRESS 0b1110100
//declares an mbed::I2C instance
//that must be defined in the main.cpp file
extern mbed::I2C Wire;
int GetVersion();
int GetTotalStrength();
int GetEvent();
#endif


B)
#include "ASensor.h"

//The touchpad datasheet did not directly indicate
//support for multi-byte sequential burst reads,
//so I chose to write the address for each byte
//in my implementation ( which is always supported by i2c)

//the sensor's address for read transactions
static constexpr uint8_t read_addr=((SENSOR_ADDRESS<<1u)|1U);
//the sensor's address for write transactions
static constexpr uint8_t write_addr=(SENSOR_ADDRESS<<1U);
//a buffer used to store data received from the remote
//sensor over i2c
static uint8_t read_buf[20];
//3 bytes to send (after sending the sensor address)
//to close the communication window
static const uint8_t com_window_end_buf[3]={0xEE,0xEE,0xFF};
//the 16-bit register address that holds the sensor's major version
//broken down into 2 8-bit values for easy sending over i2c
static const uint8_t major_ver_addr[2]={0x00,0x04};
//the 16-bit register address that holds the sensor's minor version
//broken down into 2 8-bit values for easy sending over i2c
static const uint8_t minor_ver_addr[2]={0x00,0x05};
//the 16-bit register address that holds the 8 MSB's of the
//sensor's touch strength.
//broken down into 2 8-bit values for easy sending over i2c
static const uint8_t touch_strength_high_addr[2]={0x00,0x1A};
//the 16-bit register address that holds the 8 LSB's of the
//sensor's touch strength.
//broken down into 2 8-bit values for easy sending over i2c
static const uint8_t touch_strength_low_addr[2]={0x00,0x1B};
//the 16-bit register address that holds the first set of
//detected events.
//broken down into 2 8-bit values for easy sending over i2c
static const uint8_t gesture_event_high_addr[2]={0x00,0x0D};
//the 16-bit register address that holds the second set of
//detected events.
//broken down into 2 8-bit values for easy sending over i2c
static const uint8_t gesture_event_low_addr[2]={0x00,0x0E};

//static const uint8_t major_ver_addr[2]={0x00,0x04};
//static const uint8_t minor_ver_addr[2]={0x00,0x05};

//The data sheet specified that a stop bit alone would not
//terminate an i2c communication window and allow normal sampling
//to proceed, so this function implements the correct behavior outlined
//in the data sheet to explicitly end the communication window.
static void terminate_com_window(){
Wire.write(write_addr,(const char *)com_window_end_buf,3,false);
}

//the format of the return value is as follow:
//bits 31-16: not used
//bits 15-8 : major version
//bits 7-0 : minor version
int GetVersion(){
int version=0;
//sends the write address followed by the address of the sensor's
//major version register, followed by a repeated start
Wire.write(write_addr,(const char *) major_ver_addr,2,true);
//sends the read address, and stores the received register value
// at index 0 in the read_buf, ending with a stop bit.
Wire.read(read_addr,(char*)&read_buf[0],1,false);
//places the major version in bit position 15-8 of the return variable
version|=((uint8_t)read_buf[0]<<8);
//sends the write address followed by the address of the sensor's
//minor version register, followed by a repeated start
Wire.write(write_addr,(const char *) minor_ver_addr,2,true);
//sends the read address, and stores the received register value
// at index 1 in the read_buf, ending with a stop bit.
Wire.read(read_addr,(char*)&read_buf[1],1,false);
//places the minor version in bit position 7-0 of the return variable
version|=((uint8_t)read_buf[1]);
//closes the communication window with the sensor
terminate_com_window();

return version;

}
//the format of the return value is as follow:
//bits 31-16: not used
//bits 15-0 : total strength;
int GetTotalStrength(){
int total_strength=0;
//sends the write address followed by the address of the sensor's
//register that has the 8 MSB's of the total strength, followed by a repeated start
Wire.write(write_addr,(const char *) touch_strength_high_addr,2,true);
//sends the read address, and stores the received register value
// at index 0 in the read_buf, ending with a stop bit.
Wire.read(read_addr,(char*)&read_buf[0],1,false);
//places the received MSB's in bit position 15-8
total_strength|=((uint8_t)read_buf[0]<<8);
//sends the write address followed by the address of the sensor's
//register that has the 8 LSB's of the total strength, followed by a repeated start
Wire.write(write_addr,(const char *) touch_strength_low_addr,2,true);
//sends the read address, and stores the received register value
// at index 0 in the read_buf, ending with a stop bit.
Wire.read(read_addr,(char*)&read_buf[1],1,false);
//places the received MSB's in bit position 7-0
total_strength|=((uint8_t)read_buf[1]);
//closes the communication window with the sensor
terminate_com_window();

return total_strength;
}

/*
just returning a different enumerated
type corresponding to an individual event would prevent
you from being able to recognize
multiple simultaneous event occurrences.
so I chose to adopt the following
bit-field approach for the return value,
where a 1 in the corresponding bit position
indicates the event was triggered (active),
and a 0 means it was not.

event : |swipe | swipe | swipe | swipe | press and | single | zoom | scroll | 2 finger |
| y- | y+ | x+ | x- | hold | tap | | | tap |

--------------------------------------------------------------------------------
bit position: | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
*/
int GetEvent(){
int events=0;
//sends the write address followed by the address of the sensor's
//first event register, followed by a repeated start
Wire.write(write_addr,(const char *) gesture_event_high_addr,2,true);
//sends the read address, and stores the received register value
// at index 0 in the read_buf, ending with a stop bit.
Wire.read(read_addr,(char*)&read_buf[0],1,false);
//sends the write address followed by the address of the sensor's
//second event register, followed by a repeated start
Wire.write(write_addr,(const char *) gesture_event_low_addr,2,true);
//sends the read address, and stores the received register value
// at index 1 in the read_buf, ending with a stop bit.
Wire.read(read_addr,(char*)&read_buf[1],1,false);
//closes the communication window with the sensor
terminate_com_window();
//extracts and formats the events for bit positions 8-3
events|=static_cast((0b00111111&read_buf[0]))<<3;
//extracts and formats the events for bit positions 2-0
events|=static_cast((0b00000111&read_buf[1]));

return events;
}

C/D)
#include "mbed.h"
#include "ASensor.h"
// I2C1_SDA I2C1_SCL
//assume these pins are externally pulled up.
I2C Wire(PB_7,PB_6);
//PA_9 is connected to Serial1_TX
//PA_10 is connected to Serial1_RX
BufferedSerial Serial(PA_9,PA_10,9600);

//strings to send out over the UART
//corresponding to each events occurrence.
//they are intentionally in "reverse order"
//to optimize iterating.
char event_strings[9][16]{
"2 finger tap\n",
"scroll\n",
"zoom\n",
"single tap\n",
"press and hold\n",
"swipe x-\n",
"swipe x+\n",
"swipe y+\n",
"swipe y-\n"
};
//the lengths of each possible event string (excluding the null character);
int string_lengths[9] = { 13,7,5,11,15,9,9,9,9 };


int main(){

//configure I2C to fast mode
Wire.frequency(400000);
//configure UART with 8 data bits, no parity bits,
//and 1 stop bit.
Serial.set_format(8,BufferedSerial::None,1);
int result = 0;
while(1){
//sleep for 500ms
thread_sleep_for(500);
result = GetEvent();
//iterates through the returned bitfields,
//checking if each event was triggered,
//and if it was, the corresponding message
//is printed to the console
for(int i = 0; i < 9;i++){
//checks if the bitfield is 1,
//and if it is, the corresponding message
//is sent out over Serial
if(((result >> i) & 0x01) == 1){
Serial.write(event_strings[i],string_lengths[i]);
}
}

}
}


2)
A/B)
#include "mbed.h"
#include "ASensor.h"
//the specific flag that will trigger
//the main loop to call GetEvent()
//and print its result. The flag will be set
//with a ticker callback function
#define TRIGGER 1
// I2C1_SDA I2C1_SCL
//assume these pins are externally pulled up.
I2C Wire(PB_7,PB_6);
//PA_9 is connected to Serial1_TX
//PA_10 is connected to Serial1_RX
BufferedSerial Serial(PA_9,PA_10,9600);

//strings to send out over the UART
//corresponding to each events occurrence.
//they are intentionally in "reverse order"
//to optimize iterating.
char event_strings[9][16]{
"2 finger tap\n",
"scroll\n",
"zoom\n",
"single tap\n",
"press and hold\n",
"swipe x-\n",
"swipe x+\n",
"swipe y+\n",
"swipe y-\n"
};
//the lengths of each possible event string (excluding the null character);
int string_lengths[9] = { 13,7,5,11,15,9,9,9,9 };

Ticker periodic;
EventFlags TriggerFlag;

void set_trigger(){
TriggerFlag.set(TRIGGER);
}
int main(){

//configure I2C to fast mode
Wire.frequency(400000);
//configure UART with 8 data bits, no parity bits,
//and 1 stop bit.
Serial.set_format(8,BufferedSerial::None,1);
int result = 0;
//attaches the set_trigger() function
//to the Ticker, which will call the function
//every 500 milliseconds
periodic.attach(set_trigger,500ms);
while(1){
//waits for the trigger flag to be set by the
//attached ticker function. After the flag is set,
//the wait_all function will wake up the main thread,
//and clear the flag to prepare for the next interrupt
//once it fully passes through one iteration of the while loop
TriggerFlag.wait_all(TRIGGER);
result = GetEvent();
//iterates through the returned bitfields,
//checking if each event was triggered,
//and if it was, the corresponding message
//is printed to the console
for(int i = 0; i < 9;i++){
//checks if the bitfield is 1,
//and if it is, the corresponding message
//is sent out over Serial
if(((result >> i) & 0x01) == 1){
Serial.write(event_strings[i],string_lengths[i]);
}
}

}
}


3)
#include "mbed.h"
#include "ASensor.h"
//the specific flag that will trigger
//the main loop to call GetEvent()
//and print its result. The flag will be set
//with a ticker callback function
#define TRIGGER 1
// I2C1_SDA I2C1_SCL
//assume these pins are externally pulled up.
I2C Wire(PB_7,PB_6);
//PA_9 is connected to Serial1_TX
//PA_10 is connected to Serial1_RX
BufferedSerial Serial(PA_9,PA_10,9600);

//strings to send out over the UART
//corresponding to each events occurrence.
//they are intentionally in "reverse order"
//to optimize iterating.
char event_strings[9][16]{
"2 finger tap\n",
"scroll\n",
"zoom\n",
"single tap\n",
"press and hold\n",
"swipe x-\n",
"swipe x+\n",
"swipe y+\n",
"swipe y-\n"
};
//the lengths of each possible event string (excluding the null character);
int string_lengths[9] = { 13,7,5,11,15,9,9,9,9 };

Ticker periodic;
//Event Flags used to trigger
//periodic events.
EventFlags TriggerFlag;
//Our board's LEDs aren't actually
//connected to pwm pins, but assume
//that for this problem they are.
PwmOut pwm_str(LED0);
void set_trigger(){
TriggerFlag.set(TRIGGER);
}
int main(){

//configure I2C to fast mode
Wire.frequency(400000);
//configure UART with 8 data bits, no parity bits,
//and 1 stop bit.
Serial.set_format(8,BufferedSerial::None,1);
int result = 0;
//sets the pwm signals
//period to 50 milliseconds
pwm_str.period(50ms);
//set the initial pwm
//duty cycle to an arbitrary value.
//I chose 50%
pwm_str.write(0.5f);
//attaches the set_trigger() function
//to the Ticker, which will call the function
//every 500 milliseconds
periodic.attach(set_trigger,500ms);
while(1){
//waits for the trigger flag to be set by the
//attached ticker function. After the flag is set,
//the wait_all function will wake up the main thread,
//and clear the flag to prepare for the next interrupt
//once it fully passes through one iteration of the while loop
TriggerFlag.wait_all(TRIGGER);
result = GetEvent();

//calls GetTotalStrength(), casts its
//return value to a float, divides that value
//by the maximum possible value of a 16 bit number,
//and sets the result as the pwm duty cycle.
pwm_str.write(
static_cast(GetTotalStrength()) / (65535.0f)
);
//iterates through the returned bitfields,
//checking if each event was triggered,
//and if it was, the corresponding message
//is printed to the console
for(int i = 0; i < 9;i++){
//checks if the bitfield is 1,
//and if it is, the corresponding message
//is sent out over Serial
if(((result >> i) & 0x01) == 1){
Serial.write(event_strings[i],string_lengths[i]);
}
}

}
}


essay、essay代写