University projects
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1136 lines
40 KiB

  1. CCS PCM C Compiler, Version 3.239, 31482 08-Feb-07 14:54
  2. Filename: Y:\Year 2\EE2A\PIC-LCD\4bit\lcd_display_4bit.lst
  3. ROM used: 441 words (11%)
  4. Largest free fragment is 2048
  5. RAM used: 71 (41%) at main() level
  6. 80 (46%) worst case
  7. Stack: 5 locations
  8. *
  9. 0000: MOVLW 00
  10. 0001: MOVWF 0A
  11. 0002: GOTO 10A
  12. 0003: NOP
  13. .................... /*
  14. .................... * Authors: Sam Black, Sam Burras, Ben Francis
  15. .................... *
  16. .................... * Version 1.0 Date: 07/02/07
  17. .................... *
  18. .................... * Program to send strings to the LCD using
  19. .................... * a 4-bit driver
  20. .................... *
  21. .................... */
  22. ....................
  23. .................... #include <16F648A.h>
  24. .................... //////// Standard Header file for the PIC16F648A device ////////////////
  25. .................... #device PIC16F648A
  26. .................... #list
  27. ....................
  28. .................... #include <string.h>
  29. .................... ////////////////////////////////////////////////////////////////////////////
  30. .................... //// (C) Copyright 1996,2003 Custom Computer Services ////
  31. .................... //// This source code may only be used by licensed users of the CCS C ////
  32. .................... //// compiler. This source code may only be distributed to other ////
  33. .................... //// licensed users of the CCS C compiler. No other use, reproduction ////
  34. .................... //// or distribution is permitted without written permission. ////
  35. .................... //// Derivative programs created using this software in object code ////
  36. .................... //// form are not restricted in any way. ////
  37. .................... ////////////////////////////////////////////////////////////////////////////
  38. ....................
  39. .................... #ifndef _STRING
  40. .................... #define _STRING
  41. .................... #include <stddef.h>
  42. .................... ///////////////////////////////////////////////////////////////////////////
  43. .................... //// (C) Copyright 1996,2003 Custom Computer Services ////
  44. .................... //// This source code may only be used by licensed users of the CCS C ////
  45. .................... //// compiler. This source code may only be distributed to other ////
  46. .................... //// licensed users of the CCS C compiler. No other use, reproduction ////
  47. .................... //// or distribution is permitted without written permission. ////
  48. .................... //// Derivative programs created using this software in object code ////
  49. .................... //// form are not restricted in any way. ////
  50. .................... ///////////////////////////////////////////////////////////////////////////
  51. ....................
  52. .................... #ifndef _STDDEF
  53. ....................
  54. .................... #define _STDDEF
  55. ....................
  56. .................... #if sizeof(int *)==1
  57. .................... #define ptrdiff_t int
  58. .................... #else
  59. .................... #define ptrdiff_t long
  60. .................... #endif
  61. ....................
  62. .................... #define size_t int
  63. .................... #define wchar_t char
  64. .................... #define NULL 0
  65. ....................
  66. .................... #define offsetof(s,f) (offsetofbit(s,f)/8)
  67. ....................
  68. .................... #endif
  69. ....................
  70. .................... #include <ctype.h>
  71. .................... ////////////////////////////////////////////////////////////////////////////
  72. .................... //// (C) Copyright 1996,2003 Custom Computer Services ////
  73. .................... //// This source code may only be used by licensed users of the CCS C ////
  74. .................... //// compiler. This source code may only be distributed to other ////
  75. .................... //// licensed users of the CCS C compiler. No other use, reproduction ////
  76. .................... //// or distribution is permitted without written permission. ////
  77. .................... //// Derivative programs created using this software in object code ////
  78. .................... //// form are not restricted in any way. ////
  79. .................... ////////////////////////////////////////////////////////////////////////////
  80. ....................
  81. .................... #ifndef _CTYPE
  82. .................... #define _CTYPE
  83. ....................
  84. .................... #define islower(x) isamong(x,"abcdefghijklmnopqrstuvwxyz")
  85. .................... #define isupper(x) isamong(x,"ABCDEFGHIJKLMNOPQRSTUVWXYZ")
  86. .................... #define isalnum(x) isamong(x,"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
  87. .................... #define isalpha(x) isamong(x,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
  88. .................... #define isdigit(x) isamong(x,"0123456789")
  89. .................... #define isspace(x) (x==' ')
  90. .................... #define isxdigit(x) isamong(x,"0123456789ABCDEFabcdef")
  91. .................... #define iscntrl(x) (x<' ')
  92. .................... #define isprint(x) (x>=' ')
  93. .................... #define isgraph(x) (x>' ')
  94. .................... #define ispunct(x) ((x>' ')&&!isalnum(x))
  95. ....................
  96. .................... #endif
  97. ....................
  98. ....................
  99. ....................
  100. ....................
  101. ....................
  102. .................... //////////////////////////////////////////////
  103. .................... //// Uncomment the following define to ////
  104. .................... //// allow some functions to use a ////
  105. .................... //// quicker algorithm, but use more ROM ////
  106. .................... //// ////
  107. .................... //// #define FASTER_BUT_MORE_ROM ////
  108. .................... //////////////////////////////////////////////
  109. ....................
  110. ....................
  111. ....................
  112. .................... /*Copying functions*/
  113. .................... /* standard template:
  114. .................... void *memmove(void *s1, void *s2, size_t n).
  115. .................... Copies max of n characters safely (not following ending '\0')
  116. .................... from s2 in s1; if s2 has less than n characters, appends 0 */
  117. ....................
  118. .................... char *memmove(void *s1,char *s2,size_t n)
  119. .................... {
  120. .................... char *sc1;
  121. .................... char *sc2;
  122. .................... sc1=s1;
  123. .................... sc2=s2;
  124. .................... if(sc2<sc1 && sc1 <sc2 +n)
  125. .................... for(sc1+=n,sc2+=n;0<n;--n)
  126. .................... *--sc1=*--sc2;
  127. .................... else
  128. .................... for(;0<n;--n)
  129. .................... *sc1++=*sc2++;
  130. .................... return s1;
  131. .................... }
  132. ....................
  133. .................... /* compiler ignored the name 'strcpy()'; perhaps, it's reserved?
  134. .................... Standard template: char *strcpy(char *s1, const char *s2)
  135. .................... copies the string s2 including the null character to s1*/
  136. ....................
  137. .................... char *strcopy(char *s1, char *s2)
  138. .................... {
  139. .................... char *s;
  140. ....................
  141. .................... for (s = s1; *s2 != 0; s++, s2++) {
  142. .................... *s = *s2;
  143. .................... }
  144. .................... *s = *s2;
  145. .................... return(s1);
  146. .................... }
  147. ....................
  148. .................... /* standard template:
  149. .................... char *strncpy(char *s1, const char *s2, size_t n).
  150. .................... Copies max of n characters (not following ending '\0')
  151. .................... from s2 in s1; if s2 has less than n characters, appends 0 */
  152. ....................
  153. .................... char *strncpy(char *s1, char *s2, size_t n)
  154. .................... {
  155. .................... char *s;
  156. ....................
  157. .................... for (s = s1; n > 0 && *s2 != '\0'; n--)
  158. .................... *s++ = *s2++;
  159. .................... for (; n > 0; n--)
  160. .................... *s++ = '\0';
  161. ....................
  162. .................... return(s1);
  163. .................... }
  164. .................... /***********************************************************/
  165. ....................
  166. .................... /*concatenation functions*/
  167. .................... /* standard template: char *strcat(char *s1, const char *s2)
  168. .................... appends s2 to s1*/
  169. ....................
  170. .................... char *strcat(char *s1, char *s2)
  171. .................... {
  172. .................... char *s;
  173. ....................
  174. .................... for (s = s1; *s != '\0'; ++s);
  175. .................... while(*s2 != '\0')
  176. .................... {
  177. .................... *s = *s2;
  178. .................... ++s;
  179. .................... ++s2;
  180. .................... }
  181. ....................
  182. .................... *s = '\0';
  183. .................... return(s1);
  184. .................... }
  185. .................... /* standard template: char *strncat(char *s1, char *s2,size_t n)
  186. .................... appends not more than n characters from s2 to s1*/
  187. ....................
  188. .................... char *strncat(char *s1, char *s2, size_t n)
  189. .................... {
  190. .................... char *s;
  191. ....................
  192. .................... for (s = s1; *s != '\0'; ++s);
  193. .................... while(*s2 != '\0' && 0<n)
  194. .................... {
  195. .................... *s = *s2;
  196. .................... ++s;
  197. .................... ++s2;
  198. .................... --n;
  199. .................... }
  200. ....................
  201. .................... *s = '\0';
  202. .................... return(s1);
  203. .................... }
  204. ....................
  205. .................... /***********************************************************/
  206. ....................
  207. ....................
  208. .................... /*comparison functions*/
  209. .................... /* standard template: signed int memcmp(void *s1, void *s2).
  210. .................... Compares s1 & s2; returns -1 if s1<s2, 0 if s1=s2, 1 if s1>s2 */
  211. ....................
  212. .................... signed int memcmp(void * s1,char *s2,size_t n)
  213. .................... {
  214. .................... char *su1, *su2;
  215. .................... for(su1=s1, su2=s2; 0<n; ++su1, ++su2, --n)
  216. .................... {
  217. .................... if(*su1!=*su2)
  218. .................... return ((*su1<*su2)?-1:+1);
  219. .................... }
  220. .................... return 0;
  221. .................... }
  222. ....................
  223. .................... /* standard template: int strcmp(const char *s1, const char *s2).
  224. .................... Compares s1 & s2; returns -1 if s1<s2, 0 if s1=s2, 1 if s1>s2 */
  225. ....................
  226. .................... signed int strcmp(char *s1, char *s2)
  227. .................... {
  228. .................... for (; *s1 == *s2; s1++, s2++)
  229. .................... if (*s1 == '\0')
  230. .................... return(0);
  231. .................... return((*s1 < *s2) ? -1: 1);
  232. .................... }
  233. .................... /* standard template: int strcoll(const char *s1, const char *s2).
  234. .................... Compares s1 & s2; returns -1 if s1<s2, 0 if s1=s2, 1 if s1>s2 */
  235. ....................
  236. .................... signed int strcoll(char *s1, char *s2)
  237. .................... {
  238. .................... for (; *s1 == *s2; s1++, s2++)
  239. .................... if (*s1 == '\0')
  240. .................... return(0);
  241. .................... return((*s1 < *s2) ? -1: 1);
  242. .................... }
  243. ....................
  244. .................... /* standard template:
  245. .................... int strncmp(const char *s1, const char *s2, size_t n).
  246. .................... Compares max of n characters (not following 0) from s1 to s2;
  247. .................... returns same as strcmp */
  248. ....................
  249. .................... signed int strncmp(char *s1, char *s2, size_t n)
  250. .................... {
  251. .................... for (; n > 0; s1++, s2++, n--)
  252. .................... if (*s1 != *s2)
  253. .................... return((*s1 <*s2) ? -1: 1);
  254. .................... else if (*s1 == '\0')
  255. .................... return(0);
  256. .................... return(0);
  257. .................... }
  258. .................... /* standard template:
  259. .................... int strxfrm(const char *s1, const char *s2, size_t n).
  260. .................... transforms maximum of n characters from s2 and places them into s1*/
  261. .................... size_t strxfrm(char *s1, char *s2, size_t n)
  262. .................... {
  263. .................... char *s;
  264. .................... int n1;
  265. .................... n1=n;
  266. .................... for (s = s1; n > 0 && *s2 != '\0'; n--)
  267. .................... *s++ = *s2++;
  268. .................... for (; n > 0; n--)
  269. .................... *s++ = '\0';
  270. ....................
  271. .................... return(n1);
  272. .................... }
  273. ....................
  274. ....................
  275. ....................
  276. ....................
  277. ....................
  278. .................... /***********************************************************/
  279. .................... /*Search functions*/
  280. .................... /* standard template: void *memchr(const char *s, int c).
  281. .................... Finds first occurrence of c in n characters of s */
  282. ....................
  283. .................... char *memchr(void *s,int c,size_t n)
  284. .................... {
  285. .................... char uc;
  286. .................... char *su;
  287. .................... uc=c;
  288. .................... for(su=s;0<n;++su,--n)
  289. .................... if(*su==uc)
  290. .................... return su;
  291. .................... return NULL;
  292. .................... }
  293. ....................
  294. .................... /* standard template: char *strchr(const char *s, int c).
  295. .................... Finds first occurrence of c in s */
  296. ....................
  297. .................... char *strchr(char *s, int c)
  298. .................... {
  299. .................... for (; *s != c; s++)
  300. .................... if (*s == '\0')
  301. .................... return(0);
  302. .................... return(s);
  303. .................... }
  304. .................... /* standard template:
  305. .................... size_t strcspn(const char *s1, const char *s2).
  306. .................... Computes length of max initial segment of s1 that
  307. .................... consists entirely of characters NOT from s2*/
  308. ....................
  309. .................... int *strcspn(char *s1, char *s2)
  310. .................... {
  311. .................... char *sc1, *sc2;
  312. ....................
  313. .................... for (sc1 = s1; *sc1 != 0; sc1++)
  314. .................... for (sc2 = s2; *sc2 != 0; sc2++)
  315. .................... if (*sc1 == *sc2)
  316. .................... return(sc1 - s1);
  317. .................... return(sc1 - s1);
  318. .................... }
  319. .................... /* standard template:
  320. .................... char *strpbrk(const char *s1, const char *s2).
  321. .................... Locates first occurence of any character from s2 in s1;
  322. .................... returns s1 if s2 is empty string */
  323. ....................
  324. .................... char *strpbrk(char *s1, char *s2)
  325. .................... {
  326. .................... char *sc1, *sc2;
  327. ....................
  328. .................... for (sc1 = s1; *sc1 != 0; sc1++)
  329. .................... for (sc2 = s2; *sc2 != 0; sc2++)
  330. .................... if (*sc1 == *sc2)
  331. .................... return(sc1);
  332. .................... return(0);
  333. .................... }
  334. ....................
  335. ....................
  336. .................... /* standard template: char *strrchr(const char *s, int c).
  337. .................... Finds last occurrence of c in s */
  338. ....................
  339. .................... char *strrchr(char *s, int c)
  340. .................... {
  341. .................... char *p;
  342. ....................
  343. .................... for (p = 0; ; s++)
  344. .................... {
  345. .................... if (*s == c)
  346. .................... p = s;
  347. .................... if (*s == '\0')
  348. .................... return(p);
  349. .................... }
  350. .................... }
  351. .................... /* computes length of max initial segment of s1 consisting
  352. .................... entirely of characters from s2 */
  353. ....................
  354. .................... int *strspn(char *s1, char *s2)
  355. .................... {
  356. .................... char *sc1, *sc2;
  357. ....................
  358. .................... for (sc1 = s1; *sc1 != 0; sc1++)
  359. .................... for (sc2 = s2; ; sc2++)
  360. .................... if (*sc2 == '\0')
  361. .................... return(sc1 - s1);
  362. .................... else if (*sc1 == *sc2)
  363. .................... break;
  364. .................... return(sc1 - s1);
  365. .................... }
  366. .................... /* standard template:
  367. .................... char *strstr(const char *s1, const char *s2);
  368. .................... Locates first occurence of character sequence s2 in s1;
  369. .................... returns 0 if s2 is empty string
  370. ....................
  371. .................... Uncomment #define FASTER_BUT_MORE_ROM at the top of the
  372. .................... file to use the faster algorithm */
  373. .................... char *strstr(char *s1, char *s2)
  374. .................... {
  375. .................... char *s, *t;
  376. ....................
  377. .................... #ifdef FASTER_BUT_MORE_ROM
  378. .................... if (*s2 == '\0')
  379. .................... return(s1);
  380. .................... #endif
  381. ....................
  382. .................... while (*s1)
  383. .................... {
  384. .................... for(s = s1, t = s2; *t && *s == *t; ++s, ++t);
  385. ....................
  386. .................... if (*t == '\0')
  387. .................... return s1;
  388. .................... ++s1;
  389. .................... #ifdef FASTER_BUT_MORE_ROM
  390. .................... while(*s1 != '\0' && *s1 != *s2)
  391. .................... ++s1;
  392. .................... #endif
  393. .................... }
  394. .................... return 0;
  395. .................... }
  396. ....................
  397. .................... /* standard template: char *strtok(char *s1, const char *s2).
  398. ....................
  399. .................... Finds next token in s1 delimited by a character from separator
  400. .................... string s2 (which can be different from call to call). First call
  401. .................... starts at beginning of s1 searching for first character NOT
  402. .................... contained in s2; returns 0 if none is found.
  403. .................... If one is found, it is the start of first token (return value).
  404. .................... Function then searches from there for a character contained in s2.
  405. .................... If none is found, current token extends to end of s1, and subsequent
  406. .................... searches for a token will return 0. If one is found, it is
  407. .................... overwritten by '\0', which terminates current token. Function saves
  408. .................... pointer to following character from which next search will start.
  409. .................... Each subsequent call, with 0 as first argument, starts searching
  410. .................... from saved pointer */
  411. ....................
  412. .................... char *strtok(char *s1, char *s2)
  413. .................... {
  414. .................... char *beg, *end;
  415. .................... static char *save;
  416. *
  417. 010F: CLRF 20
  418. ....................
  419. .................... beg = (s1)? s1: save;
  420. .................... beg += strspn(beg, s2);
  421. .................... if (*beg == '\0')
  422. .................... {
  423. .................... *save = ' ';
  424. .................... return(0);
  425. .................... }
  426. .................... end = strpbrk(beg, s2);
  427. .................... if (*end != '\0')
  428. .................... {
  429. .................... *end = '\0';
  430. .................... end++;
  431. .................... }
  432. .................... save = end;
  433. .................... return(beg);
  434. .................... }
  435. ....................
  436. .................... /*****************************************************************/
  437. .................... /*Miscellaneous functions*/
  438. .................... /* standard template
  439. .................... maps error number in errnum to an error message string
  440. .................... Returns: Pointer to string
  441. .................... */
  442. .................... #ifdef _ERRNO
  443. .................... char * strerror(int errnum)
  444. .................... {
  445. .................... char s[15];
  446. .................... switch( errnum)
  447. .................... {
  448. .................... case 0:
  449. .................... strcpy(s,"no errors");
  450. .................... return s;
  451. .................... case EDOM :
  452. .................... strcpy(s,"domain error");
  453. .................... return s;
  454. .................... case ERANGE:
  455. .................... strcpy(s,"range error");
  456. .................... return s;
  457. .................... }
  458. .................... }
  459. .................... #ENDIF
  460. .................... /* standard template: size_t strlen(const char *s).
  461. .................... Computes length of s1 (preceding terminating 0) */
  462. ....................
  463. .................... int *strlen(char *s)
  464. .................... {
  465. .................... char *sc;
  466. ....................
  467. .................... for (sc = s; *sc != 0; sc++);
  468. .................... return(sc - s);
  469. .................... }
  470. ....................
  471. .................... /* standard template: size_t stricmp(const char *s1, const char *s2).
  472. .................... Compares s1 to s2 ignoring case (upper vs. lower) */
  473. ....................
  474. .................... signed int stricmp(char *s1, char *s2)
  475. .................... {
  476. .................... for(; *s1==*s2||(isalpha(*s1)&&isalpha(*s2)&&(*s1==*s2+32||*s2==*s1+32));
  477. .................... s1++, s2++)
  478. .................... if (*s1 == '\0')
  479. .................... return(0);
  480. .................... return((*s1 < *s2) ? -1: 1);
  481. .................... }
  482. ....................
  483. ....................
  484. .................... /* standard template: char *strlwr(char *s).
  485. .................... Replaces uppercase letters by lowercase;
  486. .................... returns pointer to new string s */
  487. ....................
  488. .................... char *strlwr(char *s)
  489. .................... {
  490. .................... char *p;
  491. ....................
  492. .................... for (p = s; *p != '\0'; p++)
  493. .................... if (*p >= 'A' && *p <='Z')
  494. .................... *p += 'a' - 'A';
  495. .................... return(s);
  496. .................... }
  497. ....................
  498. ....................
  499. .................... /************************************************************/
  500. ....................
  501. ....................
  502. .................... #endif
  503. ....................
  504. .................... #use delay(clock=4000000)
  505. *
  506. 001C: MOVLW 6A
  507. 001D: MOVWF 04
  508. 001E: MOVF 00,W
  509. 001F: BTFSC 03.2
  510. 0020: GOTO 030
  511. 0021: MOVLW 01
  512. 0022: MOVWF 78
  513. 0023: CLRF 77
  514. 0024: DECFSZ 77,F
  515. 0025: GOTO 024
  516. 0026: DECFSZ 78,F
  517. 0027: GOTO 023
  518. 0028: MOVLW 4A
  519. 0029: MOVWF 77
  520. 002A: DECFSZ 77,F
  521. 002B: GOTO 02A
  522. 002C: NOP
  523. 002D: NOP
  524. 002E: DECFSZ 00,F
  525. 002F: GOTO 021
  526. 0030: RETLW 00
  527. .................... #fuses NOWDT, INTRC_IO, NOPUT, NOPROTECT, NOLVP, NOMCLR
  528. .................... #include "LCD_4BIT.H"
  529. .................... /* LCD 4-bit driver
  530. .................... *
  531. .................... * Authors: Sam Black, Sam Burras, Ben Francis
  532. .................... *
  533. .................... * Derived from Custom Computer Services
  534. .................... * (C) Copyright 1996, 2003 LCD.C
  535. .................... *
  536. .................... * Version 1.0 Date: 07/02/07
  537. .................... *
  538. .................... */
  539. ....................
  540. .................... struct lcd_pin_map {
  541. .................... boolean rs;
  542. .................... boolean rw;
  543. .................... boolean enable;
  544. .................... boolean button;
  545. .................... int data : 4;
  546. .................... };
  547. ....................
  548. .................... /* Create structs to map I/O */
  549. .................... struct lcd_pin_map lcd;
  550. .................... struct lcd_pin_map lcd_dir;
  551. ....................
  552. .................... /* Set ports up correctly */
  553. .................... #byte lcd=0x06
  554. .................... #byte lcd_dir=0x86
  555. ....................
  556. .................... /* Send initialization sequence */
  557. .................... /* No cursor */
  558. .................... byte CONST lcd_init_nocursor[4] = {0x28, 0x0C, 0x01, 0x06};
  559. .................... /* Cursor */
  560. .................... byte CONST lcd_init_cursor[4] = {0x28, 0x0E, 0x01, 0x06};
  561. .................... /* Scrolling */
  562. .................... byte CONST lcd_init_scrolling[4] = {0x20, 0x0C, 0x01, 0x05};
  563. ....................
  564. .................... /* Set direction of pins to send chars to LCD */
  565. .................... /* RS, RW, ENABLE, BUTTON, DATA */
  566. .................... struct lcd_pin_map CONST lcd_write = {0, 0, 0, 1, 0};
  567. ....................
  568. .................... /* Set direction of pins to read status from LCD */
  569. .................... struct lcd_pin_map CONST lcd_read = {1, 0, 0, 1, 1};
  570. ....................
  571. .................... /* Based on lcd.c */
  572. .................... void lcd_send_nibble( byte n ) {
  573. ....................
  574. .................... lcd.enable = 1;
  575. 0031: BSF 06.2
  576. .................... delay_us(50);
  577. 0032: MOVLW 10
  578. 0033: MOVWF 77
  579. 0034: DECFSZ 77,F
  580. 0035: GOTO 034
  581. 0036: NOP
  582. .................... lcd.data = n;
  583. 0037: SWAPF 69,W
  584. 0038: ANDLW F0
  585. 0039: MOVWF 77
  586. 003A: MOVLW 0F
  587. 003B: ANDWF 06,W
  588. 003C: IORWF 77,W
  589. 003D: MOVWF 06
  590. .................... delay_ms(1);
  591. 003E: MOVLW 01
  592. 003F: MOVWF 6A
  593. 0040: CALL 01C
  594. .................... lcd.enable = 0;
  595. 0041: BCF 06.2
  596. .................... delay_us(50);
  597. 0042: MOVLW 10
  598. 0043: MOVWF 77
  599. 0044: DECFSZ 77,F
  600. 0045: GOTO 044
  601. 0046: NOP
  602. .................... }
  603. 0047: RETLW 00
  604. ....................
  605. .................... /* Based on lcd.c */
  606. .................... void lcd_send_byte( byte address, byte n ) {
  607. ....................
  608. .................... /* Set port direction */
  609. .................... lcd_dir = lcd_write;
  610. 0048: MOVLW 08
  611. 0049: BSF 03.5
  612. 004A: MOVWF 06
  613. .................... /* Set what we are writing to */
  614. .................... /* 0 is Instruction */
  615. .................... /* 1 is Data */
  616. .................... lcd.rs = address;
  617. 004B: BCF 03.5
  618. 004C: BTFSS 66.0
  619. 004D: BCF 06.0
  620. 004E: BTFSC 66.0
  621. 004F: BSF 06.0
  622. .................... /* Write to LCD */
  623. .................... lcd.rw = 0;
  624. 0050: BCF 06.1
  625. .................... delay_us(500);
  626. 0051: MOVLW A6
  627. 0052: MOVWF 77
  628. 0053: DECFSZ 77,F
  629. 0054: GOTO 053
  630. 0055: NOP
  631. .................... lcd_send_nibble(n>>4);
  632. 0056: SWAPF 67,W
  633. 0057: MOVWF 68
  634. 0058: MOVLW 0F
  635. 0059: ANDWF 68,F
  636. 005A: MOVF 68,W
  637. 005B: MOVWF 69
  638. 005C: CALL 031
  639. .................... delay_ms(1);
  640. 005D: MOVLW 01
  641. 005E: MOVWF 6A
  642. 005F: CALL 01C
  643. .................... lcd_send_nibble(n & 0xf);
  644. 0060: MOVF 67,W
  645. 0061: ANDLW 0F
  646. 0062: MOVWF 68
  647. 0063: MOVWF 69
  648. 0064: CALL 031
  649. .................... /* Reset RW/RS */
  650. .................... lcd.rw = 1;
  651. 0065: BSF 06.1
  652. .................... lcd.rs = 0;
  653. 0066: BCF 06.0
  654. .................... delay_us(500);
  655. 0067: MOVLW A6
  656. 0068: MOVWF 77
  657. 0069: DECFSZ 77,F
  658. 006A: GOTO 069
  659. 006B: NOP
  660. ....................
  661. .................... }
  662. 006C: RETLW 00
  663. ....................
  664. .................... /* Based on lcd.c */
  665. .................... boolean lcd_read_status() {
  666. ....................
  667. .................... boolean status;
  668. .................... /* Set port direction */
  669. .................... lcd_dir = lcd_read;
  670. .................... /* Read from the LCD */
  671. .................... lcd.rw = 1;
  672. .................... delay_us(1);
  673. .................... lcd.enable = 1;
  674. .................... delay_us(1);
  675. .................... status = lcd.rs;
  676. .................... lcd.enable = 0;
  677. .................... delay_us(2);
  678. .................... /* Return the status */
  679. .................... return(status);
  680. .................... }
  681. ....................
  682. .................... /* Based on lcd.c */
  683. .................... void lcd_init(int init) {
  684. ....................
  685. .................... int i;
  686. ....................
  687. .................... lcd_dir = lcd_write;
  688. 006D: MOVLW 08
  689. 006E: BSF 03.5
  690. 006F: MOVWF 06
  691. .................... lcd.rs = 0;
  692. 0070: BCF 03.5
  693. 0071: BCF 06.0
  694. .................... lcd.rw = 0;
  695. 0072: BCF 06.1
  696. .................... lcd.enable = 0;
  697. 0073: BCF 06.2
  698. .................... delay_ms(15);
  699. 0074: MOVLW 0F
  700. 0075: MOVWF 6A
  701. 0076: CALL 01C
  702. ....................
  703. .................... for(i=0; i<=3; i++) {
  704. 0077: CLRF 62
  705. 0078: MOVF 62,W
  706. 0079: SUBLW 03
  707. 007A: BTFSS 03.0
  708. 007B: GOTO 084
  709. .................... lcd_send_nibble(0x03);
  710. 007C: MOVLW 03
  711. 007D: MOVWF 69
  712. 007E: CALL 031
  713. .................... delay_ms(5);
  714. 007F: MOVLW 05
  715. 0080: MOVWF 6A
  716. 0081: CALL 01C
  717. .................... }
  718. 0082: INCF 62,F
  719. 0083: GOTO 078
  720. ....................
  721. .................... /* Semd extra init nibble */
  722. .................... lcd_send_nibble(0x02);
  723. 0084: MOVLW 02
  724. 0085: MOVWF 69
  725. 0086: CALL 031
  726. .................... delay_ms(5);
  727. 0087: MOVLW 05
  728. 0088: MOVWF 6A
  729. 0089: CALL 01C
  730. ....................
  731. .................... switch (init) {
  732. 008A: MOVF 61,W
  733. 008B: XORLW 01
  734. 008C: BTFSC 03.2
  735. 008D: GOTO 095
  736. 008E: XORLW 03
  737. 008F: BTFSC 03.2
  738. 0090: GOTO 0A4
  739. 0091: XORLW 01
  740. 0092: BTFSC 03.2
  741. 0093: GOTO 0B3
  742. 0094: GOTO 0C2
  743. .................... case 1 : for(i=0; i<=3; i++)
  744. 0095: CLRF 62
  745. 0096: MOVF 62,W
  746. 0097: SUBLW 03
  747. 0098: BTFSS 03.0
  748. 0099: GOTO 0A3
  749. .................... lcd_send_byte(0, lcd_init_nocursor[i]); break;
  750. 009A: MOVF 62,W
  751. 009B: CALL 004
  752. 009C: MOVWF 63
  753. 009D: CLRF 66
  754. 009E: MOVF 63,W
  755. 009F: MOVWF 67
  756. 00A0: CALL 048
  757. 00A1: INCF 62,F
  758. 00A2: GOTO 096
  759. 00A3: GOTO 0D1
  760. .................... case 2 : for(i=0; i<=3; i++)
  761. 00A4: CLRF 62
  762. 00A5: MOVF 62,W
  763. 00A6: SUBLW 03
  764. 00A7: BTFSS 03.0
  765. 00A8: GOTO 0B2
  766. .................... lcd_send_byte(0, lcd_init_cursor[i]); break;
  767. 00A9: MOVF 62,W
  768. 00AA: CALL 00C
  769. 00AB: MOVWF 63
  770. 00AC: CLRF 66
  771. 00AD: MOVF 63,W
  772. 00AE: MOVWF 67
  773. 00AF: CALL 048
  774. 00B0: INCF 62,F
  775. 00B1: GOTO 0A5
  776. 00B2: GOTO 0D1
  777. .................... case 3 : for(i=0; i<=3; i++)
  778. 00B3: CLRF 62
  779. 00B4: MOVF 62,W
  780. 00B5: SUBLW 03
  781. 00B6: BTFSS 03.0
  782. 00B7: GOTO 0C1
  783. .................... lcd_send_byte(0, lcd_init_scrolling[i]); break;
  784. 00B8: MOVF 62,W
  785. 00B9: CALL 014
  786. 00BA: MOVWF 63
  787. 00BB: CLRF 66
  788. 00BC: MOVF 63,W
  789. 00BD: MOVWF 67
  790. 00BE: CALL 048
  791. 00BF: INCF 62,F
  792. 00C0: GOTO 0B4
  793. 00C1: GOTO 0D1
  794. .................... default : for(i=0; i<=3; i++)
  795. 00C2: CLRF 62
  796. 00C3: MOVF 62,W
  797. 00C4: SUBLW 03
  798. 00C5: BTFSS 03.0
  799. 00C6: GOTO 0D0
  800. .................... lcd_send_byte(0, lcd_init_nocursor[i]); break;
  801. 00C7: MOVF 62,W
  802. 00C8: CALL 004
  803. 00C9: MOVWF 63
  804. 00CA: CLRF 66
  805. 00CB: MOVF 63,W
  806. 00CC: MOVWF 67
  807. 00CD: CALL 048
  808. 00CE: INCF 62,F
  809. 00CF: GOTO 0C3
  810. 00D0: GOTO 0D1
  811. .................... }
  812. .................... }
  813. 00D1: RETLW 00
  814. ....................
  815. .................... /* Based on lcd.c */
  816. .................... void lcd_putc( char c ) {
  817. .................... switch (c) {
  818. 00D2: MOVF 65,W
  819. 00D3: XORLW 0C
  820. 00D4: BTFSC 03.2
  821. 00D5: GOTO 0DD
  822. 00D6: XORLW 04
  823. 00D7: BTFSC 03.2
  824. 00D8: GOTO 0E5
  825. 00D9: XORLW 02
  826. 00DA: BTFSC 03.2
  827. 00DB: GOTO 0EA
  828. 00DC: GOTO 0EF
  829. .................... /* clear the screen */
  830. .................... case '\f' : lcd_send_byte(0, 0x01);
  831. 00DD: CLRF 66
  832. 00DE: MOVLW 01
  833. 00DF: MOVWF 67
  834. 00E0: CALL 048
  835. .................... delay_ms(2); break;
  836. 00E1: MOVLW 02
  837. 00E2: MOVWF 6A
  838. 00E3: CALL 01C
  839. 00E4: GOTO 0F5
  840. .................... /* back space */
  841. .................... case '\b' : lcd_send_byte(0, 0x08); break;
  842. 00E5: CLRF 66
  843. 00E6: MOVLW 08
  844. 00E7: MOVWF 67
  845. 00E8: CALL 048
  846. 00E9: GOTO 0F5
  847. .................... /* new line */
  848. .................... case '\n' : lcd_send_byte(0, 0xC0); break;
  849. 00EA: CLRF 66
  850. 00EB: MOVLW C0
  851. 00EC: MOVWF 67
  852. 00ED: CALL 048
  853. 00EE: GOTO 0F5
  854. ....................
  855. .................... default : lcd_send_byte(1, c); break;
  856. 00EF: MOVLW 01
  857. 00F0: MOVWF 66
  858. 00F1: MOVF 65,W
  859. 00F2: MOVWF 67
  860. 00F3: CALL 048
  861. 00F4: GOTO 0F5
  862. .................... }
  863. .................... }
  864. 00F5: RETLW 00
  865. ....................
  866. ....................
  867. ....................
  868. .................... char INITMESSAGE[16] = "How can I help?";
  869. *
  870. 0110: MOVLW 48
  871. 0111: MOVWF 21
  872. 0112: MOVLW 6F
  873. 0113: MOVWF 22
  874. 0114: MOVLW 77
  875. 0115: MOVWF 23
  876. 0116: MOVLW 20
  877. 0117: MOVWF 24
  878. 0118: MOVLW 63
  879. 0119: MOVWF 25
  880. 011A: MOVLW 61
  881. 011B: MOVWF 26
  882. 011C: MOVLW 6E
  883. 011D: MOVWF 27
  884. 011E: MOVLW 20
  885. 011F: MOVWF 28
  886. 0120: MOVLW 49
  887. 0121: MOVWF 29
  888. 0122: MOVLW 20
  889. 0123: MOVWF 2A
  890. 0124: MOVLW 68
  891. 0125: MOVWF 2B
  892. 0126: MOVLW 65
  893. 0127: MOVWF 2C
  894. 0128: MOVLW 6C
  895. 0129: MOVWF 2D
  896. 012A: MOVLW 70
  897. 012B: MOVWF 2E
  898. 012C: MOVLW 3F
  899. 012D: MOVWF 2F
  900. 012E: CLRF 30
  901. .................... char MESSAGE1[16] = "The answer?";
  902. 012F: MOVLW 54
  903. 0130: MOVWF 31
  904. 0131: MOVLW 68
  905. 0132: MOVWF 32
  906. 0133: MOVLW 65
  907. 0134: MOVWF 33
  908. 0135: MOVLW 20
  909. 0136: MOVWF 34
  910. 0137: MOVLW 61
  911. 0138: MOVWF 35
  912. 0139: MOVLW 6E
  913. 013A: MOVWF 36
  914. 013B: MOVLW 73
  915. 013C: MOVWF 37
  916. 013D: MOVLW 77
  917. 013E: MOVWF 38
  918. 013F: MOVLW 65
  919. 0140: MOVWF 39
  920. 0141: MOVLW 72
  921. 0142: MOVWF 3A
  922. 0143: MOVLW 3F
  923. 0144: MOVWF 3B
  924. 0145: CLRF 3C
  925. 0146: CLRF 3D
  926. 0147: CLRF 3E
  927. 0148: CLRF 3F
  928. 0149: CLRF 40
  929. .................... char MESSAGE2[16] = "Forty Two.";
  930. 014A: MOVLW 46
  931. 014B: MOVWF 41
  932. 014C: MOVLW 6F
  933. 014D: MOVWF 42
  934. 014E: MOVLW 72
  935. 014F: MOVWF 43
  936. 0150: MOVLW 74
  937. 0151: MOVWF 44
  938. 0152: MOVLW 79
  939. 0153: MOVWF 45
  940. 0154: MOVLW 20
  941. 0155: MOVWF 46
  942. 0156: MOVLW 54
  943. 0157: MOVWF 47
  944. 0158: MOVLW 77
  945. 0159: MOVWF 48
  946. 015A: MOVLW 6F
  947. 015B: MOVWF 49
  948. 015C: MOVLW 2E
  949. 015D: MOVWF 4A
  950. 015E: CLRF 4B
  951. 015F: CLRF 4C
  952. 0160: CLRF 4D
  953. 0161: CLRF 4E
  954. 0162: CLRF 4F
  955. 0163: CLRF 50
  956. .................... char MESSAGE3[16] = " ?noitseuQ ehT";
  957. 0164: MOVLW 20
  958. 0165: MOVWF 51
  959. 0166: MOVWF 52
  960. 0167: MOVLW 3F
  961. 0168: MOVWF 53
  962. 0169: MOVLW 6E
  963. 016A: MOVWF 54
  964. 016B: MOVLW 6F
  965. 016C: MOVWF 55
  966. 016D: MOVLW 69
  967. 016E: MOVWF 56
  968. 016F: MOVLW 74
  969. 0170: MOVWF 57
  970. 0171: MOVLW 73
  971. 0172: MOVWF 58
  972. 0173: MOVLW 65
  973. 0174: MOVWF 59
  974. 0175: MOVLW 75
  975. 0176: MOVWF 5A
  976. 0177: MOVLW 51
  977. 0178: MOVWF 5B
  978. 0179: MOVLW 20
  979. 017A: MOVWF 5C
  980. 017B: MOVLW 65
  981. 017C: MOVWF 5D
  982. 017D: MOVLW 68
  983. 017E: MOVWF 5E
  984. 017F: MOVLW 54
  985. 0180: MOVWF 5F
  986. 0181: CLRF 60
  987. ....................
  988. .................... void send_string(int delay, char string[])
  989. .................... {
  990. .................... int i;
  991. ....................
  992. .................... /* send the string */
  993. .................... for(i=0; string[i] != '\0'; i++)
  994. *
  995. 00F6: CLRF 63
  996. 00F7: MOVF 62,W
  997. 00F8: ADDWF 63,W
  998. 00F9: MOVWF 04
  999. 00FA: MOVF 00,F
  1000. 00FB: BTFSC 03.2
  1001. 00FC: GOTO 109
  1002. .................... {
  1003. .................... lcd_putc(string[i]);
  1004. 00FD: MOVF 62,W
  1005. 00FE: ADDWF 63,W
  1006. 00FF: MOVWF 04
  1007. 0100: MOVF 00,W
  1008. 0101: MOVWF 64
  1009. 0102: MOVWF 65
  1010. 0103: CALL 0D2
  1011. .................... delay_ms(delay);
  1012. 0104: MOVF 61,W
  1013. 0105: MOVWF 6A
  1014. 0106: CALL 01C
  1015. .................... }
  1016. 0107: INCF 63,F
  1017. 0108: GOTO 0F7
  1018. .................... }
  1019. 0109: RETLW 00
  1020. ....................
  1021. .................... void send_string_reverse(int delay, char string[])
  1022. .................... {
  1023. .................... int i;
  1024. ....................
  1025. .................... /* send the string */
  1026. .................... for(i=14; i>=0; i--)
  1027. .................... {
  1028. .................... lcd_putc(string[i]);
  1029. .................... delay_ms(delay);
  1030. .................... }
  1031. .................... }
  1032. ....................
  1033. .................... int main(void)
  1034. 010A: CLRF 04
  1035. 010B: MOVLW 1F
  1036. 010C: ANDWF 03,F
  1037. 010D: MOVLW 07
  1038. 010E: MOVWF 1F
  1039. .................... {
  1040. .................... /* Init the Display */
  1041. .................... lcd_init(2);
  1042. *
  1043. 0182: MOVLW 02
  1044. 0183: MOVWF 61
  1045. 0184: CALL 06D
  1046. .................... /* Clear the screen */
  1047. .................... lcd_putc('\f');
  1048. 0185: MOVLW 0C
  1049. 0186: MOVWF 65
  1050. 0187: CALL 0D2
  1051. .................... /* Send the message */
  1052. .................... send_string(5, INITMESSAGE);
  1053. 0188: MOVLW 05
  1054. 0189: MOVWF 61
  1055. 018A: MOVLW 21
  1056. 018B: MOVWF 62
  1057. 018C: CALL 0F6
  1058. ....................
  1059. .................... /* Display on the first line after button press */
  1060. .................... while(lcd.button == 1)
  1061. .................... { }
  1062. 018D: BTFSC 06.3
  1063. 018E: GOTO 18D
  1064. .................... lcd_putc('\f');
  1065. 018F: MOVLW 0C
  1066. 0190: MOVWF 65
  1067. 0191: CALL 0D2
  1068. .................... send_string(1000, MESSAGE1);
  1069. 0192: MOVLW E8
  1070. 0193: MOVWF 61
  1071. 0194: MOVLW 31
  1072. 0195: MOVWF 62
  1073. 0196: CALL 0F6
  1074. ....................
  1075. .................... while(lcd.button == 1)
  1076. .................... { }
  1077. 0197: BTFSC 06.3
  1078. 0198: GOTO 197
  1079. .................... lcd_putc('\f');
  1080. 0199: MOVLW 0C
  1081. 019A: MOVWF 65
  1082. 019B: CALL 0D2
  1083. .................... /* New line */
  1084. .................... lcd_putc('\n');
  1085. 019C: MOVLW 0A
  1086. 019D: MOVWF 65
  1087. 019E: CALL 0D2
  1088. .................... send_string(5, MESSAGE2);
  1089. 019F: MOVLW 05
  1090. 01A0: MOVWF 61
  1091. 01A1: MOVLW 41
  1092. 01A2: MOVWF 62
  1093. 01A3: CALL 0F6
  1094. .................... /* Add delay for button debouncing */
  1095. .................... delay_ms(500);
  1096. 01A4: MOVLW 02
  1097. 01A5: MOVWF 61
  1098. 01A6: MOVLW FA
  1099. 01A7: MOVWF 6A
  1100. 01A8: CALL 01C
  1101. 01A9: DECFSZ 61,F
  1102. 01AA: GOTO 1A6
  1103. ....................
  1104. .................... /*wait for button press*/
  1105. .................... while(lcd.button == 1)
  1106. .................... { }
  1107. 01AB: BTFSC 06.3
  1108. 01AC: GOTO 1AB
  1109. .................... /* Re-initialise the display to scroll */
  1110. .................... lcd_init(3);
  1111. 01AD: MOVLW 03
  1112. 01AE: MOVWF 61
  1113. 01AF: CALL 06D
  1114. ....................
  1115. .................... while(1) {
  1116. .................... send_string(200, MESSAGE3);
  1117. 01B0: MOVLW C8
  1118. 01B1: MOVWF 61
  1119. 01B2: MOVLW 51
  1120. 01B3: MOVWF 62
  1121. 01B4: CALL 0F6
  1122. .................... }
  1123. 01B5: GOTO 1B0
  1124. ....................
  1125. .................... return 0;
  1126. 01B6: MOVLW 00
  1127. 01B7: MOVWF 78
  1128. .................... }
  1129. 01B8: SLEEP
  1130. Configuration Fuses:
  1131. Word 1: 3F58 NOWDT NOPUT NOPROTECT BROWNOUT NOMCLR NOLVP INTRC_IO NOCPD