Advertisement
Guest User

Untitled

a guest
Mar 28th, 2017
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.82 KB | None | 0 0
  1. /*********************************************************************************************
  2. * *
  3. * Nigel Johnson's Grand Universal Master Program (GUMP) for the FRDM-K64F board to *
  4. * show you how to access the LCD screen on the K64F board using 4-bit transfers *
  5. * *
  6. * This is version 2.0 dated 2017 03 05 *
  7. * *
  8. **********************************************************************************************
  9. Edit history
  10. 2017 02 22 NWJ converted to use on K64F
  11. 2011 01 25 NWJ changes and adds
  12. 2009 10 29 NWJ original program
  13. This program does the following:
  14.  
  15. Initialises the LCD screen
  16. Prints a welcome screen
  17. Outputs the data to the screen in hex format (each byte is two characters)
  18.  
  19. This may be useful for any future projects, such as the personal assignment for this course and Capstone!
  20.  
  21. LCD connections:
  22.  
  23. The LCD is connected to the K64F as follows:
  24.  
  25. PTC7 goes to LCD DB4, pin 11 of the LCD )
  26. PTC8 goes to LCD DB5, pin 12 of the LCD )
  27. PTC9 goes to LCD DB6, pin 13 of the LCD )
  28. PTC10 goes to LCD DB7, pin 14 of the LCD ) I know these assignments mean data will have to be shifted
  29. ) before storing, but that is life in the real world!
  30. PTC0 goes to LCD RS, pin 4 of the LCD )
  31. PTC2 goes to LCD E, pin 6 of the LCD )
  32. PTC1 goes to LCD R/-W, pin 5 of the LCD )
  33. ***********************************************************************************************/
  34. #include "MK64F12.h"
  35. #include "GUMP.h"
  36. #include "stdlib.h"
  37. #include "stdio.h"
  38. #include "String.h"
  39.  
  40. #define INIT 1 // arguments for the lcd routine
  41. #define UPDATE 2 //
  42.  
  43. char line1[]="";
  44. char line2[]="";
  45.  
  46. #pragma section m_data
  47.  
  48. char RAM_line1[16];
  49. char RAM_line2[16];
  50.  
  51. unsigned char a[16];
  52.  
  53. char *pointer;
  54. char temp;
  55. int char_Pos; // where we are in LCD line
  56. int dest;
  57. int i;
  58.  
  59.  
  60. void main(void)
  61. {
  62. while(1)
  63. {
  64. delay(2000); // Delay ~15-20 mS from power-up based on 8us delay
  65. pointer=strncpy(&RAM_line1[0],&line1[0],16); //Before we start, we copy down the intro screen from
  66. pointer=strncpy(&RAM_line2[0],&line2[0],16); // flash into the RAM buffer used for the LCD
  67. initPorts();
  68. lcd(INIT); // initialise the lcd for 4 line, 4 bit mode
  69. while(1)
  70. {
  71. randomise(); // create a 16 byte buffer with random data
  72. delay(10000); // this time way beyond spec but it seems to need it
  73. lcd(UPDATE); // output 4 lines of text
  74. delay(1000000); // give the user a chance to see turn-on banner
  75. lcd(UPDATE); // output 4 lines of text
  76. delay(1250); // wait 10 ms
  77. bubble(&a[0],16); // do a bubble sort
  78. ascii(); // copy the numbers and convert to ascii
  79. while(1){}; // Wait forever to leave display static after bubble finishes
  80. }
  81. }
  82. }
  83. /********************************************************************************
  84. *
  85. * LCD DRIVER
  86. *
  87. * All lcd contact done through this function.
  88. *
  89. * Calling convention:
  90. *
  91. * Type = 1, initialise the lcd for 4 line mode, 4 bit transfers
  92. * Type = 2, output 4 lines of text from buffer lline1,line2 etc
  93. *
  94. *************************************************************************************
  95. All accesses to the LCD must be done in pairs since we are in 4 bit mode and
  96. only the top 4 bits are connected to the LCD and used
  97. so: nothing can be in the lower nibble
  98. and: if we don't do it in pairs we will always be out by half a byte in following
  99. commands since the LCD will be waiting for a second write cycle
  100. *************************************************************************************/
  101. void lcd(int type)
  102. {
  103. if (type==INIT)
  104. {
  105. GPIOC_PCOR |= (1 << 0); // Clear RS to put in command mode
  106. GPIOC_PCOR |= (1 << 1); // drop R/W low
  107. e();
  108. /***************************************************************************
  109. *
  110. * First of all, send 0x30 three time to ensure chip is reset per data sheet
  111. *
  112. * The LCD based on the HD44780 will power up into 8 bit mode but
  113. * only the most significant bits of the device are connected to the K64F.
  114. * Fortunately, the reset and main functions are controlled in the upper bits
  115. *
  116. ***************************************************************************/
  117. GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
  118. GPIOC_PSOR |= (0x03 << 7); // Send command $03
  119. e();
  120. delay(513); // Delay 4.1 ms per data sheet
  121. GPIOC_PSOR |= (0x03 << 7); // Send command $03 again
  122. e();
  123. delay(13); // Delay 100 us per data sheet
  124. GPIOC_PSOR |= (0x03 << 7); // Send command $03 again
  125. e();
  126. GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
  127. delay(20);
  128. /**************************************************************************************************
  129. *
  130. * Then send 0x20. This is the last instruction that will be sent with the HD44780 in 8-bit mode.
  131. * This command will switch it into 4-bit mode. From here on, all bytes must be sent as 4-bit
  132. * nibbles, with an E pulse in between and after them,left shifted into the upper bits if necessary.
  133. *
  134. **************************************************************************************************/
  135. GPIOC_PSOR |= (0x02 << 7); // Command is 0x02 each nibble shifted left 7 bits
  136. e();
  137. GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
  138. delay(5); // Delay 40us (data sheet says 37us)
  139. /**************************************************************************************************
  140. *
  141. * Next send the command 0x28 which sets the display on and puts it into 2 line mode
  142. *
  143. **************************************************************************************************/
  144. GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
  145. GPIOC_PSOR |= (0x02 << 7); //
  146. e(); // Command is 0x28 each nibble shifted left 7 bits (function set)
  147. GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
  148. GPIOC_PSOR |= (0x08 << 7); //
  149. e(); // Command is 0x28 each nibble shifted left 7 bits (function set)
  150. GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
  151. /**************************************************************************************************
  152. *
  153. * Next send the command 0x0F which sets the display on and gives blinking cursor
  154. *
  155. **************************************************************************************************/
  156. GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
  157. e();
  158. GPIOC_PSOR |= (0x0F << 7); //
  159. e(); // Command is 0x0F each nibble shifted left 7 bits (function set)
  160. GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
  161.  
  162. /*************************************************************************************************
  163. *
  164. * Then send 0x01 to Clear display and set cursor to home position
  165. *
  166. **************************************************************************************************/
  167. GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
  168. e();
  169. GPIOC_PSOR |= (0x01 << 7); // Clear display and set cursor to location 0
  170. e(); // Command is 0x01 each nibble shifted left 7 bits (display on)
  171. GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
  172. delay(1250); // Delay 10ms per data sheet
  173. /*************************************************************************************************
  174. *
  175. * Next send command 0x0F
  176. *
  177. ************************************************************************************************/
  178. GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
  179. e();
  180. GPIOC_PSOR |= (0x0F << 7); //
  181. e();
  182. GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
  183. /*************************************************************************************************
  184. *
  185. * Now we set the Register Select line to go back into data mode. Anything sent from here on
  186. * will be 'painted' as a character on the display
  187. *
  188. *************************************************************************************************/
  189. GPIOC_PSOR |= (1 << 0); // Set RS to put in data mode
  190. /*************************************************************************************************/
  191. delay(200);
  192. }
  193. else if (type ==UPDATE)
  194. {
  195. out_Line(1);
  196. out_Line(2);
  197. }
  198. return;
  199. }
  200.  
  201. /*********************************************************************************/
  202. void initPorts()
  203. {
  204. SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK; //Enable Port C Clock Gate Control
  205. // PCR bit definitions:
  206. // 31 30 29 28 26 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  207. // <=Reserved R/O=====> ISF<Reserved=><===IRQC===> LK <=Reserved=><=MUX==><=R=>DSE ODE PFE Res SRE PE PS
  208. //
  209. // R = reserved
  210. // R/O = Read Only
  211. // ISF = interrupt status flag
  212. // IRQC = interrupt configuration
  213. // LK = Lock bits 15:0 cannot be changed until next reset
  214. // MUX = 000 Disabled
  215. // MUX = 001 Alt 0 (GPIO)
  216. // MUX = 010 to 111 Chip-specific
  217. // DSE = drive strength enable, 1= High drive strength
  218. // OPE = Open Drain Enable - removes upper driver transistor for pin
  219. // PFE = Passive Filter Enable
  220. // SRE = Slew Rate Enable
  221. // PE = Pull Enable - connects pull-up or pull-down resistor internally
  222. // PS = Pull Select - a 1 gives pull-up if PE is selected
  223. PORTC_PCR0 = 0x0100; // PORTC bit 0 is connected to LCD RS pin 4 : GPIO
  224. PORTC_PCR1 = 0x0100; // PORTC bit 1 is connected to LCD R/-W pin 5 : GPIO
  225. PORTC_PCR2 = 0x0100; // PORTC bit 2 is connected to LCD E pin 6 : GPIO
  226. PORTC_PCR3 = 0x0100; // PORTC bit 3 is connected to trigger for logic analyser : GPIO
  227. PORTC_PCR7 = 0x0100; // PORTC bit 7 is connected to LCD DB4 pin 11 : GPIO
  228. PORTC_PCR8 = 0x0100; // PORTC bit 8 is connected to LCD DB5 pin 12 : GPIO
  229. PORTC_PCR9 = 0x0100; // PORTC bit 9 is connected to LCD DB6 pin 13 : GPIO
  230. PORTC_PCR10 = 0x0100; // PORTC bit 10 is connected to LCD DB7 pin 14 : GPIO
  231. //
  232. // Bit map for general registers
  233. // 31 30 29 38 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  234. // 8 4 2 1 | 8 4 2 1 | 8 4 2 1 | 8 4 2 1 | 8 4 2 1 | 8 4 2 1 | 8 4 2 1 | 8 4 2 1
  235. //
  236. GPIOC_PDDR |= 0x078F; // Setting bits 10, 9, 8, 7, 3, 2, 1, 0 of Port C as Outputs
  237. return;
  238. }
  239. /*********************************************************************************/
  240.  
  241. void e(void) // send the E pulse to the lcd
  242. {
  243. delay(20);
  244. GPIOC_PSOR |= (1 << 2);
  245. delay(20);
  246. GPIOC_PCOR |= (1 << 2);
  247. delay(20);
  248.  
  249. return; // you have to write this!
  250. }
  251. /*********************************************************************************/
  252. void delay(int microsecs)
  253. {
  254. for(i = 0; i < microsecs; i++)
  255. {
  256. __asm("NOP");
  257. }
  258. return; // you have to write this!
  259. }
  260. /*********************************************************************************/
  261. void out_Line(int line)
  262. {
  263. switch (line)
  264. {
  265. case 1:
  266. GPIOC_PCOR |= (1 << 0); // access control register
  267. GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
  268. GPIOC_PSOR |= (0x08 << 7); // Command is 0x80 to move to line 1 column 0 shifted left 7 places
  269. e(); // This sends the upper nibble (0x8)
  270. GPIOC_PCOR |= (0xFF << 7); // Remove output just sent
  271. e(); // This sends the lower nibble (0x0)
  272. GPIOC_PSOR |= (1 << 0); // access data register, ready to send characters
  273. delay(20);
  274. pointer=&RAM_line1[0];
  275. goto common;
  276. case 2:
  277. GPIOC_PCOR |= (1 << 0); // access control register
  278. GPIOC_PSOR |= (0x0C << 7);
  279. e();
  280. GPIOC_PCOR |= (0x0F << 7); // Command is 0xC0 to move to line 1 column 0 shifted left 7 places
  281. e();
  282. GPIOC_PSOR |= (1 << 0); // access data register
  283. delay(20);
  284. pointer=&RAM_line2[0];
  285. goto common;
  286. common:
  287. for (char_Pos=0;char_Pos<16;char_Pos++)
  288. {
  289. // Process the byte to store one nibble at a time and write into data bits 7-4 of the LCD which are
  290. // connected to PORTC bits 10 - 7
  291. //
  292. temp = pointer[char_Pos]; // Get byte to process first nibble
  293. temp &= 0xF0; // Get the upper nibble only
  294. GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
  295. GPIOC_PSOR |= (temp << 3); // MSB already in bit 7, therefore only needs to be shifted 3 to left
  296. e(); // Note: Temp is an 8 bit value, and we only need to output 4 bits of it
  297. // Upper nibble will go into bits 10 - 7, lower nibble will go into bit 6-3
  298. // Normally we would not interfere with the wrong bits, but we know that these
  299. // bits are not use in this register. This is lazy programming and may lead to
  300. // bugs later. We must AND off the lower nibble before writing to PORTC
  301. GPIOC_PCOR |= (0x0F << 7); //delete nibble
  302.  
  303. // Now process the second nibble
  304. temp = pointer[char_Pos]; // Get byte to process second nibble
  305. GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
  306. temp <<= 4;
  307. temp &= 0xF0; // Make sure we only have the upper nibble
  308. GPIOC_PSOR |= (temp << 3); // MSB already in bit 7, therefore only needs to be shifted 3 to left
  309. e();
  310. GPIOC_PCOR |= (0x0F << 7); // delete nibble
  311. delay(20); // manual says wait 40us after sending a character
  312. // 160 used as an experiment when that didn't work!
  313. }
  314. }
  315. }
  316. /*********************************************************************************/
  317. void bubble(unsigned char a[],int n) // you have to write this!
  318. {
  319.  
  320.  
  321. for(int i = 0; i < (n-1); i++)
  322. {
  323. for(int t = 0; t < (n - t - 1); t++)
  324. {
  325. if(a[t] > a[t+1])
  326. {
  327. swap(a[t], a[t+1]);
  328. }
  329. ascii();
  330. lcd(UPDATE);
  331. }
  332. }
  333.  
  334. }
  335. /*********************************************************************************/
  336. void swap (unsigned char *px, unsigned char *py) // you have to write this! - it is called from bubble
  337. {
  338. char temp = &px;
  339. px = &py;
  340. py = temp;
  341. }
  342. /*********************************************************************************/
  343. void randomise(void) // you have to write this!
  344. {
  345. char r = 0;
  346. for(int g = 0; i < 16; g++)
  347. {
  348. a[g] = rand();
  349. }
  350.  
  351.  
  352. }
  353. /*********************************************************************************/
  354. void ascii(void) // this function takes the binary values in the 16 bytes
  355. // of a[], converts each byte into two right-justified
  356. // nibbles, converts them into ASCII, and stores them
  357. // in the 2 x 16 LCD buffer
  358. {
  359.  
  360. int lo,hi;
  361.  
  362.  
  363. for(i=0;i<8;i+2) // process data for first line of lcd
  364.  
  365. {
  366.  
  367. lo = a[i] & 0x0f;
  368. hi = (a[i] >> 4) & 0x0f;
  369. line1[i]= lo;
  370. line1[i+1] = hi;
  371. lcd(UPDATE);
  372. }
  373.  
  374. for(i=8;i<16;i+2) // process data for second line of lcd
  375. {
  376.  
  377. lo = a[i] & 0x0f;
  378. hi = (a[i] >> 4) & 0x0f;
  379. line2[i] = lo;
  380. line2[i+1] = hi;
  381. lcd(UPDATE);
  382. }
  383.  
  384.  
  385. }
  386. ////////////////////////////////////////////////////////////////////////////////
  387. // EOF
  388. ////////////////////////////////////////////////////////////////////////////////
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement