dspic Propellor clock project
dspic 30F3010


This page presents some projects I made that include elctronics and C programs on Microchip dspic 30F3010.
Executable and sources are provided.

Version Fr à traduire.

Choix du dspic 30F3010 :

L'intéret de ce dsPIC 30F3010 est que c'est un microcontrôleur 16 bits de chez Microchip, il comporte une interface de communication Série (SPI, SCI c'est-à-dire UART) mais aussi 6 sorties PWM, des entrées ADC (10 bits). Il a un petit noyeau DSP (multiplication) d'où le nom dsPIC par rapport aux PIC bien connus.

Caractéristiques du dsPIC 30F3010 que nous utilisersons :
    Parameter Name Value
    Vdd +5V
    UART 1
    SRAM Bytes 1024
    Program (FLASH) KBytes 24
    Pin Count 28
    I/O Ports 20
    Input Capture 4
    CPU Speed in MIPs30
    Codec Interface None
    Clock Oscillator FRC
    ADC 10-bit 6
    16-Bit Timers 5
    Pb Free Available Yes

Comme il a 28 pattes (pins) et qu'il existe en boitier DIP, il peut être facilement utilisé pour des petits projets d'électroniciens amateurs.
On le programme en assembleur ou en C. Nous avons choisi ce language à cause de son universalité et la facilité d'adaptation des algorithmes que nous avons déjà développé (pilotage de LCD, commande V/f) pour le DSP TMS 320F240.

La datasheet 70141c du dsPIC 30F3010 renseigne sur la connectique et les registres que l'on utilise pour le programmer.
Il vaut mieux regarder la documentation plus complete de toute la famille dsPIC (70046E).

Connexions du dsPIC 30F3010

Le projet :






















Voici le prog en version de développement et les schematics.
prclock :

Ce programme est un point de départ...

fichier :dl/dspic/prclock/prclock.c
   
  1. //-----------------------------------------------------------------------------
  2. // Propellor Clock
  3. // dsPIC 30F3010
  4. // L. BAGHLI 03/02/2007
  5. // version actuelle : beta Quartz=10Mhz,
  6. // IC2 repère un aimant tournant et calcule la Ts (Timer2)
  7. // Timer1 ttes les 100 us allume le diodes en fonction de la position
  8. // v0.11  09/02/2007 prise en compte sur IC2/RD0 de l'entrée IR du 1838
  9. //        decodage de la trame RC5 en cours
  10. //        MAX3233E pour envoyer les données de deboggage à un terminal RS232 via UART1
  11. //-----------------------------------------------------------------------------
  12. #include "p30F3010.h"
  13.  
  14. //Configuration bits
  15. _FOSC(CSW_FSCM_OFF & XT_PLL8)//10Mhz *8 = 80 MHz /4 = 20 MIPS maxi pour ce pic
  16. _FWDT(WDT_OFF);
  17. _FBORPOR(PBOR_OFF & BORV_27 & PWRT_16 & MCLR_EN);
  18. _FGS(CODE_PROT_OFF);
  19. //-----------------------------------------------------------------------------
  20. //Program Specific Constants
  21. #define FCY 20000000          //Instruction cycle rate (Osc x PLL / 4) = 20 MIPS
  22. #define T1Period 2000     // pour 100us à 20 MHz = T1Period = 2000=FCY*100us
  23. #define tcntPRD 10000     // combien de fois pour ariver en 1s avec des pas de 100us : 10000
  24. #define MILLISEC FCY/20000      // 1 mSec delay constant
  25. // 11 LED differentes = 1 (en fait 6 en même tps) + 8 + 2 + 1 blue donc 12 Outputs
  26. // LED bleue
  27. #define LEDBlue PORTEbits.RE8      // la derniere (pour les secondes)
  28. #define LED_E PORTE            // 6 Leds
  29. #define LED_B PORTB            // 6 Leds
  30. // IC1/RD0 et IC2/RD1 sont pour la mesure de l IR 1838 en codage RC5 et du top index du changement d etat du hall sensor SS40A
  31. #define IR_receive  PORTDbits.RD0   // InputIR module
  32. #define TopIndex    PORTDbits.RD1   // Input sends top index hall SS041 + aimant fixe.
  33.  
  34.  
  35. void setup_ports(void);
  36. void DelayNmSec(unsigned int N);
  37.  
  38. struct {
  39.       unsigned Running    :   1;
  40.       unsigned CheckRX    :   1;
  41.       unsigned SendTX   :  1;
  42.       unsigned SendIR   :  1;
  43.       unsigned Sendtheta  :   1;
  44.       unsigned SendLED    :   1;
  45.  
  46.       unsigned IR_bit   :  1;  // bit value                               
  47.       unsigned IR_toggle  :   1;    // toggle on short pulse
  48.       unsigned IR_busy    :   1;    // receive in progress                     
  49.       unsigned IR_done    :   1;    // receive done   
  50.  
  51.       unsigned charinv    :   1;    // receive done   
  52.      
  53.       unsigned unused     : 5;
  54.     } Flags;
  55. // l angle theta est codé sur 16 bits.
  56. unsigned int theta, dth, thcentre;    // angle actuel et increment angulaire, centre du caractere à afficher
  57. int Ts;    // Periode de rotation (en unités Timer2)
  58. unsigned int heure, heure1, heure2, min, min1, min2, sec, sec1, sec2, tcnt;
  59. unsigned int Ref1, Ref2;
  60. unsigned int thAigsec, thAigmin, thAigheure;    // position des aiguilles
  61. unsigned char Char2Disp, kp, EtatLEDchar; // etat des led pour les caracteres
  62. unsigned int EtatLED;  // etat des led sur 16 bits, LSB centre, MSB péripherie
  63.  
  64. int itmp;
  65. // 65536/60 et 65536/12
  66. #define c65536_60 1092
  67. #define c65536_12 5461
  68. // thc=M_PI/8;
  69. // kth=5/M_PI;
  70. // thsec1=M_PI*0.5/8;
  71. // thsec2=M_PI*15.5/8;
  72. // thmin1=M_PI*6/8+thc*0;
  73. // thmin2=M_PI*6/8+thc*1;
  74. // thcolon=M_PI;
  75. // thh1=M_PI*6/8+thc*3;
  76. // thh2=M_PI*6/8+thc*4;
  77. #define thc    0x1000
  78. #define thc_2   0x0800
  79. #define kth    0.000152587890625
  80. #define thsec1    0x0800
  81. #define thsec2    0xF800
  82. #define thmin1    0x6000
  83. #define thmin2    0x7000
  84. #define thcolon  0x8000
  85. #define thheure1  0x9000
  86. #define thheure2  0xA000
  87. // angle de 2° pour la largeur des aiguilles
  88. #define th2deg  0x016C
  89. // code des caractères inversés
  90. unsigned char invNumber[]={
  91.       0, 0, 0, 126, 129, 129, 129, 126,  // 0 inversé encore une fois
  92.       0, 0, 0, 128, 130, 130, 253, 128,  // 1
  93.       0, 0, 0, 194, 161, 145, 137, 134,  // 2
  94.       0, 0, 0, 66, 129, 137, 137, 118,    // 3
  95.       0, 32, 48, 40, 36, 34, 255, 32,   // 4
  96.       0, 0, 0, 79, 129, 137, 137, 113,    // 5
  97.       0, 0, 0, 124, 138, 137, 137, 112,  // 6
  98.       0, 0, 0, 1, 193, 49, 13, 3,    // 7
  99.       0, 0, 0, 118, 137, 137, 137, 118,  // 8
  100.       0, 0, 0, 14, 145, 145, 81, 62,      // 9
  101.       0, 0, 0, 0, 0, 102, 0, 0};     // :
  102.  
  103. // IR code -------------------------------------------
  104. unsigned char IR_time;        // count bit time
  105. unsigned int IR_tmp;        // shift bits in
  106. unsigned int IR_CodeFull;    // store result
  107. unsigned char IR_CodeAddy, IR_CodeData;
  108. #define PULSE1_2  (unsigned char)(8 * 1.5 + 1)
  109. #define PULSE2MAX (unsigned char)(8 * 2.5 + 1)
  110. // RS232 -------------------------------------------
  111. unsigned char *TXPtr;
  112. unsigned char *RXPtr;
  113. void InitUART(void);
  114. void SendMsg(void);
  115. #define CR  0x0D
  116. #define LF  0x0A
  117. #define BAUD 19200
  118. #define OffsetIRCodeData 5        // offset in OutData : position de la val de IRCodeData
  119. #define OffsetIRCodeAddy 13    // offset in OutData : position de la val de IRCodeAddy
  120. unsigned char InData[] = {"000000"};
  121. unsigned char OutData[] = {"IRD= 00 IRA= 00\r\n"};
  122. #define Offsettheta 7    // offset in OutData : position de la val de theta
  123. #define OffsetTime 18    // offset in OutData : position de la val de Time
  124. unsigned char OutTheta[] = {"theta= 0000 Time= 00:00:00\r\n"};
  125. // offset in OutEtatLed
  126. #define OffsetLED 5
  127. #define OffsetEtatLED 34
  128. #define OffsetChar 45
  129. #define Offsetkp 51
  130. unsigned char OutEtatLed[] = {"LED=[0123456789ABCDEF[  EtatLED=0xXXXX  Char=XX kp=X\r\n"};
  131. int SeqComm;    // ttes les 0.5 s
  132. #define SeqCommMax 5000
  133. //debug bad #define SeqCommMax 2000
  134. //  -------------------------------------------
  135.  
  136. //-----------------------------------------------------------------------------
  137. //  Initialise variables
  138. //-----------------------------------------------------------------------------
  139. void InitVar(void)
  140. {
  141.   Flags.Running=0;
  142.   tcnt=0;
  143.   heure=0; heure1=0; heure2=0;
  144.   min=0; min1=0; min2=0;
  145.   sec=0; sec1=0; sec2=0;
  146.   Flags.IR_done=0; Flags.IR_busy=0;
  147.   Flags.IR_bit=1;
  148.   Flags.SendIR = 0;  // clear 3 flags RS232
  149.   Flags.Sendtheta = 0;
  150.   Flags.SendLED = 0
  151. }
  152. //-----------------------------------------------------------------------------
  153. //  Setup ports
  154. //-----------------------------------------------------------------------------
  155. void setup_ports(void)
  156. {
  157.   // Clear All Ports Prior to defining I/O
  158. //  ADPCFG = 0xFFFF;        // all PORTB = Digital(1), no analog
  159.  
  160.  
  161.   PORTB=0//Initialize LED pin data to off state
  162.   PORTC=0;
  163.   PORTD=0;
  164.   PORTE=0
  165.   // Now set pin direction registers
  166. //debug_____________________________________________________________________
  167. // temporaire pour lire la valeur de theta à l aide des potars AN4 et AN5 sur ch3 et ch4
  168. //  TRISB = 0xFF00;  // RB0-5 output LED
  169.   TRISB = 0xFFF0;  // RB0-3 output LED, RB4, 5 input ADC AN4 et AN5
  170.   TRISC = 0xDFFF;   // C13  TX out, C14 RX in, le reste : input / Unused
  171.   TRISD = 0xFFFF;  // RD0 input : Topindex, RD1 input : IR_receive
  172.   TRISE = 0x0000;  // RE0-8 Output LED
  173.   TRISF = 0xFFFF;  // RFx not used (input)
  174. //debug_____________________________________________________________________
  175. // temporaire pour lire la valeur de theta à l aide des potars AN4 et AN5 sur ch3 et ch4
  176.   ADPCFG = 0xFFCF;        // all PORTB = Digital(1) ;RB4 et RB5 = analog(0)  ie 1100 1111
  177.   ADCON1 = 0x000F;        // Clearing SAMP bit SOC, 4 ch simultanés, ADC Off for configuring
  178.   ADCON2 = 0x0200;        // simulataneous sample 4 channels, ADC INTerrupt à chaque EOC=100 us
  179.   ADCHS = 0x0020;          // AN4/RB4 Ch2 Ref1, AN5/RB5 Ch3 Ref2
  180.   ADCON3 = 0x0080;        // Tad = internal RC (4uS)
  181.   ADCON1bits.ADON = 1;    // turn ADC ON
  182. // fin debug temporaire_____________________________________________________
  183. }
  184. //-----------------------------------------------------------------------------
  185. //  intitialise timer 1 et l interruption
  186. //-----------------------------------------------------------------------------
  187. void initTimer_CNx(void)
  188. {
  189. // Timer1 pour l ISR des 100 us
  190.   T1CON = 0;          // ensure Timer 1 is in reset state, internal timer clock Fosc/4, no prescale
  191.   TMR1  = 0;          // RAZ Timer1
  192.   IFS0bits.T1IF = 0// reset Timer 1 interrupt flag
  193.   IPC0bits.T1IP = 4// set Timer1 interrupt priority level to 4
  194.   IEC0bits.T1IE = 1// enable Timer 1 interrupt
  195.   PR1 = T1Period;   // set Timer 1 period register
  196. // Timer2 pour compter Ts entre 2 index
  197.   T2CON = 0x0010;   // ensure Timer 1 is in reset state, internal timer clock Fosc/4, prescale 1:8
  198.                       // ie 100 tr/s donne Ts=20e6*0.01/8 = 25000 = 0x61A8
  199.   TMR2  = 0;          // RAZ Timer2
  200.   PR2 = 0xFFFF;    // set Timer 2 period register maximum, RAZ sur index
  201.  
  202. // ICN2 enclenché sur Timer2, on rising edge pour la sonde Hall d index
  203.   IC2CON = 0x0083;
  204.   IFS0bits.IC2IF = 0// Clear IF bit
  205.   IPC1bits.IC2IP = 3// assigning Interrupt Priority to IPC Register
  206.   IEC0bits.IC2IE = 1// assiging Interrupt Enable
  207.  
  208.   T2CONbits.TON = 1// enable Timer 2 and start the count
  209.   T1CONbits.TON = 1// enable Timer 1 and start the count
  210.   }
  211. //---------------------------------------------------------------------
  212. // Check si on est sur une aiguille
  213. int  InAiguille(unsigned int th1, unsigned int th2)
  214. {
  215.   if (th1-th2<=th2deg && th1-th2>=0) return 1;   //2 degrés
  216.       else  return 0;
  217. }
  218. //---------------------------------------------------------------------------
  219. // Check si on est sur un caractere
  220. int InCaractere(unsigned int th1, unsigned int th2)
  221. {
  222. unsigned int res;
  223.   res=th1-th2;
  224.   if (th1 <th2) res=-res;
  225.   if ( res<thc_2) return 1;   //th est ds le carcatere
  226.       else        return 0;
  227. }
  228. //---------------------------------------------------------------------
  229. // Timer1 interrupt fait le calcul et l allumage des LED
  230. // ISR toutes les 100 us
  231. //---------------------------------------------------------------------
  232. void __attribute__((__interrupt__)) _T1Interrupt( void )
  233. {
  234. //PORTEbits.RE8=1;  // InterruptLED=1; 
  235.   IFS0bits.T1IF = 0
  236. //  theta+=dth;     // new position
  237. //  if (theta> depasse 2pi) alors on fait quoi ?
  238. //debug_____________________________________________________________________
  239. // temporaire pour lire la valeur de theta à l aide des potars AN4 et AN5 sur ch3 et ch4
  240.   ADCON1bits.SAMP = 0;        // start conversion
  241.   while(!ADCON1bits.DONE) {}  // attend la fin
  242.   Ref1=ADCBUF2;
  243.   Ref2=ADCBUF3;
  244. // debug
  245. //  PORTE=Ref1>>4;
  246. //  if (Ref1>512) PORTEbits.RE8=1;
  247. //        else    PORTEbits.RE8=0;
  248. //___
  249. // dummy read adcbuf 0 et 1 ?
  250. // debug
  251. //    theta=Ref1<<6;
  252.   theta=(Ref1<<6) + (Ref2<<2);    // donne une position fictive des diodes theta=(Ref1<<6) + (Ref2<<2);
  253. //  theta=Ref1;  // donne une position fictive des diodes
  254.  
  255.   if (++tcnt>=tcntPRD) 
  256.             {
  257.             tcnt=0;
  258.             sec++;
  259.             if (++sec1==10)
  260.                   {
  261.                   sec1=0;
  262.                   if (++sec2==6) 
  263.                       {
  264.                       sec=0;
  265.                       sec2=0;
  266.                       min++;
  267.                       if (++min1==10)
  268.                             {
  269.                             min1=0;
  270.                             if (++min2==6) 
  271.                                 {
  272.                                 min=0;
  273.                                 min2=0;
  274.                                 heure1++;
  275.                                 if (++heure==24)
  276.                                       {
  277.                                       heure1=0
  278.                                       heure2=0;
  279.                                       }
  280.                                   else if (heure1==10)  // n atteintt pas plus de 23 h !
  281.                                                 {
  282.                                                 heure1=0;
  283.                                                 heure2++;
  284.                                                 }
  285.                                       }
  286.                             }
  287.                       }
  288.                   }
  289.             // comme l'heure hh:mm:ss a changé => calcule la nouvelle position des aiguilles
  290.             thAigsec=c65536_60*sec;
  291.             thAigmin=c65536_60*min;
  292.             itmp=heure-12;
  293.             if (itmp<0) thAigheure=c65536_12*heure;
  294.               else      thAigheure=c65536_12*itmp;
  295.             }
  296.  
  297. // fin debug temporaire_____________________________________________________
  298. // utilisation du theta et de l heure !
  299.   Char2Disp=22; // ie pas ds un caractere
  300.   Flags.charinv=0;
  301.   if (InCaractere(theta, thsec1))   {Char2Disp=sec1;    thcentre=thsec1; Flags.charinv=1;}
  302.   if (InCaractere(theta, thsec2))   {Char2Disp=sec2;    thcentre=thsec2; Flags.charinv=1;}
  303.   if (InCaractere(theta, thmin1))   {Char2Disp=min1;    thcentre=thmin1; }
  304.   if (InCaractere(theta, thmin2))   {Char2Disp=min2;    thcentre=thmin2; }
  305.   if (InCaractere(theta, thheure1))     {Char2Disp=heure1;  thcentre=thheure1; }
  306.   if (InCaractere(theta, thheure2))     {Char2Disp=heure2;  thcentre=thheure2; }
  307.   if (InCaractere(theta, thcolon))      {Char2Disp=10;      thcentre=thcolon; } // :
  308.  
  309.  // calcule l'etat des LED
  310.   EtatLED=0;
  311.   if (InAiguille(theta,thAigheure)) EtatLED |=0x001F;
  312.   if (InAiguille(theta,thAigmin))  EtatLED |=0x007F;
  313.   if (InAiguille(theta,thAigsec))  EtatLED |=0x0080;
  314.  
  315.   EtatLEDchar=0;
  316.   if (Char2Disp!=22)
  317.     {
  318.     kp=(theta-thcentre+thc_2)>>9;  // de theta vers pixel index : 0x1000 -> 8 ie divisé par 0x200
  319.     if (Flags.charinv)  kp=7-kp;
  320.     if (kp>7)   kp=7;
  321.     EtatLEDchar=invNumber[(Char2Disp<<3)+kp];
  322.     EtatLED |= EtatLEDchar<<8;      // affiche le caractère vers l'extrémité, loin du centre de rotation
  323.     }
  324. // allume les LED
  325. // debug
  326. // ne touche pas à RE8
  327. unsigned int etatR8=PORTE & 0x100;
  328.   PORTE=(EtatLED>>8 )& 0x3F | etatR8; // 6 LED actuellement + 1 de controle/oscillo
  329.  
  330. // decode trame IR suivant RC5
  331.   if (!IR_receive==Flags.IR_bit){   // change detect
  332.                           Flags.IR_bit = ~Flags.IR_bit;    // store new state
  333.                           if( Flags.IR_busy == 0 )  {
  334.                                               if( Flags.IR_bit == 1 ){      // start pulse detect
  335.                                                                 Flags.IR_busy = 1;
  336.                                                                 IR_tmp = 1;    // == 0x2000 after 13 shift
  337.                                                                 Flags.IR_toggle = 1;
  338.                                                                 }
  339.                                               }
  340.                                         else  {
  341.                                               Flags.IR_toggle = ~Flags.IR_toggle;   // skip every second change
  342.                                               if( Flags.IR_toggle || IR_time < PULSE1_2 ){
  343. PORTEbits.RE8=1;
  344.                                                                                       Flags.IR_toggle = 1;        // false on next pulse
  345.                                                                                       IR_tmp <<= 1;    // shift
  346.                                                                                       if( Flags.IR_bit ) IR_tmp |= 1;    // add new bit
  347.                                                                                       if( IR_tmp & 0x2000 ){      // after shifted 13 times
  348.                                                                                                             IR_CodeFull = IR_tmp;
  349.                                                                                                             Flags.IR_busy = 0;
  350.                                                                                                             Flags.IR_done = 1;
  351.                                                                                                             IR_CodeAddy=IR_CodeFull>>6 & 0x1F;
  352.                                                                                                             IR_CodeData=IR_CodeFull & 0x3F;
  353.                                                                                                             }
  354. PORTEbits.RE8=0;
  355.                                                                                       }
  356.                                               }
  357.                           IR_time = PULSE2MAX;
  358.                           }
  359.     else  {
  360.           if (--IR_time==0 )      // if no change, count down
  361.                                   Flags.IR_busy = 0;        // timeout
  362.           }
  363.  
  364. // communication dsPIC -> PC
  365.   if (!--SeqComm)  {
  366.                     SeqComm=SeqCommMax;
  367. // uniquement si nouvelle donnée :    if (IR_done)  Flags.SendIR=1;
  368.                     Flags.SendIR=1;
  369.                     Flags.Sendtheta=1;
  370.                     Flags.SendLED=1;
  371.                     }
  372.  
  373. //PORTEbits.RE8=0; // InterruptLED=0; 
  374. }
  375. //---------------------------------------------------------------------
  376. // ICN2 interrupt : passage devant l index (aimant) alors mesure du chrono et RAZ
  377. //---------------------------------------------------------------------
  378. void __attribute__((__interrupt__)) _IC2Interrupt( void )
  379. {
  380.   IFS0bits.IC2IF = 0;
  381.   TMR2 = 0;              // RAZ Timer2
  382.   theta=0;      // la position aussi
  383.   if (IC1CONbits.ICBNE) Ts= IC2BUF;      // reads the input capture buffer
  384.   // calcule l incrément dth correspondant à 100 us
  385.   // il y a N increment en 0.01s : N = 0.01s/100us = Ts*8/(100e-6*20e6) = 65536/dth
  386.   // dth=65536*2000/8/Ts
  387. //debug
  388. //  dth=8192*T1Period/Ts;
  389.  
  390. }
  391. //---------------------------------------------------------------------
  392. // Below are the interrupt vectors for the serial receive and transmit
  393. //---------------------------------------------------------------------
  394. void __attribute__((__interrupt__)) _U1TXInterrupt(void)
  395. {
  396.   IFS0bits.U1TXIF = 0// clear interrupt flag
  397. }
  398. //---------------------------------------------------------------------
  399. void __attribute__((__interrupt__)) _U1RXInterrupt(void)
  400. {
  401.   IFS0bits.U1RXIF = 0// clear interrupt flag
  402.   *RXPtr = U1RXREG;
  403.   if (*RXPtr == CR)
  404.     {Flags.CheckRX = 1;
  405.     RXPtr = &InData[0];}
  406.   else *RXPtr++;
  407. }
  408. //------------------------------------------------------------------------
  409. //  Transmission over serial
  410. void InitUART(void)
  411. {
  412. // Initialize the UART1 for BAUD = 19,200 
  413.   U1MODE = 0x8400;  // enable + alternate pins
  414. //  U1MODE = 0x8000;  // enable + normal pins
  415.   U1STA = 0x0000;
  416.   U1BRG = ((FCY/16)/BAUD) - 1// set baud to 19200
  417.   IEC0bits.U1RXIE = 1;      // enable RX interrupt
  418.   RXPtr = &InData[0];  // point to first char in receive buffer
  419.   Flags.CheckRX = 0;      // clear rx and tx flags
  420.   Flags.SendTX = 0;
  421.  
  422.   U1STAbits.UTXEN = 1;           // Initiate transmission
  423.   SeqComm=SeqCommMax;
  424. }
  425. //------------------------------------------------------------------------
  426. // Sendfs sends the IRcode (Data & Addy) information on the uart at 19200 baud
  427. void SendIRcode()
  428. {
  429. unsigned int k;
  430. unsigned char c;
  431. // Codage ASCII de la donnée  
  432.   k = IR_CodeData;
  433.   c = k/10;
  434.   if (c > 0)
  435.     k = k - c*10;
  436.   OutData[OffsetIRCodeData] = (c + 0x30);
  437.   OutData[OffsetIRCodeData+1] = (char)(k + 0x30);
  438.  
  439.   k = IR_CodeAddy;    //format à revoir ....
  440.   c = k/10;
  441.   if (c > 0)
  442.     k = k - c*10;
  443.   OutData[OffsetIRCodeAddy] = (c + 0x30);
  444.   OutData[OffsetIRCodeAddy+1] = (char)(k + 0x30);
  445.  
  446.   TXPtr = &OutData[0];
  447.   SendMsg();
  448. }
  449. //------------------------------------------------------------------------
  450. // Sendfs sends the theta information on the uart at 19200 baud
  451. void Sendthetacode()
  452. {
  453. unsigned int k;
  454. unsigned char c;
  455. // Codage ASCII de la donnée hexa
  456.   k = theta;
  457.   c=k & 0x000F;
  458.   if (c<=9) c+=0x30;
  459.     else    c+=0x37;
  460.   OutTheta[Offsettheta+3]=c;
  461.  
  462.   c=k>>4 & 0x000F;
  463.   if (c<=9) c+=0x30;
  464.     else    c+=0x37;
  465.   OutTheta[Offsettheta+2]=c;
  466.  
  467.   c=k>>8 & 0x000F;
  468.   if (c<=9) c+=0x30;
  469.     else    c+=0x37;
  470.   OutTheta[Offsettheta+1]=c;
  471.  
  472.   c=k>>12 & 0x000F;
  473.   if (c<=9) c+=0x30;
  474.     else    c+=0x37;
  475.   OutTheta[Offsettheta]=c;
  476. // codage ASCII de l heure
  477.   OutTheta[OffsetTime](heure2 + 0x30);
  478.   OutTheta[OffsetTime+1]=(heure1 + 0x30);
  479.   OutTheta[OffsetTime+3]=(min2 + 0x30);
  480.   OutTheta[OffsetTime+4]=(min1 + 0x30);
  481.   OutTheta[OffsetTime+6]=(sec2 + 0x30);
  482.   OutTheta[OffsetTime+7]=(sec1 + 0x30);
  483.  
  484.   TXPtr = &OutTheta[0];
  485.   SendMsg();
  486. }//------------------------------------------------------------------------
  487. // Sendfs sends the LED information on the uart at 19200 baud
  488. void SendLEDcode()
  489. {
  490. unsigned int k;
  491. unsigned char c;
  492. // Codage ASCII de la donnée hexa
  493.   for (k=0; k<16; k++)
  494.     if ((EtatLED>>k)&1 == 1)  OutEtatLed[OffsetLED+k]=0x2A;
  495.         else              OutEtatLed[OffsetLED+k]=0x20;
  496.  
  497.   k = EtatLED;
  498.   c=k & 0x000F;
  499.   if (c<=9) c+=0x30;
  500.     else    c+=0x37;
  501.   OutEtatLed[OffsetEtatLED+3]=c;
  502.  
  503.   c=k>>4 & 0x000F;
  504.   if (c<=9) c+=0x30;
  505.     else    c+=0x37;
  506.   OutEtatLed[OffsetEtatLED+2]=c;
  507.  
  508.   c=k>>8 & 0x000F;
  509.   if (c<=9) c+=0x30;
  510.     else    c+=0x37;
  511.   OutEtatLed[OffsetEtatLED+1]=c;
  512.  
  513.   c=k>>12 & 0x000F;
  514.   if (c<=9) c+=0x30;
  515.     else    c+=0x37;
  516.   OutEtatLed[OffsetEtatLED]=c;
  517. // Char
  518.   k = Char2Disp;
  519.   c = k/10;
  520.   if (c > 0)
  521.     k = k - c*10;
  522.   OutEtatLed[OffsetChar] = (c + 0x30);
  523.   OutEtatLed[OffsetChar+1] = (char)(k + 0x30);
  524. // kp
  525.   OutEtatLed[Offsetkp] = (kp + 0x30);
  526.  
  527.   TXPtr = &OutEtatLed[0];
  528.   SendMsg();
  529. }
  530. //-----------------------------------------------------------------------------
  531. void SendMsg(void)
  532. {
  533. while (*TXPtr)
  534.   {
  535.   while (U1STAbits.UTXBF);
  536.   U1TXREG = *TXPtr++;
  537.   }
  538. }
  539. //-----------------------------------------------------------------------------
  540. //Main routine
  541. int main(void)
  542. {
  543.   setup_ports();
  544.   InitVar();
  545.   InitUART();
  546.   initTimer_CNx();
  547.  
  548.   while(1)
  549.     { 
  550.  
  551.     if (Flags.SendIR)
  552.       {
  553.       SendIRcode();  // send present fs serially
  554.       Flags.SendIR = 0;  // clear flag
  555.       }
  556.     if (Flags.Sendtheta)
  557.       {
  558.       Sendthetacode();    // send present fs serially
  559.       Flags.Sendtheta = 0;    // clear flag
  560.       }
  561.     if (Flags.SendLED)
  562.       {
  563.       SendLEDcode();    // send present fs serially
  564.       Flags.SendLED = 0;    // clear flag
  565.       }
  566. } // end of while (1)
  567. } // end of main
  568.  
  569. //=============================================================================
  570. //Error traps
  571. //-----------------------------------------------------------------------------
  572. //Oscillator Fail Error trap routine
  573. void _ISR _OscillatorFail(void)
  574. { 
  575.   while(1); //Wait forever
  576. }
  577. //-----------------------------------------------------------------------------
  578. //Address Error trap routine
  579. void _ISR _AddressError(void)
  580. {
  581.   while(1); //Wait forever
  582. }
  583. //-----------------------------------------------------------------------------
  584. //Stack Error trap routine
  585. void _ISR _StackError(void)
  586. {
  587.   while(1); //Wait forever
  588. }
  589. //-----------------------------------------------------------------------------
  590. //Math (Arithmetic) Error trap routine
  591. void _ISR _MathError(void)
  592. {
  593.   while(1); //Wait forever
  594. }
  595. //---------------------------------------------------------------------
  596. // This is a generic 1ms delay routine to give a 1mS to 65.5 Seconds delay
  597. // For N = 1 the delay is 1 mS, for N = 65535 the delay is 65,535 mS.
  598. // Note that FCY is used in the computation.  Please make the necessary
  599. // Changes(PLLx4 or PLLx8 etc) to compute the right FCY as in the define
  600. // statement above.
  601. //---------------------------------------------------------------------
  602. void DelayNmSec(unsigned int N)
  603. {
  604. unsigned int j;
  605. while(N--)
  606.   for(j=0;j < MILLISEC;j++);
  607. }
  608. //---------------------------------------------------------------------
  609.  


Under construction (21/01/2007) revenez plus tard...



Download executable and sources.
Download :
prclock.c   Sources C du projet.


Back to homepage

Last update : 21/01/2007