BASIC4MCU | 질문게시판 | Atmega 코드 좀 봐주세요.
페이지 정보
작성자 chelsea 작성일2022-07-04 10:48 조회418회 댓글1건첨부파일
본문
안녕하세요...
다음과 같이 동작 Fllow에 맞춰 코드을 작성해보았는데 현재 모듈이 없어 확인이 어렵습니다.
모듈이 오기 전 작성한 코드에 오류가 있는지 확인하고 싶은데 조언 부탁드립니다.
1. PD7이 Low일 때 온도와 관계없이 팬 동작 x
2. PD7 High가 입력되면
3. 온도에 따라 팬이 동작(25도 미만이면 duty60%, 25도~27도 이면 duty 78%,27도 이상이면 100%)
4. PD7 High 입력 후 6초 이전까지 PD3,PD5 Low PD6 High
4. 6초 이후 PD3,PD5 High PD6 Low(PD7이 Low될 때까지 유지)
5. flowrate가 0이면 PD1 High, Flowrate가 0이 아니면 PD1 Low (PD7이 High 일때)
첨부된 파일은 온도테이블입니다.
*LCD 출력
1열 Water : 값 표시
2열 temp : 값 표시
//Atmega8
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//
#define LCD_RS 0x10 // PC4
#define LCD_EN 0x20 // PC5
#define LCD_DIR DDRC
#define LCD_PORT PORTC
//
#define LCD_Clear 0x01
#define LCD_Cursor 0x03 //function set:4bit data, 2line display, 5*8 dots
#define LCD_Function_Set 0x28
#define LCD_On 0x0E //0000 11(set display)1(cursor)0(blink)
#define LCD_Entry 0x06 //Cursor increased, no shift
#define input 0x80 //HP Connector input
//
volatile float calibrationfactor=98,flowrate=0,cal=0;
volatile int pulsecount=0,millisec=0,val=0;
volatile char sec=0;
volatile long R=0;
volatile double Thermister=0;
//
void init_port()
{
DDRB = 0x04;
PORTB = 0x00;
DDRD = 0x8B;
PORTD = 0x40;
}
void Write_Command_LCD(char Command){
LCD_PORT=(Command >> 4)|LCD_EN; _delay_us(1); LCD_PORT&=~LCD_EN; _delay_us(1);
LCD_PORT=(Command&0x0F)|LCD_EN; _delay_us(1); LCD_PORT&=~LCD_EN; _delay_ms(2);
}
//
void PutsChar_LCD(int data){
LCD_PORT=(data >> 4)|LCD_RS|LCD_EN; _delay_us(1); LCD_PORT&=~LCD_EN; _delay_us(1);
LCD_PORT=(data&0x0F)|LCD_RS|LCD_EN; _delay_us(1); LCD_PORT&=~LCD_EN; _delay_us(40);
}
//
void String_LCD(char *s){ while(*s)PutsChar_LCD(*s++); }
//
void LCD_Init(void){
LCD_DIR=0xFF;
LCD_PORT=0x00;
_delay_ms(50);
Write_Command_LCD(LCD_Function_Set);
Write_Command_LCD(LCD_On);
Write_Command_LCD(LCD_Clear);
Write_Command_LCD(LCD_Entry);
Write_Command_LCD(0x02); //Return Home
}
void Cooler()
{
if(Thermister<=25)
{
OCR1B=128;
_delay_ms(300);
}
else if(25<Thermister&&Thermister<27)
{
OCR1B=200;
_delay_ms(300);
}
else if(Thermister>=27)
{
OCR1B=255;
_delay_ms(300);
}
}
void ADC_Init()
{
ADCSRA = 0x=87; //Enable ADC, fr/128
ADCSRA |= (1<<ADSC);
while ((ADCSRA &(1<<ADIF))==0); //monitor end of conversion interrupt flag
ADCSRA |=(1<<ADIF); //set the ADIF bit of ADCSRA register
return(ADCW);
}
int ADC()
{
ADMUX = 0x46;
}
void getTemp()
{
val = ADC(); //store adc value on val register
R=10000*(1023/val-1.0); //calculate the resistance
Thermister = log(R); //calculate natural of resistance
Thermister = 1/(0.8483323763e-03 + (2.581286591e-04 * Thermister) + (1.641220112e-07 * Thermister * Thermister * Thermister)) ; //A=0.8483323763e-03, B=2.581286591e-04, C=1.641220112e-07
Thermister = Thermister - 273.15; //covert kelvin to C
return Thermister;
}
//
void init_timer0()
{
TCCR0 = (1<<CS02); //분주비 256
TCTN0 = 6; //TNCT0의 초기값 6
TIMSK = (1<<TOIE0); //타이머 인터럽트 enable
}
void init_timer1()
{
//set mode: Mode 06 (8Bit Fast PWM)
//f_pwm = f_clk/ N * (1+Top) = 16,000,000Hz / 64 * (1+255) = 976.5625Hz
//( N :Pre-scale factor = 64)
TCCR1A|=(1<<COM1A1)|(0<<COM1A0)|(1<<COM1B1)|(0<<COM1B0)|(0<<WGM11)|(1<<WGM10);
TCCR1B=(0<<WGM13)|(1<<WGM12)|(0<<CS12)|(1<<CS11)|(1<<CS10);
TIMSK=(1<<OCIE1A);
/*TCCR0A=(1<<WGM01); TIMSK0|=(1<<OCIE0A); TCCR0B|=(1<<CS02)|(1<<CS00); OCR0A=0x07;*/
}
//
ISR(TIMER0_COMPA_vect) //1ms
{
if(PIND & input == 1){
Cooler(); // Hand piece 연결되면 High 입력
if(++millisec>=1000){ //1sec
millisec=0;
if(sec<6){
if(++sec>=6)PORTD=0x28; //6sec (PD6)Off,(PD5)on,(PD3)On
}
cal=pulsecount/calibrationfactor; //L/min
flowrate=cal*60; //L/hour
if(flowrate==0){
PORTD|= 0x02; //PD1 High Output(Water flow signal)
}
else PORTD&=~0x02; //PD1 Low Output
pulsecount=0;
}
}
}
ISR(TIMER1_COMPA_vect)
{
}
//
ISR(INT0_vect){ pulsecount++; }
//
int main(void){
char water[20]={0};
char Tbuf[20]={0};
double temp;
init_port();
init_timer0();
init_timer1();
MCUCR|=(0<<ISC00)|(1<<ISC01); //The falling edge of INT0 generates an interrupt request.
GICR|=(1<<INT0); //INT0 Enable
sei();
LCD_Init();
ADC_Init();
while(1){
temp=getTemp();
sprintf(water,"WATER:%0.1f L/H",flowrate);
Write_Command_LCD(0x80);
String_LCD(water);
_delay_ms(100);
sprintf(Tbuf,"temp:%0.1f C ",temp);
Write_Command_LCD(0xc0);
String_LCD(Tbuf);
_delay_ms(100);
}
}
댓글 1
조회수 418master님의 댓글
master 작성일
동작 시켜보고 문제가 발생하고, 본인 능력으로 해결이 안될 때 질문을 해주세요
동작 전 코드 체크는 스스로 하시고요
조언을 드리자면
알고리즘을 잘 작성하면
코드는 알고리즘 대로 타이핑하면 그만입니다.
언어의 문법은 쉽게 숙련이 되지만 알고리즘은 좀 더 어렵습니다.
시간에 여유가 있으면 알고리즘부터 잘 작성하고, 알고리즘대로 코드를 작성했는지 체크하세요