/*
* ES_Prak_01.c
*
* Created: 07.04.2014 14:42:04
* Author: Ehlers
*/
/*
* Definitions
*/
#define F_CPU 1000000UL
#define I2C_DEVICE_ADDRESS (0xE0)
#define TEST_LED_DISPLAY 1
#define TEST_ADC_READ 0
#define TEST_I2C_READREGISTER 1
#define BUFFSIZE 20
/*
* Includes
*/
#include <avr/io.h>
// include this to get access to uint8_t, uint16_t and so on...
#include <stdint.h>
#include <stdio.h>
#include <util/delay.h>
// include the header for I2C communication
#include "i2c_master.h"
#include "uart.h"
/*
* Exercise 01
*/
void led_init()
{
// configure Port B as output (set all bits in DDRB high)
DDRB = ~0; //0b11111111
}
void led_display(uint16_t value)
{
uint8_t mask = 0;
// create mask
for (uint8_t i = value / 128; i >= 0; i--)
{
// shift the bit mask and set the lsb high
mask = (mask << 1) | 1;
}
// set the output of Port B
PINB = mask;
}
/*
* Exercise 02
*/
void adc_init()
{
// set prescaler to 128
ADCSRA = (1 << ADEN) | (1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2);
// set AVCC (VCC = 5V) as reference
ADMUX = (1 << REFS0);
// start blind conversion
adc_read(0);
}
uint16_t adc_read(uint8_t channel)
{
// create mux mask
uint8_t muxMask = (1 << MUX0) | (1 << MUX1) | (1 << MUX2) | (1 << MUX3) | (1 << MUX4);
// clear all channel bits
ADMUX &= ~muxMask;
// set the passed channel (and clear not allowed bits)
ADMUX |= (channel & muxMask);
// start conversion
ADCSRA |= (1 << ADSC);
// wait until the conversion is complete
while (ADCSRA & (1 << ADSC));
// read value of the low byte
uint16_t value = ADCL;
// add the high byte (and shift its value)
value |= (ADCH << 8);
return value;
}
/*
* Exercise 03
*/
void i2c_writeRegister(uint8_t add, uint8_t reg, uint8_t dat)
{
// connect to address add
i2c_start(add & ~1);
// chose register to reg
i2c_write(reg);
// write dat into register reg
i2c_write(dat);
// stop connection
i2c_stop();
}
uint8_t i2c_readRegister(uint8_t add, uint8_t reg)
{
// connect to address add
i2c_start(add & ~1);
// chose register to reg
i2c_write(reg);
// start read connection
i2c_rep_start(add | 1);
uint8_t dat = 0;
// read value from reg into dat
i2c_readNak(&dat);
// stop connection
i2c_stop();
// return read data
return dat;
}
int main(void)
{
// Initialization
sei();
uart_init();
// initialize the AD converter
adc_init();
// declare string buffer
char buff[BUFFSIZE];
while(1)
{
#if TEST_LED_DISPLAY == 1
// test led_display
for (uint16_t testNum = 0; testNum < 1024; testNum++)
{
led_display(testNum);
_delay_ms(8);
}
#elif TEST_ADC_READ == 1
// test adc_read
led_display(adc_read(0));
#elif TEST_I2C_READREGISTER == 1
// test i2c_readRegister
uint16_t distance = i2c_readRegister(I2C_DEVICE_ADDRESS, 3);
distance |= (i2c_readRegister(I2C_DEVICE_ADDRESS, 2) << 8);
snprintf(buf, BUFFSIZE, "%u\n", distance);
uart_sendstring(buff);
_delay_ms(1024);
#else
// TODO
#endif
}
}
Comments