Advertisement
Guest User

RX problems

a guest
Sep 22nd, 2010
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 24.09 KB | None | 0 0
  1. //********************************************************************
  2. // Data Acquisition Code for PIC18F4580 Microchip Microprocessor.
  3. // Controls acquiring data from sensors, writing the data to an SD
  4. // card for storage, and communicating with a Zigbee IEEE802.15
  5. // wireless module to send the data to a computer base station for near
  6. // real-time monitoring.
  7. //********************************************************************
  8.  
  9. //* T O - D O   L I S T **********************************************
  10. //
  11. //      -implement interrupt service functions
  12. //          -Set flags and deal with them in main
  13. //      -rewrite main to handle the flags
  14. //      -if send buffer is sufficiently empty, fill it with more data
  15. //          -else, start loop over
  16. //********************************************************************
  17.  
  18. //* D I S C U S S I O N **********************************************
  19. // Transmit interrupt cannot be enabled right away. If there is no
  20. // data to send then the transmit interrupt will always be active,
  21. // getting us caught in an interrupt loop.
  22. //
  23. // Solution: Enable the interrupt each time data is added to the send
  24. // buffer, and disable the interrupt after the last byte has been sent
  25. // (curpos == endpos)
  26. //********************************************************************
  27.  
  28.  
  29.  
  30. /** C O N F I G U R A T I O N   B I T S ******************************/
  31.  
  32. //Configuration bits set in MPLAB for now, will put them in code later
  33.  
  34.  
  35. /** I N C L U D E S **************************************************/
  36. #include "p18f4580.h"
  37. #include "delays.h"
  38. #include "stdio.h"
  39.  
  40. /** D E F I N E S ****************************************************/
  41. //   NAME REGISTER.BIT
  42. #define TRMT TXSTAbits.TRMT
  43. //#define BRGH TXSTAbits.BRGH
  44. //#define BRG16 BAUDCONbits.BRG16
  45. #define SPEN RCSTA.7
  46. #define CREN RCSTAbits.CREN
  47. #define ADPins 5
  48. #define USED_AD_PINS 5
  49. #define LED_ERROR PORTCbits.RC2
  50.  
  51. /** S C R E E N   D E F I N E S **************************************/
  52.  
  53. #define E LATCbits.LATC5
  54. #define RW LATCbits.LATC4
  55. #define RS LATCbits.LATC3
  56. #define DATA PORTD
  57.  
  58.  
  59. /** P R O T O T Y P E S **********************************************/
  60.  
  61. void sdINIT();
  62. void uartINIT();
  63. void sdWritePacket(unsigned char packetType, unsigned char data);
  64. void sdHandshake(static unsigned char signalID);
  65. void rxEnable();
  66. void adINIT();
  67. void adCalculate();
  68. void pinSwitch(unsigned char pin);
  69. void lcdINIT();
  70. void writeScreen(unsigned char data[], int length);
  71. unsigned char dataSend(unsigned char arr[]);
  72. void ERRORCODE(int x);
  73. void alertRED();
  74. void alertGREEN();
  75. void prepareDataToSend(static char signalID, static unsigned int time, static unsigned char bufferInput);
  76. void addToBuffer(static unsigned char bufferInput);
  77. char numToASCII(static unsigned char num);
  78. void *makeString(static unsigned int toString);
  79. char makeDigit(static unsigned int *digit, static unsigned int base);
  80. void globalInterruptINIT();
  81. void RXInterruptINIT();
  82. void TXInterruptINIT();
  83.  
  84.  
  85. /** D A T A   B U F F E R S   A N D   F L A G S **********************/
  86.  
  87. #pragma udata buffer                // buffer is declared to be the 5th bank.
  88. static unsigned char TXBuffer[128]; //This space is allocated just for the stuff listed here.
  89. static unsigned char bufferInput;
  90. static unsigned char signalID;
  91. static unsigned char num;
  92. static unsigned int *digit;
  93. static unsigned int base;
  94. static unsigned int toString;
  95.  
  96. #pragma idata
  97. static unsigned char TXCurrentPos = 0x00;   //after sending a byte, increment the curpos by 1
  98. static unsigned char TXEndPos = 0x00;       //after adding a byte to the buffer, increment the endpos
  99. static unsigned int i = 0x00;
  100.  
  101. static unsigned char ByteReceived = 0x00;       // Set in the interrupt so it can be passed to main
  102.                                                 // After main reads it, main should clear it
  103.  
  104. static unsigned char countdown = 0x01;          //Initally set to '1' so the auto baud byte gets sent.
  105.  
  106. static unsigned char waitingForACK = 0;
  107. static unsigned char currentlySendingHandshake = 0; //If 1 then we're sending handshake
  108.                                                     //else we're sending data
  109. static unsigned int time = 0x0000;
  110.  
  111. /** D E C L A R A T I O N S *****************************************
  112.  
  113. //creates a two dimensional array used to store the pins[pinA][data1][data2]
  114. //and their AD values.                                  [pinB][data1][data2]
  115. unsigned char DATA_ARRAY[USED_AD_PINS][3];
  116.  
  117. //size counts the size of the array we will be sending to the SD card
  118. //each time we do. This will be used in the handshake to tell the SD
  119. // module the number of bytes to expect. If we make any changes to the
  120. // packet scheme this will need to be changed.
  121. unsigned char size = USED_AD_PINS * 3;
  122.  
  123. **********************************************************************/
  124.  
  125.  
  126. /** I N T E R R U P T S **********************************************/
  127.  
  128. #pragma interrupt InterruptVectorHigh
  129. void InterruptVectorHigh(void){
  130.    
  131.  
  132.     if(PIR1bits.RCIF == 1){
  133.    
  134.         ByteReceived = RCREG;
  135.        
  136.         if(waitingForACK == 1){ //if we're waiting for ACK..
  137.             if(ByteReceived == 0x06){ //and we get ACK
  138.                 currentlySendingHandshake = ~currentlySendingHandshake;
  139.                
  140.                 if(currentlySendingHandshake == 1){
  141.                     countdown = 13;     //Send the 13 bytes needed for the handshake.
  142.                 }
  143.    
  144.                 if(currentlySendingHandshake == 0){
  145.                    
  146.                     countdown = 13;     //Send the thirteen bytes we want to write the sd card.
  147.                 }
  148.                
  149.                 if((TXEndPos - TXCurrentPos) > 0){
  150.                     PIE1bits.TXIE = 1;      //Finally reenable TX INT.
  151.                 }                           //if there is data to send
  152.                
  153.                 waitingForACK = 0;          //we're no longer waiting for ACK
  154.             }
  155.         }
  156.     }
  157.    
  158.     else if (PIR1bits.TXIF == 1){
  159.    
  160.         if((TXEndPos - TXCurrentPos) > 0){                          // if there is data in the buffer
  161.             TXREG = TXBuffer[TXCurrentPos];             // send next byte
  162.             TXCurrentPos = TXCurrentPos + 0x01;         // update to the new position
  163.                                    
  164.             if(TXCurrentPos == 128){
  165.                 TXCurrentPos = 0;
  166.             }
  167.             countdown--;                               
  168.         }
  169.        
  170.         if(countdown == 0){
  171.             waitingForACK = 1; //we're now waiting for ack
  172.             PIE1bits.TXIE = 0; //stop sending data until we get ack
  173.         }
  174.        
  175.         if((TXEndPos - TXCurrentPos) == 0){
  176.             PIE1bits.TXIE = 0; // If we run out of data in the buffer
  177.                                // pause TX
  178.         }
  179.     }
  180. }
  181.  
  182. #pragma interruptlow InterruptVectorLow
  183. void InterruptVectorLow(void){
  184.  
  185.  
  186.  
  187. }
  188.  
  189.  
  190. /** M A I N ***********************************************************/
  191.  
  192. #pragma code
  193.  
  194. void main (void){
  195.    
  196.     //Reset sd card module.
  197.     TRISD = 0x00;          
  198.     LATDbits.LATD3 = 0;     // Pull RD3 'low', which will activate the reset on the sd card module.
  199.     Delay10KTCYx(10);      
  200.     LATDbits.LATD3 = 1;     // Pull RD3 'high', activating the sd card module.
  201.  
  202.     uartINIT();
  203.     rxEnable();
  204.     globalInterruptINIT();
  205.     TXInterruptINIT();
  206.     RXInterruptINIT();
  207.    
  208.     Delay10KTCYx(100);      // Delay a while to give the SD card some time
  209.    
  210.     sdINIT();               // Send the auto baud bit.
  211.    
  212.    
  213.     //Loop to add data to the buffer. Increments the time and
  214.     //signal data so we can make sure everything is getting
  215.     //written to the sd card.
  216.     bufferInput = 0x0000;
  217.     for(time; time < 0x004; time++){
  218.         prepareDataToSend(0x10, time, bufferInput);
  219.         bufferInput = bufferInput + 0x0013;
  220.     }
  221.    
  222.     alertRED(); // Turn red LED on when all data has been put in buffer
  223.     while(1){
  224.        
  225.         if((TXEndPos - TXCurrentPos) == 0){
  226.             LATDbits.LATD1 = 1;
  227.         } //if the buffer is empty turn on the green LED
  228.        
  229.     }
  230.    
  231.     //We can hook up the Oscilloscope to the red and green lights
  232.     //to time how long it takes for all the data to transfer
  233.     //and get our bit rate
  234.    
  235.  
  236. }
  237.  
  238. //*********************************************************************
  239. // sdINIT is called at power on to set up and initialize the SD module
  240. //
  241. // Notes:
  242. //    * After supplying power to the SD module, 500ms wait time must be
  243. //      given before sending or receiving data. During this time the SD
  244. //      module may throw off junk data so RX should be disabed on the
  245. //      PIC.
  246. //    * A single character 'U' is sent over the serial interface so
  247. //      that the SD module can determine the PIC's baud rate. If the
  248. //      character was received successfully, then the module will return
  249. //      the ACK byte (06hex)
  250. //    * After receiving the ACK, the SD module is ready to receive Disk
  251. //      Drive commands from the host PIC as specified in the
  252. //      GOLDELOX-DOS-COMMANDS pdf.
  253. //*********************************************************************
  254. void sdINIT(){
  255.     addToBuffer(0x55);
  256. }
  257.  
  258. //*********************************************************************
  259. // addToBuffer adds a packet of data to the send buffer.
  260. // toAdd[] = signalID, time3time2time1time0, data3data2data1data0, /n
  261. void prepareDataToSend(static char signalID, static unsigned int time, static unsigned char bufferInput){
  262.  
  263.     sdHandshake(signalID);
  264.    
  265.     addToBuffer(numToASCII(signalID)); //convert the hex value to ascii
  266.     addToBuffer(0x2C);                 //add a comma
  267.     makeString(time);                  //makeString adds to buffer
  268.     addToBuffer(0x2C);
  269.     makeString(bufferInput);
  270.     addToBuffer(0x2C);
  271.     addToBuffer(0x0A);
  272.  
  273. }
  274.  
  275. void addToBuffer(static unsigned char bufferInput){
  276.  
  277.     TXBuffer[TXEndPos] = bufferInput;
  278.     TXEndPos = TXEndPos + 0x01;
  279.     if(TXEndPos == 128){
  280.         TXEndPos = 0;
  281.     }
  282.    
  283.     if(waitingForACK == 0){
  284.         PIE1bits.TXIE = 1;      //Enable the TX interrupt
  285.     }                           //If we're not waiting for ack
  286.    
  287. }
  288.  
  289. char numToASCII(static unsigned char num){
  290.  
  291.     return (num + 0x30);
  292.  
  293. }
  294.  
  295. //*********************************************************************
  296. // This function handles the handshaking with the SD module. It's tasks
  297. // include sending handshaking packet to the SD module and confirming
  298. // receipt.
  299. //
  300. // Packet Structure:
  301. // * 40 74 80 [filename; 1 - 12 bytes] 00 [packet size; 4 bytes]
  302. //
  303. // Packet example:
  304. // Write 50 byte of data to the file ABCD in append mode:
  305. // * 40 74 80 41 42 43 44 00 00 00 00 32
  306. //  
  307. // After sending the above packet, the SD module should send back 0x06.
  308. // If it doesn't try sending the packet again. If it does, return.
  309. //
  310. // Notes:
  311. //    * Currently supports block sizes of up to 255 bytes. For larger
  312. //      sizes, the function should accept an integer and use masking
  313. //      and shifting to break the integer into four characters that can
  314. //      easily be sent to the SD card. Since we shouldn't get anywhere
  315. //      near 255 bytes, I'm opting to keep the code simpler for now.
  316. //  
  317. //*********************************************************************
  318. void sdHandshake(static unsigned char signalID){
  319.  
  320.     unsigned char arr[13] = {0x40, 0x74, 0x88, signalID, 0x2E, 0x63,
  321.                             0x73, 0x76, 0x00, 0x00, 0x00, 0x00, 0x0D};
  322.    
  323.     i = 0x00;
  324.     for(i = 0; i < 13; i=i+0x01){
  325.         addToBuffer(arr[i]);
  326.     }
  327.    
  328. }
  329.  
  330. //**********************************************************************
  331. // makeDigit and makeString is an awesome hackjob to get around the fact
  332. // that the PIC18 ISA doesn't include a DIV instruction, and thus DIVs
  333. // suck balls. Given the number 345, you will need to subtract 100 3
  334. // times until that number is less than 100
  335. //**********************************************************************
  336. char makeDigit(static unsigned int *digit, static unsigned int base){
  337.  
  338.     int count;
  339.    
  340.     for(count = 0; *digit >= base; count++){
  341.         *digit -= base;
  342.     }
  343.    
  344.     return count;
  345.        
  346. }
  347.  
  348. void *makeString(static unsigned int toString){
  349.  
  350.     addToBuffer(numToASCII(makeDigit(&toString, 1000)));
  351.     addToBuffer(numToASCII(makeDigit(&toString, 100)));
  352.     addToBuffer(numToASCII(makeDigit(&toString, 10)));
  353.     addToBuffer(numToASCII(makeDigit(&toString, 1)));
  354.  
  355. }
  356.  
  357. //*********************************************************************
  358. // uartINIT is called at power on to set up the UART bus to communicate
  359. // with the SD module.
  360. //
  361. // Notes:
  362. //    * The UART bus operates on the PORTC block.
  363. //    * To initialize the bus, SPEN(RCSTA7) and TRISC7 must be set to
  364. //      1, while TRISC6 must be cleared to 0.
  365. //    * The configuration of the UART bus is configured through the
  366. //      TXSTA, RCSTA, and BAUDCON registers as defined on pages 230-233
  367. //      in the PIC18F4580 specification sheet.
  368. //*********************************************************************
  369. void uartINIT(){
  370.     //LATCbits.LATD7 = 1;
  371.     //LATCbits.LATD6 = 0;
  372.    
  373.     TXSTA = 0b00100110;
  374.     RCSTA = 0b10010000;
  375.     BAUDCON = 0b01001000;
  376.    
  377.     //SPEN = 1; //serial port enable
  378.     //TXEN = 1; //transfer enable
  379.     //GIE = 1; //global interrupt enable
  380.     //PEIE = 1; //peripheral interrupt enable
  381.     //TXIE = 1; //transfer interrupt enable
  382.    
  383.     //The following lines set the baud rate
  384.     //BRGH = 1; //BRGH
  385.     //BRG16 = 1; //BRG16
  386.     SPBRGH = 0; //SPBRG values can be taken from the PIC Spec sheet
  387.     SPBRG = 86; //dependant on your desired baud rate and Fosc.
  388.     // in this case we are aiming for a baud rate of 115.2k, with an
  389.     // actual rate of 114.943k, giving a low error rate of .22%.
  390.     // 115.2k falls within the SD modules accepted range of 300 - 256k.
  391.     // These values assume that BRGH and BRG16 values are set.
  392.    
  393. }
  394.  
  395. //*********************************************************************
  396. // Enables Interrupts
  397. //*********************************************************************
  398. void globalInterruptINIT(){
  399.  
  400.     INTCONbits.GIE = 1; //global interrupt enable
  401.    
  402.     INTCONbits.PEIE = 1; //peripheral interrupt enable
  403.     RCONbits.IPEN = 1; // Priority levels enabled; two priority level
  404.    
  405. }
  406.  
  407. void RXInterruptINIT(){
  408.  
  409.     PIR1bits.RCIF = 0; //Ensure that the flag is cleared
  410.     PIE1bits.RCIE = 1; //Enable EUSART RX interrupt
  411.     IPR1bits.RCIP = 0; //RX priority low
  412.  
  413. }
  414.  
  415. void TXInterruptINIT(){
  416.  
  417.     PIR1bits.TXIF = 0; //Ensure that the flag is cleared
  418.     PIE1bits.TXIE = 0; //Cant start interrupt right away.See discussion
  419.     IPR1bits.RCIP = 0; //TX priority low
  420.  
  421. }
  422.  
  423. //*********************************************************************
  424. // Checks flags to determine which interrupt triggered the interrupt
  425. // vector. Because we want to spend as little time in the interrupt as
  426. // possible, we will simply set our own private global flag and deal
  427. // with the interrupt in main
  428. //*********************************************************************
  429.  
  430.  
  431. void InterruptServiceHigh(){
  432.  
  433.     //Currently no high level interrupts
  434.     //will eventually be used for ADC interrupts
  435.  
  436. }
  437.  
  438.  
  439. //*********************************************************************
  440. // This function writes data to the SD card by sending commands and
  441. // data to the SD module. This method should call a submethod to do the
  442. // handshaking and packet management with the SD module first, and then
  443. // continue on to send the data after the handshaking is complete.
  444. //
  445. // Notes:
  446. //    * Handshaking is done in a seperate function.
  447. //    * variables passed in need to cover at least the data type, the
  448. //      time when the data occured, and the data itself.
  449. //    * There could be a subfunction that catches the data sent to this
  450. //      function and stores it in an array until a predetermined size
  451. //      reached, at which time the buffer would flush all at once. This
  452. //      is what the Cornell team did with a buffer size of 50.
  453. //    * When writing integer values to the register, they should be
  454. //      converted to binary values and there whould be no problems as
  455. //      the decimal values are less that 1023. For now I am working
  456. //      under this assumption.
  457. //*********************************************************************
  458. void sdWritePacket(unsigned char packetType, unsigned char data){
  459.     unsigned char arr[] = {packetType, data};
  460.  
  461. }
  462.  
  463.  
  464. //*********************************************************************
  465. // This function takes an array of characters and loads them to the
  466. // TXREG register for sending on the USART bus. Data that is in the
  467. // TXREG register is emptied one bit at a time into the transmit
  468. // register. When the register is empty the TRMT flag is set to 1 and
  469. // the next byte can be loaded. When a byte is loaded into the TXREG
  470. // register, it is immidiately sent as long as TXEN bit is set.
  471. // Currently this will catch the program and wait until the current
  472. // packet has finished sending until returning to main. If this takes
  473. // too long then this will be a problem. Options to fix that include
  474. // increasing the baud rate closer to 256k (the SD module's maxiumum),
  475. // or using interrupts to come back to this stage every time TXREG
  476. // clears. This would be the best option as the program could queue up
  477. // packets as it is sending, ensuring that as soon as one packet is
  478. // finished, another is ready to be sent. But I'm rambling now, so..
  479. //*********************************************************************
  480. unsigned char dataSend(unsigned char arr[]){
  481.     int count;
  482.     int x = sizeof(arr);
  483.     for(count = 0; count < x; count++){
  484.         while(TRMT == 0){
  485.                
  486.         }
  487.         TXREG = arr[count];
  488.         TRMT = 0;
  489.     }
  490. }
  491.  
  492. //*********************************************************************
  493. // This method sends the handshake packet to the SD module and listens
  494. // for 0x06 after the send is complete. Currently the loop is hard
  495. // coded for 12 bytes because tat is the size of the packet. This
  496. // allows for filenames of 4 characters. For a longer or shorter
  497. // filename the number in the loop will have to be changed.
  498. //*********************************************************************
  499. unsigned char handshakeSend(unsigned char arr[]){
  500.     int count;
  501.     for(count = 0; count < 12; count++){
  502.         while(TRMT == 0){
  503.             //while already transmitting, wait
  504.         }
  505.        
  506.         //Then we can send the next byte
  507.        
  508.         TXREG = arr[count];
  509.         TRMT = 1; //Set TRMT to 1. Will clear automagically
  510.     }
  511.  
  512. }
  513.  
  514.  
  515.  
  516. //*********************************************************************
  517. // This function enables receiving data on the USART bus. This is in a
  518. // seperate function because during the first 500ms of the SD module
  519. // starting it may throw off junk data.
  520. //*********************************************************************
  521. void rxEnable(){
  522.     CREN = 1;
  523. }
  524.  
  525.  
  526. //*********************************************************************
  527. // This function initializes the analog to digital converter block
  528. // (A/D).
  529. // Configuration of the A/D block is done in three registers:
  530. // * ADCON0 - controls the operation, so will be used to select from
  531. //            which pin the voltage should be read
  532. // * ADCON1 - configures the functions on the port pins
  533. // * ADCON2 - configures the A/D clock source, acquisition time, and
  534. //            justification.
  535. //
  536. // The holding capacitor must be given time to charge to the sensor's
  537. // voltage level, with the time needed varying depending on the
  538. // impedance of the sensor, the voltage the PIC is running at, and the
  539. // impedance of the wire. This is something that will have to be
  540. // determined once we have the sensors in hand
  541. //
  542. // Notes:
  543. //    * The A/D block has pins primarily on the A block, and are
  544. //      desiganted by ANx on the pin diagram
  545. //    * The last four bits on ADCON1 select which pins (AN0 - 10)
  546. //      should be configured as analog inputs. 0000 means that they are
  547. //      all analog inputs, but this may not be desired. We may wish to
  548. //      use them as digital I/O pins instead
  549. //    * Bits 4 and 3 of ADCON1 select the pic as the voltage reference
  550. //      source if cleared, otherwise pins AN3:4 are used as reference
  551. //*********************************************************************
  552.  
  553. void adINIT(){
  554.    
  555.     ADCON1 = 0b00000000;
  556.     ADCON2 = 0b10101010;
  557.  
  558. }
  559.  
  560.  
  561. //*********************************************************************
  562. // This function controls the A/D block to grab values from all of the
  563. // sensors in order and store their values in an array to later use to
  564. // build and send a data packet to the peripherals. The results from
  565. // the conversion are stored in the registers ADRESH and ADRESL in the
  566. // form 000000XX | XXXXXXXX, where ADRESH is the first byte and ADRESL
  567. // is the second.
  568. //
  569. // Notes:
  570. //    * It should be configured so that after setting Go_Done there is
  571. //      some wait time before the actual conversion occurs, and enough
  572. //      wait time for the conversion to fully finish.
  573. //    * For the greatest accuracy, the processor must go into sleep
  574. //      mode during conversion. I'm unsure if this is done
  575. //      automatically when the conversion starts or if it must be put
  576. //      to sleep manually
  577. //*********************************************************************
  578.  
  579. void adCalculate(){
  580.     unsigned char pinNumber;
  581.     for(pinNumber = 0x00; pinNumber <= 0x0a; pinNumber = (pinNumber + 0x01)){
  582.         pinSwitch(pinNumber);
  583.         ADCON0bits.GO_DONE = 1;     //start AD conversion
  584.         //saveDataToArray(pinNumber);
  585.        
  586.        
  587.     }
  588.    
  589. }
  590.  
  591.  
  592. //*********************************************************************
  593. // This method changes the register ADCON0 to indicate the desired
  594. // pin on which we wish to perform an AD conversion. The position
  595. // should be kept track of in a for loop in the parent function and
  596. // passed in as a parameter.
  597. //*********************************************************************
  598. void pinSwitch(unsigned char pinNumber){
  599.         unsigned char temp;
  600.         temp = ADCON0;              //read
  601.         temp &= 0xc3;                //clear
  602.         temp |= (pinNumber << 2);   //mask and shift
  603.         ADCON0 = temp;              //write
  604. }
  605.  
  606.  
  607. //*********************************************************************
  608. // This function initializes the LCD screen by sending initialization
  609. // characters or something
  610. //*********************************************************************
  611.  
  612. void lcdINIT(){
  613.     unsigned char arr[6] = {0x38, 0x0c, 0x01, 0x06, 0x02, 0x01};
  614.     TRISD = 0x00;
  615.     TRISCbits.TRISC5 = 0;
  616.     TRISCbits.TRISC4 = 0;
  617.     TRISCbits.TRISC3 = 0;
  618.     LATDbits.LATD5 = 0;
  619.     LATDbits.LATD4 = 0;
  620.     LATDbits.LATD3 = 0;
  621.     Delay10KTCYx(1000);
  622.     DATA = 0b00111000; //functionSet
  623.     Delay100TCYx(1);
  624.     E=1;
  625.     Delay1KTCYx(2);
  626.     E=0;
  627.     Delay1KTCYx(5);
  628.  
  629.     DATA = 0b00001100; //Display On/Off
  630.     Delay100TCYx(1);
  631.     E=1;
  632.     Delay1KTCYx(2);
  633.     E=0;
  634.     Delay1KTCYx(5);
  635.  
  636.     DATA = 0b00000001; //Clear Display
  637.     Delay100TCYx(1);
  638.     E=1;
  639.     Delay1KTCYx(2);
  640.     E=0;
  641.     Delay1KTCYx(65);
  642.  
  643.     DATA = 0b00000110; //EntrySet
  644.     Delay100TCYx(1);
  645.     E=1;
  646.     Delay1KTCYx(2);
  647.     E=0;
  648.     Delay1KTCYx(5);
  649.  
  650.     DATA = 0b00000010; //Return home
  651.     Delay100TCYx(1);
  652.     E=1;
  653.     Delay1KTCYx(2);
  654.     E=0;
  655.     Delay1KTCYx(65);
  656.  
  657.     DATA = 0x01; //registerset
  658.     Delay100TCYx(1);
  659.     E=1;
  660.     Delay1KTCYx(2);
  661.     E=0;
  662.     Delay1KTCYx(0);
  663.     LATCbits.LATC3 = 1;
  664. }
  665.  
  666.  
  667. //*********************************************************************
  668. // This function writes data to the screen by setting the RD pins to
  669. // the data and toggling the enable pin.
  670. //*********************************************************************
  671.  
  672. void writeScreen(unsigned char data[], int length){
  673.     int count = 0;
  674.     for(count = 0; count < length; count++){
  675.         LATD = data[count];
  676.         Delay1KTCYx(1); //delay .1ms @ 10Mhz
  677.         E = 1;
  678.         Delay1KTCYx(1);   //delay .1ms @ 40mhz
  679.         E = 0;
  680.         Delay1KTCYx(1);    //delay .1ms @ 40mhz
  681.     }
  682. }
  683.  
  684.  
  685.  
  686. //*********************************************************************
  687. // This function will flash an LED attached to an unused pin in case
  688. // an error occurs and a message is not able to be printed to the LCD
  689. // screen, or the LCD screen never gets implemented. This function will
  690. // flash an LED on or off every .1 seconds a specified number of times,
  691. // and then leave a one second pause before starting to flash again.
  692. // The number of flashes could be counted and referenced in the code
  693. // or later a PDF to find out what went wrong. For example, one error
  694. // code could be used to indicate that there is no SD card in the
  695. // SD module. If the LCD screen is working, it could be used to display
  696. // additional information related to the error, and then the primary
  697. // reason for the LED would be to attract attention to the error.
  698. //*********************************************************************
  699. void ERRORCODE(int x){
  700.     int count;
  701.     TRISD = 0b00000000;
  702.     while(1){
  703.         for(count = 0; count < x; count++){
  704.             LATDbits.LATD1 = 1;
  705.             Delay10KTCYx(10);
  706.             LATDbits.LATD1 = 0;
  707.             Delay10KTCYx(10);
  708.         }
  709.        
  710.         Delay10KTCYx(200);
  711.     }
  712. }
  713.  
  714. void alertRED(){
  715.     TRISD = 0b00000000;
  716.     LATDbits.LATD0 = ~LATDbits.LATD0;
  717.     Delay10KTCYx(10);
  718. }
  719.  
  720. void alertGREEN(){
  721.     TRISD = 0b00000000;
  722.     LATDbits.LATD1 = ~LATDbits.LATD1;
  723.     Delay10KTCYx(10);
  724. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement