This code is from project: Water meter counter
adc.h
#ifndef _H_ADC_
#define _H_ADC_
#include "main.h"
class Adc {
public:
Adc();
unsigned char get(unsigned char);
};
#endif
adc.cpp
#include "adc.h"
#include <avr/io.h>
Adc::Adc() {
// Set reference voltage
// REFS[0..1] = low -> AREF
L(ADMUX, REFS0);
L(ADMUX, REFS1);
// prescaler set
// ADPS[0..2] = / 128
H(ADCSRA, ADPS0);
H(ADCSRA, ADPS1);
H(ADCSRA, ADPS2);
// watch only 8bits from ADCH
H(ADMUX, ADLAR);
// enable ADC
H(ADCSRA, ADEN);
}
unsigned char Adc::get(unsigned char pin) {
// Clear register
ADCH=0x00;
// clear pin register
ADMUX&=~0x07;
// set pin from 0 to 7 (function parameter);
ADMUX|=pin;
// start processing
H(ADCSRA, ADSC);
// wait for processing ends
while(IS(ADCSRA, ADSC));
// return 8-bit data
return ADCH;
}
delay.h
#ifndef _H_DELAY_
#define _H_DELAY_
#include "main.h"
#include <util/delay.h>
#define nop() __asm__ __volatile__("nop")
void delay_ms(unsigned short ms);
void delay_us(unsigned short us);
#endif
delay.cpp
#include "delay.h"
void delay_ms(unsigned short ms) {
while ( ms ) {
ms--;
_delay_ms(1);
}
}
void delay_us(unsigned short us) {
while ( us ) {
us--;
_delay_us(1);
}
}
led_nums.h
#ifndef _H_LED_NUMS_
#define _H_LED_NUMS_
#define Dec2Bcd(dec) (((dec / 10) << 4) + (dec % 10))
#define RED 0
#define BLUE 4
class LedNums {
private:
char nums[8];
public:
LedNums();
~LedNums();
void init(void);
void drive(void);
void set(unsigned char, unsigned short);
};
#endif
led_nums.cpp
#include "led_nums.h"
#include "main.h"
#include "delay.h"
#include <avr/io.h>
LedNums::LedNums() {
}
LedNums::~LedNums() {
}
/****************************************************************************/
/* This function get a short number and puts it to 'nums' array which is */
/* used to display numbers on 2 led displays */
/****************************************************************************/
void LedNums::set(unsigned char offset, unsigned short n) {
// 4 digit
nums[0 + offset] = (n / 1000);
n-= (nums[0 + offset] * 1000);
// 3 digit
nums[1 + offset] = (n / 100);
n-= (nums[1 + offset] * 100);
// 2 digit
nums[2 + offset] = (n / 10);
// 1 digit
n-= (nums[2 + offset] * 10);
nums[3 + offset] = n;
// add + 48 (0 in ascii)
nums[0 + offset]+=48;
nums[1 + offset]+=48;
nums[2 + offset]+=48;
nums[3 + offset]+=48;
}
/****************************************************************************/
/* Init ports */
/****************************************************************************/
void LedNums::init(void) {
// set PORTB as output
DDRB = 0xFF;
// set part of PORTC as output
DDRC = 0x0F;
// initial values
PORTC = 0x0F;
PORTB = 0x00;
}
/****************************************************************************/
/* Drive leds */
/****************************************************************************/
void LedNums::drive(void) {
unsigned char i = 0;
unsigned char n = 0;
// go throught all 8 digits
for(i=0; i<8;i++) {
// substract 48 (ascii 0)
n = nums[7-i] - 48;
// send BCD value to port C (connected to DM7447)
PORTC = Dec2Bcd(n);
// enable one digit
PORTB = (1 << i);
// red one is darker than blue, so we add here a bigger delay
if(i>3) {
// bigger delay -> brighter
delay_us(24);
}
else {
// smaller delay, power attached for a short time -> darker
delay_us(4);
}
// turn of digit
PORTB = 0;
}
}
main.h
#ifndef _H_MAIN_ #define _H_MAIN_ #define F_CPU 1000000L #define H(a,b) a |=(1<<(b)) #define L(a,b) a &=~(1<<(b)) #define IS(a,b) bit_is_set(a,b) #define BS(a,b) (a & (1<<(b))) #endif #ifndef F_CPU #error CPU speed unknown #endif
main.cpp
#include "main.h"
#include "operators.h"
#include "delay.h"
#include "led_nums.h"
#include "adc.h"
#include <avr/interrupt.h>
#include <avr/wdt.h> // WATCHDOG
#include <stdlib.h>
/****************************************************************************/
/* Object pointers */
/****************************************************************************/
LedNums *ln;
Adc *adc;
/****************************************************************************/
/* main function */
/****************************************************************************/
int main()
{
ln = new LedNums;
adc = new Adc;
ln->init();
ln->set(RED, 1234);
ln->set(BLUE, 1231);
unsigned char hot = 0;
unsigned char cold = 0;
unsigned char old_hot = 0;
unsigned char old_cold = 0;
unsigned char hot_diff = 1;
unsigned char cold_diff = 1;
unsigned short count = 0;
unsigned short counter_hot = 0;
unsigned short counter_cold = 0;
while(1) {
count++;
// do this very often
if(count % 3 == 0) {
// get value from ADC, pin 4 and 5
hot = adc->get(4);
cold = adc->get(5);
// this code is very dirty and it was written only to check
// if this device have a chance to work, so don't be mad
// I will fix this :)
// back spot on water meter gives number 120 from CNY70,
// so we wait for in, and then increment liter counter
if(hot == 120 && old_hot < 120) {
counter_hot++;
// very ugly hack -> we ignore fluctuations here
delay_ms(1000);
}
if(cold == 120 && old_cold < 120) {
counter_cold++;
// very ugly hack -> we ignore fluctuations here
delay_ms(1000);
}
old_cold = cold;
old_hot = hot;
}
// now we can set variables in LedNums class
if(count > 30) {
ln->set(RED, counter_hot);
ln->set(BLUE, counter_cold);
count = 0;
}
// put power to 8 digits
ln->drive();
}
return 0;
}
operators.h
#ifndef _H_OPERATORS_ #define _H_OPERATORS_ #include <stdlib.h> void * operator new(size_t size); #endif
operators.cpp
#include "operators.h"
void * operator new(size_t size)
{
return malloc(size);
}
Makefile
CPU=atmega8 GCC=avr-g++ CFLAGS= -Os -mmcu=$(CPU) -Wall -fpack-struct -fshort-enums -funsigned-bitfields -Wl,--relax -fno-move-loop-invariants -funsigned-char -fno-inline-small-functions -fdata-sections -fno-tree-loop-optimize -lprintf_min INCLUDES= LIBS= OBJCPY=avr-objcopy OBJECTS=main.o operators.o delay.o led_nums.o adc.o PROJECT_NAME=mega8 HEX_FILE=$(PROJECT_NAME).hex HEX_FILE_DUMP=$(PROJECT_NAME)_dump.hex PROG=uisp PROG_FLAGS=-dprog=dapa all: cls $(PROJECT_NAME) obj size #upload $(PROJECT_NAME): $(OBJECTS) $(GCC) -o $(PROJECT_NAME) $(OBJECTS) $(CFLAGS) $(LIBS) $(INCLUDES) main.o: main.cpp main.h templates.h $(GCC) $(CFLAGS) $(INCLUDES) -c main.cpp operators.o: operators.cpp operators.h $(GCC) $(CFLAGS) $(INCLUDES) -c operators.cpp delay.o: delay.cpp delay.h $(GCC) $(CFLAGS) $(INCLUDES) -c delay.cpp led_nums.o: led_nums.cpp $(GCC) $(CFLAGS) $(INCLUDES) -c led_nums.cpp adc.o: adc.cpp $(GCC) $(CFLAGS) $(INCLUDES) -c adc.cpp obj: $(OBJECTS) $(OBJCPY) -O ihex $(PROJECT_NAME) $(HEX_FILE) clean: rm -f $(PROJECT_NAME) $(OBJECTS) $(HEX_FILE) cls: clear size: du -b $(HEX_FILE) upload: all $(HEX_FILE) $(PROG) $(PROG_FLAGS) --erase --upload if=$(HEX_FILE) download: $(PROG) $(PROG_FLAGS) --download of=$(HEX_FILE_DUMP)
No comments:
Post a Comment