PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Cơ bản về vi điều khiển và PIC (http://www.picvietnam.com/forum/forumdisplay.php?f=8)
-   -   có ai có thể giúp e với code lcd này ko ạ!!!! (http://www.picvietnam.com/forum/showthread.php?t=30725)

vietnhoc 13-10-2012 03:16 AM

có ai có thể giúp e với code lcd này ko ạ!!!!
 
1 Attachment(s)
#include<p33FJ128MC202.h>
#include<stdio.h>
#include<stdlib.h>
#include <p33FJ128MC202.h>

_FOSCSEL (FNOSC_PRIPLL);
_FOSC(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMD_XT);
_FWDT(FWDTEN_OFF);
/*cac hang so cua chuong trinh*/
#define LCD_EN LATA4 //Tin hieu Enable cho LCD, chan RRA4
#define LCD_RW LATA1 //Tin hieu Read/Write cho LCD, chan RA1
#define LCD_RS LATA0 //Tin hieu Reset cho LCD, chan RA0
#define LCD_DATA LATB //Cac tin hieu Data cho LCD, )
#define LCD_TRIS TRISB //Tristate cua cac tin hieu Data cho LCD

#define LCD_clear 0x01 //Xoa man hinh LCD
#define LCD_home 0x02 //Tro ve dau dong
#define LCD_normal 0x06 //Che do nhap du lieu binh thuong
#define LCD_normal_s 0x07 //Che do nhap du lieu binh thuong, dich man hinh
#define LCD_off 0x08 //Tat man hinh
#define LCD_on 0x0C //Bat man hinh
#define LCD_on_crsr 0x0E //Bat man hinh va con tro
#define LCD_on_blink 0x0F //Bat man hinh va con tro (nhap nhay)
#define LCD_4b2l 0x28 //Che do 2 dong, giao tiep 4 bit du lieu
#define LCD_homeL1 0x80 //Ve dau dong 1
#define LCD_homeL2 0xC0 //Ve dau dong 2



/*================================================= =============*/
/*-----------------------------------------------------------------------------------------------------*/


unsigned char time_out,idx,i;

void initPORTS(void);
void initLCD(void);
void init_TMR1(void);
void LCD_cmd4(unsigned char);
void LCD_data4(unsigned char);
/*------------------------------*/

void initPORTS(void)
{
LCD_DATA &= 0xfff0; /*xoa cac chn du lieu*/
LCD_TRIS=0xfff0; /*chon cac chan du lieu la RB8-RB11 lam ngo ra*/
TRISAbits.TRISA4=0; /*cho phep LCD hoat dong chan Ra4*/
LATAbits.LCD_EN=0; /*chon chan RA4 lam ngo ra*/
TRISAbits.TRISA1=0; /*chon doc hay ghi du lieu chan RB14*/
LATAbits.LCD_RW=0; /*chon chan RB14 lam ngo ra*/
TRISAbits.TRISA0=0; /*chon du lieu hay lenh chan RB15*/
LATAbits.LCD_RS=0; /*chon chan RB15 lam ngo ra*/

}
void init_TMR1(void)
{
TMR1=0;
T1CON=0x0000; /

}

void init_LCD()
{

LCD_cmd4(LCD_4b2l); //Dat che do giao tiep 4-bit, man hinh 2 dong
delay_ms(1);
LCD_cmd4(LCD_off); //Tat man hinh
delay_ms(1);
LCD_cmd4(LCD_normal); //Che do nhap du lieu binh thuong
delay_ms(1);
LCD_cmd4(LCD_on_blink); //Bat man hinh, hien con tro nhap nhay
delay_ms(1);
LCD_cmd4(LCD_clear); //Xoa man hinh
delay_ms(5);
}

void LCD_cmd4(unsigned char cmd) /*ghi lenh co ma lenh cmd*/
{
unsigned temp0,i;
LATAbits.LCD_RW=0; /*chon che do ghi*/
LATAbits.LCD_RS=0; /*chon che do ghi lenh*/
temp0 = LCD_DATA & 0xFFF0; /*luu lai cac trang thai truoc khi ghi lenh ra LCD*/
LCD_DATA = (temp0)|(cmd>>4); /* lay 4 bits cao cua cmd*/

LATAbits.LCD_EN = 1; /*cho lcd hoat dong*/
for(i=0;i<10;i++); /*tao tre cho qua trinh truyen*/
LATAbits.LCD_EN=0; /*ngat lcd*/
temp0 = LCD_DATA & 0xFFF0; /*luu cac trang thai truoc do*/
LCD_DATA = (temp0) | (cmd&0x0F); /*lay 4 bit thap cua cmd*/

LATAbits.LCD_EN=1;
for(i=0;i<50;i++);
LATAbits.LCD_EN=0;
}



void LCD_data4(unsigned char data)
{

unsigned temp2,i;

LATAbits.LCD_RW=0; /*che do ghi*/
LATAbits.LCD_RS=1; /*che do ghi du lieu*/
temp2=LCD_DATA & 0xFFF0; /*luu gia tri truoc khi ghi du lieu*/
LCD_DATA=((temp2)|(data>>4)) ; /*lay 4 bit cao cua data*/
LATAbits.LCD_EN=1;
for(i=0;i<10;i++);
LATAbits.LCD_EN=0;

temp2=LCD_DATA & 0xFFF0; /*luu gia tri truoc khi ghi du lieu*/

LCD_DATA= ((temp2)| (data & 0x0F)); /* lay 4 bit thap*/
LATAbits.LCD_EN=1;
for(i=0;i<100;i++);
LATAbits.LCD_EN=0;

}
void LCD_chuoi(unsigned char *s)
{
while(*s)
{
LCD_data4(*s);
s++;
}
}
/*chuong trinh ngat timer 1*/


void delay_ms(unsigned int n)
{
T1CONbits.TON=1;
while (n--)
{
TMR1 = 0;
while (TMR1<8000);
}


}
int main()
{

int i;

initPORTS();
delay_ms(10);
init_TMR1();
delay_ms(50);
init_LCD();
delay_ms(100);
while(1)
{
LCD_data4(0x46);
delay_ms(100);
LCD_cmd4(LCD_homeL2);
LCD_chuoi("bkhn");

delay_ms(50);
};
return 1;
}

e thử mãi mà ko thể hiển thị LCD trong khi xuất ra các chân vi điều khiển và lcd rồi :(

vietnhoc 13-10-2012 10:16 AM

e sửa đi sửa lại mà lcd vân ko hoạt động.mặc dù chân lcd có tín hiệu.:(
rất mong các anh chỉ giáo.
e đang rất cần ạ.:(

handsometran 15-10-2012 02:28 PM

Trích:

Nguyên văn bởi vietnhoc (Post 78461)
e sửa đi sửa lại mà lcd vân ko hoạt động.mặc dù chân lcd có tín hiệu.:(
rất mong các anh chỉ giáo.
e đang rất cần ạ.:(

Bạn xem trang này: http://www.hocavr.com/index.php/app/textlcd ở chế độ 4bit thì mỗi lần chuyển dữ liệu từ Pic sang cần phải kiểm tra tình trạng busy của LCD, còn không thì bạn phải delay khoảng 100ms. Chúc bạn thành công!

vietnhoc 15-10-2012 04:55 PM

e cảm ơn anh.nhưng e thử delay 100ms rồi mà lCD vẫn trắng trơn.
e chỉ đề phòng trường hợp bị treo do lcd bị hỏng nên e ko cho đọc cờ bận thôi anh ạ,anh xem có lỗi j nũa ko giúp e ạ.e mới làm về dspic.:(

buivantuyen89th 18-10-2012 12:15 PM

Bạn nên lên mạng tải thư viện lcd về mà đọc mà tìm hiểu.mình thường dùng thu viện có sẵn thôi.miễn là mình hiểu nó. thường thì các thu vien đó chan RW nối trực tiếp xuồng mass.
chúc bạn thành công!

handsometran 01-11-2012 02:33 PM

Trích:

Nguyên văn bởi vietnhoc (Post 78501)
e cảm ơn anh.nhưng e thử delay 100ms rồi mà lCD vẫn trắng trơn.
e chỉ đề phòng trường hợp bị treo do lcd bị hỏng nên e ko cho đọc cờ bận thôi anh ạ,anh xem có lỗi j nũa ko giúp e ạ.e mới làm về dspic.:(

Bạn cũng cần phải tạo 1 “xung cạnh xuống” ở chân EN mỗi lần xuất dữ liệu 4bit. Chú ý là phải xuất 4bit cao trước và 4bit thấp theo sau.

vietnhoc 02-11-2012 12:00 PM

e tạo rồi mà anh.nhưng nó vẫn ko chạy cho.nên e chuyển sang 8bit rồi anh ạ.hơi tốn chân tí,nhưng mà cũng dc,
thanks anh.
nếu dc thì hôm sau e hỏi anh về đọc ADC tí.:D

handsometran 02-11-2012 12:50 PM

Trích:

Nguyên văn bởi vietnhoc (Post 78980)
e tạo rồi mà anh.nhưng nó vẫn ko chạy cho.nên e chuyển sang 8bit rồi anh ạ.hơi tốn chân tí,nhưng mà cũng dc,
thanks anh.
nếu dc thì hôm sau e hỏi anh về đọc ADC tí.:D

Nếu em viết bằng MPLAP IDE v8.87 HT PIC 9.8 PRO, thì em chỉ cần #include file lcd.c vào chương trình main là ok.
//*******File lcd.h(file header) được #include trong file lcd.c******//
#ifndef _LCD_H_
#define _LCD_H_

#include <htc.h>

#ifndef _XTAL_FREQ
#define _XTAL_FREQ 8000000
#endif


/* Display ON/OFF Control defines */
#define DON 0b00001111 /* Display on */
#define DOFF 0b00001011 /* Display off */
#define CURSOR_ON 0b00001111 /* Cursor on */
#define CURSOR_OFF 0b00001101 /* Cursor off */
#define BLINK_ON 0b00001111 /* Cursor Blink */
#define BLINK_OFF 0b00001110 /* Cursor No Blink */

/* Cursor or Display Shift defines */
#define SHIFT_CUR_LEFT 0b00000100 /* Cursor shifts to the left */
#define SHIFT_CUR_RIGHT 0b00000101 /* Cursor shifts to the right */
#define SHIFT_DISP_LEFT 0b00000110 /* Display shifts to the left */
#define SHIFT_DISP_RIGHT 0b00000111 /* Display shifts to the right */

/* Function Set defines */
#define FOUR_BIT 0b00101100 /* 4-bit Interface */
#define EIGHT_BIT 0b00111100 /* 8-bit Interface */
#define LINE_5X7 0b00110000 /* 5x7 characters, single line */
#define LINE_5X10 0b00110100 /* 5x10 characters */
#define LINES_5X7 0b00111000 /* 5x7 characters, multiple line */


/* Chổ này thay đổi tùy ý không cần thiết là chung 1 Port */
#ifndef LCD_RS
#define LCD_RS RD1
#define LCD_EN RD3
#define LCD_RW RD2
#define LCD_DATA4 RD4
#define LCD_DATA5 RD5
#define LCD_DATA6 RD6
#define LCD_DATA7 RD7

#define LCD_RS_TRIS TRISD1
#define LCD_EN_TRIS TRISD3
#define LCD_RW_TRIS TRISD2
#define LCD_DATA4_TRIS TRISD4
#define LCD_DATA5_TRIS TRISD5
#define LCD_DATA6_TRIS TRISD6
#define LCD_DATA7_TRIS TRISD7
#endif

//typedef unsigned char unsigned char; // 8-bit unsigned

typedef union _BYTE_VAL
{
unsigned char Val;
struct
{
unsigned char b0:1;
unsigned char b1:1;
unsigned char b2:1;
unsigned char b3:1;
unsigned char b4:1;
unsigned char b5:1;
unsigned char b6:1;
unsigned char b7:1;
} bits;
} BYTE_VAL;

void lcd_init();
unsigned char lcd_busy();
unsigned char lcd_get_byte(unsigned char rs);
void lcd_put_byte(unsigned char a,unsigned char b);
void lcd_gotoxy(unsigned char col, unsigned char row);
void lcd_putc(char c);
void lcd_puts(const char* s);
#endif

//*******File lcd.c được #include trong file main.c******//
//**Chứa các lệnh điều khiển lcd 16x2**************//
#include <stdlib.h>
#include <ctype.h>
#include "lcd.h"

void lcd_init(){
unsigned char i;
LCD_EN_TRIS = 0;
LCD_RS_TRIS = 0;
LCD_RW_TRIS = 0;
LCD_DATA4_TRIS = 0;
LCD_DATA5_TRIS = 0;
LCD_DATA6_TRIS = 0;
LCD_DATA7_TRIS = 0;
LCD_EN = 0;
LCD_RS = 0;
LCD_RW = 0;

__delay_ms(100); // delay for power on

// reset LCD
lcd_put_byte(0,0x30);
__delay_ms(50);
lcd_put_byte(0,0x30);
__delay_ms(50);
lcd_put_byte(0,0x32);
__delay_ms(100); // delay for LCD reset
__delay_ms(100); // delay for LCD reset
__delay_ms(100); // delay for LCD reset

while(lcd_busy());
lcd_put_byte(0,FOUR_BIT & LINES_5X7); // Set LCD type
while(lcd_busy());

lcd_put_byte(0,DOFF&CURSOR_OFF&BLINK_OFF); // display off
while(lcd_busy());
lcd_put_byte(0,DON&CURSOR_OFF&BLINK_OFF); // display on
while(lcd_busy());

lcd_put_byte(0,0x01); // clear display and move cursor to home
while(lcd_busy());
lcd_put_byte(0,SHIFT_CUR_LEFT); // cursor shift mode
while(lcd_busy());
lcd_put_byte(0,0x01); // clear display and move cursor to home
while(lcd_busy());
}
unsigned char lcd_busy()
{
unsigned char busy;

LCD_DATA4_TRIS = 1;
LCD_DATA5_TRIS = 1;
LCD_DATA6_TRIS = 1;
LCD_DATA7_TRIS = 1;

LCD_RW = 1;
LCD_RS = 0;
__delay_us(20);
LCD_EN = 1;
__delay_us(20);

busy = LCD_DATA7;

LCD_EN = 0;
__delay_us(20);
LCD_EN = 1;
__delay_us(20);
LCD_EN = 0;


return busy;
}
unsigned char lcd_get_byte(unsigned char rs)
{
BYTE_VAL b;

LCD_DATA4_TRIS = 1;
LCD_DATA5_TRIS = 1;
LCD_DATA6_TRIS = 1;
LCD_DATA7_TRIS = 1;

LCD_RW = 1;
LCD_RS = 0;
if(rs) LCD_RS = 1;
__delay_us(20);
LCD_EN = 1;
__delay_us(20);

b.bits.b7 = LCD_DATA7;
b.bits.b6 = LCD_DATA6;
b.bits.b5 = LCD_DATA5;
b.bits.b4 = LCD_DATA4;

LCD_EN = 0;
__delay_us(20);
LCD_EN = 1;
__delay_us(20);
b.bits.b3 = LCD_DATA7;
b.bits.b2 = LCD_DATA6;
b.bits.b1 = LCD_DATA5;
b.bits.b0 = LCD_DATA4;
LCD_EN = 0;

return b.Val;
}
void lcd_put_byte(unsigned char rs, unsigned char b)
{
BYTE_VAL temp;

LCD_DATA4_TRIS = 0;
LCD_DATA5_TRIS = 0;
LCD_DATA6_TRIS = 0;
LCD_DATA7_TRIS = 0;

LCD_RS = 0;
if(rs) LCD_RS = 1;

__delay_us(20);
LCD_RW = 0;
__delay_us(20);
LCD_EN = 0;

temp.Val = b;

//==send the high nibble====================================//
LCD_DATA4 = temp.bits.b4;
LCD_DATA5 = temp.bits.b5;
LCD_DATA6 = temp.bits.b6;
LCD_DATA7 = temp.bits.b7;
__delay_us(20);
LCD_EN = 1;
__delay_us(20);
LCD_EN = 0;
//==send the low nibble=====================================//
LCD_DATA4 = temp.bits.b0;
LCD_DATA5 = temp.bits.b1;
LCD_DATA6 = temp.bits.b2;
LCD_DATA7 = temp.bits.b3;
__delay_us(20);
LCD_EN = 1;
__delay_us(20);
LCD_EN = 0;
}
//================================================== ============//

//================================================== ============//
void lcd_putc(char c){
switch(c){
case '\f':
lcd_put_byte(0,1);
while(lcd_busy());
break;
case '\n':
lcd_gotoxy(0,1);
//lcd_put_byte(0,2);
while(lcd_busy());
break;
default:
if(isprint(c)){
lcd_put_byte(8, c);
while(lcd_busy());
}
break;
}
}
//================================================== ============//
void lcd_gotoxy( char x, char y)
{char address;
switch(y) {
case 0 : address=0x80;break;//row=1,col=0
case 1 : address=0xc0;break;//row=2,col=0
case 2 : address=0x94;break;//row=1.col=20
case 3 : address=0xd4;break;//row=2,col=84
}
address=address+x;//move col to expect position
lcd_put_byte(0,0x80|address);
}
//================================================== ============//
/*void lcd_gotoxy(unsigned char col, unsigned char row)
{
unsigned char address;

if(row!=0)
address=0x40;
else
address=0;

address += col;
lcd_put_byte(0,0x80|address);
while(lcd_busy());
}*/
void lcd_puts(const char* s)
{
while(*s){
lcd_putc(*s++);
}
}
//================================================== ==
/*void LCD_ShiftLeft(void)
{
lcd_put_byte(0,0x18);
}
void LCD_ShiftRight(void)
{
lcd_put_byte(0,0x1C);
}*/

void lcd_moveright(unsigned char p){
char i;
for(i=0;i<p;i++){
lcd_put_byte(0,28);
__delay_ms(100);
}
}

void lcd_moveleft(unsigned char p){
char i;
for(i=0;i<p;i++){
lcd_put_byte(0,24);
__delay_ms(100);
}
}
//Chúc bạn thành công!

vietnhoc 05-11-2012 12:08 AM

thankyou anh.e đã làm dc.:D
thế là đớ tốn chân.
anh có rành về ADC ko.cho e hỏi tí.:D

handsometran 06-11-2012 02:35 PM

Trích:

Nguyên văn bởi vietnhoc (Post 79104)
thankyou anh.e đã làm dc.:D
thế là đớ tốn chân.
anh có rành về ADC ko.cho e hỏi tí.:D

Dùng ADC cũng không khó, nhưng có 1 điểm lưu ý là không thể dùng quá 1 kênh ADC tại 1 thời điểm. Nếu muốn dùng ADC bạn chỉ cần chèn hàm khởi tạo ADC và hàm đọc kết quả ADC vào trong file main.c thôi. Rồi trong chương trình chính bạn cứ cho biến ADON=1, GODONE=1 và chờ đến khi GODONE=0, thì lấy kết quả chuyển đổi nằm trong thanh ghi ADRESL và ADRESH. Bạn xem lại datasheet sẽ rõ hơn.
//===================INITIALIZE ADC MODUL=======================//
void init_adc()
{
ANS3 = 1; //SET RA3 RECEIVING ANALOG SIGNAL
//SEE DATASHEET PAGE 99
VCFG0 = VCFG1 = 0; //SELECT VOLT REFERENCE BY INPUT RA3
ADCS0 = ADCS1 = 1; //Nguon dao dong Frc<=>500kHz
ADFM = 1; //Canh phai ket qua
CHS0 = CHS1 = 1;
CHS2 = CHS3 = 0; //SELECT ADC CHANEL 3
ADON = 0;// Turn on function of ADC modul
GODONE = 0;//Will set on in main program
__delay_ms(1);//Waiting for MCU starting
}
//=====KHOI TAO HAM DOC ADC, gia tri tra ve la so nguyen======//
int readADC()
{
int kq;//Define variable kq as integer
GODONE=1;//Start ADC modul
ADON=1;
while(GODONE);//Loop run when bit GODONE=0_see datasheet
kq=((ADRESH<<8)|ADRESL);
return kq;
}

vietnhoc 07-11-2012 01:13 PM

e viết hàm ADC rồi.e muốn phản hồi điện áp ở đầu ra rồi điều chỉnh duty.
điện áp đầu ra là 5v.cho vào chan AN0.nhưng ko biết lúc cho điện áp phản hồi qua bộ chia áp có thể cho thẳng vào vi điều khiên hay phải mắc thêm tụ nữa ạ.

handsometran 09-11-2012 12:06 PM

Trích:

Nguyên văn bởi vietnhoc (Post 79151)
e viết hàm ADC rồi.e muốn phản hồi điện áp ở đầu ra rồi điều chỉnh duty.
điện áp đầu ra là 5v.cho vào chan AN0.nhưng ko biết lúc cho điện áp phản hồi qua bộ chia áp có thể cho thẳng vào vi điều khiên hay phải mắc thêm tụ nữa ạ.

Lưu ý về dòng ra vào các port VDK PIC chỉ trong khoảng<=20mA nên bạn nên mắc nối tiếp chân AN0 con điện trở 1K, mà ADC có phần điện áp tham khảo nội và ngoại. Tôi thì chọn nội, còn ngoại thì bạn phải làm mạch ổn áp để tạo ra điện áp chuẩn, hơi phức tạp.
Giá trị sau chuyển đổi của bộ ADC là số nhị phân 10bit, tức là 0-->1024. Nhưng duty cycle của bộ PWM thay đổi bằng cách thay đổi giá trị thanh ghi CCPR1L chỉ có 8bit, nên khi đọc giá trị ADC bạn nên đọc 8bit trong thanh ghi ADRESL. Bài hoàn chỉnh tôi có đăng trong topic http://www.picvietnam.com/forum/showthread.php?t=30520. Bạn vào tham khảo nhé.

vietnhoc 10-11-2012 11:29 AM

e dùng dspic 33f anh ạ.duty trong thanh ghi 16 bit rồi.ko lo anh ạ.nhưng e ko hiểu điện áp tham khảo nội là sao.e dùng 2 chân AVDD làm Vref+ và chân AVSS làm chân Vref-.điện áp của dspic tầm 3.3v.nếu dùng điện áp tham khảo nội thì dùng như thế nào.anh có thể chỉ e dc ko.thanks anh.

handsometran 20-11-2012 03:35 PM

Trích:

Nguyên văn bởi vietnhoc (Post 79270)
e dùng dspic 33f anh ạ.duty trong thanh ghi 16 bit rồi.ko lo anh ạ.nhưng e ko hiểu điện áp tham khảo nội là sao.e dùng 2 chân AVDD làm Vref+ và chân AVSS làm chân Vref-.điện áp của dspic tầm 3.3v.nếu dùng điện áp tham khảo nội thì dùng như thế nào.anh có thể chỉ e dc ko.thanks anh.

Điện áp tham khảo ngoại Vref+<=Vdd.
http://ns2.upanh.com/b5.s34.d1/0d5f4...2.untitled.jpg[/url]
Muốn dùng điện áp tham khảo + và - là tham khảo nội thì set VCFG2 = 1 hoặc VCFG0=VCFG1=VCFG2=0. Còn dùng kiểu khác bạn cứ xem bảng. Datasheet chỉ rỏ hết đó bạn.


Múi giờ GMT. Hiện tại là 02:08 AM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam