Project/Firmware
선풍기 ATMEGA
ETIT
2020. 4. 28. 13:57
/*
* UART0_POLLING.c
*
* Created: 2020-04-10 오전 11:56:02
* Author : master
*/
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include
#include // printf 첫번째 설정
#include <avr/interrupt.h> // #1. intrrupt 라이브러리를 include 한다.
// Add rx_Interrupt
#include
#include "uart0.h"
#include "DHT.h" // #1_DHT11 헤더를 추가 한다.
/*--------- spi rfid rc522 통신 헤더 화일 ------------*/
#include "mfrc522.h" // rfid 관련헤더 화일
#include "spi.h" // spi 통신을 위한 헤더 화일
#include "I2C.h" // LCD 사용을 위한 헤더파일
#include "I2C_LCD.h"
#define YES 1 //값을 읽으면 들어가게 만든다.
#define PE7 7 //모터 제어핀 정의
#define PE2 2 //모터 제어핀 정의
#define PE3 3 //모터 제어핀 정의
#define MAX_LEN 5// rfid
FILE OUTPUT = FDEV_SETUP_STREAM(UART0_transmit, NULL, _FDEV_SETUP_WRITE); // 2.printf로 설정하기 위한 작업
void smartfan_main(void);
void init_pwm1(void);
int rfid_read(void);
// UART0 USART1_RX_vect가 호출 한다.
extern volatile int i; // buffer 의 index 변수
extern volatile unsigned char buffer[100]; // UART 부터 읽어온 data를 \r 이나 \n을 만날때 까지 저장할 공간
extern volatile int rxReadyFlag; // \r이나 \n을 만났다는 인디케이터 flag변수
unsigned char dht11_on_off = YES; // #3_DHT11 dht11의 정보를 PC로 올려 줄건지 말건지를 indicator flag
unsigned char fan_on_off = 0;
unsigned char fan_count = 0;
unsigned char temp[2], hum[2]; // #4_DHT11 온도.습도를 읽어서 저장할 공간 정의
unsigned int mycard[4][5] ={{217, 163, 183, 193, 12},{201,236,219,193,63},{228, 57, 175, 42, 88},{-20986, 7068, 47, 32, 32}};
int first_compare_count = 0; // 처음 댄 카드가 일치하는 여부 판단
int next_compare_count = 0; // 태그를 유지할 경우, 일치하는 카드인지 판단
volatile int count = 0; // 오버플로우 인터럽트 발생 횟수를 세는 counter
ISR(USART0_RX_vect) // UART1로 부터 1byte가 들어 오면 interrupt가 발생되어 이곳으로 들어 온다.
{
UART0_ISR_Receive();
}
// TIMER0 overflow interrupt service 함수
// 16KHZ 인 경우 약 16ms 마다 이곳으로 들어 온다.
int main(void)
{
smartfan_main(); //5. 온.습도 정보를 읽어서 UART0에 출력해서 putty로 나오도록 한다.
}
/*
결선방법
RFID-RC522 ATMEGA128A
SDA ----- PORTB.0 // 슬레이브 선택
SCK ----- PORTB.1 // 시리얼클럭
MOSI ----- PORTB.2 // 마스터 --> 슬레이브
MISO ----- PORTB.3 // 슬레이브-->마스터
IRQ ----- 연결안함
GND ----- GND
RST ----- +3.3V
VCC ----- +3.3v
*/
void init_pwm1(void)
{
// 모드 14, 8비트 고속 PWM 모드 Timer counter 3번
TCCR3A |= (1 << WGM30);
TCCR3B |= (1 << WGM32);
// 비반전 모드 TOP : 0xFF 비교일치값 : OCR3B 레지스터
TCCR3A |= (1 << COM3A1);
TCCR3B |= (1 << CS31) | (1 << CS30); // 분주율 64
// 16000000HZ / 64 ==> 250000Hz
// 256 / 250000 ==> 1.02ms
// 127 / 250000 ==> 0.5ms
OCR3A = 0;
}
int rfid_read()
{
unsigned char byte_rfid; // rfid 읽은 상태 체크 변수
unsigned char str[MAX_LEN]; // rfid 값을 읽어을 string 변수
unsigned char fail_save_str[5];
unsigned char Lcd_buffer[15];
int pass_flag = 0;
bool ex_success= false;
spi_init(); // spi 초기화
mfrc522_init(); // rfid rc522을 초기화
byte_rfid = 0x55; // 01010101
// 10101010 0xaa
_delay_ms(1500);
byte_rfid = mfrc522_read(VersionReg); // rfid 버젼을 읽는다.
if (byte_rfid == 0x92)
{
printf("RC522v2 Detected!!!!\r\n");
}
else if (byte_rfid == 0x91 || byte_rfid == 0x90)
{
printf("RC522v1 Detected!!!!\r\n");
}
else
{
printf("No reader Found!!!!\r\n");
}
_delay_ms(1500);
byte_rfid = mfrc522_read(ComIEnReg);
mfrc522_write(ComIEnReg, byte_rfid|0x20);
byte_rfid = mfrc522_read(DivIEnReg);
mfrc522_write(ComIEnReg, byte_rfid|0x80);
_delay_ms(1500);
UART0_printf_string("spi rfid_rc522 test\r\n"); // 2,
while (1)
{
byte_rfid = mfrc522_request(PICC_REQALL, str);
if(byte_rfid == CARD_FOUND)
{
for (int j = 0; j < MAX_LEN; j++)
str[j] = ' ';
byte_rfid = mfrc522_get_card_serial(str);
for (int j = 0; j < 4; j++)
{
first_compare_count = 0;
int k;
for (k = 0; k < 5; k++)
{
if (str[k] == mycard[j][k])
first_compare_count++;
else
break;
}
if (first_compare_count == 5)
{
if(str[k-1] == mycard[2][k-1])
{
PORTA = 0x01;
printf("GOODBYE\r\n");
pass_flag = 2;
sprintf(Lcd_buffer, "%d %d %d %d %d\r\n", mycard[j][0],mycard[j][1],mycard[j][2],mycard[j][3],mycard[j][4]);
printf("%s",Lcd_buffer);
I2C_LCD_write_string_XY(0, 0,"GOODBYE");
I2C_LCD_write_string_XY(1, 0,Lcd_buffer);
_delay_ms(30);
break;
}
if(str[k-1] == mycard[1][k-1])
{
PORTA = 0x02;
printf("HELLOW KIMHYESU\r\n");
pass_flag = 1;
sprintf(Lcd_buffer, "%d %d %d %d %d\r\n", mycard[j][0],mycard[j][1],mycard[j][2],mycard[j][3],mycard[j][4]);
printf("%s",Lcd_buffer);
I2C_LCD_write_string_XY(0, 0,"KIMHYESU COME");
I2C_LCD_write_string_XY(1, 0,Lcd_buffer);
_delay_ms(30);
break;
}
if(str[k-1] == mycard[0][k-1])
{
PORTA = 0x01;
printf("HELLOW JINSUBRO\r\n");
pass_flag = 1;
sprintf(Lcd_buffer, "%d %d %d %d %d\r\n", mycard[j][0],mycard[j][1],mycard[j][2],mycard[j][3],mycard[j][4]);
printf("%s",Lcd_buffer);
I2C_LCD_write_string_XY(0, 0,"JINSUBRO COME");
I2C_LCD_write_string_XY(1, 0,Lcd_buffer);
_delay_ms(30);
break;
}
}
}
}
if(pass_flag == 1 || pass_flag == 2)
break;
}
return pass_flag;
}
/*
* UART0로부터 수신하는 문자는 INTERRUPT로 받고
* 송신 하는 문자는 polling으로 처리 한다.
*/
void smartfan_main()
{
unsigned char *receiveData;
char buffer_TH[50]; // 온도.습도 정보를 statamet로 구성 하기 위한 공간
DDRA = 0xFF; // 포트a led 설정
PORTA |= 0b00000000; // 포트a led 제어
DDRB |= 0xf0; // rfid 설정
DDRE |=(1 << PE7)|(1 << PE2)|(1 << PE3); //모터 동작 설정
UART0_init(); //1 UART1 초기화
I2C_LCD_init(); // lcd 초기화
init_pwm1();
sei(); // global interrupt enable
stdout = &OUTPUT; // 3.printf 설정을 위한 3번째 작업: OUTPUT 포인터를 stdout에 설정을 하는 작업
while(1)
{
int rfid_success = rfid_read();
if(rfid_success == 1)
{
UART0_printf_string("SMART FAN START\r\n"); // 2
while(1) //0이 아니면 돌아라
{
PORTE &= 0b00000100;
PORTE |= 0b00000100; // 정방향 회전 PE7:1 PE2: 0
if(fan_count == 1) OCR3A = 127;//미풍
if(fan_count == 2) OCR3A = 190;//중풍
if(fan_count == 3) OCR3A = 255;//강풍
if (rxReadyFlag == YES) // #4 완전한 message가 buffer에 들어 왔는지 check
{
receiveData = getRxString();//값을 입력받으면
if (strncmp(receiveData,"motoroff",sizeof("motoroff")) == 0)
{
while(1)
{
PORTE |= 0b000000100;
OCR3A = 0;
if (strncmp(receiveData,"motorona",sizeof("motorona")) == 0)
{
fan_count = 1;
break;
}
if (strncmp(receiveData,"motoronb",sizeof("motoronb")) == 0)
{
fan_count = 2;
break;
}
if (strncmp(receiveData,"motoronc",sizeof("motoronc")) == 0)
{
fan_count = 3;
break;
}
}
}
if (strncmp(receiveData,"motorona",sizeof("motorona")) == 0)
{
fan_count = 1;
}
if (strncmp(receiveData,"motoronb",sizeof("motoronb")) == 0)
{
fan_count = 2;
}
if (strncmp(receiveData,"motoronc",sizeof("motoronc")) == 0)
{
fan_count = 3;
}
}
}
}
else if(rfid_success == 2)
{
break;
}
}
}