-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmcp3208.c
113 lines (103 loc) · 2.57 KB
/
mcp3208.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <avr/io.h>
#include <avr/interrupt.h>
#include "mcp3208.h"
#include "CAN-MFA.h"
#include <util/delay.h>
#if HAVE_MCP_ADC
#define SPI_PORT PORTE
#define SPI_DDR DDRE
#define SPI_PIN PINE
#define MOSI PE1
#define MISO PE0
#define SCK PE2
//#endif
//#if 1
void mcp3208_spi_delay(unsigned int NOPcount)
{
unsigned int n;
for(n=0;n<=NOPcount;n++)
{
asm volatile ("nop" ::);
}
}
//#endif
void mcp3208_spi_init(void)
{
//#if HAVE_MCP_ADC
// MOSI und CLK auf Ausgang setzen
SPI_DDR |= (1<<MOSI);
SPI_DDR |= (1<<SCK);
// MOSI und CLK auf HIGH setzen
SPI_PORT |= (1<<MOSI);
SPI_PORT |= (1<<SCK);
// MISO auf Eingang setzen
SPI_DDR &= ~(1<<MISO);
ADC_CS_DDR |= (1<<ADC_CS);
ADC_CS_PORT |= (1<<ADC_CS);
//#endif
}
uint8_t mcp3208_spi_write(char dataout)
{
//#if HAVE_MCP_ADC
uint8_t datain=0;
cli();
//das Byte wird Bitweise nacheinander Gesendet MSB zuerst
for (uint8_t a=8; a>0; a--){
datain<<=1; //Schieben um das Richtige Bit zusetzen
SPI_PORT &=~(1<<SCK); // Clock auf LOW
/*
asm volatile ("nop"::);
asm volatile ("nop"::);
asm volatile ("nop"::);
asm volatile ("nop"::);
*/
if (dataout & 0x80){ //Ist Bit a in Byte gesetzt
SPI_PORT |=(1<<MOSI); //Set Output High
}
else{
SPI_PORT &=~(1<<MOSI); //Set Output Low
}
//mcp3208_spi_delay(delayCount ); //_delay_us(2);
if (SPI_PIN & (1<<MISO)) //Lesen des Pegels
{
datain |= 1;
}else{
asm volatile ("nop"::);
}
/*
asm volatile ("nop"::);
asm volatile ("nop"::);
*/
//mcp3208_spi_delay(delayCount ); //_delay_us(2);
SPI_PORT |=(1<<SCK); // Clock auf High
//mcp3208_spi_delay( 2 * delayCount ); //_delay_us(4);
dataout<<=1; //Schiebe um nächstes Bit zusenden
}
sei();
return datain;
//#else
return 0;
//#endif
}
unsigned int mcp3208_spi_read(uint8_t type,uint8_t channel)
{
//#if HAVE_MCP_ADC
uint8_t tempHigh,tempLow,tempType,dummy;
ADC_CS_PORT &= ~(1<<(ADC_CS)); //setbitLow CS Pin
mcp3208_spi_delay(delayCount );
tempType = (type & 0x01) << 1 ;
tempLow = (channel & 0x03) << 6;
tempHigh = (channel & 0x04) >> 2;
tempHigh |= (0x04)|(tempType); // 0x04 --> startBit
dummy = mcp3208_spi_write(tempHigh); // Write control HighByte return not care
dummy = dummy;
tempHigh = mcp3208_spi_write(tempLow); // Write control LowByte return A/D-MSB data
tempLow = mcp3208_spi_write(0x00); // Write Null byte 0x00 return A/D-LSB data
//mcp3208_spi_delay(delayCount );
ADC_CS_PORT |= (1<<(ADC_CS)); //setbitHigh CS Pin
return (((tempHigh & 0x0F)<<8)|tempLow); // return 16bit variable (12bit A/D data)
//#else
return 0;
//#endif
}
#endif