BASIC4MCU | 질문게시판 | 답변 : atmega128 초보입니다.
페이지 정보
작성자 master 작성일2018-12-01 14:41 조회7,351회 댓글1건
https://www.basic4mcu.com/bbs/board.php?bo_table=gac&wr_id=6120
본문
// MCU BASIC: https://www.basic4mcu.com// DateTime : 2018-12-01 오후 2:45:45// by Ok-Hyun Park//#include <avr/io.h>#include <util/delay.h>#include <avr/interrupt.h>#include <string.h>#include <stdlib.h>#include <stdio.h>//-RGB LCD 제어 PORT&PIN---------------------------------------------------------------#define RGB_DATA_DDR DDRA //-Data Bus제어 Port#define RGB_DATA_PORT PORTA#define DATA_D4 PA0 //-Data Bus PIN#define DATA_D5 PA1#define DATA_D6 PA2#define DATA_D7 PA3#define RGB_LCD_DDR DDRF //-RGB LCD 제어 Port#define RGB_LCD_PORT PORTF#define RS_BIT PF2 //-Register Select: LOW-Command,HIGH-Data#define RW_BIT PF3 //-Read/Wite: LOW-Wite HIGH-Read#define EN_BIT PF4 //-Enable Pin: LOW-Disable HIGH-Enable#define RED_BIT PF5 //-Red Backlight: LOW-Off HIGH-On#define GREEN_BIT PF6 //-Green Backight: LOW-Off HIGH-On#define BLUE_BIT PF7 //-Blue Backlight: LOW-Off HIGH-On//-RBG LCD 제어관련 상수---------------------------------------------------------------#define ALL_SET 0xff //-모든 Pin 1로 셋#define ALL_CLEAR 0x00 //-모든 Pin 0으로 클리어#define DDRAM_ADDR 0x80 //-DD(Display Data)RAM 주소//-RBG LCD 제어관련 명령어--------------------------------------------------------------#define CMD_CLEAR_DISPLAY 0x01 //-CLEAR_DISPLAY(0x01)#define CMD_RETURN_HOME 0x02 //-RETURN_HOME(0x02)#define CMD_ENTRYMODE_SET 0x06 //-ENTRYMODE_SET(0x04)|Left(0x02)|Shift Decrement(0x00)#define CMD_DISPLAY_CONTROL 0x0C //-DISPLAY_CONTROL(0x08)|Display On(0x04)|Cursor Off(0x00)|Blink Off(0x00)#define CMD_CURSOR_SHIFT_RIGHT 0x1C //-CURSOR_SHIFT(0x10)|Shift Move(0x08)|Move Right(0x04)#define CMD_FUNCTION_SET 0x28 //-FUNCTION_SET(0x02)|4BIT(0x00)|2 Line(0x08)|5x8 Dots(0x00)#define CMD_8BIT_MODE 0x03 //-FUNCTION_SET(0x02)|8BIT(0x01)#define CMD_4BIT_MODE 0x03 //-FUNCTION_SET(0x02)|4BIT(0x00)#define DDRAM_FS_ADDR 0x0#define DDRAM_EF_ADDR 0x0F#define DDRAM_SS_ADDR 0x40#define DDRAM_SF_ADDR 0x4F//#define LX_LIMIT 100 //-LED Off 되는 한계 값 정의//-LED 관련#define DDR_LED DDRD#define PORT_LED PORTD#define LED_ON 0x00#define LED_OFF 0xF0/*-------------------------------------------------------------------------*///-Temp관련#define TEMP_ADDR 72 //-온도센서의 Slave 주소#define TEMP_ADDR_W TEMP_ADDR<<1 //-Write 주소#define TEMP_ADDR_R (TEMP_ADDR<<1)+1 //_ Read 주소#define TEMP_REG 0 //_ 온도 데이터 저장 Reg.주소#define TEMP_LIMIT 25 //_ DC Motor ON 되는 한계 값//-Clock 제어를 위한 선언#define CPU_CLOCK 16000000 //_ 16MHz#define SCL_FREQUENCY 400000 //_ 400KHz//-DC 모터 제어를 위한 정의#define DCM_DDR DDRB // B포트를 모두 출력으로#define DCM_PORT PORTB // B포트를 모두 출력으로 8칸이 다 1이 출력된다는거임#define FORWARD_BIT 0#define BACKWARD_BIT 1//-온도값 저장 전역 변수 선언volatile unsigned int gTempValue; //_ 측정된 온도 값 저장//-USART 제어를 위한 전역 변수 선언volatile unsigned int gLightValue; //-측정된 조도값 저장/*=====================================함수 선언=========================================================*/void RGB_LCD_Init(void);void RGB_LCD_Enable(void);void RGB_LCD_Write(unsigned char nValue);void Set4BitMode(void);void SendText(unsigned char addrCommand,char*szText);void SendCommandl(unsigned char command);void SendData(unsigned char data);void LCD_Display(void);void ADC_LED_Init(void);void ADC_Convert(void);void LED_OnOff(unsigned char nNum);//_ Temp&ADCvoid TEMP_DC_Init(void);void TEMP_Read(void);//_ DC Motorvoid Run_DCM(void);void Stop_DCM(void);//void TEMP_DC_Init(void){//-DC Motor 초기화DCM_DDR|=(1<<FORWARD_BIT)|(1<<BACKWARD_BIT); //-PB0,PB1 비트 Output으로 설정DCM_PORT&=~((1<<FORWARD_BIT)|(1<<BACKWARD_BIT)); //-DC모터 구동 정지로 설정//-Temp TWI 초기화TWSR&=~((1<<TWPS1)|(1<<TWPS0)); //-분주비 설정TWBR=(CPU_CLOCK/SCL_FREQUENCY-16)/ 2; //-TWI 통신 속도 설정}//void TEMP_Read(void){unsigned char arrTemp[2]; //-읽어온 2byte 데이터 저장unsigned int nTmp; //-12bit 온도 값 저장float fCValue; //-섭씨로 변환한 값 저장//-START conditionTWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);while(!(TWCR&(1<<TWINT)));//-Slave Addr+Read 전송TWDR=TEMP_ADDR_R;TWCR=(1<<TWINT)|(1<<TWEN);while(!(TWCR&(1<<TWINT)));//-측정된 온도값 읽기for(int i=0; i<2; i++){ TWCR=(1<<TWINT)|(1<<TWEA)|(1<<TWEN); while(!(TWCR&(1<<TWINT))); arrTemp[i]=TWDR; }nTmp=arrTemp[0]<<8; nTmp=nTmp|arrTemp[1]; nTmp=nTmp>>4; //-측정된 12bit 온도 데이터 계산fCValue=(float)nTmp*0.0625; //-온도값을 섭씨로 변환->data_value*0.0625--------------TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN); _delay_ms(5); //-STOP conditionif((int)fCValue>TEMP_LIMIT)Run_DCM(); else Stop_DCM();gTempValue=(int)fCValue; //-섭씨 온도값 저장}//void Run_DCM(void){ //-DC Motor 동작DCM_PORT&=~((1<<FORWARD_BIT)|(1<<BACKWARD_BIT)); //-정방향으로 회전DCM_PORT|=(1<<FORWARD_BIT);}//void Stop_DCM(void){ DCM_PORT=(1<<FORWARD_BIT)|(1<<BACKWARD_BIT); }/*=LED관련 함수*///-LED On/Offvoid LED_OnOff(unsigned char nNum){if(nNum==LED_ON)PORT_LED=0x00; //-4개 LED ONelse PORT_LED=0xF0; //-4개 LED OFF}/*=ADC&Light 관련 함수*///-ADC&Light 초기화void ADC_LED_Init(void){//-LED 초기화DDR_LED|=0xF0; PORT_LED|=0xF0;//-ADC0 채널,AREF 기준 전압 및 채널을 선택ADMUX=0;//-채널,활성화,프리스케일 설정ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);}/*==ADC 변환 함수 구현*/void ADC_Convert(void){unsigned int result;cli(); //-ADC 변환 중 인터럽트 금지ADCSRA|=(1<<ADSC); //-ADC 변환 시작while(!(ADCSRA&(1<<ADIF))); //-ADC 변환 완료 신호 대기result=ADCL; //-변환 결과 저장result|=((ADCH&0x03)<<8);sei(); //-인터럽트 허용if(result>LX_LIMIT)LED_OnOff(LED_OFF); //-CDS Value>50 LED OFFelse LED_OnOff(LED_ON); //-CDS Value<=50 LED ON//-조도값 저장gLightValue=result;}//void SendCommand(unsigned char command){ //-RBG_LCD 명령어 전달 함수 구현---------------------------------RGB_LCD_PORT&=~((1<<RS_BIT)|(1<<RW_BIT)|(1<<EN_BIT)); //-Command 전송을 위한 RS=0,RW=0,EN=0RGB_LCD_Write(command>>4); RGB_LCD_Write(command); //-Data Bus에 CMD 쓰기}//void SendData(unsigned char data){ //-RBG_LCD 데이터 전달 함수 구현---------------------------------RGB_LCD_PORT|=(1<<RS_BIT); RGB_LCD_PORT&=~((1<<RS_BIT)|(1<<EN_BIT)); //-Data 전송을 위한 RS=1,RW=0,EN=0RGB_LCD_Write(data>>4); RGB_LCD_Write(data);}//void SendText(unsigned char addrCommand,char*szText){ //-RBG_LCD 문자열 출력 함수 구현---------------------------------SendCommand(addrCommand); //-DD Ram 주소 전달while(*szText!='\0'){ SendData(*szText); szText++; }}//void RGB_LCD_Write(unsigned char nValue){ //-RBG_LCD 명령어/데이터 레지스터 기록 구현---------------------------------int nTmp=0;RGB_DATA_PORT=0x00;for(int nldx=0; nldx<4; nldx++){ nTmp=(nValue>>nldx)&0x01; RGB_DATA_PORT|=(nTmp<<(DATA_D4+nldx)); }RGB_LCD_Enable();}//void RGB_LCD_Enable(void){RGB_LCD_PORT|=(1<<EN_BIT); _delay_us(1); RGB_LCD_PORT&=~(1<<EN_BIT); _delay_us(100);}//void Set4BitMode(void){ //-RBG_LCD 4bit 인터페이스 설정 구현---------------------------------RGB_LCD_PORT&=~((1<<RS_BIT)|(1<<RW_BIT)|(1<<EN_BIT)); //-Command 전송을 위한 RS=0,RW=0,EN=0RGB_LCD_Write(CMD_8BIT_MODE); _delay_us(4500);RGB_LCD_Write(CMD_8BIT_MODE); _delay_us(4500);RGB_LCD_Write(CMD_8BIT_MODE); _delay_us(150);RGB_LCD_Write(CMD_4BIT_MODE);}//void RGB_LCD_Init(void){RGB_LCD_DDR=((1<<RS_BIT)|(1<<RW_BIT)|(1<<EN_BIT)|(1<<RED_BIT)|(1<<GREEN_BIT)|(1<<BLUE_BIT));RGB_LCD_PORT&=~((1<<RS_BIT)|(1<<RW_BIT)|(1<<EN_BIT)|(1<<RED_BIT)|(1<<GREEN_BIT)|(1<<BLUE_BIT));RGB_DATA_DDR=ALL_SET; RGB_DATA_PORT=ALL_CLEAR; //-Data 입력 Pin Output 설정 및 초기화Set4BitMode(); //-(2)RGB LCD 인터페이스 설정SendCommand(CMD_FUNCTION_SET); //-(3)RGB LCD 출력을 위한 설정 //-LCD의 행,열,글자 크기 설정SendCommand(CMD_DISPLAY_CONTROL); //-디스플레이,커서,문자 깜빡임 On/Off 설정SendCommand(CMD_ENTRYMODE_SET); //-커서 이동 방향,문자 디스플레이 이동 여부 설정SendCommand(CMD_CLEAR_DISPLAY); //-LCD 화연 지우고 커서는 1행 1열 위치,DDRAM AC=0RGB_LCD_PORT|=(1<<GREEN_BIT); //-Green Backlight 켜기_delay_us(2000);}//void LCD_Display(void){ //-측정된 온도,조도값 LCD에 출력--------------------------char arrTmp[16]="",pTmp[4]="";itoa(gTempValue,pTmp,10); strcat(arrTmp,"T: "); strcat(arrTmp,pTmp); strcat(arrTmp,"C"); //-온도값 문자열로 변환itoa(gLightValue,pTmp,10); strcat(arrTmp,"L: "); strcat(arrTmp,pTmp); strcat(arrTmp,"Lx "); //-조도값 문자열로 변환SendText(DDRAM_ADDR|DDRAM_FS_ADDR,arrTmp);}/*===========================*/// DESC:(1)일정 온도 이상이 되면 DC모터를 회전시키고 일정 밝기 이하면 LED를 켜준다.//-(2)RGB_LCD에 현재 온도와 조도를 표시해 준다./*===========================*//*==Main 함수 구현==============*/int main(void){ADC_LED_Init(); //-Light&LED 초기화TEMP_DC_Init(); //-Temp&DC 초기화RGB_LCD_Init(); //-RGB_LCD 초기화while(1){TEMP_Read(); //-온도 측정ADC_Convert(); //-조도 측정LCD_Display(); //-현재 온도.조도 LCD 출력_delay_ms(1000);}return 0;}
타이핑 오타는 백만개라고 하더라도 자신이 직접 찾아야합니다.
댓글 1
조회수 7,351master님의 댓글
master 작성일
본인 능력으로 오타도 찾지 못할만큼 복잡한 소스라면 이해하는 것도 어려울테니
간단하고 쉬운 예제를 많이 공부한 후에 복잡한 소스를 보시는 것이 힘이 덜 듭니다.