BASIC4MCU | 질문게시판 | 질문있습니다.
페이지 정보
작성자 Busan 작성일2019-12-27 01:28 조회3,678회 댓글1건본문
밑줄 친 부분은 제가 LCD 안정화 코드를 따온 것입니다. 신경 안쓰셔도 됩니다. 적어둔 코드는 화재 감지기를 한 번 구현해본 것인데 가변 저항을 돌려 4.0V 이상 일 때 화재로 판단하여 LED 점등(PA7 단자) 및 스피커 알람, LCD에 fire 점등이며 평상시에는 전압만 출력합니다. 구동이 잘됩니다.
#include <mega128.h>
#include <delay.h>
#define LINE2 0xC0 // 2nd Line Move
#define HOME 0x02 // Cursor Home
#define RSHIFT 0x1C // Display Right Shift
#define LSHIFT 0x18 // Display Left Shift
#define DISPON 0x0c // Display On
#define DISPOFF 0x08 // Display Offvoid LCD_init(void);
void LCD_String(char flash *str);
void Busy(void);
void Command(unsigned char);
void Data(unsigned char);
void adc_display(void);int adc_value = 0;
float Vref = 5.0, Vwarn = 4.0, Vdetect = 0;
int cnt_bell = 0;void main(void)
{
ADMUX = 0x00;
ADCSRA = 0x87;
ETIMSK = 0x04;
TCCR3A = 0x00;
TCCR3B = 0x04;
TCNT3H = 0x85;
TCNT3L = 0xED;
DDRB = 0x30;
DDRA = 0x80;
PORTA = 0xff;
SREG = 0x80;
LCD_init();
adc_display();
while(1){
ADCSRA = 0xc7;
while((ADCSRA & 0x10) == 0);
adc_value0 = (int)ADCL + ((int)ADCH << 8);
Vdetect = (float)adc_value * Vref / 1024;
}
}
interrupt [TIM3_OVF] void timer_tin0 (void)
{
TCNT3H = 0x85;
TCNT3L = 0xED;
if(Vdetect >= Vwarn){
TCCR1A = 0x40;
TCCR1B = 0x0a;
if(cnt_bell == 0){
PORTA = 0x00;
OCR1A = 2082;
Command(CLEAR);
LCD_String("fire!!!");
cnt_bell = 1;
}
else{
PORTA = 0xff;
OCR1A = 2777;
Command(CLEAR);
cnt_bell = 0;
}
}
else{
TCCR1A = 0x00;
TCCR1B = 0x0a;
PORTA = 0xff;
adc_display();
}
}
void adc_display(void)
{
int temp0 = 0, temp1 = 0, temp = 0;
Command(CLEAR);
LCD_String("Value:");temp = (int)(Vdetect * 10 + 0.5);
temp1 = temp / 10;
temp0 = temp % 10;
Data(0x30 + temp1);
LCD_String(".");
Data(0x30 + temp0);
LCD_String("V");
}
// LCD 초기화 함수
void LCD_init(void)
{
DDRC = 0xFF; // 포트 C 출력 설정
PORTC &= 0xFB; //E = 0;
// 충분한 지연시간을 통한 안정화 과정
delay_ms(15);
Command(0x20); // D5=1
delay_ms(5);
Command(0x20); // D5=1
delay_us(100);
Command(0x20); // D5=1// 초기화 과정
Command(0x28); // function set
Command(0x06); // entry mode set
Command(0x01); // all clear
Command(0x0c); // display on
}// 인스트럭션 쓰기 함수
void Command(unsigned char byte)
{
Busy();// 인스트럭션 상위 바이트
PORTC = (byte & 0xF0); // 데이터
PORTC &= 0xFE; // RS = 0;
PORTC &= 0xFD; // RW = 0;
delay_us(1);
PORTC |= 0x04; // E = 1;
delay_us(1);
PORTC &= 0xFB; // E = 0;// 인스트럭션 하위 바이트
PORTC = ((byte<<4) & 0xF0); // 데이터
PORTC &= 0xFE; // RS = 0;
PORTC &= 0xFD; // RW = 0;
delay_us(1);
PORTC |= 0x04; // E = 1;
delay_us(1);
PORTC &= 0xFB; // E = 0;
}// 문자열 출력 함수
void LCD_String(char flash *str)
{
char flash *pStr=0;pStr = str;
while(*pStr) Data(*pStr++);
}// char flash : pointer declaration for program memory
// char eeprom : pointer declaration for EEPROM//데이터 쓰기 함수
void Data(unsigned char byte)
{
Busy();
// 데이터 상위 바이트
PORTC = (byte & 0xF0); // 데이터
PORTC |= 0x01; //RS = 1;
PORTC &= 0xFD; //W = 0;
delay_us(1);
PORTC |= 0x04; //E = 1;
delay_us(1);
PORTC &= 0xFB; //E = 0;// 데이터 하위 바이트
PORTC = ((byte<<4) & 0xF0); // 데이터
PORTC |= 0x01; //RS = 1;
PORTC &= 0xFD; //RW = 0;
delay_us(1);
PORTC |= 0x04; //E = 1;
delay_us(1);
PORTC &= 0xFB; //E = 0;
}// Busy Flag Check -> 일반적인 BF를 체크하는 것이 아니라
// 일정한 시간 지연을 이용한다.
void Busy(void)
{
delay_ms(2);
}
위 코드와
#include <mega128.h>
#include <delay.h>#define LINE2 0xC0 // 2nd Line Move
#define HOME 0x02 // Cursor Home
#define RSHIFT 0x1C // Display Right Shift
#define LSHIFT 0x18 // Display Left Shift
#define DISPON 0x0c // Display On
#define DISPOFF 0x08 // Display Offvoid LCD_init(void);
void LCD_String(char flash *str);
void Busy(void);
void Command(unsigned char);
void Data(unsigned char);
void degree_display(void);
void v_value(void);int rot_base=375, rot_min=275, rot_max=475;
int rot_delta1=1, rot_delta2=4, rot_delta=0;
int rot_value=0, rot_dir=2;
int adc_value=0;
float Vref=5.0, f_val=0;
int temp10=0;void main(void)
{
DDRB=0xff;
DDRF=0xff;
ADMUX=0x00;
ADCSRA=0b10000111;
ETIMSK=0b00000100;
TCCR3A=0x00;
TCCR3B=0b00000100;
TCNT3H=0xE7;
TCNT3L=0x96;
TCCR1A=0b10000010;
TCCR1B=0b00011011;
ICR1H=0x09;
ICR1L=0xc3;SREG=0b10000000;
rot_value=rot_base;
OCR1A=rot_value;LCD_init();
degree_display();
while(1)
{
v_value();
if(temp10>0&&temp10<=15)
{
rot_dir=1;
rot_delta=rot_delta2;
}
else if(temp10>15&&temp10<=20)
{
rot_dir=1;
rot_delta=rot_delta1;
}
else if(temp10>30&&temp10<=35)
{
rot_dir=0;
rot_delta=rot_delta1;
}
else if(temp10>35&&temp10<=50)
{
rot_dir=0;
rot_delta=rot_delta2;
}
else
{
rot_dir=2;
OCR1A=rot_value;
}
}
}interrupt [TIM3_OVF] void timer_int3(void)
{
TCNT3H=0xE7;
TCNT3L=0x96;
if(rot_dir==0)
{
if(rot_value<=rot_max)
{
rot_value+=rot_delta;
}
else
{
rot_value=rot_max;
}
OCR1A=rot_value;
}
else if(rot_dir==1)
{
if(rot_value>=rot_min)
{
rot_value-=rot_delta;
}
else
{
rot_value=rot_min;
}
OCR1A=rot_value;
}
degree_display();
}
void v_value(void)
{
ADCSRA=0b11000111;
while((ADCSRA&0x10)==0);
adc_value=(int)ADCL+((int)ADCH<<8);
f_val=(float)adc_value*Vref/1024;
temp10=(int)(f_val*10+0.5);
}void degree_display(void)
{
float degree_value=0;
int temp0=0, temp1=0, temp2=0, temp=0;
int v1=0, v2=0;
Command(HOME);
LCD_String("Degree : ");
if(rot_value>=rot_base)
{
degree_value=(float)(rot_value-rot_base)*80/200;
LCD_String("+");
}
else
{
degree_value=(float)(rot_base-rot_value)*80/200;
LCD_String("-");
}
temp=(int)(degree_value*10);
temp2=temp/100;
temp=temp%100;
temp1=temp/10;
temp0=temp%10;
Data(0x30+temp2);
Data(0x30+temp1);
LCD_String(".");
Data(0x30+temp0);
Command(LINE2);
LCD_String("Value : ");
v1=temp10/10;
v2=temp10%10;
Data(0x30+v1);
LCD_String(".");
Data(0x30+v2);
LCD_String("V");
}
// LCD 초기화 함수
void LCD_init(void)
{
DDRC = 0xFF; // 포트 C 출력 설정
PORTC &= 0xFB; //E = 0;
// 충분한 지연시간을 통한 안정화 과정
delay_ms(15);
Command(0x20); // D5=1
delay_ms(5);
Command(0x20); // D5=1
delay_us(100);
Command(0x20); // D5=1// 초기화 과정
Command(0x28); // function set
Command(0x06); // entry mode set
Command(0x01); // all clear
Command(0x0c); // display on
}
// 인스트럭션 쓰기 함수
void Command(unsigned char byte)
{
Busy();// 인스트럭션 상위 바이트
PORTC = (byte & 0xF0); // 데이터
PORTC &= 0xFE; // RS = 0;
PORTC &= 0xFD; // RW = 0;
delay_us(1);
PORTC |= 0x04; // E = 1;
delay_us(1);
PORTC &= 0xFB; // E = 0;// 인스트럭션 하위 바이트
PORTC = ((byte<<4) & 0xF0); // 데이터
PORTC &= 0xFE; // RS = 0;
PORTC &= 0xFD; // RW = 0;
delay_us(1);
PORTC |= 0x04; // E = 1;
delay_us(1);
PORTC &= 0xFB; // E = 0;
}// 문자열 출력 함수
void LCD_String(char flash *str)
{
char flash *pStr=0;pStr = str;
while(*pStr) Data(*pStr++);
}// char flash : pointer declaration for program memory
// char eeprom : pointer declaration for EEPROM//데이터 쓰기 함수
void Data(unsigned char byte)
{
Busy();
// 데이터 상위 바이트
PORTC = (byte & 0xF0); // 데이터
PORTC |= 0x01; //RS = 1;
PORTC &= 0xFD; //W = 0;
delay_us(1);
PORTC |= 0x04; //E = 1;
delay_us(1);
PORTC &= 0xFB; //E = 0;// 데이터 하위 바이트
PORTC = ((byte<<4) & 0xF0); // 데이터
PORTC |= 0x01; //RS = 1;
PORTC &= 0xFD; //RW = 0;
delay_us(1);
PORTC |= 0x04; //E = 1;
delay_us(1);
PORTC &= 0xFB; //E = 0;
}// Busy Flag Check -> 일반적인 BF를 체크하는 것이 아니라
// 일정한 시간 지연을 이용한다.
void Busy(void)
{
delay_ms(2);
}
위 코드는
RC 서보 모터를 시작할 때 0도로 설정하고
가변저항의 값을
3V - 3.5V 구간으로 조정하면, CW 방향으로 100msec 단위로 0.4도씩 증가
3.5V - 5V 구간으로 조정하면, CW 방향으로 100msec 단위로 1.6도씩 증가
2V -1.5V 구간으로 조정하면, CCW 방향으로 100msec 단위로 0.4도씩 증가
1.5V - 0V 구간으로 조정하면, CCW 방향으로 100msec 단위로 1.6도씩 증가
2-3V 구간으로 조정하면, 모터 현재 각도를 유지하고 현재 각도를 LCD에 출력하게 끔 코딩했습니다. 잘 돌아갑니다.
제가 하고 싶은것은 위 코드 2개를 이용하여 0 - 1.5V까지는 서보모터가 약하게 돌며
1.5V - 3V까지는 중간으로 돌며
3V - 4V가 되면 빠르게 돌면서
4V에 도달 시 화재로 판단하여 LED 점등(PA7 단자) 및 스피커 알람, LCD에 fire 점등을 하고 싶습니다.
따로 따로는 가능한데 둘을 취합하는 과정에서 자꾸 문제가 생겨 문의합니다...
오늘 답변은 정말 감사했습니다.
댓글 1
조회수 3,678master님의 댓글
master 작성일
무슨 문제가 생긴다는 것인지 상세하게 적으셔야합니다.
전체를 봐드리려면 보드가 있어야합니다.
보드가 없어서 불가능하므로 답변이 가능한 부분을 질문해주세요