Advertisement
Guest User

DMX_Transmitter_For_PIC24FJ64GA002

a guest
Jul 11th, 2012
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.98 KB | None | 0 0
  1. /******************************************************************************/
  2. /* Files to Include                                                           */
  3. /******************************************************************************/
  4.  
  5. /* Device header file */
  6. #if defined(__PIC24E__)
  7.     #include <p24Exxxx.h>
  8. #elif defined(__PIC24F__)
  9.     #include <p24Fxxxx.h>
  10. #elif defined(__PIC24H__)
  11.     #include <p24Hxxxx.h>
  12. #endif
  13.  
  14. _CONFIG1(JTAGEN_OFF & GCP_OFF & GWRP_ON & BKBUG_ON & ICS_PGx1
  15.         & FWDTEN_OFF & WINDIS_ON & FWPSA_PR32 & WDTPS_PS32768);
  16. _CONFIG2(IESO_ON & WUTSEL_LEG & SOSCSEL_SOSC & FNOSC_FRCPLL
  17.         & FCKSM_CSDCMD & OSCIOFNC_ON & IOL1WAY_OFF & I2C1SEL_PRI & POSCMOD_NONE);
  18.  
  19.  
  20. #include <stdint.h>        /* Includes uint16_t definition                    */
  21. #include <stdbool.h>       /* Includes true/false definition                  */
  22.  
  23. #include "system.h"        /* System funct/params, like osc/peripheral config */
  24. #include "user.h"          /* User funct/params, such as InitApp              */
  25.  
  26. /******************************************************************************/
  27. /* Global Variable Declaration                                                */
  28. /******************************************************************************/
  29.  
  30. // Define DMX values here
  31. //uint8_t dmx_values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  32. #define START_BYTE 0
  33. #define TOP_R 0
  34. #define TOP_G 255
  35. #define TOP_B 0
  36.  
  37. #define BOT_R 0
  38. #define BOT_G 255
  39. #define BOT_B 255
  40.  
  41. #define R 0
  42. #define G 1
  43. #define B 2
  44.  
  45. uint8_t dmx_values[] = {0, 255, 255, TOP_R, TOP_G, TOP_B, BOT_R, BOT_G, BOT_B, 0, 0, 0};
  46.  
  47. uint8_t dmx_rotation[][3][3] = {
  48.     {
  49.         {255, 0, 0},
  50.         {0, 255, 0},
  51.         {0, 0, 255}
  52.     },
  53.     {
  54.         {125, 0, 125},
  55.         {0, 0, 0},
  56.         {125, 0, 125}
  57.     },
  58.     {
  59.         {0, 0, 255},
  60.         {0, 255, 0},
  61.         {255, 0, 0}
  62.     }
  63. };
  64.  
  65. uint16_t num_dmx_rot = sizeof(dmx_rotation)/(9*sizeof(uint8_t));
  66. #define NEXT(val) ((val == num_dmx_rot-1) ? 0 : val+1)
  67. #define PREV(val) ((val == 0) ? num_dmx_rot-1 : val-1)
  68.  
  69. uint16_t rot_counter = 0;
  70. uint8_t rot_update = 0;
  71. uint8_t rot_period_c = 0;
  72. uint16_t counter = 0;
  73. uint16_t dmx_progress = 0;
  74. uint16_t num_dmx_values = sizeof(dmx_values)/sizeof(uint8_t);
  75. uint8_t break_sent = 0;
  76.  
  77. uint16_t voltage = 0;
  78. uint8_t value = 0;
  79.  
  80. /****************************************************************************/
  81.  
  82. int16_t main(void)
  83. {
  84.    
  85.     /*
  86.      * Set clock speed to 32MHz => instruction clock to 16MHz
  87.      */
  88.     CLKDIVbits.RCDIV = 0b000;   //Prescaler 1: CLKDIV<10:8> Default: 001 = 4Mhz output | 000 = 8Mhz
  89.     CLKDIVbits.DOZEN = 0b0; // Enable prescaler
  90.     //CLKDIVbits.DOZE = 0b010;    //Prescaler 2: CLKDIR<14:12> Default: 011 = 1:8 | 000 = 1:1
  91.     OSCCON = 0x11C0;     //select INTERNAL RC, Post Scale PPL
  92.  
  93.     /* Initialize IO ports and peripherals */
  94.     AD1PCFG = 0xFFFF; // Disable Analog inputs
  95.     TRISB = 0X0000; // All pins output
  96.     TRISA = 0X0000; // All pins output
  97.  
  98.     /* Configure UART */
  99.     RPOR1bits.RP3R = 3;  //UART1 transmit set to RB3
  100.     U1BRG = 3; //set baud speed
  101.     U1MODE = 0x8001; //turn on module
  102.     //U1STA = 0x8400; //set interrupts => Set interrupt if buffer is empty
  103.     U1STA = 0x0400; //set interrupts => Set interrupt if char is sent
  104.  
  105.      /* Configure timer 1 */
  106.     PR1 = 0x056A;
  107.  
  108.     IPC0bits.T1IP = 5;   //set interrupt priority
  109.     IFS0bits.T1IF = 0;   //reset interrupt flag
  110.     IEC0bits.T1IE = 1;   //turn on the timer1 interrupt
  111.     T1CONbits.TON = 0;   //turn OFF the timer
  112.  
  113.     /* Configure timer 2 */
  114.     //PR2 = 0x056A;
  115.  
  116.     IPC1bits.T2IP = 2;   //set interrupt priority
  117.     IFS0bits.T2IF = 0;   //reset interrupt flag
  118.     IEC0bits.T2IE = 1;   //turn on the timer1 interrupt
  119.     T2CONbits.TCKPS = 0b11; // Set prescaler to 1:256
  120.     T2CONbits.TON = 1;   //turn ON the timer
  121.  
  122.  
  123.     //reset RX interrupt flag
  124.     INTCON2 = 0x0000;    // Setup INT0, INT1, INT2, interupt on falling edge
  125.     IFS0bits.U1TXIF = 0; // Reset flag
  126.     IPC3bits.U1TXIP = 1; // Set low priority
  127.  
  128.     IEC0bits.U1TXIE = 1;    /*Enable UART1TX Interrupt Service Routine */
  129.  
  130.     LATBbits.LATB0 = 1;
  131.     LATBbits.LATB1 = 0;
  132.     LATAbits.LATA1 = 1;
  133.  
  134.     // Start with a break, initialize all the packages
  135.     dmx_progress = 0; // Reset the counter
  136.     U1STAbits.UTXEN = 0; // Disable UART transmit pin
  137.     LATBbits.LATB3 = 0; // Clear the transmit pin
  138.     T1CONbits.TON = 1;   //turn on timer 1
  139.  
  140.     /* AD Conversion init*/
  141.     AD1CON1 = 0x80E4; //Turn on, auto sample start, auto-convert
  142.     AD1CON2 = 0x0000; //Vref+ (vdd), Vref- (vss), int every conversion, MUXA only
  143.     AD1CON3 = 0x1F05; //31 Tad auto-sample, Tad = 5*Tcy
  144.  
  145.     AD1CHS = 0; // Connect AN0 to AD hardware
  146.     AD1PCFGbits.PCFG0 = 0;  //Disable digital input on AN0
  147.     AD1CSSL = 0;     //No scanned inputs
  148.  
  149.     // Initialise values
  150.     dmx_values[0] = dmx_rotation[rot_counter][0][R];
  151.     dmx_values[1] = dmx_rotation[rot_counter][0][G];
  152.     dmx_values[2] = dmx_rotation[rot_counter][0][B];
  153.  
  154.     dmx_values[3] = dmx_rotation[rot_counter][1][R];
  155.     dmx_values[4] = dmx_rotation[rot_counter][1][G];
  156.     dmx_values[5] = dmx_rotation[rot_counter][1][B];
  157.  
  158.     dmx_values[6] = dmx_rotation[rot_counter][2][R];
  159.     dmx_values[7] = dmx_rotation[rot_counter][2][G];
  160.     dmx_values[8] = dmx_rotation[rot_counter][2][B];
  161.  
  162.     while(1)
  163.     {
  164.         // Reading Analog values
  165.         while (!AD1CON1bits.DONE);
  166.         voltage = ADC1BUF0;
  167.         value = (uint8_t)(voltage>>2);
  168.  
  169.         // Counter acts as debugger
  170.         if(counter == 10000)
  171.         {
  172.             LATBbits.LATB0 = ~LATBbits.LATB0;
  173.             counter = 0;
  174.         }
  175.  
  176.         if(rot_update == 1)
  177.         {
  178.             rot_update = 0;
  179.             rot_period_c++;
  180.            
  181.             rot_counter = PREV(rot_counter);
  182.  
  183.             dmx_values[0] = dmx_rotation[rot_counter][0][R];
  184.             dmx_values[1] = dmx_rotation[rot_counter][0][G];
  185.             dmx_values[2] = dmx_rotation[rot_counter][0][B];
  186.  
  187.             dmx_values[3] = dmx_rotation[rot_counter][1][R];
  188.             dmx_values[4] = dmx_rotation[rot_counter][1][G];
  189.             dmx_values[5] = dmx_rotation[rot_counter][1][B];
  190.  
  191.             dmx_values[6] = dmx_rotation[rot_counter][2][R];
  192.             dmx_values[7] = dmx_rotation[rot_counter][2][G];
  193.             dmx_values[8] = dmx_rotation[rot_counter][2][B];
  194.         }
  195.     }
  196. }
  197.  
  198. //Interrupt routine
  199. void __attribute__((__interrupt__, auto_psv)) _U1TXInterrupt(void)
  200. {
  201.     if(dmx_progress < num_dmx_values)
  202.     {
  203.         // Transmit a byte
  204.         U1TXREG = dmx_values[dmx_progress++];
  205.     }
  206.     else
  207.     {
  208.         // Restart DMX procedure from the Break
  209.         LATBbits.LATB3 = 0; // Clear the transmit pin
  210.         U1STAbits.UTXEN = 0; // Disable UART transmit pin
  211.        
  212.         PR1 = 0x056A;       // Set 88µS time
  213.         T1CONbits.TON = 1;   //turn on the timer
  214.         LATBbits.LATB1 = 1;
  215.         dmx_progress = 0; // Reset the counter
  216.     }
  217.     counter++; // Debug counter
  218.     IFS0bits.U1TXIF = 0;    //Clear the U1TX interrupt flag
  219. }
  220.  
  221. //_T1Interrupt() is the T1 interrupt service routine (ISR).
  222. void __attribute__((__interrupt__, auto_psv)) _T1Interrupt(void)
  223. {
  224.     if(break_sent == 0)
  225.     { // 88µS break has been sent
  226.         LATBbits.LATB3 = 1;
  227.         break_sent = 1;
  228.         PR1 = 0x007E;   // Set 8µS MAB time
  229.     }
  230.     else
  231.     { // 8µS MAB has been sent
  232.         break_sent = 0;
  233.         T1CONbits.TON = 0;   //turn off the timer
  234.  
  235.         U1STAbits.UTXEN = 1; // Enable UART transmit pin
  236.         U1TXREG = START_BYTE; //dmx_values[0];
  237.         dmx_progress = 0; // Fire start byte into UART
  238.  
  239.         LATBbits.LATB1 = 0; //Toggle output to LED
  240.     }
  241.     IFS0bits.T1IF = 0; // Clear timer interrupt flag
  242. }
  243.  
  244. //_T2Interrupt() is the T2 interrupt service routine (ISR).
  245. void __attribute__((__interrupt__, auto_psv)) _T2Interrupt(void)
  246. {
  247.     LATAbits.LATA1 = ~LATAbits.LATA1;   //Toggle output to LED
  248.     rot_update = 1;
  249.     IFS0bits.T2IF = 0; // Clear timer interrupt flag
  250. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement