Data problem on PIC16F616 (To LCD) - Page 1
Forum section: electronics / general

author: Madsaaby
author_rank: Regular Contributor
timestamp: May 21, 2012, 01:25:17 am
content: Hey FolksI have a problem with the PIC16F616. I'm trying to drive a LDC Display (HD44780) in 4 Bit mode (To display temps, but nothing else than the display is connected yet.).I noticed that the data on two of the lines were bad.. The high bits were only 400 us long, while they were 2 ms on the other two..So, I tried changing different things, making sure ADC, timers, comparators were off etc. Nothing solved the problem, until I selected a different output pin on the MCU, then the data became fine..I'm getting the same problem on the following pins: RA1,RA2, RC1-RC4.It's the first time I use the 16F616, so I might have missed something.. I did try the same lcd driver on the PIC16F628a where it worked fine..I guess its not the driver thats bad when it helps to select a different pin ?Any ideas why this happens, only on some pins ?Ask if you need more info, I know I didn't tell much, but don't really know where the problem comes from.. :/I use the HI-Tech C compiler, and the following LCD Driver and C code..(I've put in some delays to separate things a little)C Code:#include <htc.h>#include "lcd.h"#include <stdio.h>#include <stdlib.h>#ifndef _XTAL_FREQ#define _XTAL_FREQ 4000000#endifvoidmain(){// CMCON = 0xff;T1CON =0;C1ON =0;C2ON =0;ADON =0;TRISA= 0x00;TRISC= 0x00;__delay_us(100);lcd_init();__delay_us(100);// lcd_goto(0);// lcd_puts("Random Shit");// lcd_goto(0x40);// lcd_puts("0101010");}Driver:/** LCD interface example* Uses routines from delay.c* This code will interface to a standard LCD controller* like the Hitachi HD44780. It uses it in 4 bit mode, with* the hardware connected as follows (the standard 14 pin* LCD connector is used):** PORTB bits 0-3 are connected to the LCD data bits 4-7 (high nibble)* PORTA bit 2 is connected to the LCD RS input (register select)* PORTA bit 3 is connected to the LCD EN bit (enable)** To use these routines, set up the port I/O (TRISA, TRISB) then* call lcd_init(), then other routines as required.** Copywrite Craig Lee 1998**/#define _XTAL_FREQ 4000000#include <pic.h>#include "lcd.h"#include "stdio.h"#define LCD_RS RC4 // Register select#define LCD_EN RA4 // Enable#define LCD_D4 RC1 // Data bits#define LCD_D5 RA0 // Data bits#define LCD_D6 RC5 // Data bits#define LCD_D7 RA5 // Data bits#define LCD_STROBE ((LCD_EN = 1),(__delay_us(200)),(LCD_EN=0))/* write a byte to the LCD in 4 bit mode */voidlcd_write(unsigned char c){__delay_us(100);if(c & 0x80) LCD_D7=1; else LCD_D7=0;if(c & 0x40) LCD_D6=1; else LCD_D6=0;if(c & 0x20) LCD_D5=1; else LCD_D5=0;if(c & 0x10) LCD_D4=1; else LCD_D4=0;__delay_us(100);LCD_STROBE;if(c & 0x08) LCD_D7=1; else LCD_D7=0;if(c & 0x04) LCD_D6=1; else LCD_D6=0;if(c & 0x02) LCD_D5=1; else LCD_D5=0;if(c & 0x01) LCD_D4=1; else LCD_D4=0;__delay_us(100);LCD_STROBE;__delay_us(40);}/** Clear and home the LCD*/voidlcd_clear(void){LCD_RS = 0;lcd_write(0x1);__delay_ms(2);}/* write a string of chars to the LCD */voidlcd_puts(const char * s){LCD_RS = 1; // write characters__delay_us(100);while(*s) lcd_write(*s++);}/* write one character to the LCD */voidlcd_putch(unsigned char c){LCD_RS = 1; // write characterslcd_write(c);}/** Go to the specified position*/voidlcd_goto(unsigned char pos){__delay_us(100);LCD_RS = 0;__delay_us(100);lcd_write(0x80 + pos);__delay_us(100);}/* initialise the LCD - put into 4 bit mode */voidlcd_init(void){LCD_RS = 0; // write control bytes__delay_ms(15);// power on delayLCD_D4 = 1; // init!LCD_D5 = 1; //__delay_us(100);LCD_STROBE;__delay_ms(5);LCD_STROBE; // init!__delay_us(100);LCD_STROBE; // init!__delay_ms(5);LCD_D4 = 0; // set 4 bit mode__delay_us(100);LCD_STROBE;__delay_us(40);lcd_write(0x28);// 4 bit mode, 1/16 duty, 5x8 font, 2lineslcd_write(0x0C);// display onlcd_write(0x06);// entry mode advance cursorlcd_write(0x01);// clear display and reset cursor}Best regardsMads

author: baljemmett
author_rank: Unknown
timestamp: May 21, 2012, 02:27:01 pm
content: Quote from: Madsaaby on May 21, 2012, 01:25:17 amI see your code turns the ADC and comparators off, but you don't clear the ANSEL register -- it defaults to all-ones at power up (so all analogue-capable pins are set as analogue inputs). Not sure whether that will interfere with digital output at all, but it might be worth chucking an ANSEL = 0; in there to see if it makes any difference?Ah - I see you're doing bit operations on the output pins - on the PIC that's a read-modify-write operation, i.e. rather than just setting the relevant bit in the output latch it reads the digital state of the port as a whole, changes the specified bit, and then writes the result to the output latch. A pin configured as an analogue input will always read 0 on the digital side, so I suspect as soon as you try to set a bit on a given port any other analogue pins on that port will go to 0 at the same time.

author: Madsaaby
author_rank: Regular Contributor
timestamp: May 21, 2012, 09:35:24 pm
content: Quote from: baljemmett on May 21, 2012, 02:27:01 pmHi baljemmettThank you very much, I must have missed the ANSEL register while skimming through the datasheet (And didn't know of its existence)..It's working just fine after clearing those bitsI have a lot yet to learn, I see. Didn't know about the "whole port" read, modify, write either..Thanks again for the help, and for the well explained answerBest regardsMads

author: dcel
author_rank: Regular Contributor
timestamp: June 16, 2012, 09:27:18 pm
content: How is the Battle going? Anything useful and/or functional? I have a tube full of pic16f616 that I intend to drive the box full of 8x2 lcds that I got at the swapmeet. I figure that it would be a cool starter project to get an adc set up to measure voltage and display that on the 8x2 lcd. Problem is I just havent the time to get into the lab lately.Chris

author: Madsaaby
author_rank: Regular Contributor
timestamp: June 26, 2012, 07:05:55 pm
content: Quote from: dcel on June 16, 2012, 09:27:18 pmHi ChrisThe PIC16f616's are running sweet, after I set the ANSEL register correctly. I also got a whole tube of them, and find them quite nice for small projects. The only disadvantage I found is that it's missing eeprom. I did finish my temp display, and also made a small analog PSU with digital voltage and amp reading.. I am currently working on a small but very loud alarm clock, all of them including the 16F616.. I'm sure you will find good use for the mcu's, sounds like a nice project..-Mads