Giúp em Code ADC đọc LM35 ko chạy

vungocbac

Trứng gà
em viêt code đọc nhiệt độ từ LM35 the nay nhung khi mo phong thi không chạy?
các anh chị giúp em xem em thiếu những chỗ nào?
thanks anh chị

HTML:
#include <htc.h>
#include <stdio.h>
#include "lcd.h"
__CONFIG(FOSC_INTRC_NOCLKOUT&MCLRE_ON*WDTE_OFF&LVP_OFF);
#define _XTAL_FREQ      4000000
  //**************************CAC HAM TRONG CHUONG TRINH
void adc_init();
void lcd_init();
void adc_lcd();
void interrupt_init();
//--------------------------------
//KHOI TAP PORT
void port_init()
               {
                   ANSEL|=1<<3;
                   ANSELH|=0;      //RA3 LA INPUT
                   TRISA0=1;
                   TRISB=0X00;     //PORTB LA OUTPUT
                   TRISE=0X00;
                   lcd_init();
                   lcd_puts("DO NHIET DO");
                   lcd_goto(1,1);
                   lcd_puts("LM35");
                   __delay_ms(1000);
               }
//-------------------------------
void adc_init()
              {
                  ADCS1=1;            //CHON TAN SO LAY MAU
                  ADCS0=0;            //suy ra toc do chuyen doi ADC la Fosc/32.
                  VCFG1=0;            // chon dien ap lay mau la dien ap noi
                  VCFG0=0;
                  CHS3=0;
                  CHS2=0;              //chon kenh AN3
                  CHS1=1;
                  CHS0=1;
                  ADFM=1;              //CHON DINH DANG KET QUA ADC    
                  ADON=1;              //KET QUA DICH PHAI
              } 
//-------------------------
void interrupt_init()
               { 
                 ADIF=0;
                 ADIE=1;
                 GIE=1;
                 PEIE=1;          //VI NGAT NGOAI VI NEN SET=1
                }
//---------------------------
void interrupt isr()
                {
                   int read_adc,val,temp;
                      if(ADIE&&ADIF)
                             {
                                ADIF=0;
                                read_adc=(ADRESH<<8|ADRESL);
                                read_adc=(read_adc*5000)/1024;
                                temp=read_adc/10;
                              }
                }
void lcd_adc(int i)
                {
                  char a,b,c,d;
                  a=i/1000;
                  b=(i-a*1000)/100;
                  c=(i-a*1000-b*100)/10;
                  d=i-a*1000-b*100-c*10; 
                  lcd_putc(a+0x30);
                  lcd_putc(b+0x30);
                  lcd_putc(c+0x30);
                  lcd_putc(d+0x30);
                  lcd_puts("C");
                  }
void main()
                   {
                    port_init();
                    adc_init();
                    interrupt_init();
                    lcd_init();
                     while(1)
                            {
                              __delay_ms(100);
                              lcd_clear();
                              GO_nDONE;
                             }
                    }
 

vungocbac

Trứng gà
mình thêm vào rồi.
van không chạy.

void main()
{
port_init();
adc_init();
interrupt_init();
lcd_init();
adc_lcd();
while(1)
{
__delay_ms(100);
lcd_clear();
GO_nDONE;
}
}
 

light

Thành Viên PIF
bạn phải đặt trong vòng while chứ, làm vậy nó hiển thị được 1 lần rồi vô while nó clear lcd liên tục roài, bạn làm lại xem được không
 

vungocbac

Trứng gà
đâu bạn?
để ngoài chứ nhỉ?
vong lặp While chi la để chip không bị treo thôi mà
 

light

Thành Viên PIF
bạn phải gọi hàmtrong while nó mới hiển thị chứ, trong hàm while của bạn chỉ có lcd_clear vậy là nó sẽ xóa lcd liên tục sao
 

Manhdd

Cố Vấn CLB
Staff member
Bạn cho vào vòng while như thế nào nhỉ?
- Lưu ý là hàm void lcd_adc(int i) cần phải truyền đối số để lấy đó hiện lên LCD.
- Hàm này nên gọi interrupt hơn vì interrupt xảy ra sau khi chuyển đổi ADC xong.
 

vungocbac

Trứng gà
chu nhiệm có thể hướng dẫn mình kĩ chút được ko?
đoạn này em không hiểu lắm.
 

vungocbac

Trứng gà
Thanks bạn light và Chủ nhiệm.sau môt hồi nghiên cứu và sửa chữa thì e cũng chỉnh code lại được thế này.
LCD đã chạy được.nhưng không hiển thị được nhiệt độ. toàn la 4 số 0000 ạ.
các anh chị xem code em con thiếu gì nữa nhé.
cám ơn anh chị.


Code:
#include <htc.h>
#include <stdio.h>
#include "lcd.h"
__CONFIG(FOSC_INTRC_NOCLKOUT&MCLRE_ON*WDTE_OFF&LVP_OFF);
#define _XTAL_FREQ      4000000
unsigned char temp;
//--------------------------------
//KHOI TAP PORT
void port_init()
               {
                   ANSEL|=1<<3;
                   ANSELH|=0;      //RA3 LA INPUT
                   TRISA0=1;
                   TRISB=0X00;     //PORTB LA OUTPUT
                   TRISE=0X00;                 
               }
//-------------------------------
void adc_init()
              {
                  ADCS1=1;            //CHON TAN SO LAY MAU
                  ADCS0=0;            //suy ra toc do chuyen doi ADC la Fosc/32.
                  VCFG1=0;            // chon dien ap lay mau la dien ap noi
                  VCFG0=0;
                  CHS3=0;
                  CHS2=0;              //chon kenh AN3
                  CHS1=1;
                  CHS0=1;
                  ADFM=1;              //CHON DINH DANG KET QUA ADC    
                  ADON=1;              //KET QUA DICH PHAI
              } 
//-------------------------
void interrupt_init()
               { 
                 ADIF=0;
                 ADIE=1;
                 T0IF=0;
                 T0IE=1;
                 T0IE=0X0C;
                 GIE=1;
                 PEIE=1;          //VI NGAT NGOAI VI NEN SET=1
                }
//---------------------------
void interrupt isr()
                {
                   if(T0IF&&T0IE)
                     {
                      int read_adc;
                      if(ADIE&&ADIF)
                             {
                                ADIF=0;
                                read_adc=(ADRESH<<8|ADRESL);
                                read_adc=(read_adc*5000)/1024;
                                temp=read_adc/10;
                              }
                     T0IF=0;
                     TMR0=0X0C;
                    }
                 
                }  
//------------------------------------------
void lcd_adc(int i)
                {  
                
                  char a,b,c,d;
                  a=i/1000;
                  b=(i-a*1000)/100;
                  c=(i-a*1000-b*100)/10;
                  d=i-a*1000-b*100-c*10; 
                  lcd_putc(a+0x30);
                  lcd_puts(".");
                  lcd_putc(b+0x30);
                  lcd_putc(c+0x30);
                  lcd_putc(d+0x30);
                  lcd_puts("  C");
                  
                  }
//-----------------------------
void main()
             {
                    
                    lcd_init(); 
                    adc_init();                                 
                    __delay_ms(100);
                     port_init();
                     interrupt_init();
                   
                while(1)
               {    
                   lcd_clear();
                   lcd_puts("DO NHIET DO=LM35");
                   lcd_gotoxy(4,1);
                   lcd_adc(temp);                                         
                   GO_nDONE;
                   __delay_ms(100);
               }      
         }
 

electric_man

Thành Viên PIF
không biết có nhìn nhầm không. nhưng bạn chon RA3 là input mà thấy bạn đấu vào chân RA1. xem lại thử nhen!!
 

vungocbac

Trứng gà
mình sơ suất quá.chắc tối qua buồn ngủ.
nhưng đổi lại về RA3 vẫn như vậy mà.huhuhu
help me!
 

2death

Cố Vấn CLB
Staff member
Em xem các phần tô màu sau đây và chỉnh lại xem nó có chạy được không:

Code:
#include <htc.h>
#include <stdio.h>
#include "lcd.h"
__CONFIG(FOSC_INTRC_NOCLKOUT&MCLRE_ON*WDTE_OFF&LVP_OFF);
#define _XTAL_FREQ      4000000
unsigned char temp;
//--------------------------------
//KHOI TAP PORT
void port_init()
               {
                   ANSEL|=1<<3;
                   ANSELH|=0;      //RA3 LA INPUT
[B][COLOR="red"]                   TRISA0=1; // Tại sao đang chọn kênh AN3 mà lại cho TRISA0 = 1?
[/COLOR][/B]                   TRISB=0X00;     //PORTB LA OUTPUT
                   TRISE=0X00;                 
[COLOR="red"]//Đối với các port là Output, sau khi cấu hình cho thanh ghi TRIS của PORT, nên xuất giá trị khởi động cho Port luôn.
PORTE= 0x00 hay 0xFF; tùy bạn muốn khi khởi động các chân output là 0 hay 1
PORTB= 0x00 hay 0xFF;
Để tránh ngoại vi chạy ngoài ý muốn khi khởi động.[/COLOR]

               }
//-------------------------------
void adc_init()
              {
                  ADCS1=1;            //CHON TAN SO LAY MAU
                  ADCS0=0;            //suy ra toc do chuyen doi ADC la Fosc/32.
                  VCFG1=0;            // chon dien ap lay mau la dien ap noi
                  VCFG0=0;
                  CHS3=0;
                  CHS2=0;              //chon kenh AN3
                  CHS1=1;
                  CHS0=1;
                  ADFM=1;              //CHON DINH DANG KET QUA ADC    
                  ADON=1;              //KET QUA DICH PHAI
              } 
//-------------------------
void interrupt_init()
               { 
                 ADIF=0;
                 ADIE=1;
                 T0IF=0;
                 T0IE=1;
                 T0IE=0X0C;
                 GIE=1;
                 PEIE=1;          //VI NGAT NGOAI VI NEN SET=1
                }
//---------------------------
[B][COLOR="red"]// Đoạn chương trình này nó chạy có đúng không nhỉ :D.
// Ý đồ của bạn là: định thời gian đọc ADC về = Timer0.
// Theo như chương trình này: khi xảy ra Ngắt --> Nhảy vô ISR, kiểm tra nếu là ngắt Timer0, thì kiểm tra nếu là Ngắt ADC?
// Thì đọc kết quả ADC :D

// Nhờ các bạn đang học code cho PIC887 vào giải thích nhé. 
[/COLOR][/B]void interrupt isr()
                {
                   if(T0IF&&T0IE)
                     {
                      int read_adc;
                      if(ADIE&&ADIF)
                             {
                                ADIF=0;
                                read_adc=(ADRESH<<8|ADRESL);
                                read_adc=(read_adc*5000)/1024;
                                temp=read_adc/10;
                              }
                     T0IF=0;
                     TMR0=0X0C;
                    }
                 
                }  
//------------------------------------------
void lcd_adc(int i)
                {  
                
                  char a,b,c,d;
                  a=i/1000;
                  b=(i-a*1000)/100;
                  c=(i-a*1000-b*100)/10;
                  d=i-a*1000-b*100-c*10; 
                  lcd_putc(a+0x30);
                  lcd_puts(".");
                  lcd_putc(b+0x30);
                  lcd_putc(c+0x30);
                  lcd_putc(d+0x30);
                  lcd_puts("  C");
                  
                  }
//-----------------------------
void main()
             {
[COLOR="red"]                    //Nên Port_init() trước rồi mới adc_init() chứ. Thứ tự nên là:
                     port_init();
                    adc_init();  
                     interrupt_init();
                               
                    lcd_init(); 
                    __delay_ms(100);[/COLOR]

                    lcd_init(); 
                    adc_init();                                 
                    __delay_ms(100);
                     port_init();
                     interrupt_init();
                   
                while(1)
               {    
                   lcd_clear();
                   lcd_puts("DO NHIET DO=LM35");
                   lcd_gotoxy(4,1);
                   lcd_adc(temp);                                         
                   GO_nDONE;
                   __delay_ms(100);
               }      
         }
 

vungocbac

Trứng gà
EM CÁM ƠN 2DEATH ĐÃ GIÚP EM SỬA CODE.DO ĐANG BẬP BẸ VIẾT VỚI LẠI VIẾT THEO CÁCH NHỚ NÊN CÒN SAI SÓT NHIỀU.
EM ĐÃ SỬA NHƯNG CÓ VẺ VẪN SAI CHỊ Ạ.EM LẠI LAM PHIỀN ANH CHỊ RỒI.

PHP:
#include <htc.h>
#include <stdio.h>
#include "lcd.h"
__CONFIG(FOSC_INTRC_NOCLKOUT&MCLRE_ON*WDTE_OFF&LVP_OFF);
#define _XTAL_FREQ      4000000
unsigned char temp;
//--------------------------------
//KHOI TAP PORT
void port_init()
               {
                   ANSEL|=1<<3;
                   ANSELH|=0;      //RA3 LA INPUT
                   TRISA3=1;      //chỗ này em đã thay
                   TRISB=0X00;     //PORTB LA OUTPUT
                   PORTB=0X00;
                   TRISE=0X00;
                   PORTE=0X00;
                               
               }
//-------------------------------
void adc_init()
              {
                  ADCS1=1;            //CHON TAN SO LAY MAU
                  ADCS0=0;            //suy ra toc do chuyen doi ADC la Fosc/32.
                  VCFG1=0;            // chon dien ap lay mau la dien ap noi
                  VCFG0=0;
                  CHS3=0;
                  CHS2=0;              //chon kenh AN3
                  CHS1=1;
                  CHS0=1;
                  ADFM=1;              //CHON DINH DANG KET QUA ADC    
                  ADON=1;              //KET QUA DICH PHAI
              } 
//-------------------------
void interrupt_init()
               { 
                 GIE=1;
                 PEIE=1;          //VI NGAT NGOAI VI NEN SET=1
                 ADIF=0;
                 ADIE=1;
                 T0IF=0;
                 T0IE=1;
                 T0IE=0X0C;
                
                }
//---------------------------
void interrupt isr()
                {
                   if(T0IF&&T0IE)
                     {
                      int read_adc;
                      if(PEIE&&ADIE&&ADIF)
                             {
                                ADIF=0;
                                read_adc=(ADRESH<<8)|ADRESL;
                                read_adc=(read_adc*5000)/1024;
                                temp=read_adc/10;
                              }
                     T0IF=0;
                     TMR0=0X0C;
                    }
                 
                }  
//------------------------------------------
void lcd_adc(int i)
                {  
                
                  char a,b,c,d;
                  a=i/1000;
                  b=(i-a*1000)/100;
                  c=(i-a*1000-b*100)/10;
                  d=i-a*1000-b*100-c*10; 
                  lcd_putc(a+0x30);
                  lcd_puts(".");
                  lcd_putc(b+0x30);
                  lcd_putc(c+0x30);
                  lcd_putc(d+0x30);
                  lcd_puts("  C");
                  
                  }
//-----------------------------
void main()
             {
                    port_init(); 
                    adc_init();                              //sắp xếp đúng thứ tự
                    interrupt_init();
                    lcd_init();
                     __delay_ms(100);
                   
                while(1)
               {    
                   lcd_clear();
                   lcd_puts("DO NHIET DO=LM35");
                   lcd_gotoxy(4,1);
                   lcd_adc(temp);                                         
                   GO_nDONE;
                   __delay_ms(100);
               }      
         }
 

2death

Cố Vấn CLB
Staff member
Chương trình chỗ này chưa được hợp lý:
PHP:
void interrupt isr()
                {
                   if(T0IF&&T0IE)
                     {
                      int read_adc;
                      if(PEIE&&ADIE&&ADIF)
                             {
                                ADIF=0;
                                read_adc=(ADRESH<<8)|ADRESL;
                                read_adc=(read_adc*5000)/1024;
                                temp=read_adc/10;
                              }
                     T0IF=0;
                     TMR0=0X0C;
                    }
                 
                }
Tại 1 thời điểm ISR chỉ phục vụ cho 1 ngắt xảy ra thôi.
 

vungocbac

Trứng gà
EM ĐÃ BỎ NGẮT TIME0 ĐI CHỈ CÒN NGẮT ĐỂ ĐỌC adc NHƯNG VẪN VÂY???
PHP:
      #include <htc.h>
#include <stdio.h>
#include "lcd.h"
__CONFIG(FOSC_INTRC_NOCLKOUT&MCLRE_ON*WDTE_OFF&LVP_OFF);
#define _XTAL_FREQ      4000000
unsigned char temp;
//--------------------------------
//KHOI TAP PORT
void port_init()
               {
                   ANSEL|=1<<3;
                   ANSELH|=0;      //RA3 LA INPUT
                   TRISA3=1;
                   TRISB=0X00;     //PORTB LA OUTPUT
                   PORTB=0X00;
                   TRISE=0X00;
                   PORTE=0X00;
               
                   PSA=0;
                   PS2=1;
                   PS1=1;
                   PS0=1;
                               
               }
//-------------------------------
void adc_init()
              {
                  ADCS1=1;            //CHON TAN SO LAY MAU
                  ADCS0=0;            //suy ra toc do chuyen doi ADC la Fosc/32.
                  VCFG1=0;            // chon dien ap lay mau la dien ap noi
                  VCFG0=0;
                  CHS3=0;
                  CHS2=0;              //chon kenh AN3
                  CHS1=1;
                  CHS0=1;
                  ADFM=1;              //CHON DINH DANG KET QUA ADC    
                  ADON=1;              //KET QUA DICH PHAI
              } 
//-------------------------
void interrupt_init()
               { 
             
                 PEIE=1;          //VI NGAT NGOAI VI NEN SET=1
                 ADIF=0;
                 ADIE=1;
               
                
                }
//---------------------------
void interrupt isr()
                {
                   int read_adc;
                      if(ADIE&&ADIF)
                             {
                                ADIF=0;
                                read_adc=(ADRESH<<8|ADRESL);
                                read_adc=(read_adc*5000)/1024;
                                temp=read_adc/10;
                              }
                 
                }  
//------------------------------------------
void lcd_adc(int i)
                {  
                
                  char a,b,c,d;
                  a=i/1000;
                  b=(i-a*1000)/100;
                  c=(i-a*1000-b*100)/10;
                  d=i-a*1000-b*100-c*10; 
                  lcd_putc(a+0x30);
                  lcd_puts(".");
                  lcd_putc(b+0x30);
                  lcd_putc(c+0x30);
                  lcd_putc(d+0x30);
                  lcd_puts("  C");
                  
                  }
//-----------------------------
void main()
             {
                    port_init(); 
                    adc_init();                                 
                    interrupt_init();
                    lcd_init();
                     __delay_ms(100);
                   
                while(1)
               {    
                   lcd_clear();
                   lcd_puts("DO NHIET DO=LM35");
                   lcd_gotoxy(4,1);
                   lcd_adc(temp);                                         
                   GO_nDONE;
                   __delay_ms(100);
               }      
         }
 

2death

Cố Vấn CLB
Staff member
Em bắt đầu cảm thấy mình kém quá. :((
Có gì đâu mà xoắn thế :D
Ai mới bắt đầu mà chả như vậy. Chưa chạy thì sửa tiếp tới khi nào chạy mới thôi.
Mỗi lần sửa lỗi là ghi nhớ thêm 1 điều, sau này code sẽ pro hơn (ít ra là hơn chắc mấy bạn copy - paste rồi build successful:D)

Thử chỉnh tiếp chỗ này:
Code:
   read_adc=(read_adc*5000)/1024;
Do biến read_adc đặt kiểu là "int", kết quả phép tính này thực hiện lần lượt là read_adc*5000, xong mới chia 1024.

Sau phép nhân có thể nó đã bị tràn Bit --> kết quả phép nhân là "0".

Vậy em có thể thay kiểu "int" thành 1 kiểu khác, kích thước lớn hơn.

Hoặc thay vì nhân 5000 rồi 1024, thì nhân nó với 1 số tương đương mà nhỏ hơn (rút gọn)

p/s: Nếu chưa chạy nữa, thì em mô tả cụ thể xem, LCD hiển thị được gì?
 
Top