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