Thông báo

Collapse
No announcement yet.

Cần giúp đỡ code AVR : khi chạy truyền tin UART thì timer 1 không hoạt động, DS1307 bị reset thời gian như ban đầu

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Cần giúp đỡ code AVR : khi chạy truyền tin UART thì timer 1 không hoạt động, DS1307 bị reset thời gian như ban đầu

    Mình đang lập trình mình test, AVR giao tiếp DS1307 hiển thị giờ phút giây trên LCD, sử dụng ngắt ngoài INT0 để kích hoạt việc đếm xung timer 1.
    Lỗi:
    + khi không truyền nhận UART (k dùng hàm transmit_frames mình viết) thì chạy oke. khi có ngắt ngoài sẽ bắt đầu đếm xung trên timer1 hiển thị LCD
    + khi sử dụng dùng hàm transmit_frames mình viết UART thì mỗi khi có ngắt đồng hồ ds1307 reset về giá trị khởi tạo, số xung luôn là 0, k đếm được xung.
    Rất mong các bác chỉ giáo. thanks

    /************************************************** ***
    This program was produced by the
    CodeWizardAVR V2.05.0 Professional
    Automatic Program Generator
    © Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
    http://www.hpinfotech.com

    Project : Belt-weight
    Version : 1.0
    Date : 06-06-2015
    Author : Nguyen Cong Trung
    Company : Vietnam Metrology Institute
    Comments:


    Chip type : ATmega32A
    Program type : Application
    AVR Core Clock frequency: 8.000000 MHz
    Memory model : Small
    External RAM size : 0
    Data Stack size : 512
    ************************************************** ***/

    #include <mega32a.h>
    #include <delay.h>

    // I2C Bus functions
    #asm
    .equ __i2c_port=0x15 ;PORTC
    .equ __sda_bit=1
    .equ __scl_bit=0
    #endasm


    #ifndef RXB8
    #define RXB8 1
    #endif

    #ifndef TXB8
    #define TXB8 0
    #endif

    #ifndef UPE
    #define UPE 2
    #endif

    #ifndef DOR
    #define DOR 3
    #endif

    #ifndef FE
    #define FE 4
    #endif

    #ifndef UDRE
    #define UDRE 5
    #endif

    #ifndef RXC
    #define RXC 7
    #endif

    #define FRAMING_ERROR (1<<FE)
    #define PARITY_ERROR (1<<UPE)
    #define DATA_OVERRUN (1<<DOR)
    #define DATA_REGISTER_EMPTY (1<<UDRE)
    #define RX_COMPLETE (1<<RXC)

    #define BAUD 9600 // define baud
    #define BAUDRATE ((F_CPU)/(BAUD*16UL)-1) // set baudrate value for UBRR
    #ifndef F_CPU
    #define F_CPU 16000000UL // set the CPU clock
    #endif

    #define byte_start 0x55 //ky tu U
    #define byte_stop 0x3F //ky tu ?



    #include <i2c.h>

    // DS1307 Real Time Clock functions
    #include <ds1307.h>

    // Alphanumeric LCD Module functions
    #include <alcd.h>

    // Declare your global variables here
    unsigned int so_xung=0,flag_int0=0;
    unsigned char start,stop,h,m,s,date,month,year;
    char buffer[11];

    void lcd_ds1307() //doc du lieu tu ds1307 hien thi ra LCD
    {
    rtc_get_time(&h,&m,&s);
    rtc_get_date(&date,&month,&year);
    }
    // Timer1 overflow interrupt service routine
    interrupt [TIM1_OVF] void timer1_ovf_isr(void)
    {
    // Place your code here
    so_xung=0;
    TCNT1H=0x00; //bat dau dem tu so 0000
    TCNT1L=0x00;
    }
    //************************************************** **khoi tao ************************************************** **
    void uart_init()
    {
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    UCSRB=0xD8;
    UBRRH=(BAUDRATE>>8);
    UBRRL=BAUDRATE; //set baud rate
    UCSRC|=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);// 8bit data format
    }
    //************************************Ham truyen 1 byte UART **********************************************
    void uart_transmit(unsigned char data)
    {
    while (!( UCSRA & (1<<UDRE))); // wait while register is free
    UDR = data; // load data in the register
    }
    //************************************Ham truyen n byte trong buff ************************************
    // frames theo dang U - n byte date - ? ************************************************** ********************
    void transmit_frames(char number) // ham truyen n byte
    {
    char j=0;
    uart_transmit(0x55); //start byte U
    for(j=1;j<=number;j++) //n byte data trong bo dem
    {
    uart_transmit(buffer[j]);
    };
    uart_transmit(0x3F); // stop byte ?
    delay_ms(10);
    }
    // External Interrupt 0 service routine
    interrupt [EXT_INT0] void ext_int0_isr(void)
    {
    // Place your code here
    flag_int0++;
    if(flag_int0==1) {transmit_frames(2);}
    }
    //************************************************** * HIEN THI SO NGUYEN DUONG Z **************************************
    void lcd_putnum(unsigned long int z) //hien thi toi da 5 so (bien 4 byte , max 4,294,967,295 int 2 byte 65535)
    {
    unsigned long z1,z2,z3,z4,z5;
    z1=z/10000;
    z2=(z-10000*z1)/1000;
    z3=(z-10000*z1-1000*z2)/100;
    z4=(z-10000*z1-1000*z2-100*z3)/10;
    z5= z-10000*z1-1000*z2-100*z3-10*z4;
    if(z1>0)
    {
    lcd_putchar(z1+48);
    lcd_putchar(z2+48);
    lcd_putchar(z3+48);
    lcd_putchar(z4+48);
    lcd_putchar(z5+48);
    }
    else
    if (z2>0)
    {
    lcd_putchar(z2+48);
    lcd_putchar(z3+48);
    lcd_putchar(z4+48);
    lcd_putchar(z5+48);
    }
    else
    if (z3>0)
    {
    lcd_putchar(z3+48);
    lcd_putchar(z4+48);
    lcd_putchar(z5+48);
    }
    else
    if (z4>0)
    {
    lcd_putchar(z4+48);
    lcd_putchar(z5+48);
    }
    else
    {
    lcd_putchar(z5+48);
    };
    }

    //====================================
    void lcd_hienthi()
    {

    //doan lenh sau thuc hien viec neu chua co ngat INT0 thi reset timer T1 va bien so xung
    //neu co ngat thi lap tuc cap nhat lien tuc gia tri timer T1
    if(flag_int0==1)
    {
    so_xung=TCNT1H;
    so_xung=so_xung<<8;
    so_xung=so_xung+ TCNT1L;
    }
    else
    {
    so_xung=0;
    TCNT1H=0x00;
    TCNT1L=0x00;
    }
    lcd_clear();
    lcd_gotoxy(0,0); lcd_putsf("so_xung ="); lcd_gotoxy(11,0);lcd_putnum(so_xung);
    lcd_gotoxy(0,1); lcd_putsf("4096 xung/s");
    lcd_gotoxy(0,2);
    lcd_putchar(h/10+48);
    lcd_putchar(h%10+48);
    lcd_putsf(":");
    lcd_putchar(m/10+48);
    lcd_putchar(m%10+48);
    lcd_putsf(":");
    lcd_putchar(s/10+48);
    lcd_putchar(s%10+48);
    lcd_gotoxy(10,2);
    lcd_putchar(date/10+48);
    lcd_putchar(date%10+48);
    lcd_putsf(":");
    lcd_putchar(month/10+48);
    lcd_putchar(month%10+48);
    lcd_putsf(":20");
    lcd_putchar(year/10+48);
    lcd_putchar(year%10+48);delay_ms(100);
    }

    void main(void)
    {
    // Declare your local variables here

    // Input/Output Ports initialization
    // Port A initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTA=0x00;
    DDRA=0x00;

    // Port B initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTB=0x00;
    DDRB=0x00;

    // Port C initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTC=0x00;
    DDRC=0x00;

    // Port D initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTD=0x00;
    DDRD=0x00;

    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: Timer 0 Stopped
    // Mode: Normal top=0xFF
    // OC0 output: Disconnected
    TCCR0=0x00;
    TCNT0=0x00;
    OCR0=0x00;

    // Timer/Counter 1 initialization
    // Clock source: T1 pin Rising Edge
    // Mode: Normal top=0x0FFF
    // OC1A output: Discon.
    // OC1B output: Discon.
    // Noise Canceler: On
    // Input Capture on Falling Edge
    // Timer1 Overflow Interrupt: On
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: Off
    // Compare B Match Interrupt: Off
    TCCR1A=0x00;
    TCCR1B=0x87;
    TCNT1H=0x00; //bat dau dem tu so 0000
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;

    // Timer/Counter 2 initialization
    // Clock source: System Clock
    // Clock value: Timer2 Stopped
    // Mode: Normal top=0xFF
    // OC2 output: Disconnected
    ASSR=0x00;
    TCCR2=0x00;
    TCNT2=0x00;
    OCR2=0x00;

    // External Interrupt(s) initialization
    // INT0: On
    // INT0 Mode: Rising Edge
    // INT1: On
    // INT1 Mode: Rising Edge
    // INT2: On
    // INT2 Mode: Rising Edge
    GICR|=0xE0;
    MCUCR=0x0F;
    MCUCSR=0x40;
    GIFR=0xE0;

    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x04;

    // USART initialization
    // USART disabled
    uart_init();

    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;
    SFIOR=0x00;

    // ADC initialization
    // ADC disabled
    ADCSRA=0x00;

    // SPI initialization
    // SPI disabled
    SPCR=0x00;

    // TWI initialization
    // TWI disabled
    TWCR=0x00;

    // I2C Bus initialization
    i2c_init();

    // DS1307 Real Time Clock initialization
    // Square wave output on pin SQW/OUT: On
    // Square wave frequency: 4096 Hz
    rtc_init(1,1,0);

    // Alphanumeric LCD initialization
    // Connections specified in the
    // Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
    // RS - PORTA Bit 0
    // RD - PORTA Bit 1
    // EN - PORTA Bit 2
    // D4 - PORTA Bit 4
    // D5 - PORTA Bit 5
    // D6 - PORTA Bit 6
    // D7 - PORTA Bit 7
    // Characters/line: 20
    lcd_init(20);
    rtc_set_time(10,10,20);
    rtc_set_date(30,04,15);
    buffer[1]=64; //@
    buffer[2]=64; //@
    // Global enable interrupts
    #asm("sei")
    while (1)
    {
    // Place your code here
    lcd_ds1307();
    lcd_hienthi();
    }
    }

  • #2
    hàm UART mình đã test chạy oke, mình thử truyền nhận với máy tính đều ngon... mình k biết xung đột ở đâu??? có người nói do uart vs timer 1 dùng chung thanh ghi nên mỗi khi truyền nhận uart thì timer 1 sẽ lại được cấu hình lại, nhưng trong tài liệu atmega32 không nói gì về việc dùng chung này nên mình nghĩ không phải. và atmega32 có thanh ghi riêng cấu hình tốc độ Baurarate là thanh ghi UBRR gì đấy rồi...

    Comment


    • #3
      Trước khi đọc giá trị từ thanh ghi của timer1 thì disable toàn bộ Ngắt .... Nếu không giá trị đọc được sẽ = Zero. Đọc xong rồi thì lại Enable Ngắt lại thôi.

      #asm("cli")
      so_xung = TCNT1; // Tương đương so_xung = (TCNT1H<<8) + TCNT1L;
      #asm("sei")
      Module RF chuyên dụng điều khiển, truyền dữ liệu, thiết kế đề tài, dự án điện tử - chuyển giao công nghệ... ĐT: 0904964977 - email: dientuqueduong@yahoo.com

      Comment


      • #4
        Thank bacs queduong nhieu. nhưng nguồn gốc vấn đề không phải vì cái đó hôm nay e ngồi cả chiều với thầy hướng dẫn tốt nghiệp, loại bỏ tất cả các khả năng cuối cùng lỗi do phần uart_init(); e cóp trên mạng về, truyền oke nhưng mỗi khi truyền xong là reset... Sử dụng hàm của code vision tự tạo là oke luôn. Vì nó làm em mất ăn mất ngủ mấy ngày nay. Vì rõ ràng là truyền đc nên k nghĩ nó sai, mà cứ thêm code truyền tin thì hệ thống k chạy...

        Comment


        • #5
          mà em đang sử dụng module D-mi32 hight power của bác, truyền k dây tốt lắm. mình số 0974692012 , trước đến tận nhà bác test giùm 2 module chắc bác nhớ !!!

          Comment


          • #6
            Nguyên văn bởi hunter8x2012 Xem bài viết
            Thank bacs queduong nhieu. nhưng nguồn gốc vấn đề không phải vì cái đó hôm nay e ngồi cả chiều với thầy hướng dẫn tốt nghiệp, loại bỏ tất cả các khả năng cuối cùng lỗi do phần uart_init(); e cóp trên mạng về, truyền oke nhưng mỗi khi truyền xong là reset... Sử dụng hàm của code vision tự tạo là oke luôn. Vì nó làm em mất ăn mất ngủ mấy ngày nay. Vì rõ ràng là truyền đc nên k nghĩ nó sai, mà cứ thêm code truyền tin thì hệ thống k chạy...
            À, ở trên mình nói chỉ riêng cái vấn đề đọc giá trị của thanh ghi timer/ counter 1 thôi ... chứ nếu sai ở phần UART thì bạn cần sửa, cách tốt nhất mà không debug được thì làm riêng từng khối hoặc /* */ rồi test từng cụm một trên chính cái mạch đó rồi ghép các chương trình vào với nhau là OK nhất.
            Thông thường nếu CODE quá lớn cỡ 32K đến vài trăm KB thì nên viết mỗi cái ra một file chương trình riêng ... rồi include vào.

            --- Cảm ơn bạn đã dùng và ủng hộ sản phẩm. !
            Module RF chuyên dụng điều khiển, truyền dữ liệu, thiết kế đề tài, dự án điện tử - chuyển giao công nghệ... ĐT: 0904964977 - email: dientuqueduong@yahoo.com

            Comment

            Về tác giả

            Collapse

            hunter8x2012 Tìm hiểu thêm về hunter8x2012

            Bài viết mới nhất

            Collapse

            Đang tải...
            X