Olá, pessoal !
Passando pra deixar mas um exemplo de código, aqui demonstrando como usar o modulo analógico digital do microcontrolador C8051F382, e imprimir isto na porta serial RS232.
O código fonte:
// Target: C8051F382 // Tool chain: Simplicity Studio / Keil C51 9.51 // Command Line: None // // // Release 1.0 // 12_05_2021 // autor:Aguivone M. Fógia // exemplo de como usar o ADC( e comunicação serial // usando o port 2.7 // //----------------------------------------------------------------------------- // Includes //----------------------------------------------------------------------------- #include <SI_C8051F380_Register_Enums.h> #include <stdio.h> //----------------------------------------------------------------------------- // Global CONSTANTS //----------------------------------------------------------------------------- #define SYSCLK 12000000 // SYSCLK frequency in Hz #define BAUDRATE 115200 // Baud rate of UART in bps #define INT_DEC 256 // Integrate and decimate ratio #define TIMER0_RELOAD_HIGH 0 // Timer0 High register #define TIMER0_RELOAD_LOW 255 // Timer0 Low register //----------------------------------------------------------------------------- // Function PROTOTYPES //----------------------------------------------------------------------------- SI_INTERRUPT_PROTO(ADC0_ISR, ADC0EOC_IRQn); SI_INTERRUPT_PROTO(Timer2_ISR, TIMER2_IRQn); void Oscillator_Init (void); void Port_Init (void); void Timer2_Init(void); void ADC0_Init(void); void UART0_Init (void); unsigned char porta4 = 0XFF; void delay_ms(int16_t ms); //----------------------------------------------------------------------------- // Global Variables //----------------------------------------------------------------------------- int32_t RESULT; // ADC0 decimated value, one for each // analog input //----------------------------------------------------------------------------- // SiLabs_Startup() Routine // ---------------------------------------------------------------------------- void SiLabs_Startup (void) { PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer } //----------------------------------------------------------------------------- // MAIN Routine //----------------------------------------------------------------------------- void main (void) { uint32_t measurement; bool flag; // enable) Oscillator_Init (); // Initialize system clock to // 12MHz Port_Init (); // Initialize crossbar and GPIO Timer2_Init(); // Init Timer2 to generate // overflows to trigger ADC UART0_Init(); // Initialize UART0 for printf's ADC0_Init(); // Initialize ADC0 IE_EA = 1; // Enable global interrupts while (1) { IE_EA = 0; // Disable interrupts printf("\f"); // The 10-bit ADC value is averaged across INT_DEC measurements. // The result is then stored in RESULT, and is right-justified // The measured voltage applied to the port pins is then: // // Vref (mV) // measurement (mV) = --------------- * Result (bits) // (2^10)-1 (bits) measurement = RESULT * 4.887; printf("Tensao lida: %4ld mV\n",measurement); IE_EA = 1; // Re-enable interrupts delay_ms(10); if(flag==1) { P4 = 0; flag = 0; } else { P4 = 255; flag = 1; } } } //----------------------------------------------------------------------------- // Initialization Subroutines //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // SYSCLK_Init //----------------------------------------------------------------------------- // // Return Value : None // Parameters : None // // This routine initializes the system clock to use the internal 12MHz // oscillator as its clock source. Also enables missing clock detector reset. // void Oscillator_Init (void) { OSCICN = 0x83; // Configure internal oscillator for // its highest frequency RSTSRC = 0x04; // Enable missing clock detector } //----------------------------------------------------------------------------- // Port_Init //----------------------------------------------------------------------------- // // Return Value : None // Parameters : None // // Configure the Crossbar and GPIO ports. // // P0.4 - UART TX (push-pull) // P0.5 - UART RX // P2.7 - analog input (ADC0) // //----------------------------------------------------------------------------- void Port_Init (void) { P2SKIP = 0x80; // pula a entrada analogica XBR0 = 0x01; // CP1AE,CP1E,CP0AE,CP0E,SYSCKE,SMB0E,SPI0E,(UART0E) XBR2 = 0x00; // RESRV,RSRV,RESRV,RESRV,RESRV,RESRV,SMB1E, UART1E XBR1 = 0xC2; // WEAKPUD,(XBARE),T1E,T0E,ECIE,(PCA0ME):000:Nenhum,001:CEX0,010:CEX0eCEX1,... VDM0CN = 0x80; // Colocado porque senão da problema na gravacao da flash(já estava isso) RSTSRC = 0x02; // ativa reset de falha de oscilação. P0MDOUT |= 0x10; // Enable TX0 as a push-pull output P1MDOUT = 0x00; // enable Switches as open-drain P2MDOUT = 0x00; // enable Switches as open-drain P3MDOUT = 0x00; // enable Switches as open-drain P4MDOUT = 0x04; // enable Switches as open-drain //configura portas P0MDIN = 0xFF; // are digital P1MDIN = 0xFF; // are digital P2MDIN = 0x7F; //seta pino P2.7 como entrada analogica P3MDIN = 0xFF; // are digital P4MDIN = 0xFF; // are digital } //----------------------------------------------------------------------------- // Timer2_Init //----------------------------------------------------------------------------- // // Return Value : None // Parameters : None // // Configure Timer2 to 16-bit auto-reload and generate an interrupt at 10 us // intervals. Timer2 overflows automatically triggers ADC0 conversion. // //----------------------------------------------------------------------------- void Timer2_Init (void) { TMR2CN = 0x00; // Stop Timer2; Clear TF2; // use SYSCLK as timebase, 16-bit // auto-reload CKCON |= 0x10; // Select SYSCLK for timer 2 source TMR2RL = 65535 - (SYSCLK / 10000); // Init reload value for 10 us TMR2 = 0xffff; // Set to reload immediately IE_ET2 = 1; // Enable Timer2 interrupts TMR2CN_TR2 = 1; // Start Timer2 } //----------------------------------------------------------------------------- // ADC0_Init //----------------------------------------------------------------------------- // // Return Value : None // Parameters : None // // Configures ADC0 to make single-ended analog measurements on Port 2 according // to the values of <ANALOG_INPUTS> and <PIN_TABLE>. // //----------------------------------------------------------------------------- void ADC0_Init (void) { ADC0CN = 0x02; // ADC0 disabled, normal tracking, // conversion triggered on TMR2 overflow REF0CN = 0x03; // Enable internal VREF AMX0P = 0X1A; // ADC0 input = P2.7 (para microcontrolador de 48 pinos) AMX0N = 0x1F; // ADC0 negative input = GND // i.e., single ended mode ADC0CF = ((SYSCLK/3000000)-1)<<3; // Set SAR clock to 3MHz ADC0CF |= 0x00; // Right-justify results EIE1 |= 0x08; // Enable ADC0 EOC interrupt ADC0CN_ADEN = 1; // Enable ADC0 } //----------------------------------------------------------------------------- // UART0_Init //----------------------------------------------------------------------------- // // Return Value : None // Parameters : None // // Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1. // //----------------------------------------------------------------------------- void UART0_Init (void) { SCON0 = 0x10; // SCON0: 8-bit variable bit rate // level of STOP bit is ignored // RX enabled // ninth bits are zeros // clear SCON0_RI and SCON0_TI bits // seta automaticamente o valor a ser colocado no TH1 if (SYSCLK/BAUDRATE/2/256 < 1) { TH1 = -(SYSCLK/BAUDRATE/2); CKCON |= 0x08; // T1M = 1; SCA1:0 = xx } else if (SYSCLK/BAUDRATE/2/256 < 4) { TH1 = -(SYSCLK/BAUDRATE/2/4); CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01 CKCON |= 0x01; } else if (SYSCLK/BAUDRATE/2/256 < 12) { TH1 = -(SYSCLK/BAUDRATE/2/12); CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00 } else if (SYSCLK/BAUDRATE/2/256 < 48) { TH1 = -(SYSCLK/BAUDRATE/2/48); CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10 CKCON |= 0x02; } else { while (1); // Error. Unsupported baud rate } TL1 = TH1; // Init Timer1 TMOD &= ~0xF0; // TMOD: timer 1 in 8-bit autoreload TMOD |= 0x20; TCON_TR1 = 1; // START Timer1 SCON0_TI = 1; // Indicate TX0 ready } //----------------------------------------------------------------------------- // Interrupt Service Routines //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Timer2_ISR //----------------------------------------------------------------------------- //usa overflow para verificar o ADC // //incrementa o proximo ADC a ser lido quando for ler 2 ou mais ADCS SI_INTERRUPT(Timer2_ISR, TIMER2_IRQn) { TMR2CN_TF2H = 0; //limpa interrupção do timer 2 //para 1 adc somente pode até desligar esse timer } //----------------------------------------------------------------------------- // ADC0_ISR //----------------------------------------------------------------------------- // // This ISR averages <INT_DEC> samples for each analog MUX input then prints // the results to the terminal. The ISR is called after each ADC conversion, // which is triggered by Timer2. // //----------------------------------------------------------------------------- SI_INTERRUPT(ADC0_ISR, ADC0EOC_IRQn) { ADC0CN_ADINT = 0; // Clear ADC conversion complete RESULT = ADC0; // Read the ADC value and add it to the // running total } //----------------------------------------------------------------------------- // Support Subroutines //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Timer0_Init //----------------------------------------------------------------------------- // // Return Value : None // Parameters : // 1) int16_t ms - number of milliseconds to wait // range is positive range of an int: 0 to 32767 // // This function configures the Timer0 as a 16-bit timer, interrupt enabled. // Using the internal osc. at 12MHz with a prescaler of 1:8 and reloading the // T0 registers with TIMER0_RELOAD_HIGH/LOW, it will wait for <ms> // milliseconds. // Note: The Timer0 uses a 1:12 prescaler //----------------------------------------------------------------------------- void delay_ms(int16_t ms) { TH0 = TIMER0_RELOAD_HIGH; // Init Timer0 High register TL0 = TIMER0_RELOAD_LOW ; // Init Timer0 Low register TMOD |= 0x01; // Timer0 in 16-bit mode CKCON &= 0xFC; // Timer0 uses a 1:12 prescaler TCON_TR0 = 1; // Timer0 ON while(ms) { TCON_TF0 = 0; // Clear flag to initialize while(!TCON_TF0); // Wait until timer overflows ms--; // Decrement ms } TCON_TR0 = 0; // Timer0 OFF } //----------------------------------------------------------------------------- // End Of File //-----------------------------------------------------------------------------
formatado por : http://hilite.me/ 01/09/2021.
Nenhum comentário :
Postar um comentário
olá,digite aqui seu comentário!