C: UART and CdS photocell

/**************************************
3/28/2019
ADC for CdS photocell and user input 
that provides
voltage readings via UART
***************************************/

/***************INCLUDES***************/
#include <avr/io.h>
#include <avr/interrupt.h>

/***********INITIALIZATIONS************/
int16_t result;
volatile  adc_conv_rdy = 0;
uint8_t  low_byte;
uint8_t  high_byte;

#define LETTER 0x41
#define ZERO 0x30
#define CR 0x0D
#define LF 0x0A
#define ONE 0x31
#define TWO 0X32

/************FUNCTIONS*****************/
void adc_init(void);
void tcc0_init(void);
void usartd0_init(void);
void usart_d0_out_char(char c);
void output_voltage(int16_t result);

/***************MAIN*******************/
int main(void){

tcc0_init();
adc_init();
usartd0_init();

PMIC.CTRL = PMIC_HILVLEN_bm; //enable
sei();

while(1){
if( adc_conv_rdy=1 ) { //check if ready
adc_conv_rdy=0;

usart_d0_out_char(low_byte);
usart_d0_out_char(high_byte);
}
}
}
/**************************************
This function initializes the ADC for
the CdS photocell on port A with port B
as ref
***************************************/
void adc_init(void){

PORTA.DIRCLR = PIN1_bm | PIN6_bm; //set dir for diff
PORTB.DIRCLR = PIN0_bm; //AREF in

ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc | ADC_CONMODE_bm; //signed, right adj., normal

ADCA.REFCTRL= ADC_REFSEL_AREFB_gc; //AREF = 2.5V

ADCA.CH0.CTRL=  ADC_CH_INPUTMODE_DIFFWGAIN_gc; //AID w gain
ADCA.CH0.MUXCTRL= ADC_CH_MUXPOS_PIN1_gc | ADC_CH_MUXNEG_PIN6_gc; //pos & neg
ADCA.CH0.INTCTRL = ADC_CH_INTMODE_COMPLETE_gc |  ADC_CH_INTLVL_HI_gc; //conversion complete, high

ADCA.EVCTRL= 0x01; //channel 0

ADCA.CTRLA |= ADC_ENABLE_bm; //enable
}
/**************************************
This function initializes tcc0 counter
Clock frequency = 2MHz duration = 0.005
prescalar = 256
***************************************/
void tcc0_init(void){

TCC0.CNT = 0;
TCC0.PER =(2000000 *(.005))/ 256; //P = (f*s)/prescalar
TCC0.CTRLA= TC_CLKSEL_DIV256_gc;

EVSYS_CH0MUX= EVSYS_CHMUX_TCC0_OVF_gc; //trigger
}
/**************************************
This function initializes the UART
baud rate = 115200Hz
word = 8 no parity stop bit = 1
***************************************/
void usartd0_init(void){

PORTD_DIRSET = PIN3_bm; //Tx output

USARTD0_CTRLB = USART_RXEN_bm | USART_TXEN_bm; //enables

USARTD0_CTRLC = USART_CMODE_ASYNCHRONOUS_gc |USART_PMODE_DISABLED_gc|
(0<<USART_SBMODE_bp)|USART_CHSIZE_8BIT_gc; //0 = 1stop, 1 = 2stop

USARTD0_BAUDCTRLA= 0x03; //BSEL = 3
USARTD0_BAUDCTRLB = 0xB0; //BSCALE = -5
}
/**************************************
This function outputs a char to PC
***************************************/
void usart_d0_out_char(char c){

uint8_t  status;

status = USARTD0.STATUS; //status

while ( (status&USART_DREIF_bm) != USART_DREIF_bm ){
status = USARTD0.STATUS; //polling
}

USARTD0.DATA= c; //write
}

/**************************************
This interrupt routine outputs
the low and high byte voltage
at 200Hz
***************************************/
ISR(ADCA_CH0_vect){

adc_conv_rdy=1;

result = ADCA_CH0_RES;

high_byte = (uint8_t)((result>>8) & 0xFF);
low_byte= (uint8_t)(result & 0xFF);
}
/**************************************
This interrupt routine switches between
CdS and user input
***************************************/
ISR(USARTD0_RXC_vect){

int8_t Variable;

Variable = USARTD0_DATA;

if ( Variable==ONE){ //CdS
ADCA.CH0.MUXCTRL= ADC_CH_MUXPOS_PIN1_gc | ADC_CH_MUXNEG_PIN6_gc;
}
else if( Variable==TWO){ //user input
ADCA.CH0.MUXCTRL= ADC_CH_MUXPOS_PIN4_gc | ADC_CH_MUXNEG_PIN5_gc;
}
else{ //do nothing
ADCA.CH0.MUXCTRL |= ADCA.CH0.MUXCTRL;
}
}

Comments

Popular posts from this blog

MATLAB: signal processing chorus with sample