⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adc.c

📁 MANTIS是由科罗拉多大学开发的传感器网络嵌入式操作系统。 这是mantis的0.9.5版本的源码。
💻 C
字号:
//  This file is part of MANTIS OS, Operating System//  See http://mantis.cs.colorado.edu/////  Copyright (C) 2003,2004,2005 University of Colorado, Boulder////  This program is free software; you can redistribute it and/or//  modify it under the terms of the mos license (see file LICENSE)#include "mos.h"#ifndef PLATFORM_LINUX#include "dev.h"#include "mutex.h"#include "sem.h"#include "adc.h"static mos_sem_t adc_sem;static uint8_t mode;mos_mutex_t adc_mutex;static uint8_t adc_channel;static uint16_t adc_val;#ifndef ARCH_AVRvoid adc_init(void){   }#else#ifdef ARCH_AVR#define adc_on() ADCSRA |= (1 << ADEN) | (1 << ADIE) | (1 << ADIF)#define adc_off() ADCSRA &= ~(1 << ADEN)#elif defined(PLATFORM_TELOSB)#define adc_on()    /* turn on reference generator */	\   ADC12CTL0 |= REF2_5V | REFON;			\   /* turn on ADC12 */					\   ADC12CTL0 |= ADC12ON;				\   /* enable conversion to take place */		\   /* ADC12CTL0 |= ENC; */#define adc_off()    /* turn off reference voltage */	\   /* ADC12CTL0 &= ~REFON; */				\   /* turn off adc core */	 			\   /* ADC12CTL0 &= ~ADC12ON; */#endifvoid adc_init(void){   //init adc state   mos_sem_init(&adc_sem, 0);   mos_mutex_init(&adc_mutex);   mode = DEV_MODE_OFF;   adc_off();   adc_channel = 1;   ADCSRA |= (1 << ADPS2) | (1 << ADPS1);}static void adc_set_channel(uint8_t ch){   adc_off();   ADMUX = ch /*| (1 << REFS0) | (1 << REFS1)*/; //set the channel   adc_channel = ch;   adc_on();}uint16_t adc_poll(uint8_t ch){   uint16_t ret_val;   if(mode == DEV_MODE_OFF)      adc_on();   if(ch != adc_channel)      adc_set_channel(ch);      ADCSRA &= ~(1 << ADIE); //disable the AD Interrupt   ADCSRA |= (1 << ADIF); //clear any old conversions...   ADCSRA |= (1 << ADEN) | (1 << ADSC); //turn on on and start conversion   //poll ADSC (clears once conversion is complete)   while (ADCSRA & (1 << ADSC))      ;   ret_val = ADCL;     ret_val |= (ADCH << 8);   if(ch != adc_channel)      adc_set_channel(adc_channel);      if(mode == DEV_MODE_OFF)      adc_off();      return ret_val;}uint16_t adc_read_channel16(uint8_t ch){   uint16_t retval;      //turn on if necessary   if(mode == DEV_MODE_OFF)      adc_on();      //set to appropriate channel   if(ch != adc_channel)      adc_set_channel(ch);      //start the conversion, enable interrupt    ADCSRA |= (1 << ADIF);   ADCSRA |= (1 << ADSC) | (1 << ADIE) | (1 << ADEN);      // Wait for the conversion interrupt handler to post the semaphore.   mos_sem_wait(&adc_sem);   retval = adc_val;      if(ch != adc_channel)      adc_set_channel(adc_channel);      if(mode == DEV_MODE_OFF)      adc_off();      return retval;}uint8_t adc_read_channel8(uint8_t ch){   return adc_read_channel16(ch) >> 2;}//TODO: add support for nonblocking, fast read for use by CSMA driver/*implement the dev layer interface*//*reading the adc gets the current value of the current channel (use ioctl  to change channels).  A 1-byte read returns an 8-bit conversion.  Any larger  read returns a 10-bit conversion, with the MSB first.*/uint16_t dev_read_DEV_ADC(void *buf, uint16_t count){   //copy into the provided buffer   if(count == 1) {      //write as a byte      ((uint8_t *)buf)[0] = adc_read_channel8(adc_channel);      count = 1;   } else {      //write as a 16-bit word      ((uint16_t *)buf)[0] = adc_read_channel16(adc_channel);      count = 2;   }   return count;}uint16_t dev_write_DEV_ADC(const void *buf, uint16_t count){   return DEV_UNSUPPORTED;}/*the adc turns on automatically and stays on.  Use the mode function  to turn it back off to save power.*///TODO: come up with a better way to handle ADC modesuint8_t dev_mode_DEV_ADC(uint8_t new_mode){   if(mode == new_mode)      return new_mode;      mode = new_mode;      switch(new_mode) {   case DEV_MODE_OFF:      adc_off();      break;   case DEV_MODE_IDLE:      break;   case DEV_MODE_ON:      adc_on();      break;   }   return new_mode;}/*this implements specific commands to the adc device*/uint8_t dev_ioctl_DEV_ADC(int8_t request, ...){   int arg;   va_list ap;      va_start(ap, request);      switch(request) {   case ADC_SET_CHANNEL:      // extract from varargs (must be at least 16 bits)      arg = va_arg(ap, int);      adc_channel = arg; //record channel setting      adc_set_channel(adc_channel);      break;   default:      return DEV_BAD_IOCTL;   }   va_end(ap);      return DEV_OK;}SIGNAL(SIG_ADC){   // grab the conversion value, low MUST be first   adc_val = ADCL;   adc_val |= (ADCH << 8);   mos_sem_post(&adc_sem);}#endif#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -