디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

[일반] 회로도랑 코드 올립니다! 도움부탁드립니다.앱에서 작성

임갤러(203.241) 2023.08.08 16:50:29
조회 490 추천 0 댓글 28
														

제가 시작한지 얼마 안 된 학생이라 다른 거 쓸 줄 몰라서 손으로 최대한 그렸어요 ㅠㅠ 죄송합니다.

75e98071b3876d84239b82e4479c706a3290f7dfcd07ffd7abb370eec29418b0097f4894cd07202fbb0d4311fa0460a92751ea7a1e


#include "stm32f10x.h"             
#include "systeminit.h"

/*RS,RW,E 등의 정의*/
#define RS_H (GPIOA->BSRR =0x00000800)    //RS=PA.11 =1
#define RS_L (GPIOA->BSRR =0x08000000)    //RS=PA.11 =0
#define RW_H (GPIOA->BSRR =0x00000020)    //RW=PA.5  =1
#define RW_L (GPIOA->BSRR =0x00200000)    //RW=PA.5  =0
#define E_H  (GPIOA->BSRR =0x00000010)    //E=PA.4 =1
#define E_L  (GPIOA->BSRR =0x00100000)    //E=PA.4 =0

int a=0;
int i=0;
float duty = 1500;
unsigned  char AD_val2, AD_val;

void ALLTHE_ANNOUNCE(void) {
  
  RCC->APB2ENR =0X0000020D;        //GPIOA,GPIOB에 RCC 클럭 공급 , AFIO ON, ADC1
  GPIOB->CRH =0x33333333;    //GPIO_E(15:8)를 50MHz push pull 출력으로
  GPIOA->CRH =0x00003000;    //GPIO_A(11,5,4)를 50MHz PP 출력으로
  GPIOA->CRL =0x0B330003;       // PA0 50MHz push pull 출력 LED , PA1 = analog input 채널1 지정, PA4 5 = LCD, PA6 = 서모보터
  RCC->CFGR = 0x001F8402;      //시스템클럭 36MHz, APB1 클럭 18MHz, APB2 클럭 36MHz로 하기 위한 
  RCC->CR = 0x01010082;        //RCC_CFGR와 RCC_CR의 설정
  RCC->APB1ENR = 0x00000003;   //timer2, timer3,clock enable
}


void adc_0(void) {
  
  
  /*ADC1 구성*/
  ADC1->CR1 = 0x00000000;     //Indefendent mode(DUALMODE=0),EOC인터럽트 disable(EOCIE=0),스캔 disable(SCAN=0) 
  ADC1->CR2 = 0x001E0002;     //external event에 의한 변환이되,트리거는 SWSTART(EXTTRIG=1,EXTSEL=7)
                              //연속변환(CONT=1),우측배치(ALIGN=0)
  ADC1->SQR1 &= 0xFF0FFFFF;   //변환채채널 수=1(L=0)
  ADC1->SMPR2|= (3<< 5);   //샘플 시간=55.5 cycle(SMP1=5)
  ADC1->SQR3 |= (1<< 0);    //채널 1를 첫번째로 변환(SQ1=1)

  /*ADC on*/
  ADC1->CR2 |= 0x00000001;      //ADC on(ADON=1)
 
  /*눈금 보정*/ 
  ADC1->CR2  |= 0x00000008;  
  while (ADC1->CR2 & 0x00000008);//reset이 끝날 때까지 대기 
  ADC1->CR2  |= 0x00000004;      //보정 시작
  while (ADC1->CR2 & 0x00000004);//보정이 끝날 때까지 대기
 
  /*변환 시작*/  
  ADC1->CR2 |= 0x00400000;      //SW에 의한 정규변환 시작
  

    /*AD변환이 끝났는지를 보고, AD변환값을 읽어서 전압값으로 고친다*/
  
      while (!(ADC1->SR & 0x00000002)); //EOC=1? 변환이 끝났는가?
    
      AD_val = ADC1->DR & 0xFFF;        //yes이면 변환값을 읽어서 
      AD_val = (3.3 * AD_val*1000) / (4096*100);  // ADC기준전압=3.3V: 4096=12비트 AD 변환이므로
                        //원래 AD_val = (3.3 * AD_val) / 4096인데, 나눗셈에서 소수부분이 짤려지는 것 때문에
                        //1000을 곱하고,100으로 나누어 소숫점 아래 한자리를 표시할 수 있게 함 
                        /*AD변환값 AD_val를 각 단위별 AD_val BCD로 바꾼다*/
      
      
      AD_val2 = '0'+ (AD_val%100)/10;  //AD_val의 10단위 BCD 
   
      if(AD_val2!=49) { 
        
        GPIOA->ODR = 0X00;
      }
      else if(AD_val2==49){
      
        GPIOA->ODR = 0X01;
      }
      
  
}


/*인터럽트 허용*/
void interrupt_1(void){
   
   TIM2->DIER = 0x0001;  /* interrupt on update, TIM_DIER_UIE=0x0001 */
   NVIC_SetPriority(TIM2_IRQn,(1<<__NVIC_PRIO_BITS)-1); //set priority to 1
   NVIC_EnableIRQ(TIM2_IRQn);
   TIM2->EGR = 0x0001;        //TIM_EGR_UG; 
  
}


/*(us*마이크로) 초 지연루틴*/
void Delay_us(unsigned int us){ //(us*마이크로) 초 마큼 지연     
  
     volatile unsigned int ncount=1*us;
     for(; ncount !=0; ncount--);
     
 }


/*(ms*미리) 초 지연루틴*/
void Delay_ms(unsigned int ms) { //(ms*미리) 초 마큼 지연    
 
     volatile unsigned int ncount=4000*ms; 
     for(; ncount !=0; ncount--);
 
}


/*LCD에 명령을 기록하는 루틴*/
void write_cmd(u8 cmd) {    
     u16  iu16;
     Delay_ms(5);              //명령을 할 수 있을 때까지 기다림( busy() 대용임)
        
     RS_L;                     //RS=0(명령 모드), R/W=0(기록 모드), E=1(E펄스)
     RW_L;                    
     E_H;                      //아래 E_L과 함께 E펄스(명령 앞뒤엔 이것이 있어야 함)
                               //E가 high인 경우에만 명령을 할 수 있음
     iu16 = (u16)(cmd << 8);   //하위 바이트에 있는 명령 cmd를 상위 바이트로 옮겨셔  
     GPIOB->ODR = iu16;        //GPIOG_ODR의 상위 바이트(비트 15:8)를 통하여 IR에 기록한다
     Delay_ms(2);              //동작시간

     E_L;
 }


/*LCD에 데이터를 기록하는 루틴*/
void write_char(u8 data) {          
     u16 du16;
          
     RS_H;                     //RS=1(데이터 모드), R/W=0(기록 모드), E=1(E펄스) 
     RW_L;
     E_H; 
   
     du16 = (u16) (data << 8); //하위 바이트에 있는 문자데이터 data를 상위 바이트로 옮겨서 
     GPIOB->ODR = du16;        //GPIOG_ODR의 상위 바이트(비트 15:8)를 통하여 DR에 기록한다   
     Delay_ms(2); 

     E_L;   
  }


 /*LCD 초기화 루틴*/
void init_LCD(void) {
     Delay_ms(16);
     ALLTHE_ANNOUNCE();      //앞에서 정의한 LCD 관계 레지스터들의 값
  
     write_cmd(0x38);          // FUNCTION SET 명령
     Delay_ms(5);              // 4.1msec 지연
     write_cmd(0x38);          // FUNCTION SET 명령
     Delay_us(120);
     write_cmd(0x38);          // FUNCTION SET 명령
     Delay_us(250);

     write_cmd(0x38);          // FUNCTION SET 명령, 8비트 interface
     write_cmd(0x08);          // DISPLAY OFF 명령
     write_cmd(0x0C);          // DISPLAY ON 명령
     write_cmd(0x01);          // CLEAR DISPLAY 명령
     write_cmd(0x06);          // ENTRY MODE SET 명령
 }


 /* TIM2 1초 주기 */
void sec_1(void){
  
  TIM2->CR1 = 0;
  TIM2->CR2 = 0;
  TIM2->CNT = 0;               //timer2 counter의 초기화
  TIM2->SR = 0;                //clear FLAG
  
  TIM2->PSC = 36000;           //prescaler, 36000000/36000=1000(Hz)
  TIM2->ARR = 1000 -1;         //period, 1000/1000=1(Hz)=1(Sec)
  
}


 /* 1초로 1주일 */
void TIM2_IRQHandler(void){
  TIM2->SR = 0;
   i++;
   a++;
  
   
   if(i<=9){
     
     if(i==1){
       init_LCD();               // LCD 초기화
     }
     u8 g;
    
     u8 table1[16]="TODAY IS SUNDAY " ; //LCD에 표시할 문자데이터의 테이블
     u8 table2[16]="NEXT IS MONDAY  ";
     
     write_cmd(0x80);          // 제 1라인의 최초번지(DDRAM의 0번지)를 지정하고
     for(g=0; g<16; g++) {     // table_1에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table1[g]);
     }
 
     write_cmd(0xC0);          // 제 2라인의 최초번지를 지정하고
     for(g=0; g<16; g++) {     // table_2에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table2[g]); 
     }
   }
   
     else if(10<=i && i<=15){
       
     u8 h;
  
     u8 table3[16]="TODAY IS MONDAY ";
     u8 table4[16]="NEXT IS TUESDAY ";
     
     write_cmd(0x80);          // 제 1라인의 최초번지(DDRAM의 0번지)를 지정하고
     for(h=0; h<16; h++) {     // table_1에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table3[h]);
     }

     write_cmd(0xC0);          // 제 2라인의 최초번지를 지정하고
     for(h=0; h<16; h++) {     // table_2에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table4[h]); 
     }
   }
   
     else if(16<=i && i<=176400){
       
     u8 j;
     
     u8 table5[16]="TODAY IS TUESDAY";
     u8 table6[17]="NEXT IS WEDNESDAY";
     
     write_cmd(0x80);          // 제 1라인의 최초번지(DDRAM의 0번지)를 지정하고
     for(j=0; j<16; j++) {     // table_1에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table5[j]);
     }
 
     write_cmd(0xC0);          // 제 2라인의 최초번지를 지정하고
     for(j=0; j<17; j++) {     // table_2에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table6[j]); 
     }
 
   }
   
     else if(176400<=i && i<=262800){
       
     u8 k;
     
     u8 table7[18]="TODAY IS WEDNESDAY";
     u8 table8[16]="NEXT IS THURSDAY";
     
     write_cmd(0x80);          // 제 1라인의 최초번지(DDRAM의 0번지)를 지정하고
     for(k=0; k<16; k++) {     // table_1에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table7[k]);
     }
  
     write_cmd(0xC0);          // 제 2라인의 최초번지를 지정하고
     for(k=0; k<16; k++) {     // table_2에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table8[k]); 
     }
   }
   
   else if(262800<=i && i<=349200){
     u8 l;
    
     u8 table9[17]="TODAY IS THURSDAY";
     u8 table10[14]="NEXT IS FRIDAY";
     
     write_cmd(0x80);          // 제 1라인의 최초번지(DDRAM의 0번지)를 지정하고
     for(l=0; l<17; l++) {     // table_1에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table9[l]);
     }
   
     write_cmd(0xC0);          // 제 2라인의 최초번지를 지정하고
     for(l=0; l<14; l++) {     // table_2에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table10[l]); 
     }
   }
   
   else if(349200<=i && i<=435600){
     u8 m;
   
     u8 table11[15]="TODAY IS FRIDAY";
     u8 table12[16]="NEXT IS SATURDAY";
     
     write_cmd(0x80);          // 제 1라인의 최초번지(DDRAM의 0번지)를 지정하고
     for(m=0; m<15; m++) {     // table_1에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table11[m]);
     }

     write_cmd(0xC0);          // 제 2라인의 최초번지를 지정하고
     for(m=0; m<16; m++) {     // table_2에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table12[m]); 
     }
   }
   
   else if(435600<=i && i<=522000){
     u8 n;
    
     u8 table13[17]="TODAY IS SATURDAY";
     u8 table14[14]="NEXT IS SUNDAY";
     
     write_cmd(0x80);          // 제 1라인의 최초번지(DDRAM의 0번지)를 지정하고
     for(n=0; n<16; n++) {     // table_1에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table13[n]);
     }
   
     write_cmd(0xC0);          // 제 2라인의 최초번지를 지정하고
     for(n=0; n<14; n++) {     // table_2에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table14[n]); 
     }
   }
   
   else if(522000<=i && i<=604800){
     u8 o;
      
     u8 table1[16]="TODAY IS SUNDAY "; //LCD에 표시할 문자데이터의 테이블
     u8 table2[16]="NEXT IS MONDAY  ";
     
     write_cmd(0x80);          // 제 1라인의 최초번지(DDRAM의 0번지)를 지정하고
     for(o=0; o<16; o++) {     // table_1에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table1[o]);
     }
   
     write_cmd(0xC0);          // 제 2라인의 최초번지를 지정하고
     for(o=0; o<16; o++) {     // table_2에 있는 문자데이터를 차례로 불러 지정된 라인에 기록한다
        write_char(table2[o]); 
     }
    
     if (i==604800){
       i=0;
   }
 }
   if(a==3000){
     
     duty= duty-600;
    
   }
   else if(a==3001){
     
     duty=duty+600;
     
   }
   
   else if(a==3002){
     
     a=0;
     
   }
    TIM3->CCR1 = (float)duty;
   
}


 /* TIM3 서보모터 */
void servomotor_timer34(void) {
  
  /*출력포트 설정*/
  TIM3->CR1 = 0X0080;       //ARPE=1(Aoto-reload preload register 활성화),CKD=00(clock division 없음),
                                    //DIR=0(up counter),CMS=00(edge aligned mode)
  TIM3->PSC = 36;            //카운터 클럭=36MHz/(36)=1000000Hz
  
 /*듀티비=7.5%의 PWM을 내기 위한 TIM3 설정*/
  TIM3->ARR = 20000 -1;      //TIM3주파수=TIM3 couter clock/(TIM3_ARR+1)=1000000Hz/20000=50Hz; ARR=펄스폭  
  TIM3->CCR1 = 1500;        //TIM3_CNT duty cycle =[TIM3_CCR1/(TIM3_ARR+1)]*100

 /*PWM 모드 설정*/ 
  TIM3->CCER = 0x0000;      //CCMR1 설정을 위해 필요함
  TIM3->CCMR1 = 0x0068;     //OC1M=110(PWM mode 1), OC1PE=1(enable preload register:주기적인 펄스 가능)

 /*카운터와 PWM 활성화, 초기화*/ 
  TIM3->CR1 |= 0x0001;      //TIM3 enable   
  TIM3->CCER  |= 0x0001;    //CC1E=1(TIM_OutputState enable: OC1출력을 output핀으로 송출 가능)
  TIM3->EGR = 0x0001;       //UG(카운터 초기화, 레지스터들 update)
  
}


int main(void){
    
  ALLTHE_ANNOUNCE(); 
  
  /*1초를 위한 타이머 설정*/ 
  sec_1();
  
  servomotor_timer34();

  interrupt_1();
  /*카운팅 시작*/
  TIM2->CR1 = 0x0001;          //upcount,timer2 counting 시작
  
  
   adc_0();
   
   
}

- dc official App

추천 비추천

0

고정닉 0

0

댓글 영역

전체 댓글 0
등록순정렬 기준선택
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 말머리 제목 글쓴이 작성일 조회 추천
2868 설문 힘들게 성공한 만큼 절대 논란 안 만들 것 같은 스타는? 운영자 24/06/10 - -
3155 공지 [공지] 멤버만 글쓸수있게 변경함 [2] 퍼플승연갤로그로 이동합니다. 23.11.27 993 0
2745 공지 [공지] 임베디드 갤러리 규칙 퍼플승연갤로그로 이동합니다. 23.10.11 739 0
3657 일반 초보 임붕이...선배님들에게 질문이 있어서 글 남겨요. [7] 임붕이 06.09 195 0
3656 일반 이더넷,usb같은 서브시스템들 회로는 뭐로 공부하나요? [2] 임붕이 06.09 102 0
3655 일반 현재 임베디드 희망하는 대3입니다 [15] 임붕이 06.09 222 0
3654 일반 혹시 실리콘 랩스 관련 강의같은거 있을까요?? 임붕이 06.08 34 0
3653 일반 지금 허리라인 뒤진게 큰거같다 [5] 임붕이 06.08 171 0
3652 일반 임베디드 입사하는게 맞을까 [9] 임붕이 06.08 226 0
3651 일반 퇴사하고싶을때 들으면 좋은 노래 [1] 임붕이 06.08 112 2
3650 일반 고등학생입니다. 앞으로의 방향성에 대해서 조언듣고 싶어요. [11] 임붕이 06.08 213 1
3649 일반 복수전공 담학기 4학년인데 방학때 뭘 해야할까요..? [6] 임붕이 06.07 176 0
3648 일반 나 이런 갤러리 있는 줄도 모르고 프로그래밍 갤러리에서 놀고 있었음 [2] 임붕이 06.07 180 0
3647 일반 지금 취업 존네 어렵다드라 [12] 임붕이 06.07 461 0
3646 일반 학과 이름/수강 과목 많이 중요함? [2] 임붕이 06.06 168 0
3645 일반 임베디드 sw쪽 공부하려고 하는데 [4] 임붕이 06.06 173 0
3644 일반 엔지니어 역량 [33] 임붕이 06.06 425 0
3643 일반 보통 여기서 말하는 반도체가 공정쪽인가요?? [2] 임붕이 06.06 166 0
3642 일반 다들 취미가 있으신가요? [10] 임붕이 06.05 277 0
3641 일반 23살 애송이 전기과 임베디드관련 취업 질문 [6] 임붕이 06.05 273 0
3640 일반 보드 연결 초심자질문 [12] 임붕이 06.04 289 0
3639 일반 돈 많이 벌자 그게 최고다.. [1] 임붕이 06.03 205 0
3638 일반 이온전지를 어떻게 활용가능할까 [2] 임붕이 06.03 104 0
3637 일반 펌웨어에서 전문가란 뭘까 [1] 임붕이 06.03 230 0
3635 일반 임베디드 hw 가 따로 잇어요.? [6] 임붕이 06.03 248 0
3634 일반 임베디드는 서울/경기에 일자리가 더 적은가..? [1] 임붕이 06.03 211 0
3632 일반 다재다능 vs 한우물만파기 [7] 임붕이 06.02 252 0
3631 일반 내일 FPGA 신입 첫출근인데 [2] 임붕이 06.02 224 0
3630 일반 여러분은 개발자라고 칭하나요 엔지니어라 칭하나요 [7] 임붕이 06.02 247 0
3629 일반 원래 hdl도 sw로 퉁침? [7] 임붕이 06.02 211 0
3627 일반 임베디드 책하나 써보려하는데 수요있을까? [15] 임붕이 06.01 362 0
3626 일반 운영체제 과제하는데 막막하다.. [2] 임붕이 05.31 239 1
3625 일반 임베디드 관련 고등학교 생기부 임붕이 05.31 112 0
3624 일반 tft SPI 통신 시도중인데 어렵네 [2] 임붕이 05.31 145 0
3623 일반 리눅스 커널 공부하려는데 커널 버전 질문... [3] 임붕이 05.31 202 0
3622 일반 임베디드SW 직군 희망하는데 마이크로프로세서 과목을 못들었습니다.. [1] 임붕이 05.31 252 0
3621 일반 vscode 사용시 질문좀 [4] 임붕이 05.31 169 0
3620 일반 물경력 5년차 코더인데 뭐가 낳음? [8] 임붕이 05.30 401 0
3618 일반 코딩좋으면 임베디드말고 다른거하는게 [6] 임붕이 05.29 545 0
3617 일반 내가 생각하는 임베디드 끝판왕 [8] 임붕이 05.29 485 0
3616 일반 HW 1년 조금 넘었는데 FW도 해보려고 하는데 [12] 임붕이 05.27 452 0
3615 일반 기계과 4학년인데 임베디드 준비 괜찮을까요? [1] 임붕이 05.27 298 0
3614 일반 임베디드 sw는 비전공자가 진입하기 많이 힘든가요 [15] 임붕이 05.26 541 0
3613 일반 Fw신입분들 보통 합격 하실 때 까지 이력서 얼마정도 쓰셨나요 [6] 임붕이 05.25 453 0
3612 일반 센서리스 BLDC 제어 [7] 임붕이 05.25 359 0
3611 일반 임베디드 HW직군과 SW직군 차이가 이거 맞나요?? [5] 임붕이 05.25 496 0
3610 일반 영상처리 같은거 배우고싶은데 책추천좀 [2] 임붕이 05.25 304 0
3609 일반 임베디드SW쪽은 정년하고도 일할거리 있나요? [2] 임붕이 05.24 476 0
3608 일반 학부로 fpga 취업하려면 뭘 해야할까요 [3] 임붕이 05.24 334 0
3607 일반 Npu 회사 다니는 사람? 임붕이 05.24 136 0
3606 일반 Zybo z7-20 [5] 임붕이 05.24 226 0
3605 일반 .. [6] 임붕이 05.24 369 0
3604 일반 힘들다기 보단 그냥 손을 못대겠다 [3] 임붕이 05.24 398 0
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2