ravi_karthik
Newbie level 3
- Joined
- Apr 7, 2014
- Messages
- 4
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1
- Activity points
- 114
Trying to communicate with lpc2148 inbuilt i2c protocol(i2c0) to external adc chip (pcf8591 philips adc-dac chip) to read adc voltage from it.
But proteus simulation with lpc2138 is not responding to the code written.Being a newbie to i2c protocol specifically on LPC2148, can anyone guide me on this.
Slave address = 0x90;
But proteus simulation with lpc2138 is not responding to the code written.Being a newbie to i2c protocol specifically on LPC2148, can anyone guide me on this.
Slave address = 0x90;
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 #include <LPC21xx.H> float vol; unsigned char voltage[7]; //i2c register configurations #define STA 0x20 #define SIC 0x08 #define SI 0x08 #define STO 0x10 #define STAC 0x20 #define AA 0x04 // Define LCD PinIO Mask // RS = P1.16 // EN = P1.17 // D4 = P1.18 // D5 = P1.19 // D6 = P1.20 // D7 = P1.21 #define LCD_RS 0x00010000 // P1.16(0000 0000 0000 000x 0000 0000 0000 0000) #define LCD_EN 0x00020000 // P1.17(0000 0000 0000 00x0 0000 0000 0000 0000) #define LCD_D4 0x00040000 // P1.18(0000 0000 0000 0x00 0000 0000 0000 0000) #define LCD_D5 0x00080000 // P1.19(0000 0000 0000 x000 0000 0000 0000 0000) #define LCD_D6 0x00100000 // P1.20(0000 0000 000x 0000 0000 0000 0000 0000) #define LCD_D7 0x00200000 // P1.21(0000 0000 00x0 0000 0000 0000 0000 0000) #define LCD_DATA (LCD_D7|LCD_D6|LCD_D5|LCD_D4) #define LCD_IOALL (LCD_D7|LCD_D6|LCD_D5|LCD_D4|LCD_RS|LCD_EN) #define lcd_rs_set() IOSET1 = LCD_RS // RS = 1 (Select Instruction) #define lcd_rs_clr() IOCLR1 = LCD_RS // RS = 0 (Select Data) #define lcd_en_set() IOSET1 = LCD_EN // EN = 1 (Enable) #define lcd_en_clr() IOCLR1 = LCD_EN // EN = 0 (Disable) // xxxx xxx0 0000 0000 0000 0000 0000 0000 #define lcd_dir_write() IODIR1 |= 0x003F0000 // LCD Data Bus = Write //#define lcd_dir_read() IODIR1 &= 0xFFC3FFFF // LCD Data Bus = Read #define lcd_clear() lcd_write_control(0x01) // Clear Display #define lcd_cursor_home() lcd_write_control(0x02) // Set Cursor = 0 #define lcd_display_on() lcd_write_control(0x0E) // LCD Display Enable #define lcd_display_off() lcd_write_control(0x08) // LCD Display Disable #define lcd_cursor_blink() lcd_write_control(0x0F) // Set Cursor = Blink #define lcd_cursor_on() lcd_write_control(0x0E) // Enable LCD Cursor #define lcd_cursor_off() lcd_write_control(0x0C) // Disable LCD Cursor #define lcd_cursor_left() lcd_write_control(0x10) // Shift Left Cursor #define lcd_cursor_right() lcd_write_control(0x14) // Shift Right Cursor #define lcd_display_sleft() lcd_write_control(0x18) // Shift Left Display #define lcd_display_sright() lcd_write_control(0x1C) // Shift Right Display /***********************/ /* Enable Pulse to LCD */ /***********************/ void enable_lcd(void) // Enable Pulse { unsigned int i; // Delay Count lcd_en_set(); // Enable ON for (i=0;i<400000;i++); lcd_en_clr(); // Enable OFF } /***********************/ /* Delay Time Function */ /* 1-4294967296 */ /***********************/ void delay(unsigned long int count1) { while(count1 > 0) {count1--;} // Loop Decrease Counter } /****************************/ /* Strobe 4-Bit Data to LCD */ /****************************/ void lcd_out_data4(unsigned char val) { IOCLR1 = (LCD_DATA); // Reset 4-Bit Pin Data IOSET1 = (val<<18); // EN,0,RW,RS:DDDD:0000:0000:0000:0000:0000:0000 } /****************************/ /* Write Data 1 Byte to LCD */ /****************************/ void lcd_write_byte(unsigned char val) { lcd_out_data4((val>>4)&0x0F); // Strobe 4-Bit High-Nibble to LCD enable_lcd(); // Enable Pulse lcd_out_data4(val&0x0F); // Strobe 4-Bit Low-Nibble to LCD enable_lcd(); // Enable Pulse delay(100000); //while(busy_lcd()); // Wait LCD Execute Complete } /****************************/ /* Write Instruction to LCD */ /****************************/ void lcd_write_control(unsigned char val) { lcd_rs_clr(); // RS = 0 = Instruction Select lcd_write_byte(val); // Strobe Command Byte } /****************************/ /* Write Data(ASCII) to LCD */ /****************************/ void lcd_write_ascii(unsigned char c) { lcd_rs_set(); // RS = 1 = Data Select lcd_write_byte(c); // Strobe 1 Byte to LCD } /*******************************/ /* Initial 4-Bit LCD Interface */ /*******************************/ void lcd_init() { unsigned int i; // LCD Initial Delay Count PINSEL2 = 0x00000000; // GPIO1[31..26] = I/O Function lcd_dir_write(); // LCD Data Bus = Write for (i=0;i<1000;i++); // Power-On Delay (15 mS) IOCLR1 = (LCD_IOALL); // Reset (RS,RW,EN,4-Bit Data) Pin IOSET1 = (LCD_D5|LCD_D4); // DDDD:EN,RW,RS,0:0000:0000:0000:0000:0000:0000 enable_lcd(); // Enable Pulse for (i=0;i<100;i++); // Delay 4.1mS IOCLR1 = (LCD_IOALL); // Reset (RS,RW,EN,4-Bit Data) Pin IOSET1 = (LCD_D5|LCD_D4); // DDDD:EN,RW,RS,0:0000:0000:0000:0000:0000:0000 enable_lcd(); // Enable Pulse for (i=0;i<100;i++); // delay 100uS IOCLR1 = (LCD_IOALL); // Reset (RS,RW,EN,4-Bit Data) Pin IOSET1 = (LCD_D5|LCD_D4); // DDDD:EN,RW,RS,0:0000:0000:0000:0000:0000:0000 enable_lcd(); // Enable Pulse delay(10000); //while(busy_lcd()); // Wait LCD Execute Complete IOCLR1 = (LCD_IOALL); // Reset (RS,RW,EN,4-Bit Data) Pin IOSET1 = (LCD_D5); // DDDD:EN,RW,RS,0:0000:0000:0000:0000:0000:0000 enable_lcd(); // Enable Pulse delay(10000); //while(busy_lcd()); // Wait LCD Execute Complete lcd_write_control(0x28); // Function Set (DL=0 4-Bit,N=1 2 Line,F=0 5X7) lcd_write_control(0x0C); // Display on/off Control (Entry Display,Cursor off,Cursor not Blink) lcd_write_control(0x06); // Entry Mode Set (I/D=1 Increment,S=0 Cursor Shift) lcd_write_control(0x01); // Clear Display (Clear Display,Set DD RAM Address=0) for (i=0;i<100000;i++); // Wait Command Ready } /***************************/ /* Set LCD Position Cursor */ /***************************/ void goto_cursor(unsigned char i) { i |= 0x80; // Set DD-RAM Address Command lcd_write_control(i); } /************************************/ /* Print Display Data(ASCII) to LCD */ /************************************/ void lcd_print(unsigned char* str) { int i; for (i=0;i<16 && str[i]!=0;i++) // 16 Character Print { lcd_write_ascii(str[i]); // Print Byte to LCD } } void InitI2C(void) { I2CONCLR = 0xFF; I2SCLL = 75; //speed at 15MHz pclk and i2c bus communication at 100kHz I2SCLH = 75; I2CONSET = 0x40; //Active Master Mode on I2C bus } void SendI2CAddress(unsigned char Addr_S) { unsigned char r; IO0DIR = 0x01; I2CONCLR = 0xFF; // clear I2C - included if User forgot to "StopI2C()" // else this function would hang. I2CONSET = 0x40; // Active Master Mode on I2C bus if((Addr_S & 0x01)) // test if it's reading I2CONSET = STA | AA; // set STA - allow master to acknowlege slave; else I2CONSET = STA; // set STA dont allow acknowledges; while(I2STAT!=0x08) ; // Wait for start to be completed I2DAT = Addr_S; // Charge slave Address I2CONCLR = SIC | STAC; // Clear i2c interrupt bit to send the data while( ! ( I2CONSET & SI)) ; // wait till status available r=I2STAT; // read Status. See standard error codes pdf (link in manual). if(!(Addr_S & 0x01)) { // if we are doing a write if (r != 0x18) { // look for "SLA+W has been transmitted; ACK has been received" if ( r==0x20 ) // check for "SLA+W has been transmitted; NOT ACK has been received" IO0SET = 0x01; // led at pin0.0 indication no acknowlege - probably no device there. Return a 1 in longjmp } } else { if (r != 0x40) { // look for "SLA+R has been transmitted; ACK has been received" if ( r==0x48 ) // check for "SLA+R has been transmitted; NOT ACK has been received" IO0SET = 0x01; // led at pin0.0other error - return status code in longjmp } } } unsigned char ReadI2C(void) { unsigned char r; I2CONCLR = SIC; // clear SIC; while( ! (I2CONSET & 0x8)); // wait till status available r=I2STAT; // check for error if (r != 0x50) { // look for "Data byte has been received; ACK has been returned" IO0SET = 0x01; // led at pin0.0 read fail indication } return I2DAT; } void WriteI2C(unsigned char Data) { unsigned char r; I2DAT = Data; // Charge Data I2CONCLR = 0x8; // SIC; Clear i2c interrupt bit to send the data while( ! (I2CONSET & 0x8)); // wait till status available r=I2STAT; if (r != 0x28) { // look for "Data byte in S1DAT has been transmitted; ACK has been received" IO0SET = 0x01; // led at pin0.0 write fail indication } } void StopI2C(void) { I2CONCLR = SIC; I2CONSET = STO; while((I2CONSET&STO)) ; // wait for Stopped bus I2C } float adc_voltage(void) { // Read the voltage from a PCF8591 A/D device unsigned char r; PINSEL0 = 0x50; // Set pinouts p0.2 and p0.3 as scl0 and sda0 respectively InitI2C(); SendI2CAddress(0x90); // PCF8591 A/D device address SendI2CAddress(0x91); // Start the read SendI2CAddress(0x00); // Start the read ReadI2C(); // dummy read cycle to do the first conversion r=ReadI2C(); // read the result StopI2C(); return r; // return the voltage read } /* Main Program Start Here */ int main(void) { lcd_init(); // Initial LCD while(1) // Loop Continue { vol = adc_voltage()/255*5*10; voltage [0] = (unsigned char) vol/10 +0x30; voltage [1] = '.'; voltage [2] = (unsigned char) vol % 10 + 0x30; lcd_write_control(0x01); // Clear Display (Clear Display,Set DD RAM Address=0) goto_cursor(0x00); // Set Cursor Line-1 lcd_print(voltage); // Display LCD Line-1 delay(100000); } }